@switchbot/homebridge-switchbot 0.1.2-beta.7 → 0.2.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (106) hide show
  1. package/.github/ISSUE_TEMPLATE/feature-request.yml +1 -1
  2. package/.github/dependabot.yml +2 -0
  3. package/.github/workflows/codeql-analysis.yml +71 -0
  4. package/CHANGELOG.md +5 -1
  5. package/README.md +2 -1
  6. package/config.schema.json +420 -471
  7. package/dist/devices/bots.d.ts +19 -5
  8. package/dist/devices/bots.d.ts.map +1 -1
  9. package/dist/devices/bots.js +172 -148
  10. package/dist/devices/bots.js.map +1 -1
  11. package/dist/devices/bulb.d.ts +8 -6
  12. package/dist/devices/bulb.d.ts.map +1 -1
  13. package/dist/devices/bulb.js +45 -28
  14. package/dist/devices/bulb.js.map +1 -1
  15. package/dist/devices/contact.d.ts +10 -5
  16. package/dist/devices/contact.d.ts.map +1 -1
  17. package/dist/devices/contact.js +94 -63
  18. package/dist/devices/contact.js.map +1 -1
  19. package/dist/devices/curtains.d.ts +14 -5
  20. package/dist/devices/curtains.d.ts.map +1 -1
  21. package/dist/devices/curtains.js +174 -120
  22. package/dist/devices/curtains.js.map +1 -1
  23. package/dist/devices/humidifiers.d.ts +6 -6
  24. package/dist/devices/humidifiers.d.ts.map +1 -1
  25. package/dist/devices/humidifiers.js +78 -94
  26. package/dist/devices/humidifiers.js.map +1 -1
  27. package/dist/devices/indoorcam.d.ts +43 -0
  28. package/dist/devices/indoorcam.d.ts.map +1 -0
  29. package/dist/devices/indoorcam.js +241 -0
  30. package/dist/devices/indoorcam.js.map +1 -0
  31. package/dist/devices/meters.d.ts +8 -5
  32. package/dist/devices/meters.d.ts.map +1 -1
  33. package/dist/devices/meters.js +126 -92
  34. package/dist/devices/meters.js.map +1 -1
  35. package/dist/devices/motion.d.ts +9 -5
  36. package/dist/devices/motion.d.ts.map +1 -1
  37. package/dist/devices/motion.js +74 -59
  38. package/dist/devices/motion.js.map +1 -1
  39. package/dist/devices/plugs.d.ts +5 -4
  40. package/dist/devices/plugs.d.ts.map +1 -1
  41. package/dist/devices/plugs.js +65 -56
  42. package/dist/devices/plugs.js.map +1 -1
  43. package/dist/irdevices/airconditioners.d.ts +3 -3
  44. package/dist/irdevices/airconditioners.d.ts.map +1 -1
  45. package/dist/irdevices/airconditioners.js +12 -7
  46. package/dist/irdevices/airconditioners.js.map +1 -1
  47. package/dist/irdevices/airpurifiers.d.ts +3 -3
  48. package/dist/irdevices/airpurifiers.d.ts.map +1 -1
  49. package/dist/irdevices/airpurifiers.js +1 -1
  50. package/dist/irdevices/airpurifiers.js.map +1 -1
  51. package/dist/irdevices/cameras.d.ts +3 -3
  52. package/dist/irdevices/cameras.d.ts.map +1 -1
  53. package/dist/irdevices/cameras.js +1 -1
  54. package/dist/irdevices/cameras.js.map +1 -1
  55. package/dist/irdevices/fans.d.ts +3 -3
  56. package/dist/irdevices/fans.d.ts.map +1 -1
  57. package/dist/irdevices/fans.js +11 -12
  58. package/dist/irdevices/fans.js.map +1 -1
  59. package/dist/irdevices/lights.d.ts +3 -3
  60. package/dist/irdevices/lights.d.ts.map +1 -1
  61. package/dist/irdevices/lights.js +1 -1
  62. package/dist/irdevices/lights.js.map +1 -1
  63. package/dist/irdevices/others.d.ts +3 -3
  64. package/dist/irdevices/others.d.ts.map +1 -1
  65. package/dist/irdevices/others.js +8 -8
  66. package/dist/irdevices/others.js.map +1 -1
  67. package/dist/irdevices/tvs.d.ts +3 -3
  68. package/dist/irdevices/tvs.d.ts.map +1 -1
  69. package/dist/irdevices/tvs.js +16 -6
  70. package/dist/irdevices/tvs.js.map +1 -1
  71. package/dist/irdevices/vacuumcleaners.d.ts +3 -3
  72. package/dist/irdevices/vacuumcleaners.d.ts.map +1 -1
  73. package/dist/irdevices/vacuumcleaners.js +2 -3
  74. package/dist/irdevices/vacuumcleaners.js.map +1 -1
  75. package/dist/irdevices/waterheaters.d.ts +3 -3
  76. package/dist/irdevices/waterheaters.d.ts.map +1 -1
  77. package/dist/irdevices/waterheaters.js +2 -2
  78. package/dist/irdevices/waterheaters.js.map +1 -1
  79. package/dist/platform.d.ts +14 -5
  80. package/dist/platform.d.ts.map +1 -1
  81. package/dist/platform.js +420 -418
  82. package/dist/platform.js.map +1 -1
  83. package/dist/settings.d.ts +18 -15
  84. package/dist/settings.d.ts.map +1 -1
  85. package/package.json +65 -65
  86. package/src/devices/bots.ts +188 -165
  87. package/src/devices/bulb.ts +48 -40
  88. package/src/devices/contact.ts +100 -73
  89. package/src/devices/curtains.ts +192 -140
  90. package/src/devices/humidifiers.ts +82 -124
  91. package/src/devices/indoorcam.ts +303 -0
  92. package/src/devices/meters.ts +130 -110
  93. package/src/devices/motion.ts +80 -69
  94. package/src/devices/plugs.ts +67 -65
  95. package/src/irdevices/airconditioners.ts +14 -10
  96. package/src/irdevices/airpurifiers.ts +4 -4
  97. package/src/irdevices/cameras.ts +4 -4
  98. package/src/irdevices/fans.ts +14 -18
  99. package/src/irdevices/lights.ts +4 -4
  100. package/src/irdevices/others.ts +12 -14
  101. package/src/irdevices/tvs.ts +21 -10
  102. package/src/irdevices/vacuumcleaners.ts +5 -9
  103. package/src/irdevices/waterheaters.ts +5 -5
  104. package/src/platform.ts +455 -619
  105. package/src/settings.ts +19 -15
  106. package/.github/workflows/issue-validate.yml +0 -18
@@ -2,7 +2,7 @@ import { Service, PlatformAccessory, Units, CharacteristicValue, MacAddress } fr
2
2
  import { SwitchBotPlatform } from '../platform';
3
3
  import { interval, Subject } from 'rxjs';
4
4
  import { skipWhile } from 'rxjs/operators';
5
- import { DeviceURL, device, deviceStatusResponse } from '../settings';
5
+ import { DeviceURL, device, devicesConfig } from '../settings';
6
6
 
7
7
  /**
8
8
  * Platform Accessory
@@ -25,7 +25,7 @@ export class Meter {
25
25
  WaterLevel!: CharacteristicValue;
26
26
 
27
27
  // Others
28
- deviceStatus!: deviceStatusResponse;
28
+ deviceStatus!: any;
29
29
  BLEtemperature!: number;
30
30
  BLEHumidity!: number;
31
31
  switchbot!: {
@@ -50,7 +50,7 @@ export class Meter {
50
50
  constructor(
51
51
  private readonly platform: SwitchBotPlatform,
52
52
  private accessory: PlatformAccessory,
53
- public device: device,
53
+ public device: device & devicesConfig,
54
54
  ) {
55
55
  // default placeholders
56
56
  this.BatteryLevel = 0;
@@ -58,16 +58,16 @@ export class Meter {
58
58
  this.StatusLowBattery = this.platform.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW;
59
59
  this.CurrentRelativeHumidity = 0;
60
60
  this.CurrentTemperature = 0;
61
- if (this.platform.config.options?.ble?.includes(this.device.deviceId!)) {
61
+
62
+ // BLE Connection
63
+ if (device.ble) {
62
64
  // eslint-disable-next-line @typescript-eslint/no-var-requires
63
65
  const SwitchBot = require('node-switchbot');
64
66
  this.switchbot = new SwitchBot();
65
67
  const colon = device.deviceId!.match(/.{1,2}/g);
66
68
  const bleMac = colon!.join(':'); //returns 1A:23:B4:56:78:9A;
67
69
  this.device.bleMac = bleMac.toLowerCase();
68
- if (this.platform.config.options.debug) {
69
- this.platform.log.warn(this.device.bleMac.toLowerCase());
70
- }
70
+ this.platform.device(this.device.bleMac.toLowerCase());
71
71
  }
72
72
 
73
73
  // this is subject we use to track when we need to POST changes to the SwitchBot API
@@ -88,7 +88,7 @@ export class Meter {
88
88
  // you can create multiple services for each accessory
89
89
  (this.service =
90
90
  accessory.getService(this.platform.Service.Battery) ||
91
- accessory.addService(this.platform.Service.Battery)), `${device.deviceName} ${device.deviceType}`;
91
+ accessory.addService(this.platform.Service.Battery)), `${accessory.displayName} Battery`;
92
92
 
93
93
  // To avoid "Cannot add a Service with the same UUID another Service without also defining a unique 'subtype' property." error,
94
94
  // when creating multiple services of the same type, you need to use the following syntax to specify a name and subtype id:
@@ -105,19 +105,17 @@ export class Meter {
105
105
  this.service.setCharacteristic(this.platform.Characteristic.ChargingState, 2);
106
106
 
107
107
  // Temperature Sensor Service
108
- if (this.platform.config.options?.meter?.hide_temperature) {
109
- if (this.platform.config.options.debug) {
110
- this.platform.log.error('Removing service');
111
- }
108
+ if (device.meter?.hide_temperature) {
109
+ this.platform.device('Removing Temperature Sensor Service');
112
110
  this.temperatureservice = this.accessory.getService(this.platform.Service.TemperatureSensor);
113
111
  accessory.removeService(this.temperatureservice!);
114
112
  } else if (!this.temperatureservice) {
115
- if (this.platform.config.options?.debug) {
116
- this.platform.log.warn('Adding service');
117
- }
113
+ this.platform.device('Adding Temperature Sensor Service');
118
114
  (this.temperatureservice =
119
115
  this.accessory.getService(this.platform.Service.TemperatureSensor) ||
120
- this.accessory.addService(this.platform.Service.TemperatureSensor)), `${device.deviceName} ${device.deviceType} TemperatureSensor`;
116
+ this.accessory.addService(this.platform.Service.TemperatureSensor)), `${accessory.displayName} Temperature Sensor`;
117
+
118
+ this.service.setCharacteristic(this.platform.Characteristic.Name, `${accessory.displayName} Temperature Sensor`);
121
119
 
122
120
  this.temperatureservice
123
121
  .getCharacteristic(this.platform.Characteristic.CurrentTemperature)
@@ -129,26 +127,24 @@ export class Meter {
129
127
  minStep: 0.1,
130
128
  })
131
129
  .onGet(() => {
132
- return this.CurrentTemperature;
130
+ return Number.isNaN(this.CurrentTemperature);
133
131
  });
134
- this.platform.log.info(this.device.deviceName + ' current temperature: ' + this.CurrentTemperature + '\u2103');
135
132
  } else {
136
- if (this.platform.config.options?.debug) {
137
- this.platform.log.warn('TemperatureSensor not added.');
138
- }
133
+ this.platform.device('Temperature Sensor Not Added');
139
134
  }
140
135
 
141
136
  // Humidity Sensor Service
142
- if (this.platform.config.options?.meter?.hide_humidity) {
143
- if (this.platform.config.options.debug) {
144
- this.platform.log.error('Removing service');
145
- }
137
+ if (device.meter?.hide_humidity) {
138
+ this.platform.device('Removing Humidity Sensor Service');
146
139
  this.humidityservice = this.accessory.getService(this.platform.Service.HumiditySensor);
147
140
  accessory.removeService(this.humidityservice!);
148
141
  } else if (!this.humidityservice) {
142
+ this.platform.device('Adding Humidity Sensor Service');
149
143
  (this.humidityservice =
150
144
  this.accessory.getService(this.platform.Service.HumiditySensor) ||
151
- this.accessory.addService(this.platform.Service.HumiditySensor)), `${device.deviceName} ${device.deviceType} HumiditySensor`;
145
+ this.accessory.addService(this.platform.Service.HumiditySensor)), `${accessory.displayName} Humidity Sensor`;
146
+
147
+ this.service.setCharacteristic(this.platform.Characteristic.Name, `${accessory.displayName} Humidity Sensor`);
152
148
 
153
149
  this.humidityservice
154
150
  .getCharacteristic(this.platform.Characteristic.CurrentRelativeHumidity)
@@ -158,11 +154,8 @@ export class Meter {
158
154
  .onGet(() => {
159
155
  return this.CurrentRelativeHumidity;
160
156
  });
161
- this.platform.log.info(this.device.deviceName + ' current humidity: ' + this.CurrentRelativeHumidity + '%');
162
157
  } else {
163
- if (this.platform.config.options?.debug) {
164
- this.platform.log.warn('HumiditySensor not added.');
165
- }
158
+ this.platform.device('Adding Humidity Sensor Not Added');
166
159
  }
167
160
 
168
161
  // Retrieve initial values and updateHomekit
@@ -179,8 +172,32 @@ export class Meter {
179
172
  /**
180
173
  * Parse the device status from the SwitchBot api
181
174
  */
182
- parseStatus() {
183
- // Set Room Sensor State
175
+ async parseStatus() {
176
+ if (this.device.ble) {
177
+ this.platform.device('BLE');
178
+ await this.BLEparseStatus();
179
+ } else {
180
+ this.platform.device('OpenAPI');
181
+ await this.openAPIparseStatus();
182
+ }
183
+ }
184
+
185
+ private async BLEparseStatus() {
186
+ if (this.deviceStatus.body) {
187
+ this.BatteryLevel = 100;
188
+ } else {
189
+ this.BatteryLevel = 10;
190
+ }
191
+ if (this.BatteryLevel < 15) {
192
+ this.StatusLowBattery = 1;
193
+ } else {
194
+ this.StatusLowBattery = 0;
195
+ }
196
+ this.platform.debug(`${this.accessory.displayName}
197
+ , BatteryLevel: ${this.BatteryLevel}, StatusLowBattery: ${this.StatusLowBattery}`);
198
+ }
199
+
200
+ private async openAPIparseStatus() {
184
201
  if (this.deviceStatus.body) {
185
202
  this.BatteryLevel = 100;
186
203
  } else {
@@ -192,8 +209,8 @@ export class Meter {
192
209
  this.StatusLowBattery = 0;
193
210
  }
194
211
  // Current Relative Humidity
195
- if (!this.platform.config.options?.meter?.hide_humidity) {
196
- if (this.platform.config.options?.ble?.includes(this.device.deviceId!)) {
212
+ if (!this.device.meter?.hide_humidity) {
213
+ if (this.device.ble) {
197
214
  this.CurrentRelativeHumidity = this.BLEHumidity;
198
215
  } else {
199
216
  this.CurrentRelativeHumidity = this.deviceStatus.body.humidity!;
@@ -202,16 +219,16 @@ export class Meter {
202
219
  }
203
220
 
204
221
  // Current Temperature
205
- if (!this.platform.config.options?.meter?.hide_temperature) {
206
- if (this.platform.config.options?.ble?.includes(this.device.deviceId!)) {
222
+ if (!this.device.meter?.hide_temperature) {
223
+ if (this.device.ble) {
207
224
  this.CurrentTemperature = this.BLEtemperature;
208
225
  } else {
209
- if (this.platform.config.options?.meter?.unit === 1) {
226
+ if (this.device.meter?.unit === 1) {
210
227
  this.CurrentTemperature = this.toFahrenheit(this.deviceStatus.body.temperature!);
211
- } else if (this.platform.config.options?.meter?.unit === 0) {
228
+ } else if (this.device.meter?.unit === 0) {
212
229
  this.CurrentTemperature = this.toCelsius(this.deviceStatus.body.temperature!);
213
230
  } else {
214
- this.CurrentTemperature = this.deviceStatus.body.temperature!;
231
+ this.CurrentTemperature = this.deviceStatus.body.temperature;
215
232
  }
216
233
  }
217
234
  this.platform.debug(`Meter ${this.accessory.displayName} - Temperature: ${this.CurrentTemperature}°c`);
@@ -222,81 +239,78 @@ export class Meter {
222
239
  * Asks the SwitchBot API for the latest device information
223
240
  */
224
241
  async refreshStatus() {
225
- if (this.platform.config.options?.ble?.includes(this.device.deviceId!)) {
226
- this.platform.log.warn('BLE DEVICE-REFRESH');
227
- // eslint-disable-next-line @typescript-eslint/no-var-requires
228
- const Switchbot = require('node-switchbot');
229
- const switchbot = new Switchbot();
230
- const colon = this.device.deviceId!.match(/.{1,2}/g);
231
- const bleMac = colon!.join(':'); //returns 1A:23:B4:56:78:9A;
232
- this.device.bleMac = bleMac.toLowerCase();
233
- if (this.platform.config.options.debug) {
234
- this.platform.log.warn(this.device.bleMac!);
235
- }
236
- switchbot.onadvertisement = (ad: any) => {
237
- this.platform.log.info(JSON.stringify(ad, null, ' '));
238
- this.platform.log.warn('ad:', JSON.stringify(ad));
239
- this.platform.log.info('Temperature:', ad.serviceData.temperature.c);
240
- this.platform.log.info('Humidity:', ad.serviceData.humidity);
241
- this.BLEtemperature = ad.serviceData.temperature.c;
242
- this.BLEHumidity = ad.serviceData.humidity;
243
- };
242
+ if (this.device.ble) {
243
+ this.platform.device('BLE');
244
+ await this.BLErefreshStatus();
245
+ } else {
246
+ this.platform.device('OpenAPI');
247
+ await this.openAPIRefreshStatus();
248
+ }
249
+ }
250
+
251
+ private async BLErefreshStatus() {
252
+ this.platform.debug('Meter BLE Device RefreshStatus');
253
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
254
+ const Switchbot = require('node-switchbot');
255
+ const switchbot = new Switchbot();
256
+ const colon = this.device.deviceId!.match(/.{1,2}/g);
257
+ const bleMac = colon!.join(':'); //returns 1A:23:B4:56:78:9A;
258
+ this.device.bleMac = bleMac.toLowerCase();
259
+ this.platform.device(this.device.bleMac!);
260
+ switchbot.onadvertisement = (ad: any) => {
261
+ this.platform.debug(JSON.stringify(ad, null, ' '));
262
+ this.platform.device('ad:', JSON.stringify(ad));
263
+ this.platform.device(`Temperature: ${ad.serviceData.temperature.c}`);
264
+ this.platform.device(`Humidity: ${ad.serviceData.humidity}`);
265
+ this.BLEtemperature = ad.serviceData.temperature.c;
266
+ this.BLEHumidity = ad.serviceData.humidity;
267
+ };
268
+ this.parseStatus();
269
+ this.updateHomeKitCharacteristics();
270
+ switchbot
271
+ .startScan({
272
+ id: this.device.bleMac,
273
+ })
274
+ .then(() => {
275
+ return switchbot.wait(this.platform.config.options!.refreshRate! * 1000);
276
+ })
277
+ .then(() => {
278
+ switchbot.stopScan();
279
+ })
280
+ .catch(async (error: any) => {
281
+ this.platform.log.error(error);
282
+ await this.openAPIRefreshStatus();
283
+ });
284
+ setInterval(() => {
285
+ this.platform.log.info('Start scan ' + this.device.deviceName + '(' + this.device.bleMac + ')');
244
286
  switchbot
245
287
  .startScan({
246
- id: this.device.bleMac,
288
+ mode: 'T',
289
+ id: bleMac,
247
290
  })
248
291
  .then(() => {
249
292
  return switchbot.wait(this.platform.config.options!.refreshRate! * 1000);
250
293
  })
251
294
  .then(() => {
252
295
  switchbot.stopScan();
296
+ this.platform.log.info('Stop scan ' + this.device.deviceName + '(' + this.device.bleMac + ')');
253
297
  })
254
298
  .catch(async (error: any) => {
255
299
  this.platform.log.error(error);
256
300
  await this.openAPIRefreshStatus();
257
301
  });
258
- setInterval(() => {
259
- this.platform.log.info('Start scan ' + this.device.deviceName + '(' + this.device.bleMac + ')');
260
- switchbot
261
- .startScan({
262
- mode: 'T',
263
- id: bleMac,
264
- })
265
- .then(() => {
266
- return switchbot.wait(this.platform.config.options!.refreshRate! * 1000);
267
- })
268
- .then(() => {
269
- switchbot.stopScan();
270
- this.platform.log.info('Stop scan ' + this.device.deviceName + '(' + this.device.bleMac + ')');
271
- })
272
- .catch(async (error: any) => {
273
- this.platform.log.error(error);
274
- await this.openAPIRefreshStatus();
275
- });
276
- }, this.platform.config.options!.refreshRate! * 60000);
277
- } else {
278
- await this.openAPIRefreshStatus();
279
- }
302
+ }, this.platform.config.options!.refreshRate! * 60000);
280
303
  }
281
304
 
282
305
  private async openAPIRefreshStatus() {
283
306
  try {
284
- const deviceStatus: deviceStatusResponse = (
285
- await this.platform.axios.get(`${DeviceURL}/${this.device.deviceId}/status`)
286
- ).data;
287
- if (deviceStatus.message === 'success') {
288
- this.deviceStatus = deviceStatus;
289
- this.platform.debug(`Meter ${this.accessory.displayName} openAPIRefreshStatus - ${JSON.stringify(this.deviceStatus)}`);
290
- this.parseStatus();
291
- this.updateHomeKitCharacteristics();
292
- }
307
+ this.deviceStatus = (await this.platform.axios.get(`${DeviceURL}/${this.device.deviceId}/status`)).data;
308
+ this.platform.debug(`Meter ${this.accessory.displayName} openAPIRefreshStatus: ${JSON.stringify(this.deviceStatus)}`);
309
+ this.parseStatus();
310
+ this.updateHomeKitCharacteristics();
293
311
  } catch (e: any) {
294
- this.platform.log.error(
295
- 'Meter - Failed to update status of',
296
- this.device.deviceName,
297
- JSON.stringify(e.message),
298
- this.platform.debug(`Meter ${this.accessory.displayName} - ${JSON.stringify(e)}`),
299
- );
312
+ this.platform.log.error(`Meter ${this.accessory.displayName} failed to refresh status, Error Message: ${JSON.stringify(e.message)}`);
313
+ this.platform.debug(`Meter ${this.accessory.displayName}, Error: ${JSON.stringify(e)}`);
300
314
  this.apiError(e);
301
315
  }
302
316
  }
@@ -305,33 +319,39 @@ export class Meter {
305
319
  * Updates the status for each of the HomeKit Characteristics
306
320
  */
307
321
  updateHomeKitCharacteristics() {
308
- if (this.StatusLowBattery !== undefined) {
322
+ if (this.StatusLowBattery === undefined) {
323
+ this.platform.debug(`Meter ${this.accessory.displayName} StatusLowBattery: ${this.StatusLowBattery}`);
324
+ } else {
309
325
  this.service.updateCharacteristic(this.platform.Characteristic.StatusLowBattery, this.StatusLowBattery);
326
+ this.platform.device(`Meter ${this.accessory.displayName} updateCharacteristic StatusLowBattery: ${this.StatusLowBattery}`);
310
327
  }
311
- if (this.BatteryLevel !== undefined) {
328
+ if (this.BatteryLevel === undefined) {
329
+ this.platform.debug(`Meter ${this.accessory.displayName} BatteryLevel: ${this.BatteryLevel}`);
330
+ } else {
312
331
  this.service.updateCharacteristic(this.platform.Characteristic.BatteryLevel, this.BatteryLevel);
332
+ this.platform.device(`Meter ${this.accessory.displayName} updateCharacteristic BatteryLevel: ${this.BatteryLevel}`);
313
333
  }
314
- if (!this.platform.config.options?.meter?.hide_humidity && (this.CurrentRelativeHumidity !== undefined)) {
315
- this.humidityservice?.updateCharacteristic(
316
- this.platform.Characteristic.CurrentRelativeHumidity,
317
- this.CurrentRelativeHumidity,
318
- );
334
+ if (this.device.meter?.hide_humidity && this.CurrentRelativeHumidity === undefined) {
335
+ this.platform.debug(`Meter ${this.accessory.displayName} CurrentRelativeHumidity: ${this.CurrentRelativeHumidity}`);
336
+ } else {
337
+ this.humidityservice?.updateCharacteristic(this.platform.Characteristic.CurrentRelativeHumidity, this.CurrentRelativeHumidity);
338
+ this.platform.device(`Meter ${this.accessory.displayName} updateCharacteristic CurrentRelativeHumidity: ${this.CurrentRelativeHumidity}`);
319
339
  }
320
- if (!this.platform.config.options?.meter?.hide_temperature && (this.CurrentTemperature !== undefined)) {
321
- this.temperatureservice?.updateCharacteristic(
322
- this.platform.Characteristic.CurrentTemperature,
323
- this.CurrentTemperature,
324
- );
340
+ if (this.device.meter?.hide_temperature || this.CurrentTemperature === undefined) {
341
+ this.platform.debug(`Meter ${this.accessory.displayName} CurrentTemperature: ${this.CurrentTemperature}`);
342
+ } else {
343
+ this.temperatureservice?.updateCharacteristic(this.platform.Characteristic.CurrentTemperature, this.CurrentTemperature);
344
+ this.platform.device(`Meter ${this.accessory.displayName} updateCharacteristic CurrentTemperature: ${this.CurrentTemperature}`);
325
345
  }
326
346
  }
327
347
 
328
348
  public apiError(e: any) {
329
349
  this.service.updateCharacteristic(this.platform.Characteristic.StatusLowBattery, e);
330
350
  this.service.updateCharacteristic(this.platform.Characteristic.BatteryLevel, e);
331
- if (!this.platform.config.options?.meter?.hide_humidity) {
351
+ if (!this.device.meter?.hide_humidity) {
332
352
  this.humidityservice?.updateCharacteristic(this.platform.Characteristic.CurrentRelativeHumidity, e);
333
353
  }
334
- if (!this.platform.config.options?.meter?.hide_temperature) {
354
+ if (!this.device.meter?.hide_temperature) {
335
355
  this.temperatureservice?.updateCharacteristic(this.platform.Characteristic.CurrentTemperature, e);
336
356
  }
337
357
  }
@@ -2,7 +2,7 @@ import { Service, PlatformAccessory, CharacteristicValue, MacAddress } from 'hom
2
2
  import { SwitchBotPlatform } from '../platform';
3
3
  import { interval, Subject } from 'rxjs';
4
4
  import { skipWhile } from 'rxjs/operators';
5
- import { DeviceURL, device, deviceStatusResponse } from '../settings';
5
+ import { DeviceURL, device, devicesConfig } from '../settings';
6
6
 
7
7
  /**
8
8
  * Platform Accessory
@@ -17,7 +17,8 @@ export class Motion {
17
17
  MotionDetected!: CharacteristicValue;
18
18
 
19
19
  // Others
20
- deviceStatus!: deviceStatusResponse;
20
+ deviceStatus!: any;
21
+ BLEmotion!: boolean;
21
22
  switchbot!: {
22
23
  discover: (
23
24
  arg0:
@@ -40,22 +41,20 @@ export class Motion {
40
41
  constructor(
41
42
  private readonly platform: SwitchBotPlatform,
42
43
  private accessory: PlatformAccessory,
43
- public device: device,
44
+ public device: device & devicesConfig,
44
45
  ) {
45
46
  // default placeholders
46
47
  this.MotionDetected = false;
47
48
 
48
49
  // BLE Connection
49
- if (this.platform.config.options?.ble?.includes(this.device.deviceId!)) {
50
+ if (device.ble) {
50
51
  // eslint-disable-next-line @typescript-eslint/no-var-requires
51
52
  const SwitchBot = require('node-switchbot');
52
53
  this.switchbot = new SwitchBot();
53
54
  const colon = device.deviceId!.match(/.{1,2}/g);
54
55
  const bleMac = colon!.join(':'); //returns 1A:23:B4:56:78:9A;
55
56
  this.device.bleMac = bleMac.toLowerCase();
56
- if (this.platform.config.options.debug) {
57
- this.platform.log.warn(this.device.bleMac.toLowerCase());
58
- }
57
+ this.platform.device(this.device.bleMac.toLowerCase());
59
58
  }
60
59
 
61
60
  // this is subject we use to track when we need to POST changes to the SwitchBot API
@@ -69,14 +68,14 @@ export class Motion {
69
68
  accessory
70
69
  .getService(this.platform.Service.AccessoryInformation)!
71
70
  .setCharacteristic(this.platform.Characteristic.Manufacturer, 'SwitchBot')
72
- .setCharacteristic(this.platform.Characteristic.Model, 'SWITCHBOT-MOTION-')
73
- .setCharacteristic(this.platform.Characteristic.SerialNumber, device.deviceId);
71
+ .setCharacteristic(this.platform.Characteristic.Model, 'SWITCHBOT-WOMOTION-W1101500')
72
+ .setCharacteristic(this.platform.Characteristic.SerialNumber, device.deviceId!);
74
73
 
75
74
  // get the Battery service if it exists, otherwise create a new Motion service
76
75
  // you can create multiple services for each accessory
77
76
  (this.service =
78
77
  accessory.getService(this.platform.Service.MotionSensor) ||
79
- accessory.addService(this.platform.Service.MotionSensor)), `${device.deviceName} ${device.deviceType}`;
78
+ accessory.addService(this.platform.Service.MotionSensor)), `${accessory.displayName} Motion Sensor`;
80
79
 
81
80
  // To avoid "Cannot add a Service with the same UUID another Service without also defining a unique 'subtype' property." error,
82
81
  // when creating multiple services of the same type, you need to use the following syntax to specify a name and subtype id:
@@ -106,90 +105,99 @@ export class Motion {
106
105
  /**
107
106
  * Parse the device status from the SwitchBot api
108
107
  */
109
- parseStatus() {
110
- // Set Room Sensor State
111
- if (this.deviceStatus.body.moveDetected) {
112
- this.MotionDetected = true;
108
+ async parseStatus() {
109
+ if (this.device.ble) {
110
+ this.platform.device('BLE');
111
+ await this.BLEparseStatus();
113
112
  } else {
114
- this.MotionDetected = false;
113
+ this.platform.device('OpenAPI');
114
+ await this.openAPIparseStatus();
115
115
  }
116
116
  }
117
117
 
118
+ private async BLEparseStatus() {
119
+ this.MotionDetected = Boolean(this.BLEmotion);
120
+ this.platform.debug(`${this.accessory.displayName}, MotionDetected: ${this.MotionDetected}`);
121
+ }
122
+
123
+ private async openAPIparseStatus() {
124
+ this.MotionDetected = Boolean(this.deviceStatus.body.moveDetected);
125
+ this.platform.debug(`${this.accessory.displayName}, MotionDetected: ${this.MotionDetected}`);
126
+ }
127
+
118
128
  /**
119
129
  * Asks the SwitchBot API for the latest device information
120
130
  */
121
131
  async refreshStatus() {
122
- if (this.platform.config.options?.ble?.includes(this.device.deviceId!)) {
123
- this.platform.log.warn('BLE DEVICE-REFRESH');
124
- // eslint-disable-next-line @typescript-eslint/no-var-requires
125
- const Switchbot = require('node-switchbot');
126
- const switchbot = new Switchbot();
127
- const colon = this.device.deviceId!.match(/.{1,2}/g);
128
- const bleMac = colon!.join(':'); //returns 1A:23:B4:56:78:9A;
129
- this.device.bleMac = bleMac.toLowerCase();
130
- if (this.platform.config.options.debug) {
131
- this.platform.log.warn(this.device.bleMac!);
132
- }
133
- switchbot.onadvertisement = (ad: any) => {
134
- this.platform.log.info(JSON.stringify(ad, null, ' '));
135
- this.platform.log.warn('ad:', JSON.stringify(ad));
136
- };
132
+ if (this.device.ble) {
133
+ this.platform.device('BLE');
134
+ await this.BLErefreshStatus();
135
+ } else {
136
+ this.platform.device('OpenAPI');
137
+ await this.openAPIRefreshStatus();
138
+ }
139
+ }
140
+
141
+ private async BLErefreshStatus() {
142
+ this.platform.debug('Motion BLE Device RefreshStatus');
143
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
144
+ const Switchbot = require('node-switchbot');
145
+ const switchbot = new Switchbot();
146
+ const colon = this.device.deviceId!.match(/.{1,2}/g);
147
+ const bleMac = colon!.join(':'); //returns 1A:23:B4:56:78:9A;
148
+ this.device.bleMac = bleMac.toLowerCase();
149
+ this.platform.device(this.device.bleMac!);
150
+ switchbot.onadvertisement = (ad: any) => {
151
+ this.platform.debug(JSON.stringify(ad, null, ' '));
152
+ this.platform.device('ad:', JSON.stringify(ad));
153
+ this.BLEmotion = ad.serviceData.motion;
154
+ };
155
+ switchbot
156
+ .startScan({
157
+ id: this.device.bleMac,
158
+ })
159
+ .then(() => {
160
+ return switchbot.wait(this.platform.config.options!.refreshRate! * 1000);
161
+ })
162
+ .then(() => {
163
+ switchbot.stopScan();
164
+ })
165
+ .catch(async (error: any) => {
166
+ this.platform.log.error(error);
167
+ await this.openAPIRefreshStatus();
168
+ });
169
+ setInterval(() => {
170
+ this.platform.log.info('Start scan ' + this.device.deviceName + '(' + this.device.bleMac + ')');
137
171
  switchbot
138
172
  .startScan({
139
- id: this.device.bleMac,
173
+ mode: 'S',
174
+ id: bleMac,
140
175
  })
141
176
  .then(() => {
142
177
  return switchbot.wait(this.platform.config.options!.refreshRate! * 1000);
143
178
  })
144
179
  .then(() => {
145
180
  switchbot.stopScan();
181
+ this.platform.log.info('Stop scan ' + this.device.deviceName + '(' + this.device.bleMac + ')');
146
182
  })
147
183
  .catch(async (error: any) => {
148
184
  this.platform.log.error(error);
149
185
  await this.openAPIRefreshStatus();
150
186
  });
151
- setInterval(() => {
152
- this.platform.log.info('Start scan ' + this.device.deviceName + '(' + this.device.bleMac + ')');
153
- switchbot
154
- .startScan({
155
- mode: 'M',
156
- id: bleMac,
157
- })
158
- .then(() => {
159
- return switchbot.wait(this.platform.config.options!.refreshRate! * 1000);
160
- })
161
- .then(() => {
162
- switchbot.stopScan();
163
- this.platform.log.info('Stop scan ' + this.device.deviceName + '(' + this.device.bleMac + ')');
164
- })
165
- .catch(async (error: any) => {
166
- this.platform.log.error(error);
167
- await this.openAPIRefreshStatus();
168
- });
169
- }, this.platform.config.options!.refreshRate! * 60000);
170
- } else {
171
- await this.openAPIRefreshStatus();
172
- }
187
+ this.parseStatus();
188
+ this.updateHomeKitCharacteristics();
189
+ }, this.platform.config.options!.refreshRate! * 60000);
173
190
  }
174
191
 
175
192
  private async openAPIRefreshStatus() {
176
193
  try {
177
- const deviceStatus: deviceStatusResponse = (
178
- await this.platform.axios.get(`${DeviceURL}/${this.device.deviceId}/status`)
179
- ).data;
180
- if (deviceStatus.message === 'success') {
181
- this.deviceStatus = deviceStatus;
182
- this.platform.debug(`Motion ${this.accessory.displayName} refreshStatus - ${JSON.stringify(this.deviceStatus)}`);
183
-
184
- this.parseStatus();
185
- this.updateHomeKitCharacteristics();
186
- }
194
+ this.deviceStatus = (await this.platform.axios.get(`${DeviceURL}/${this.device.deviceId}/status`)).data;
195
+ this.platform.debug(`Motion ${this.accessory.displayName} refreshStatus: ${JSON.stringify(this.deviceStatus)}`);
196
+ this.parseStatus();
197
+ this.updateHomeKitCharacteristics();
187
198
  } catch (e: any) {
188
- this.platform.log.error(
189
- 'Motion - Failed to update status of',
190
- this.device.deviceName,
191
- JSON.stringify(e.message),
192
- this.platform.debug(`Motion ${this.accessory.displayName} - ${JSON.stringify(e)}`));
199
+ this.platform.log.error(`Motion ${this.accessory.displayName} failed to refresh status, Error Message: ${JSON.stringify(e.message)}`);
200
+ this.platform.debug(`Motion ${this.accessory.displayName}, Error: ${JSON.stringify(e)}`);
193
201
  this.apiError(e);
194
202
  }
195
203
  }
@@ -198,8 +206,11 @@ export class Motion {
198
206
  * Updates the status for each of the HomeKit Characteristics
199
207
  */
200
208
  updateHomeKitCharacteristics() {
201
- if (this.MotionDetected !== undefined) {
209
+ if (this.MotionDetected === undefined) {
210
+ this.platform.debug(`Motion ${this.accessory.displayName} MotionDetected: ${this.MotionDetected}`);
211
+ } else {
202
212
  this.service.updateCharacteristic(this.platform.Characteristic.MotionDetected, this.MotionDetected);
213
+ this.platform.device(`Motion ${this.accessory.displayName} updateCharacteristic MotionDetected: ${this.MotionDetected}`);
203
214
  }
204
215
  }
205
216