diff --git a/src/dingzAccessory.ts b/src/dingzAccessory.ts index e30b2f4..6a4d0e5 100644 --- a/src/dingzAccessory.ts +++ b/src/dingzAccessory.ts @@ -119,50 +119,32 @@ export class DingzDaAccessory extends EventEmitter { ) { super(); - // Set Base URL + // Set base info this.device = this.accessory.context.device; this.dingzDeviceInfo = this.device.hwInfo as DingzDeviceInfo; this.baseUrl = `http://${this.device.address}`; - // Sanity check for "empty" SerialNumber - this.platform.log.debug( - `Attempting to set SerialNumber (which can not be empty) -> puck_sn: <${this.dingzDeviceInfo.puck_sn}>`, + this.setAccessoryInformation(); + + // Register listener for updated device info (e.g. on restore) + this.platform.eb.on( + DingzEvent.UPDATE_INFO, + (uuid: string, deviceInfo: DeviceInfo) => { + if (uuid === this.accessory.UUID) { + this.platform.log.debug( + 'Updated device info received -> update accessory', + ); + + // Persist updated info + this.accessory.context.device = deviceInfo; + this.device = deviceInfo; + this.dingzDeviceInfo = this.device.hwInfo as DingzDeviceInfo; + this.baseUrl = `http://${this.device.address}`; + this.setAccessoryInformation(); + } + }, ); - const serialNumber: string = - this.dingzDeviceInfo.puck_sn === '' - ? this.device.mac // MAC will always be defined for a correct device - : this.dingzDeviceInfo.puck_sn; - this.accessory - .getService(this.platform.Service.AccessoryInformation)! - .updateCharacteristic( - this.platform.Characteristic.ConfiguredName, - this.device.name, - ) - .updateCharacteristic(this.platform.Characteristic.Name, this.device.name) - .updateCharacteristic( - this.platform.Characteristic.Manufacturer, - 'iolo AG', - ) - .updateCharacteristic( - this.platform.Characteristic.AppMatchingIdentifier, - 'ch.iolo.dingz.consumer', - ) - .updateCharacteristic( - this.platform.Characteristic.Model, - this.device.model as string, - ) - .updateCharacteristic( - this.platform.Characteristic.FirmwareRevision, - this.dingzDeviceInfo.fw_version ?? 'Unknown', - ) - .updateCharacteristic( - this.platform.Characteristic.HardwareRevision, - this.dingzDeviceInfo.hw_version_puck ?? 'Unknown', - ) - .setCharacteristic( - this.platform.Characteristic.SerialNumber, - serialNumber, - ); + /**** * How to discover Accessories: * - Check for UDP Packets and/or use manually configured accessories @@ -200,6 +182,8 @@ export class DingzDaAccessory extends EventEmitter { this.dingzStates.Temperature = state.sensors.room_temperature; this.dingzStates.Brightness = state.sensors.brightness; this.platform.eb.emit(DingzEvent.STATE_UPDATE); + } else { + this.platform.log.error('Can`t get device state'); } }); }, 10000); @@ -241,7 +225,7 @@ export class DingzDaAccessory extends EventEmitter { this.platform.log.debug( 'Enable PIR callback for older firmware revisions', ); - this.enablePIRCallback(); + this.enablePIRCallback(); } this.getButtonCallbackUrl().then((callBackUrl) => { if (!callBackUrl?.url.includes(this.platform.getCallbackUrl())) { @@ -275,6 +259,46 @@ export class DingzDaAccessory extends EventEmitter { }); } + private setAccessoryInformation() { + // Sanity check for "empty" SerialNumber + this.platform.log.debug( + `Attempting to set SerialNumber (which can not be empty) -> puck_sn: <${this.dingzDeviceInfo.puck_sn}>`, + ); + const serialNumber: string = + this.dingzDeviceInfo.front_sn === '' + ? this.device.mac // MAC will always be defined for a correct device + : this.dingzDeviceInfo.front_sn; + this.accessory + .getService(this.platform.Service.AccessoryInformation)! + .setCharacteristic(this.platform.Characteristic.Manufacturer, 'iolo AG') + .setCharacteristic( + this.platform.Characteristic.AppMatchingIdentifier, + 'ch.iolo.dingz.consumer', + ) + // Update info from deviceInfo + .setCharacteristic( + this.platform.Characteristic.ConfiguredName, + this.device.name, + ) + .setCharacteristic(this.platform.Characteristic.Name, this.device.name) + .setCharacteristic( + this.platform.Characteristic.Model, + this.device.model as string, + ) + .setCharacteristic( + this.platform.Characteristic.FirmwareRevision, + this.dingzDeviceInfo.fw_version ?? 'Unknown', + ) + .setCharacteristic( + this.platform.Characteristic.HardwareRevision, + this.dingzDeviceInfo.hw_version_puck ?? 'Unknown', + ) + .setCharacteristic( + this.platform.Characteristic.SerialNumber, + serialNumber, + ); + } + private addTemperatureService() { const temperatureService: Service = this.accessory.getService(this.platform.Service.TemperatureSensor) ?? @@ -1116,6 +1140,7 @@ export class DingzDaAccessory extends EventEmitter { const updatedDingzDeviceInfo: DingzDeviceInfo = this._updatedDeviceInfo ?? currentDingzDeviceInfo; + // FIXME: Make this more error proof (if input is defined) const currentDingzInputInfo: DingzInputInfoItem = this.accessory.context .device.dingzInputInfo[0]; const updatedDingzInputInfo: DingzInputInfoItem = @@ -1125,7 +1150,6 @@ export class DingzDaAccessory extends EventEmitter { .dimmerConfig; try { - // FIXME: Crashes occasionally if ( currentDingzDeviceInfo && currentDingzDeviceInfo.has_pir !== updatedDingzDeviceInfo.has_pir diff --git a/src/platform.ts b/src/platform.ts index f9a9e8a..d1a9047 100644 --- a/src/platform.ts +++ b/src/platform.ts @@ -290,8 +290,8 @@ export class DingzDaHomebridgePlatform implements DynamicPlatformPlugin { } else { this.log.warn('Accessory already initialized'); - // FIXME: Update Names et al. - this.eb.emit(DingzEvent.UPDATE_INFO, this.accessories[uuid]); + // Update Names et al. from new device info + this.eb.emit(DingzEvent.UPDATE_INFO, uuid, deviceInfo); this.accessories[uuid].identify(); return true; } diff --git a/src/util/dingzEventBus.ts b/src/util/dingzEventBus.ts index bd61803..d96a79c 100644 --- a/src/util/dingzEventBus.ts +++ b/src/util/dingzEventBus.ts @@ -1,5 +1,5 @@ import { EventEmitter } from 'events'; -import { AccessoryType, ButtonAction } from './commonTypes'; +import { ButtonAction, DeviceInfo } from './commonTypes'; import { ButtonId } from './dingzTypes'; // Platform elements @@ -21,7 +21,7 @@ export declare interface DingzEventBus { ): this; on( event: DingzEvent.UPDATE_INFO, - listener: (accessory: AccessoryType) => void, + listener: (uuid: string, deviceInfo: DeviceInfo) => void, ): this; on(event: DingzEvent.STATE_UPDATE, listener: () => void): this; @@ -37,7 +37,11 @@ export declare interface DingzEventBus { action: ButtonAction, button: ButtonId, ): boolean; - emit(event: DingzEvent.UPDATE_INFO, accessory: AccessoryType): boolean; + emit( + event: DingzEvent.UPDATE_INFO, + uuid: string, + deviceInfo: DeviceInfo, + ): boolean; emit(event: DingzEvent.STATE_UPDATE): boolean; }