Skip to content

Commit

Permalink
refactor(dingz): device discovery
Browse files Browse the repository at this point in the history
- Put device discovery back into the `dingz`
- Move to static discovery functions (`dingz`, `platform`)
- myStrom still need migration
- work [FIX] refactor dingz.updateAccessory #103
  • Loading branch information
johannrichard committed Nov 22, 2020
1 parent 7b55a0a commit d40ba1e
Show file tree
Hide file tree
Showing 7 changed files with 107 additions and 93 deletions.
105 changes: 77 additions & 28 deletions src/dingzAccessory.ts
Expand Up @@ -21,9 +21,11 @@ import {
DimmerState,
DimmerTimer,
DingzDeviceInfo,
DingzDimmerConfig,
DingzDevices,
DingzDeviceSystemConfig,
DingzDeviceDimmerConfig,
DingzDeviceInputConfig,
DingzDimmerConfigValue,
DingzInputConfig,
DingzInputInfoItem,
DingzLEDState,
DingzMotionData,
Expand Down Expand Up @@ -152,8 +154,11 @@ export class DingzDaAccessory extends EventEmitter {
);

// FIXME: Is there a better way to handle errors?
this.getConfigs()
.then(([inputConfig, dimmerConfig]) => {
DingzDaAccessory.getConfigs({
address: this.device.address,
token: this.device.token,
})
.then(({ dingzDevices, systemConfig, inputConfig, dimmerConfig }) => {
if (
inputConfig?.inputs &&
dimmerConfig?.dimmers &&
Expand Down Expand Up @@ -402,7 +407,7 @@ export class DingzDaAccessory extends EventEmitter {

const inputConfig: DingzInputInfoItem[] | undefined = this.device
.dingzInputInfo;
const dimmerConfig: DingzDimmerConfig | undefined = this.device
const dimmerConfig: DingzDeviceDimmerConfig | undefined = this.device
.dimmerConfig;

/** DIP Switch
Expand Down Expand Up @@ -1151,7 +1156,11 @@ export class DingzDaAccessory extends EventEmitter {
'-> Check for changed config.',
);

this.getConfigs().then(([inputConfig, dimmerConfig]) => {
// FIXME: [FIX] refactor dingz.updateAccessory #103
DingzDaAccessory.getConfigs({
address: this.device.address,
token: this.device.token,
}).then(({ inputConfig, dimmerConfig }) => {
if (inputConfig?.inputs[0]) {
this._updatedDeviceInputConfig = inputConfig.inputs[0];
}
Expand Down Expand Up @@ -1211,7 +1220,7 @@ export class DingzDaAccessory extends EventEmitter {
updatedDingzDeviceInfo.dip_config === 3)
) {
// Only add Dimmer 0 if we're not in "WindowCover" mode
const dimmerConfig: DingzDimmerConfig | undefined = this.device
const dimmerConfig: DingzDeviceDimmerConfig | undefined = this.device
.dimmerConfig;

this.platform.log.warn(
Expand Down Expand Up @@ -1436,12 +1445,13 @@ export class DingzDaAccessory extends EventEmitter {
* TODO: Refactor duplicate code into proper API caller
*/
private async getDingzDeviceInfo(): Promise<DingzDeviceInfo> {
const [dingzDevices] = await this.platform.getDingzDeviceInfo({
const dingzDevices = await DingzDaAccessory.getConfigs({
address: this.device.address,
token: this.device.token,
});
try {
const dingzDeviceInfo: DingzDeviceInfo = dingzDevices[this.device.mac];
const dingzDeviceInfo: DingzDeviceInfo =
dingzDevices.dingzDevices[this.device.mac];
if (dingzDeviceInfo) {
return dingzDeviceInfo;
}
Expand All @@ -1452,29 +1462,68 @@ export class DingzDaAccessory extends EventEmitter {
}

// Get Input & Dimmer Config
private async getConfigs(): Promise<[DingzInputConfig, DingzDimmerConfig]> {
const getInputConfigUrl = `${this.baseUrl}/api/v1/input_config`;
const getDimmerConfigUrl = `${this.baseUrl}/api/v1/dimmer_config`;

return Promise.all<DingzInputConfig, DingzDimmerConfig>([
this.platform.fetch({
url: getInputConfigUrl,
public static async getConfigs({
address,
token,
}: {
address: string;
token?: string;
}): Promise<{
dingzDevices: DingzDevices;
systemConfig: DingzDeviceSystemConfig;
inputConfig: DingzDeviceInputConfig;
dimmerConfig: DingzDeviceDimmerConfig;
}> {
const deviceInfoUrl = `http://${address}/api/v1/device`;
const deviceConfigUrl = `http://${address}/api/v1/system_config`;
const inputConfigUrl = `http://${address}/api/v1/input_config`;
const dimmerConfigUrl = `http://${address}/api/v1/dimmer_config`;

const [
dingzDevices,
systemConfig,
inputConfig,
dimmerConfig,
] = await Promise.all<
DingzDevices,
DingzDeviceSystemConfig,
DingzDeviceInputConfig,
DingzDeviceDimmerConfig
>([
DingzDaHomebridgePlatform.fetch({
url: deviceInfoUrl,
returnBody: true,
token: this.device.token,
token: token,
}),
this.platform.fetch({
url: getDimmerConfigUrl,
DingzDaHomebridgePlatform.fetch({
url: deviceConfigUrl,
returnBody: true,
token: this.device.token,
token: token,
}),
DingzDaHomebridgePlatform.fetch({
url: inputConfigUrl,
returnBody: true,
token: token,
}),
DingzDaHomebridgePlatform.fetch({
url: dimmerConfigUrl,
returnBody: true,
token: token,
}),
]);
return {
dingzDevices: dingzDevices,
systemConfig: systemConfig,
inputConfig: inputConfig,
dimmerConfig: dimmerConfig,
};
}

private async getDeviceMotion(): Promise<DingzMotionData> {
const getMotionUrl = `${this.baseUrl}/api/v1/motion`;
const release = await this.mutex.acquire();
try {
return await this.platform.fetch({
return await DingzDaHomebridgePlatform.fetch({
url: getMotionUrl,
returnBody: true,
token: this.device.token,
Expand All @@ -1494,7 +1543,7 @@ export class DingzDaAccessory extends EventEmitter {
const setDimmerUrl = `${this.baseUrl}/api/v1/dimmer/${index}/${
isOn ? 'on' : 'off'
}/${level ? '?value=' + level : ''}`;
await this.platform.fetch({
await DingzDaHomebridgePlatform.fetch({
url: setDimmerUrl,
method: 'POST',
token: this.device.token,
Expand All @@ -1514,7 +1563,7 @@ export class DingzDaAccessory extends EventEmitter {
// The API says the parameters can be omitted. This is not true
// {{ip}}/api/v1/shade/0?blind=<value>&lamella=<value>
const setWindowCoveringUrl = `${this.baseUrl}/api/v1/shade/${id}`;
await this.platform.fetch({
await DingzDaHomebridgePlatform.fetch({
url: setWindowCoveringUrl,
method: 'POST',
token: this.device.token,
Expand All @@ -1535,7 +1584,7 @@ export class DingzDaAccessory extends EventEmitter {
const getWindowCoveringUrl = `${this.baseUrl}/api/v1/shade/${id}`;
const release = await this.mutex.acquire();
try {
return await this.platform.fetch({
return await DingzDaHomebridgePlatform.fetch({
url: getWindowCoveringUrl,
returnBody: true,
token: this.device.token,
Expand All @@ -1554,7 +1603,7 @@ export class DingzDaAccessory extends EventEmitter {
color: string;
}): Promise<void> {
const setLEDUrl = `${this.baseUrl}/api/v1/led/set`;
await this.platform.fetch({
await DingzDaHomebridgePlatform.fetch({
url: setLEDUrl,
method: 'POST',
token: this.device.token,
Expand All @@ -1577,7 +1626,7 @@ export class DingzDaAccessory extends EventEmitter {
const getDeviceStateUrl = `${this.baseUrl}/api/v1/state`;
const release = await this.mutex.acquire();
try {
return await this.platform.fetch({
return await DingzDaHomebridgePlatform.fetch({
url: getDeviceStateUrl,
returnBody: true,
token: this.device.token,
Expand All @@ -1591,7 +1640,7 @@ export class DingzDaAccessory extends EventEmitter {
public async getButtonCallbackUrl(): Promise<AccessoryActionUrl> {
const getCallbackUrl = `${this.baseUrl}/api/v1/action/generic/generic`;
this.platform.log.debug('Getting the callback URL -> ', getCallbackUrl);
return await this.platform.fetch({
return await DingzDaHomebridgePlatform.fetch({
url: getCallbackUrl,
method: 'GET',
token: this.device.token,
Expand All @@ -1602,7 +1651,7 @@ export class DingzDaAccessory extends EventEmitter {
async enablePIRCallback() {
const setActionUrl = `${this.baseUrl}/api/v1/action/pir/press_release/enable`;
this.platform.log.debug('Enabling the PIR callback -> ');
await this.platform.fetch({
await DingzDaHomebridgePlatform.fetch({
url: setActionUrl,
method: 'POST',
token: this.device.token,
Expand Down
18 changes: 8 additions & 10 deletions src/myStromLightbulbAccessory.ts
Expand Up @@ -224,7 +224,7 @@ export class MyStromLightbulbAccessory {
}): Promise<void> {
// Weird URL :-)
const setDimmerUrl = `${this.baseUrl}/api/v1/device/${this.device.mac}`;
await this.platform.fetch({
await DingzDaHomebridgePlatform.fetch({
url: setDimmerUrl,
method: 'POST',
token: this.device.token,
Expand All @@ -241,14 +241,12 @@ export class MyStromLightbulbAccessory {

private async getDeviceReport(mac: string): Promise<MyStromLightbulbReport> {
const reportUrl = `${this.baseUrl}/api/v1/device/`;
return await this.platform
.fetch({
url: reportUrl,
returnBody: true,
token: this.device.token,
})
.then((response) => {
return response[mac];
});
return await DingzDaHomebridgePlatform.fetch({
url: reportUrl,
returnBody: true,
token: this.device.token,
}).then((response) => {
return response[mac];
});
}
}
2 changes: 1 addition & 1 deletion src/myStromPIRAccessory.ts
Expand Up @@ -265,7 +265,7 @@ export class MyStromPIRAccessory {
const getSensorsUrl = `${this.baseUrl}/api/v1/sensors`;
const release = await this.mutex.acquire();
try {
return await this.platform.fetch({
return await DingzDaHomebridgePlatform.fetch({
url: getSensorsUrl,
returnBody: true,
token: this.device.token,
Expand Down
4 changes: 2 additions & 2 deletions src/myStromSwitchAccessory.ts
Expand Up @@ -188,15 +188,15 @@ export class MyStromSwitchAccessory {

private setDeviceState(isOn: boolean) {
const relayUrl = `${this.baseUrl}/relay?state=${isOn ? '1' : '0'}`;
this.platform.fetch({
DingzDaHomebridgePlatform.fetch({
url: relayUrl,
token: this.device.token,
});
}

private async getDeviceReport(): Promise<MyStromSwitchReport> {
const reportUrl = `${this.baseUrl}/report`;
return await this.platform.fetch({
return await DingzDaHomebridgePlatform.fetch({
url: reportUrl,
returnBody: true,
token: this.device.token,
Expand Down
63 changes: 15 additions & 48 deletions src/platform.ts
Expand Up @@ -15,12 +15,7 @@ import e = require('express');
import * as os from 'os';

// Internal Types
import {
ButtonId,
DingzDevices,
DingzDeviceInfo,
DingzDeviceSystemConfig,
} from './util/dingzTypes';
import { ButtonId, DingzDeviceInfo } from './util/dingzTypes';
import { MyStromDeviceInfo, MyStromSwitchTypes } from './util/myStromTypes';

import {
Expand Down Expand Up @@ -247,8 +242,8 @@ export class DingzDaHomebridgePlatform implements DynamicPlatformPlugin {
// Run a diacovery of changed things every 10 seconds
this.log.debug(`Add configured device -> ${name} (${address})`);

const success = this.getDingzDeviceInfo({ address, token }).then(
([dingzDevices, dingzConfig]) => {
const success = DingzDaAccessory.getConfigs({ address, token }).then(
({ dingzDevices, systemConfig: dingzConfig }) => {
this.log.debug('Got Device ->', JSON.stringify(dingzDevices));
if (typeof dingzDevices !== 'undefined') {
const keys = Object.keys(dingzDevices);
Expand Down Expand Up @@ -869,7 +864,7 @@ export class DingzDaHomebridgePlatform implements DynamicPlatformPlugin {
this.log.debug('Setting the callback URL -> ', callbackUrl);
endpoints.forEach((endpoint) => {
this.log.debug(setActionUrl, 'Endpoint -> ', endpoint);
this.fetch({
DingzDaHomebridgePlatform.fetch({
url: `${setActionUrl}${endpoint}`,
method: 'POST',
token: token,
Expand Down Expand Up @@ -943,34 +938,6 @@ export class DingzDaHomebridgePlatform implements DynamicPlatformPlugin {
return `post://${hostname}:${port}/button`;
}

/**
* Device Methods -- these are used to retrieve the data from the dingz
* TODO: Refactor duplicate code into proper API caller
*/
async getDingzDeviceInfo({
address,
token,
}: {
address: string;
token?: string;
}): Promise<[DingzDevices, DingzDeviceSystemConfig]> {
const deviceInfoUrl = `http://${address}/api/v1/device`;
const deviceConfigUrl = `http://${address}/api/v1/system_config`;

return Promise.all<DingzDevices, DingzDeviceSystemConfig>([
this.fetch({
url: deviceInfoUrl,
returnBody: true,
token,
}),
this.fetch({
url: deviceConfigUrl,
returnBody: true,
token,
}),
]);
}

/**
* Device Methods -- these are used to retrieve the data from the dingz
* FIXME: API Endpoint
Expand All @@ -987,14 +954,14 @@ export class DingzDaHomebridgePlatform implements DynamicPlatformPlugin {
endpoint?: 'api/v1/info' | 'info';
}): Promise<MyStromDeviceInfo> {
const deviceInfoUrl = `http://${address}/${endpoint}`;
return await this.fetch({
return await DingzDaHomebridgePlatform.fetch({
url: deviceInfoUrl,
returnBody: true,
token,
});
}

async fetch({
static async fetch({
url,
method = 'get',
returnBody = false,
Expand All @@ -1016,15 +983,15 @@ export class DingzDaHomebridgePlatform implements DynamicPlatformPlugin {
Token: token ?? '',
},
data: body,
} as AxiosRequestConfig)
.then((response) => {
if (returnBody) {
return response.data;
} else {
return response.status;
}
})
.catch(this.handleError.bind(this));
} as AxiosRequestConfig).then((response) => {
if (returnBody) {
return response.data;
} else {
return response.status;
}
});
// FIXME: #103 Error handler at the wrong place
// .catch(this.handleError.bind(this));
return data;
}

Expand Down

0 comments on commit d40ba1e

Please sign in to comment.