Skip to content

Commit

Permalink
fix(dingz): refactor update handling
Browse files Browse the repository at this point in the history
- fetching of config updates is much more robust and centralized
- updated firmware versions are now picked up reliably
- dingz accessory constructor is simplified
- Work towards implementing [FIX] refactor dingz.updateAccessory #103
  • Loading branch information
johannrichard committed Nov 22, 2020
1 parent 155853d commit e69deb2
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 87 deletions.
168 changes: 82 additions & 86 deletions src/dingzAccessory.ts
Expand Up @@ -113,27 +113,6 @@ export class DingzDaAccessory extends EventEmitter {
this.dingzDeviceInfo = this.device.hwInfo as DingzDeviceInfo;
this.baseUrl = `http://${this.device.address}`;

this.setAccessoryInformation();

// Register listener for updated device info (e.g. on restore)
this.platform.eb.on(
DingzEvent.UPDATE_DEVICE_INFO,
(deviceInfo: DeviceInfo) => {
if (deviceInfo.mac === this.device.mac) {
this.platform.log.debug(
'Updated device info received -> update accessory',
);

// Persist updated info
this.device = deviceInfo;
this.accessory.context.device = deviceInfo;
this.dingzDeviceInfo = this.device.hwInfo as DingzDeviceInfo;
this.baseUrl = `http://${this.device.address}`;
this.setAccessoryInformation();
}
},
);

// Remove Reachability service if still present
const bridgingService: Service | undefined = this.accessory.getService(
this.platform.Service.BridgingState,
Expand All @@ -159,7 +138,7 @@ export class DingzDaAccessory extends EventEmitter {
address: this.device.address,
token: this.device.token,
})
.then(({ dingzDevices, systemConfig, inputConfig, dimmerConfig }) => {
.then(({ dingzDevices, inputConfig, dimmerConfig }) => {
if (
inputConfig?.inputs &&
dimmerConfig?.dimmers &&
Expand All @@ -168,81 +147,64 @@ export class DingzDaAccessory extends EventEmitter {
this.device.dingzInputInfo = inputConfig.inputs;
this.device.dimmerConfig = dimmerConfig;

if (dingzDevices[this.device.mac]) {
this.platform.log.debug(
'Updated device info received -> update accessory',
dingzDevices[this.device.mac],
);

// 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();

// Now we have what we need and can create the services …
this.addOutputServices();

this.platform.eb.on(
DingzEvent.REQUEST_STATE_UPDATE,
this.getDeviceStateUpdate.bind(this),
);
}
}) // FIXME: Don't chain this way, improve error handling
.then(() => {
/**
* Add auxiliary services (Motion, Temperature)
*/
if (this.dingzDeviceInfo.has_pir) {
// dingz has a Motion sensor -- let's create it
this.addMotionService();
} else {
this.platform.log.info(
'Your dingz',
this.accessory.displayName,
'has no Motion sensor.',
);
}
// dingz has a temperature sensor and an LED,
// make these available here
this.addTemperatureService();
this.addLEDService();
this.addLightSensorService();
this.addButtonServices();

this.services.forEach((service) => {
this.platform.log.info(
'Service created ->',
service.getCharacteristic(this.platform.Characteristic.Name).value,
);
});

// Only necessary for firmware version < 1.2.x
if (
this.dingzDeviceInfo.fw_version.indexOf('1.1.') === 0 ||
this.dingzDeviceInfo.fw_version.indexOf('1.0.') === 0
) {
this.platform.log.debug(
'Enable PIR callback for older firmware revisions',
);
this.enablePIRCallback();
}
this.getButtonCallbackUrl().then((callBackUrl) => {
if (!callBackUrl?.url.includes(this.platform.getCallbackUrl())) {
this.platform.log.warn(
'Update existing 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,
oldUrl: callBackUrl.url,
endpoints: endpoints,
});
/**
* Add auxiliary services (Motion, Temperature)
*/
if (this.dingzDeviceInfo.has_pir) {
// dingz has a Motion sensor -- let's create it
this.addMotionService();
} else {
this.platform.log.debug(
'Callback URL already set ->',
callBackUrl?.url,
this.platform.log.info(
'Your dingz',
this.accessory.displayName,
'has no Motion sensor.',
);
}
});
// dingz has a temperature sensor and an LED,
// make these available here
this.addTemperatureService();
this.addLEDService();
this.addLightSensorService();
this.addButtonServices();

this.services.forEach((service) => {
this.platform.log.info(
'Service created ->',
service.getCharacteristic(this.platform.Characteristic.Name)
.value,
);
});

// Retry at least once every day
retrySlow.execute(() => {
this.updateAccessory();
return true;
});
// Retry at least once every day
retrySlow.execute(() => {
this.updateAccessory();
return true;
});
}
})
.catch(this.handleFetchError.bind(this));
}
Expand Down Expand Up @@ -287,6 +249,40 @@ export class DingzDaAccessory extends EventEmitter {
);
}

private setButtonCallbacks() {
// Only necessary for firmware version < 1.2.x
if (
this.dingzDeviceInfo.fw_version.indexOf('1.1.') === 0 ||
this.dingzDeviceInfo.fw_version.indexOf('1.0.') === 0
) {
this.platform.log.debug(
'Enable PIR callback for older firmware revisions',
);
this.enablePIRCallback();
}

this.getButtonCallbackUrl().then((callBackUrl) => {
if (!callBackUrl?.url.includes(this.platform.getCallbackUrl())) {
this.platform.log.warn('Update existing 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,
oldUrl: callBackUrl.url,
endpoints: endpoints,
});
} else {
this.platform.log.debug(
'Callback URL already set ->',
callBackUrl?.url,
);
}
});
}

// Get updated device info and update the corresponding values
// TODO: #103, #116, #120, #123 -- fetch state for all device elements
private getDeviceStateUpdate() {
Expand Down
3 changes: 2 additions & 1 deletion src/platform.ts
Expand Up @@ -299,7 +299,6 @@ export class DingzDaHomebridgePlatform implements DynamicPlatformPlugin {
this.log.warn('Accessory already initialized');

// Update Names et al. from new device info
this.eb.emit(DingzEvent.UPDATE_DEVICE_INFO, deviceInfo);
this.accessories[uuid].identify();
return true;
}
Expand Down Expand Up @@ -953,6 +952,8 @@ export class DingzDaHomebridgePlatform implements DynamicPlatformPlugin {
token?: string;
endpoint?: 'api/v1/info' | 'info';
}): Promise<MyStromDeviceInfo> {
this.log.debug('Fetching myStrom Device Info:', address);

const deviceInfoUrl = `http://${address}/${endpoint}`;
return await DingzDaHomebridgePlatform.fetch({
url: deviceInfoUrl,
Expand Down

0 comments on commit e69deb2

Please sign in to comment.