@switchbot/homebridge-switchbot 0.2.0-alpha.1 → 1.0.1-beta.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 (99) hide show
  1. package/.github/workflows/nodejs-beta.yml +1 -1
  2. package/.github/workflows/nodejs.yml +1 -1
  3. package/.github/workflows/{prerelease.js → prerelease-beta.js} +0 -0
  4. package/CHANGELOG.md +1 -1
  5. package/README.md +9 -5
  6. package/config.schema.json +350 -126
  7. package/dist/devices/bots.d.ts +17 -33
  8. package/dist/devices/bots.d.ts.map +1 -1
  9. package/dist/devices/bots.js +103 -152
  10. package/dist/devices/bots.js.map +1 -1
  11. package/dist/devices/{bulb.d.ts → colorbulb.d.ts} +12 -19
  12. package/dist/devices/colorbulb.d.ts.map +1 -0
  13. package/dist/devices/{bulb.js → colorbulb.js} +32 -32
  14. package/dist/devices/colorbulb.js.map +1 -0
  15. package/dist/devices/contact.d.ts +18 -16
  16. package/dist/devices/contact.d.ts.map +1 -1
  17. package/dist/devices/contact.js +101 -44
  18. package/dist/devices/contact.js.map +1 -1
  19. package/dist/devices/curtains.d.ts +17 -51
  20. package/dist/devices/curtains.d.ts.map +1 -1
  21. package/dist/devices/curtains.js +168 -248
  22. package/dist/devices/curtains.js.map +1 -1
  23. package/dist/devices/humidifiers.d.ts +13 -4
  24. package/dist/devices/humidifiers.d.ts.map +1 -1
  25. package/dist/devices/humidifiers.js +78 -8
  26. package/dist/devices/humidifiers.js.map +1 -1
  27. package/dist/devices/indoorcam.d.ts +6 -13
  28. package/dist/devices/indoorcam.d.ts.map +1 -1
  29. package/dist/devices/indoorcam.js.map +1 -1
  30. package/dist/devices/meters.d.ts +12 -15
  31. package/dist/devices/meters.d.ts.map +1 -1
  32. package/dist/devices/meters.js +35 -44
  33. package/dist/devices/meters.js.map +1 -1
  34. package/dist/devices/motion.d.ts +17 -15
  35. package/dist/devices/motion.d.ts.map +1 -1
  36. package/dist/devices/motion.js +87 -40
  37. package/dist/devices/motion.js.map +1 -1
  38. package/dist/devices/plugs.d.ts +6 -13
  39. package/dist/devices/plugs.d.ts.map +1 -1
  40. package/dist/devices/plugs.js.map +1 -1
  41. package/dist/irdevices/airconditioners.d.ts +10 -10
  42. package/dist/irdevices/airconditioners.d.ts.map +1 -1
  43. package/dist/irdevices/airconditioners.js +29 -9
  44. package/dist/irdevices/airconditioners.js.map +1 -1
  45. package/dist/irdevices/airpurifiers.d.ts +11 -11
  46. package/dist/irdevices/airpurifiers.d.ts.map +1 -1
  47. package/dist/irdevices/airpurifiers.js.map +1 -1
  48. package/dist/irdevices/cameras.d.ts +3 -3
  49. package/dist/irdevices/cameras.d.ts.map +1 -1
  50. package/dist/irdevices/cameras.js.map +1 -1
  51. package/dist/irdevices/fans.d.ts +6 -6
  52. package/dist/irdevices/fans.d.ts.map +1 -1
  53. package/dist/irdevices/fans.js +10 -10
  54. package/dist/irdevices/fans.js.map +1 -1
  55. package/dist/irdevices/lights.d.ts +3 -3
  56. package/dist/irdevices/lights.d.ts.map +1 -1
  57. package/dist/irdevices/lights.js.map +1 -1
  58. package/dist/irdevices/others.d.ts +3 -3
  59. package/dist/irdevices/others.d.ts.map +1 -1
  60. package/dist/irdevices/others.js.map +1 -1
  61. package/dist/irdevices/tvs.d.ts +3 -3
  62. package/dist/irdevices/tvs.d.ts.map +1 -1
  63. package/dist/irdevices/tvs.js +7 -5
  64. package/dist/irdevices/tvs.js.map +1 -1
  65. package/dist/irdevices/vacuumcleaners.d.ts +3 -3
  66. package/dist/irdevices/vacuumcleaners.d.ts.map +1 -1
  67. package/dist/irdevices/vacuumcleaners.js.map +1 -1
  68. package/dist/irdevices/waterheaters.d.ts +3 -3
  69. package/dist/irdevices/waterheaters.d.ts.map +1 -1
  70. package/dist/irdevices/waterheaters.js.map +1 -1
  71. package/dist/platform.d.ts +3 -2
  72. package/dist/platform.d.ts.map +1 -1
  73. package/dist/platform.js +136 -46
  74. package/dist/platform.js.map +1 -1
  75. package/dist/settings.d.ts +50 -8
  76. package/dist/settings.d.ts.map +1 -1
  77. package/package.json +65 -65
  78. package/src/devices/bots.ts +126 -176
  79. package/src/devices/{bulb.ts → colorbulb.ts} +43 -51
  80. package/src/devices/contact.ts +124 -68
  81. package/src/devices/curtains.ts +189 -300
  82. package/src/devices/humidifiers.ts +93 -14
  83. package/src/devices/indoorcam.ts +10 -20
  84. package/src/devices/meters.ts +53 -69
  85. package/src/devices/motion.ts +108 -62
  86. package/src/devices/plugs.ts +8 -19
  87. package/src/irdevices/airconditioners.ts +43 -20
  88. package/src/irdevices/airpurifiers.ts +15 -11
  89. package/src/irdevices/cameras.ts +5 -3
  90. package/src/irdevices/fans.ts +22 -16
  91. package/src/irdevices/lights.ts +5 -3
  92. package/src/irdevices/others.ts +5 -3
  93. package/src/irdevices/tvs.ts +13 -7
  94. package/src/irdevices/vacuumcleaners.ts +5 -3
  95. package/src/irdevices/waterheaters.ts +5 -3
  96. package/src/platform.ts +148 -49
  97. package/src/settings.ts +79 -8
  98. package/dist/devices/bulb.d.ts.map +0 -1
  99. package/dist/devices/bulb.js.map +0 -1
@@ -1,8 +1,8 @@
1
- import { Service, PlatformAccessory, CharacteristicValue, MacAddress } from 'homebridge';
1
+ import { Service, PlatformAccessory, CharacteristicValue } from 'homebridge';
2
2
  import { SwitchBotPlatform } from '../platform';
3
3
  import { interval, Subject } from 'rxjs';
4
4
  import { skipWhile } from 'rxjs/operators';
5
- import { DeviceURL, device, devicesConfig } from '../settings';
5
+ import { DeviceURL, device, devicesConfig, serviceData, switchbot, deviceStatusResponse } from '../settings';
6
6
 
7
7
  /**
8
8
  * Platform Accessory
@@ -12,34 +12,31 @@ import { DeviceURL, device, devicesConfig } from '../settings';
12
12
  export class Contact {
13
13
  // Services
14
14
  private service: Service;
15
- motionService: Service;
15
+ private motionService: Service;
16
+ private lightSensorService: Service;
17
+ private batteryService?: Service;
16
18
 
17
19
  // Characteristic Values
18
20
  ContactSensorState!: CharacteristicValue;
19
21
  MotionDetected!: CharacteristicValue;
22
+ CurrentAmbientLightLevel!: CharacteristicValue;
23
+ BatteryLevel!: CharacteristicValue;
24
+ StatusLowBattery!: CharacteristicValue;
20
25
 
21
- // Others
22
- deviceStatus!: any;
23
- BLEmotion!: boolean;
24
- BLEstate!: boolean;
25
- switchbot!: {
26
- discover: (
27
- arg0:
28
- {
29
- duration: any;
30
- model: string;
31
- quick: boolean;
32
- id: MacAddress;
33
- }
34
- ) => Promise<any>;
35
- wait: (
36
- arg0: number
37
- ) => any;
38
- };
26
+ // OpenAPI others
27
+ deviceStatus!: deviceStatusResponse;
28
+
29
+ // BLE Others
30
+ switchbot!: switchbot;
31
+ serviceData!: serviceData;
32
+ battery!: serviceData['battery'];
33
+ movement!: serviceData['movement'];
34
+ doorState!: serviceData['doorState'];
35
+ lightLevel!: serviceData['lightLevel'];
39
36
 
40
37
  // Updates
41
38
  contactUbpdateInProgress!: boolean;
42
- doContactUpdate;
39
+ doContactUpdate!: Subject<void>;
43
40
 
44
41
  constructor(
45
42
  private readonly platform: SwitchBotPlatform,
@@ -74,7 +71,7 @@ export class Contact {
74
71
  .setCharacteristic(this.platform.Characteristic.Model, 'SWITCHBOT-WOCONTACT-W1201500')
75
72
  .setCharacteristic(this.platform.Characteristic.SerialNumber, device.deviceId!);
76
73
 
77
- // get the Battery service if it exists, otherwise create a new Contact service
74
+ // get the Contact service if it exists, otherwise create a new Contact service
78
75
  // you can create multiple services for each accessory
79
76
  (this.service =
80
77
  accessory.getService(this.platform.Service.ContactSensor) ||
@@ -96,6 +93,20 @@ export class Contact {
96
93
 
97
94
  this.motionService.setCharacteristic(this.platform.Characteristic.Name, `${accessory.displayName} Motion Sensor`);
98
95
 
96
+ (this.lightSensorService =
97
+ accessory.getService(this.platform.Service.LightSensor) ||
98
+ accessory.addService(this.platform.Service.LightSensor)), `${accessory.displayName} Light Sensor`;
99
+
100
+ this.lightSensorService.setCharacteristic(this.platform.Characteristic.Name, `${accessory.displayName} Light Sensor`);
101
+
102
+ if (device.ble) {
103
+ (this.batteryService =
104
+ accessory.getService(this.platform.Service.Battery) ||
105
+ accessory.addService(this.platform.Service.Battery)), `${accessory.displayName} Battery`;
106
+
107
+ this.batteryService.setCharacteristic(this.platform.Characteristic.Name, `${accessory.displayName} Battery`);
108
+ }
109
+
99
110
  // Retrieve initial values and updateHomekit
100
111
  this.updateHomeKitCharacteristics();
101
112
 
@@ -121,10 +132,41 @@ export class Contact {
121
132
  }
122
133
 
123
134
  private async BLEparseStatus() {
124
- this.MotionDetected = Boolean(this.BLEmotion);
125
- this.ContactSensorState = Boolean(this.BLEstate);
126
- this.platform.debug(`${this.accessory.displayName}
127
- , ContactSensorState: ${this.ContactSensorState}, MotionDetected: ${this.MotionDetected}`);
135
+ this.platform.debug('Contact BLE Device parseStatus');
136
+ // Movement
137
+ this.MotionDetected = Boolean(this.movement);
138
+ // Door State
139
+ switch (this.doorState) {
140
+ case 'open':
141
+ case 1:
142
+ this.ContactSensorState = this.platform.Characteristic.ContactSensorState.CONTACT_NOT_DETECTED;
143
+ break;
144
+ case 'close':
145
+ case 0:
146
+ this.ContactSensorState = this.platform.Characteristic.ContactSensorState.CONTACT_DETECTED;
147
+ break;
148
+ default:
149
+ this.platform.log.error('timeout no closed');
150
+ }
151
+ // Light Level
152
+ switch (this.lightLevel) {
153
+ case 'dark':
154
+ case 0:
155
+ this.CurrentAmbientLightLevel = 0.0001;
156
+ break;
157
+ default:
158
+ this.CurrentAmbientLightLevel = 100000;
159
+ }
160
+ // Battery
161
+ this.BatteryLevel = Number(this.battery);
162
+ if (this.BatteryLevel < 10) {
163
+ this.StatusLowBattery = this.platform.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW;
164
+ } else {
165
+ this.StatusLowBattery = this.platform.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
166
+ }
167
+
168
+ this.platform.debug(`${this.accessory.displayName}, ContactSensorState: ${this.ContactSensorState}, MotionDetected: ${this.MotionDetected}`
169
+ + `CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}, BatteryLevel: ${this.BatteryLevel}`);
128
170
  }
129
171
 
130
172
  private async openAPIparseStatus() {
@@ -155,8 +197,7 @@ export class Contact {
155
197
  }
156
198
  }
157
199
 
158
- private async BLERefreshStatus() {
159
- this.platform.debug('Contact BLE Device RefreshStatus');
200
+ private connectBLE() {
160
201
  // eslint-disable-next-line @typescript-eslint/no-var-requires
161
202
  const Switchbot = require('node-switchbot');
162
203
  const switchbot = new Switchbot();
@@ -164,47 +205,41 @@ export class Contact {
164
205
  const bleMac = colon!.join(':'); //returns 1A:23:B4:56:78:9A;
165
206
  this.device.bleMac = bleMac.toLowerCase();
166
207
  this.platform.device(this.device.bleMac!);
167
- switchbot.onadvertisement = (ad: any) => {
168
- this.platform.log.info(JSON.stringify(ad, null, ' '));
169
- this.platform.device('ad:', JSON.stringify(ad));
170
- this.BLEmotion = ad.serviceData.motion;
171
- this.BLEstate = ad.serviceData.state;
172
- };
173
- switchbot
174
- .startScan({
175
- id: this.device.bleMac,
176
- })
177
- .then(() => {
178
- return switchbot.wait(this.platform.config.options!.refreshRate! * 1000);
179
- })
180
- .then(() => {
181
- switchbot.stopScan();
182
- })
183
- .catch(async (error: any) => {
184
- this.platform.log.error(error);
185
- await this.openAPIRefreshStatus();
186
- });
187
- setInterval(() => {
188
- this.platform.log.info('Start scan ' + this.device.deviceName + '(' + this.device.bleMac + ')');
189
- switchbot
190
- .startScan({
191
- mode: 'D',
192
- id: bleMac,
193
- })
194
- .then(() => {
195
- return switchbot.wait(this.platform.config.options!.refreshRate! * 1000);
196
- })
197
- .then(() => {
198
- switchbot.stopScan();
199
- this.platform.log.info('Stop scan ' + this.device.deviceName + '(' + this.device.bleMac + ')');
200
- })
201
- .catch(async (error: any) => {
202
- this.platform.log.error(error);
203
- await this.openAPIRefreshStatus();
204
- });
208
+ return switchbot;
209
+ }
210
+
211
+ private async BLERefreshStatus() {
212
+ this.platform.debug('Contact BLE Device RefreshStatus');
213
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
214
+ const switchbot = this.connectBLE();
215
+ // Start to monitor advertisement packets
216
+ switchbot.startScan({
217
+ model: 'd',
218
+ id: this.device.bleMac,
219
+ }).then(() => {
220
+ // Set an event hander
221
+ switchbot.onadvertisement = (ad: any) => {
222
+ this.serviceData = ad.serviceData;
223
+ this.platform.device(`${this.device.bleMac}: ${JSON.stringify(ad.serviceData)}`);
224
+ this.movement = ad.serviceData.movement;
225
+ this.doorState = ad.serviceData.doorState;
226
+ this.lightLevel = ad.serviceData.lightLevel;
227
+ this.battery = ad.serviceData.battery;
228
+ this.platform.device(`${this.accessory.displayName}, Movement: ${ad.serviceData.movement}, Door State: ${ad.serviceData.doorState},`
229
+ + ` Light Level: ${ad.serviceData.lightLevel}, Battery: ${ad.serviceData.battery}`);
230
+ };
231
+ // Wait 10 seconds
232
+ return switchbot.wait(10000);
233
+ }).then(() => {
234
+ // Stop to monitor
235
+ switchbot.stopScan();
205
236
  this.parseStatus();
206
237
  this.updateHomeKitCharacteristics();
207
- }, this.platform.config.options!.refreshRate! * 60000);
238
+ }).catch(async (e: any) => {
239
+ this.platform.log.error(`BLE Connection Failed: ${e.message}`);
240
+ this.platform.log.warn('Using OpenAPI Connection');
241
+ await this.openAPIRefreshStatus();
242
+ });
208
243
  }
209
244
 
210
245
  private async openAPIRefreshStatus() {
@@ -236,10 +271,31 @@ export class Contact {
236
271
  this.motionService.updateCharacteristic(this.platform.Characteristic.MotionDetected, this.MotionDetected);
237
272
  this.platform.device(`Contact ${this.accessory.displayName} updateCharacteristic MotionDetected: ${this.MotionDetected}`);
238
273
  }
274
+ if (this.CurrentAmbientLightLevel === undefined) {
275
+ this.platform.debug(`Contact ${this.accessory.displayName} CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`);
276
+ } else {
277
+ this.lightSensorService.updateCharacteristic(this.platform.Characteristic.CurrentAmbientLightLevel, this.CurrentAmbientLightLevel);
278
+ this.platform.device(`Contact ${this.accessory.displayName} updateCharacteristic CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`);
279
+ }
280
+ if (this.BatteryLevel === undefined) {
281
+ this.platform.debug(`Contact ${this.accessory.displayName} BatteryLevel: ${this.BatteryLevel}`);
282
+ } else {
283
+ this.batteryService?.updateCharacteristic(this.platform.Characteristic.BatteryLevel, this.BatteryLevel);
284
+ this.platform.device(`Contact ${this.accessory.displayName} updateCharacteristic BatteryLevel: ${this.BatteryLevel}`);
285
+ }
286
+ if (this.StatusLowBattery === undefined) {
287
+ this.platform.debug(`Contact ${this.accessory.displayName} StatusLowBattery: ${this.StatusLowBattery}`);
288
+ } else {
289
+ this.batteryService?.updateCharacteristic(this.platform.Characteristic.StatusLowBattery, this.StatusLowBattery);
290
+ this.platform.device(`Contact ${this.accessory.displayName} updateCharacteristic StatusLowBattery: ${this.StatusLowBattery}`);
291
+ }
239
292
  }
240
293
 
241
294
  public apiError(e: any) {
242
295
  this.service.updateCharacteristic(this.platform.Characteristic.ContactSensorState, e);
243
296
  this.motionService.updateCharacteristic(this.platform.Characteristic.MotionDetected, e);
297
+ this.lightSensorService.updateCharacteristic(this.platform.Characteristic.CurrentAmbientLightLevel, e);
298
+ this.batteryService?.updateCharacteristic(this.platform.Characteristic.BatteryLevel, e);
299
+ this.batteryService?.updateCharacteristic(this.platform.Characteristic.StatusLowBattery, e);
244
300
  }
245
301
  }