diff --git a/CHANGELOG.md b/CHANGELOG.md index eabb690..059d17e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,14 @@ # Changelog -## [∞](#release-notes) Release Notes +`v3.0.0` changes a lot under the hood but does not introduce many new features. Nevertheless, because a `release-please` has been introduced _and_ some changes are made which _might_ break your setup, the version number was bumped up. -### [∞](#breaking-v20) BREAKING v2.0 +Notable changes include: + +- **discovery of changed configurations**: both changes of teh dip switch as well as input _and_ output settings (e.g. `not_connected`) are automatically reflected in the exposed accessories. This means that you can change the configuration of the outputs both in hardware (`DIP` switch) or software (output configs) and it will be automatically reflected in the exposed accessories. +- **naming of (newly discovered) devices**: new devices added by auto-discovery will now more closely follow the native naming and use the type of device plus parts of the MAC address to create the name in HomeKit. +- **further fixes**: In rare cases, if your dingz did not have a proper name set in the UI, it wouldn't run. By catching this, the plugin has become more stable. + +## [∞](#breaking-v20) BREAKING v2.0 Version `v2.0` will _break_ your setup (but only if you use blinds). If you upgrade to this version and have a dingz with blinds configured, you will have to @@ -38,7 +44,7 @@ Besides these breaking changes, `v2.0.0` will also bring a few new features to y Overall over 60 changes have been implemented, and a lot of effort and time has been invested in making the plugin more robust (and logical). It still has some rough edges, though, and things might still break. -### [∞](#detailed-changes) Detailed Changes +# [∞](#detailed-changes) Detailed Changes ## [∞](#207-2020-12-04) 2.0.7 (2020-12-04) diff --git a/config.schema.json b/config.schema.json index e35ff79..95691f7 100644 --- a/config.schema.json +++ b/config.schema.json @@ -48,6 +48,11 @@ "type": "number", "description": "In order to implement button actions, the dingz plugin exposes a webserver for callbacks. By default, it listens on port 18081. Add this setting if you want to change this." }, + "callbackOverride": { + "title": "Override generic callbacks", + "type": "boolean", + "description": "If set, actions will be overriden, that is, existing action URLs (for the 'generic' endpoint) will be replaced by an action to this server only. Useful for testing and/or resetting your devices if you homebridge server's address changes." + }, "devices": { "title": "dingz Devices", "type": "array", diff --git a/src/dingzAccessory.ts b/src/dingzAccessory.ts index 3669710..0e4a81d 100644 --- a/src/dingzAccessory.ts +++ b/src/dingzAccessory.ts @@ -138,12 +138,17 @@ export class DingzAccessory extends DingzDaBaseAccessory { dingzDevices[this.device.mac], ); + const dip_config = dingzDevices[this.device.mac].dip_config; + if (this.dingzDeviceInfo.dip_config !== dip_config) { + // DIP config has changes, invalidate config + this.device.configTimestamp = undefined; + } + // Persist updated info this.device.hwInfo = dingzDevices[this.device.mac]; this.accessory.context.device = this.device; this.dingzDeviceInfo = this.device.hwInfo as DingzDeviceInfo; this.baseUrl = `http://${this.device.address}`; - this.setAccessoryInformation(); } this.setAccessoryInformation(); this.setButtonCallbacks(); @@ -248,7 +253,18 @@ export class DingzAccessory extends DingzDaBaseAccessory { this.getButtonCallbackUrl() .then((callBackUrl) => { - if (!callBackUrl?.url.includes(this.platform.getCallbackUrl())) { + if (this.platform.config.callbackOverride) { + this.log.warn('Override callback URL ->', callBackUrl); + // Set the callback URL (Override!) + const endpoints = this.dingzDeviceInfo.has_pir + ? ['generic', 'pir/single'] + : ['generic']; + this.platform.setButtonCallbackUrl({ + baseUrl: this.baseUrl, + token: this.device.token, + endpoints: endpoints, + }); + } else if (!callBackUrl?.url.includes(this.platform.getCallbackUrl())) { this.log.warn('Update existing callback URL ->', callBackUrl); // Set the callback URL (Override!) const endpoints = this.dingzDeviceInfo.has_pir @@ -475,7 +491,7 @@ export class DingzAccessory extends DingzDaBaseAccessory { this.log.debug('Motion Update from CALLBACK'); this.motionService ?.getCharacteristic(this.platform.Characteristic.MotionDetected) - .updateValue( + .setValue( action === ButtonAction.PIR_MOTION_START ? true : false, ); } @@ -500,26 +516,26 @@ export class DingzAccessory extends DingzDaBaseAccessory { `Button ${button} (${service?.displayName}) pressed -> ${action}`, ); - // Immediately update states after button pressed - this.getDeviceStateUpdate(); - switch (action) { case ButtonAction.SINGLE_PRESS: service ?.getCharacteristic(ProgrammableSwitchEvent) - .updateValue(ProgrammableSwitchEvent.SINGLE_PRESS); + .setValue(ProgrammableSwitchEvent.SINGLE_PRESS); break; case ButtonAction.DOUBLE_PRESS: service ?.getCharacteristic(ProgrammableSwitchEvent) - .updateValue(ProgrammableSwitchEvent.DOUBLE_PRESS); + .setValue(ProgrammableSwitchEvent.DOUBLE_PRESS); break; case ButtonAction.LONG_PRESS: service ?.getCharacteristic(ProgrammableSwitchEvent) - .updateValue(ProgrammableSwitchEvent.LONG_PRESS); + .setValue(ProgrammableSwitchEvent.LONG_PRESS); break; } + + // Immediately update states after button pressed + this.getDeviceStateUpdate(); } } }, @@ -536,10 +552,14 @@ export class DingzAccessory extends DingzDaBaseAccessory { ) ?? this.accessory.addService( this.platform.Service.StatelessProgrammableSwitch, - name ?? `dingz Button ${button}`, // Name Dimmers according to WebUI, not API info + name ?? `Button ${button}`, // Name Dimmers according to WebUI, not API info button, ); + buttonService.setCharacteristic( + this.platform.Characteristic.Name, + name ?? `Button ${button}`, + ); buttonService.setCharacteristic( this.platform.Characteristic.ServiceLabelIndex, button, @@ -1052,7 +1072,7 @@ export class DingzAccessory extends DingzDaBaseAccessory { address: this.device.address, token: this.device.token, }) - .then(({ dingzDevices, dimmerConfig, blindConfig }) => { + .then(({ dingzDevices, inputConfig, dimmerConfig, blindConfig }) => { if (this.reachabilityState !== null) { this.log.warn('Device recovered from unreachable state'); this.reachabilityState = null; @@ -1079,7 +1099,8 @@ export class DingzAccessory extends DingzDaBaseAccessory { this.removeMotionService(); } } - // Update dimmer services + // Update output, blind, input services + this.device.dingzInputInfo = inputConfig.inputs; this.device.dimmerConfig = dimmerConfig; this.device.windowCoveringConfig = blindConfig.blinds; diff --git a/src/myStromButtonAccessory.ts b/src/myStromButtonAccessory.ts index ab4de63..d7f930f 100644 --- a/src/myStromButtonAccessory.ts +++ b/src/myStromButtonAccessory.ts @@ -99,10 +99,6 @@ export class MyStromButtonAccessory extends DingzDaBaseAccessory { this.platform.Characteristic.ProgrammableSwitchOutputState, ) .on(CharacteristicEventTypes.GET, this.getButtonState.bind(this)); - // .on( - // CharacteristicEventTypes.SET, - // this.setSwitchButtonState.bind(this, button), - // ); const batteryService: Service = this.accessory.getService(this.platform.Service.BatteryService) ?? diff --git a/src/myStromPIRAccessory.ts b/src/myStromPIRAccessory.ts index 36c83cc..81473b1 100644 --- a/src/myStromPIRAccessory.ts +++ b/src/myStromPIRAccessory.ts @@ -152,7 +152,17 @@ export class MyStromPIRAccessory extends DingzDaBaseAccessory { retrySlow.execute(() => { this.getButtonCallbackUrl() .then((callBackUrl) => { - if (!callBackUrl?.url.includes(this.platform.getCallbackUrl())) { + if (this.platform.config.callbackOverride) { + this.log.warn('Override callback URL ->', callBackUrl); + // Set the callback URL (Override!) + this.platform.setButtonCallbackUrl({ + baseUrl: this.baseUrl, + token: this.device.token, + endpoints: ['pir/generic'], + }); + } else if ( + !callBackUrl?.url.includes(this.platform.getCallbackUrl()) + ) { this.log.warn('Update existing callback URL ->', callBackUrl); // Set the callback URL (Override!) this.platform.setButtonCallbackUrl({