@switchbot/homebridge-switchbot 2.0.0-beta.2 → 2.0.0-beta.21

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 (113) hide show
  1. package/CHANGELOG.md +8 -1
  2. package/README.md +1 -2
  3. package/config.schema.json +75 -20
  4. package/dist/device/bot.d.ts +32 -28
  5. package/dist/device/bot.d.ts.map +1 -1
  6. package/dist/device/bot.js +646 -648
  7. package/dist/device/bot.js.map +1 -1
  8. package/dist/device/colorbulb.d.ts +34 -19
  9. package/dist/device/colorbulb.d.ts.map +1 -1
  10. package/dist/device/colorbulb.js +429 -304
  11. package/dist/device/colorbulb.js.map +1 -1
  12. package/dist/device/contact.d.ts +16 -7
  13. package/dist/device/contact.d.ts.map +1 -1
  14. package/dist/device/contact.js +288 -230
  15. package/dist/device/contact.js.map +1 -1
  16. package/dist/device/curtain.d.ts +21 -16
  17. package/dist/device/curtain.d.ts.map +1 -1
  18. package/dist/device/curtain.js +519 -489
  19. package/dist/device/curtain.js.map +1 -1
  20. package/dist/device/humidifier.d.ts +22 -18
  21. package/dist/device/humidifier.d.ts.map +1 -1
  22. package/dist/device/humidifier.js +415 -360
  23. package/dist/device/humidifier.js.map +1 -1
  24. package/dist/device/lock.d.ts +22 -8
  25. package/dist/device/lock.d.ts.map +1 -1
  26. package/dist/device/lock.js +253 -147
  27. package/dist/device/lock.js.map +1 -1
  28. package/dist/device/meter.d.ts +21 -16
  29. package/dist/device/meter.d.ts.map +1 -1
  30. package/dist/device/meter.js +325 -255
  31. package/dist/device/meter.js.map +1 -1
  32. package/dist/device/meterplus.d.ts +23 -12
  33. package/dist/device/meterplus.d.ts.map +1 -1
  34. package/dist/device/meterplus.js +346 -208
  35. package/dist/device/meterplus.js.map +1 -1
  36. package/dist/device/motion.d.ts +17 -8
  37. package/dist/device/motion.d.ts.map +1 -1
  38. package/dist/device/motion.js +261 -209
  39. package/dist/device/motion.js.map +1 -1
  40. package/dist/device/plug.d.ts +24 -16
  41. package/dist/device/plug.d.ts.map +1 -1
  42. package/dist/device/plug.js +267 -242
  43. package/dist/device/plug.js.map +1 -1
  44. package/dist/device/striplight.d.ts +51 -16
  45. package/dist/device/striplight.d.ts.map +1 -1
  46. package/dist/device/striplight.js +527 -185
  47. package/dist/device/striplight.js.map +1 -1
  48. package/dist/irdevice/airconditioner.d.ts +7 -12
  49. package/dist/irdevice/airconditioner.d.ts.map +1 -1
  50. package/dist/irdevice/airconditioner.js +261 -230
  51. package/dist/irdevice/airconditioner.js.map +1 -1
  52. package/dist/irdevice/airpurifier.d.ts +3 -3
  53. package/dist/irdevice/airpurifier.d.ts.map +1 -1
  54. package/dist/irdevice/airpurifier.js +137 -104
  55. package/dist/irdevice/airpurifier.js.map +1 -1
  56. package/dist/irdevice/camera.d.ts +9 -8
  57. package/dist/irdevice/camera.d.ts.map +1 -1
  58. package/dist/irdevice/camera.js +116 -86
  59. package/dist/irdevice/camera.js.map +1 -1
  60. package/dist/irdevice/fan.d.ts +8 -7
  61. package/dist/irdevice/fan.d.ts.map +1 -1
  62. package/dist/irdevice/fan.js +143 -109
  63. package/dist/irdevice/fan.js.map +1 -1
  64. package/dist/irdevice/light.d.ts +9 -8
  65. package/dist/irdevice/light.d.ts.map +1 -1
  66. package/dist/irdevice/light.js +120 -103
  67. package/dist/irdevice/light.js.map +1 -1
  68. package/dist/irdevice/other.d.ts +9 -8
  69. package/dist/irdevice/other.d.ts.map +1 -1
  70. package/dist/irdevice/other.js +128 -98
  71. package/dist/irdevice/other.js.map +1 -1
  72. package/dist/irdevice/tv.d.ts +10 -9
  73. package/dist/irdevice/tv.d.ts.map +1 -1
  74. package/dist/irdevice/tv.js +126 -93
  75. package/dist/irdevice/tv.js.map +1 -1
  76. package/dist/irdevice/vacuumcleaner.d.ts +7 -10
  77. package/dist/irdevice/vacuumcleaner.d.ts.map +1 -1
  78. package/dist/irdevice/vacuumcleaner.js +115 -89
  79. package/dist/irdevice/vacuumcleaner.js.map +1 -1
  80. package/dist/irdevice/waterheater.d.ts +6 -9
  81. package/dist/irdevice/waterheater.d.ts.map +1 -1
  82. package/dist/irdevice/waterheater.js +115 -89
  83. package/dist/irdevice/waterheater.js.map +1 -1
  84. package/dist/platform.d.ts +5 -5
  85. package/dist/platform.d.ts.map +1 -1
  86. package/dist/platform.js +227 -199
  87. package/dist/platform.js.map +1 -1
  88. package/dist/settings.d.ts +15 -11
  89. package/dist/settings.d.ts.map +1 -1
  90. package/dist/settings.js.map +1 -1
  91. package/package.json +12 -10
  92. package/src/device/bot.ts +641 -657
  93. package/src/device/colorbulb.ts +440 -339
  94. package/src/device/contact.ts +289 -233
  95. package/src/device/curtain.ts +523 -503
  96. package/src/device/humidifier.ts +421 -396
  97. package/src/device/lock.ts +257 -147
  98. package/src/device/meter.ts +335 -268
  99. package/src/device/meterplus.ts +354 -213
  100. package/src/device/motion.ts +264 -213
  101. package/src/device/plug.ts +270 -251
  102. package/src/device/striplight.ts +552 -207
  103. package/src/irdevice/airconditioner.ts +263 -241
  104. package/src/irdevice/airpurifier.ts +132 -103
  105. package/src/irdevice/camera.ts +112 -85
  106. package/src/irdevice/fan.ts +138 -106
  107. package/src/irdevice/light.ts +116 -103
  108. package/src/irdevice/other.ts +124 -97
  109. package/src/irdevice/tv.ts +123 -93
  110. package/src/irdevice/vacuumcleaner.ts +112 -89
  111. package/src/irdevice/waterheater.ts +111 -89
  112. package/src/platform.ts +216 -214
  113. package/src/settings.ts +15 -11
@@ -3,6 +3,7 @@ import crypto from 'crypto';
3
3
  import { Context } from 'vm';
4
4
  import { IncomingMessage } from 'http';
5
5
  import { interval, Subject } from 'rxjs';
6
+ import superStringify from 'super-stringify';
6
7
  import { SwitchBotPlatform } from '../platform';
7
8
  import { debounceTime, skipWhile, take, tap } from 'rxjs/operators';
8
9
  import { Service, PlatformAccessory, CharacteristicValue } from 'homebridge';
@@ -32,17 +33,17 @@ export class Lock {
32
33
  lockUpdateInProgress!: boolean;
33
34
  doLockUpdate!: Subject<void>;
34
35
 
36
+ // Connection
37
+ private readonly BLE = (this.device.connectionType === 'BLE' || this.device.connectionType === 'Both');
38
+ private readonly OpenAPI = (this.device.connectionType === 'OpenAPI' || this.device.connectionType === 'Both');
39
+
35
40
  constructor(private readonly platform: SwitchBotPlatform, private accessory: PlatformAccessory, public device: device & devicesConfig) {
36
41
  // default placeholders
37
42
  this.logs(device);
38
43
  this.scan(device);
39
44
  this.refreshRate(device);
40
45
  this.config(device);
41
- if (this.LockTargetState === undefined) {
42
- this.LockTargetState = false;
43
- } else {
44
- this.LockTargetState = this.accessory.context.On;
45
- }
46
+ this.conext();
46
47
 
47
48
  // this is subject we use to track when we need to POST changes to the SwitchBot API
48
49
  this.doLockUpdate = new Subject();
@@ -82,18 +83,18 @@ export class Lock {
82
83
 
83
84
  // Contact Sensor Service
84
85
  if (device.lock?.hide_contactsensor) {
85
- this.debugLog(`Lock: ${accessory.displayName} Removing Contact Sensor Service`);
86
+ this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Removing Contact Sensor Service`);
86
87
  this.contactSensorService = this.accessory.getService(this.platform.Service.ContactSensor);
87
88
  accessory.removeService(this.contactSensorService!);
88
89
  } else if (!this.contactSensorService) {
89
- this.debugLog(`Lock: ${accessory.displayName} Add Contact Sensor Service`);
90
+ this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Add Contact Sensor Service`);
90
91
  (this.contactSensorService =
91
92
  this.accessory.getService(this.platform.Service.ContactSensor) || this.accessory.addService(this.platform.Service.ContactSensor)),
92
93
  `${accessory.displayName} Contact Sensor`;
93
94
 
94
95
  this.contactSensorService.setCharacteristic(this.platform.Characteristic.Name, `${accessory.displayName} Contact Sensor`);
95
96
  } else {
96
- this.debugLog(`Lock: ${accessory.displayName} Contact Sensor Service Not Added`);
97
+ this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Contact Sensor Service Not Added`);
97
98
  }
98
99
 
99
100
  // Update Homekit
@@ -119,19 +120,33 @@ export class Lock {
119
120
  try {
120
121
  await this.pushChanges();
121
122
  } catch (e: any) {
122
- this.errorLog(`Lock: ${this.accessory.displayName} failed pushChanges`);
123
- if (this.deviceLogging.includes('debug')) {
124
- this.errorLog(`Lock: ${this.accessory.displayName} failed pushChanges,` + ` Error Message: ${JSON.stringify(e.message)}`);
125
- }
126
123
  this.apiError(e);
124
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed pushChanges with ${this.device.connectionType} Connection,`
125
+ + ` Error Message: ${superStringify(e.message)}`);
127
126
  }
128
127
  this.lockUpdateInProgress = false;
129
128
  });
130
129
  }
131
130
 
131
+ /**
132
+ * Parse the device status from the SwitchBot api
133
+ */
134
+ async parseStatus(): Promise<void> {
135
+ /*if (this.BLE && !this.SwitchToOpenAPI) {
136
+ await this.BLEparseStatus();
137
+ } else*/ if (this.OpenAPI) {
138
+ //this.SwitchToOpenAPI = false;
139
+ await this.openAPIparseStatus();
140
+ } else {
141
+ this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:`
142
+ + ` ${this.device.connectionType}, parseStatus will not happen.`);
143
+ }
144
+ }
145
+
132
146
  //{"deviceId":"DBDC23B53139","deviceType":"Smart Lock","hubDeviceId":"E68B14109DA2","lockState":"locked","doorState":"opened","calibrate":true}
133
147
 
134
- async parseStatus(): Promise<void> {
148
+ async openAPIparseStatus(): Promise<void> {
149
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIparseStatus`);
135
150
  switch (this.lockState) {
136
151
  case 'locked':
137
152
  this.LockCurrentState = this.platform.Characteristic.LockCurrentState.SECURED;
@@ -148,17 +163,32 @@ export class Lock {
148
163
  default:
149
164
  this.ContactSensorState = this.platform.Characteristic.ContactSensorState.CONTACT_DETECTED;
150
165
  }
151
- this.debugLog(`Lock: ${this.accessory.displayName} On: ${this.LockTargetState}`);
166
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.LockTargetState}`);
152
167
  }
153
168
 
169
+ /**
170
+ * Asks the SwitchBot API for the latest device information
171
+ */
154
172
  async refreshStatus(): Promise<void> {
173
+ /*if (this.BLE) {
174
+ await this.BLERefreshStatus();
175
+ } else*/ if (this.OpenAPI && this.platform.config.credentials?.token) {
176
+ await this.openAPIRefreshStatus();
177
+ } else {
178
+ this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:`
179
+ + ` ${this.device.connectionType}, refreshStatus will not happen.`);
180
+ }
181
+ }
182
+
183
+ async openAPIRefreshStatus(): Promise<void> {
184
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus`);
155
185
  try {
156
186
  const t = Date.now();
157
187
  const nonce = 'requestID';
158
188
  const data = this.platform.config.credentials?.token + t + nonce;
159
189
  const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret).update(Buffer.from(data, 'utf-8')).digest();
160
190
  const sign = signTerm.toString('base64');
161
- this.debugLog(`Lock: ${this.accessory.displayName} sign: ${sign}`);
191
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} sign: ${sign}`);
162
192
  const options = {
163
193
  hostname: HostDomain,
164
194
  port: 443,
@@ -173,37 +203,33 @@ export class Lock {
173
203
  },
174
204
  };
175
205
  const req = https.request(options, (res) => {
176
- this.debugLog(`Lock: ${this.accessory.displayName} statusCode: ${res.statusCode}`);
206
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus statusCode: ${res.statusCode}`);
177
207
  let rawData = '';
178
208
  res.on('data', (d) => {
179
209
  rawData += d;
180
- this.debugLog(`Lock: ${this.accessory.displayName} d: ${d}`);
210
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} d: ${d}`);
181
211
  });
182
212
  res.on('end', () => {
183
213
  try {
184
214
  this.deviceStatus = JSON.parse(rawData);
185
- this.debugLog(`Lock: ${this.accessory.displayName} refreshStatus: ${JSON.stringify(this.deviceStatus)}`);
215
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus: ${superStringify(this.deviceStatus)}`);
186
216
  this.lockState = this.deviceStatus.body.lockState;
187
217
  this.doorState = this.deviceStatus.body.doorState;
188
218
  this.parseStatus();
189
219
  this.updateHomeKitCharacteristics();
190
220
  } catch (e: any) {
191
- this.errorLog(`Lock: ${this.accessory.displayName} error message: ${e.message}`);
221
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} error message: ${e.message}`);
192
222
  }
193
223
  });
194
224
  });
195
225
  req.on('error', (e: any) => {
196
- this.errorLog(`Lock: ${this.accessory.displayName} error message: ${e.message}`);
226
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} error message: ${e.message}`);
197
227
  });
198
228
  req.end();
199
229
  } catch (e: any) {
200
- this.errorLog(`Lock: ${this.accessory.displayName} failed refreshStatus with OpenAPI Connection`);
201
- if (this.deviceLogging.includes('debug')) {
202
- this.errorLog(
203
- `Lock: ${this.accessory.displayName} failed refreshStatus with OpenAPI Connection,` + ` Error Message: ${JSON.stringify(e.message)}`,
204
- );
205
- }
206
230
  this.apiError(e);
231
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed openAPIRefreshStatus with ${this.device.connectionType}`
232
+ + ` Connection, Error Message: ${superStringify(e.message)}`);
207
233
  }
208
234
  }
209
235
 
@@ -214,55 +240,14 @@ export class Lock {
214
240
  * Lock - "command" "unlock" "default" = set to ???? state - LockCurrentState
215
241
  */
216
242
  async pushChanges(): Promise<void> {
217
- // Make Push On request to the API
218
- const t = Date.now();
219
- const nonce = 'requestID';
220
- const data = this.platform.config.credentials?.token + t + nonce;
221
- const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret)
222
- .update(Buffer.from(data, 'utf-8'))
223
- .digest();
224
- const sign = signTerm.toString('base64');
225
- this.debugLog(`Lock: ${this.accessory.displayName} sign: ${sign}`);
226
- let command = '';
227
- if (this.LockTargetState) {
228
- command = 'lock';
243
+ /*if (this.BLE) {
244
+ await this.BLERefreshStatus();
245
+ } else*/ if (this.OpenAPI && this.platform.config.credentials?.token) {
246
+ await this.openAPIpushChanges();
229
247
  } else {
230
- command = 'unlock';
248
+ this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:`
249
+ + ` ${this.device.connectionType}, pushChanges will not happen.`);
231
250
  }
232
- const body = JSON.stringify({
233
- 'command': `${command}`,
234
- 'parameter': 'default',
235
- 'commandType': 'command',
236
- });
237
- this.infoLog(`Lock: ${this.accessory.displayName} Sending request to SwitchBot API. body: ${body},`);
238
- const options = {
239
- hostname: HostDomain,
240
- port: 443,
241
- path: `${DevicePath}/${this.device.deviceId}/commands`,
242
- method: 'POST',
243
- headers: {
244
- 'Authorization': this.platform.config.credentials?.token,
245
- 'sign': sign,
246
- 'nonce': nonce,
247
- 't': t,
248
- 'Content-Type': 'application/json',
249
- 'Content-Length': body.length,
250
- },
251
- };
252
- const req = https.request(options, res => {
253
- this.debugLog(`Lock: ${this.accessory.displayName} statusCode: ${res.statusCode}`);
254
- this.statusCode({ res });
255
- res.on('data', d => {
256
- this.debugLog(`Lock: ${this.accessory.displayName} d: ${d}`);
257
- });
258
- });
259
- req.on('error', (e: any) => {
260
- this.errorLog(`Lock: ${this.accessory.displayName} error message: ${e.message}`);
261
- });
262
- req.write(body);
263
- req.end();
264
- this.debugLog(`Lock: ${this.accessory.displayName} pushchanges: ${JSON.stringify(req)}`);
265
- this.accessory.context.On = this.LockTargetState;
266
251
  interval(5000)
267
252
  .pipe(take(1))
268
253
  .subscribe(async () => {
@@ -270,77 +255,241 @@ export class Lock {
270
255
  });
271
256
  }
272
257
 
258
+ async BLEpushChanges(): Promise<void> {
259
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLEpushChanges`);
260
+ if (this.LockTargetState !== this.accessory.context.LockTargetState) {
261
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLEpushChanges LockTargetState: ${this.LockTargetState}`
262
+ + ` LockTargetStateCached: ${this.accessory.context.LockTargetState}`);
263
+ const switchbot = await this.platform.connectBLE();
264
+ // Convert to BLE Address
265
+ this.device.bleMac = this.device
266
+ .deviceId!.match(/.{1,2}/g)!
267
+ .join(':')
268
+ .toLowerCase();
269
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
270
+ switchbot
271
+ .discover({
272
+ model: '',
273
+ id: this.device.bleMac,
274
+ })
275
+ .then(() => {
276
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Done.`);
277
+ this.LockTargetState = this.platform.Characteristic.LockTargetState.SECURED;
278
+ })
279
+ .catch(async (e: any) => {
280
+ this.apiError(e);
281
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed BLEpushChanges with ${this.device.connectionType}`
282
+ + ` Connection, Error Message: ${superStringify(e.message)}`);
283
+ if (this.platform.config.credentials?.token && this.device.connectionType !== 'Both') {
284
+ this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} Using OpenAPI Connection`);
285
+ await this.openAPIpushChanges();
286
+ }
287
+ });
288
+ } else {
289
+ this.debugLog(
290
+ `${this.device.deviceType}: ${this.accessory.displayName} No BLEpushChanges.` + `LockTargetState: ${this.LockTargetState}, `
291
+ +`LockTargetStateCached: ${this.accessory.context.LockTargetState}`,
292
+ );
293
+ }
294
+ }
295
+
296
+ async openAPIpushChanges(): Promise<void> {
297
+ try {
298
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIpushChanges`);
299
+ if (this.LockTargetState !== this.accessory.context.LockTargetState) {
300
+ // Make Push On request to the API
301
+ const t = Date.now();
302
+ const nonce = 'requestID';
303
+ const data = this.platform.config.credentials?.token + t + nonce;
304
+ const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret)
305
+ .update(Buffer.from(data, 'utf-8'))
306
+ .digest();
307
+ const sign = signTerm.toString('base64');
308
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} sign: ${sign}`);
309
+ let command = '';
310
+ if (this.LockTargetState) {
311
+ command = 'lock';
312
+ } else {
313
+ command = 'unlock';
314
+ }
315
+ const body = superStringify({
316
+ 'command': `${command}`,
317
+ 'parameter': 'default',
318
+ 'commandType': 'command',
319
+ });
320
+ this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Sending request to SwitchBot API. body: ${body},`);
321
+ const options = {
322
+ hostname: HostDomain,
323
+ port: 443,
324
+ path: `${DevicePath}/${this.device.deviceId}/commands`,
325
+ method: 'POST',
326
+ headers: {
327
+ 'Authorization': this.platform.config.credentials?.token,
328
+ 'sign': sign,
329
+ 'nonce': nonce,
330
+ 't': t,
331
+ 'Content-Type': 'application/json',
332
+ 'Content-Length': body.length,
333
+ },
334
+ };
335
+ const req = https.request(options, res => {
336
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIpushChanges statusCode: ${res.statusCode}`);
337
+ this.statusCode({ res });
338
+ res.on('data', d => {
339
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} d: ${d}`);
340
+ });
341
+ });
342
+ req.on('error', (e: any) => {
343
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} error message: ${e.message}`);
344
+ });
345
+ req.write(body);
346
+ req.end();
347
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIpushChanges: ${superStringify(req)}`);
348
+ } else {
349
+ this.debugLog(
350
+ `${this.device.deviceType}: ${this.accessory.displayName} No openAPIpushChanges.` + `LockTargetState: ${this.LockTargetState}, `
351
+ +`LockTargetStateCached: ${this.accessory.context.LockTargetState}`,
352
+ );
353
+ }
354
+ } catch (e: any) {
355
+ this.apiError(e);
356
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed openAPIpushChanges with ${this.device.connectionType}`
357
+ + ` Connection, Error Message: ${superStringify(e.message)}`,
358
+ );
359
+ }
360
+ }
361
+
362
+ /**
363
+ * Handle requests to set the value of the "On" characteristic
364
+ */
365
+ async LockTargetStateSet(value: CharacteristicValue): Promise<void> {
366
+ this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Set LockTargetState: ${value}`);
367
+
368
+ this.LockTargetState = value;
369
+ this.doLockUpdate.next();
370
+ }
371
+
273
372
  async updateHomeKitCharacteristics(): Promise<void> {
274
373
  if (!this.device.lock?.hide_contactsensor) {
275
374
  if (this.ContactSensorState === undefined) {
276
- this.debugLog(`Lock: ${this.accessory.displayName} ContactSensorState: ${this.ContactSensorState}`);
375
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} ContactSensorState: ${this.ContactSensorState}`);
277
376
  } else {
377
+ this.accessory.context.ContactSensorState = this.ContactSensorState;
278
378
  this.contactSensorService?.updateCharacteristic(this.platform.Characteristic.ContactSensorState, this.ContactSensorState);
279
- this.debugLog(`Lock: ${this.accessory.displayName} updateCharacteristic ContactSensorState: ${this.ContactSensorState}`);
379
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic ContactSensorState: ${this.ContactSensorState}`);
280
380
  }
281
381
  }
282
382
  if (this.LockTargetState === undefined) {
283
- this.debugLog(`Lock: ${this.accessory.displayName} LockTargetState: ${this.LockTargetState}`);
383
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LockTargetState: ${this.LockTargetState}`);
284
384
  } else {
385
+ this.accessory.context.LockTargetState = this.LockTargetState;
285
386
  this.lockService.updateCharacteristic(this.platform.Characteristic.LockTargetState, this.LockTargetState);
286
- this.debugLog(`Lock: ${this.accessory.displayName} updateCharacteristic LockTargetState: ${this.LockTargetState}`);
387
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic LockTargetState: ${this.LockTargetState}`);
287
388
  }
288
389
  if (this.LockCurrentState === undefined) {
289
- this.debugLog(`Lock: ${this.accessory.displayName} LockCurrentState: ${this.LockCurrentState}`);
390
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LockCurrentState: ${this.LockCurrentState}`);
290
391
  } else {
392
+ this.accessory.context.LockCurrentState = this.LockCurrentState;
291
393
  this.lockService.updateCharacteristic(this.platform.Characteristic.LockCurrentState, this.LockCurrentState);
292
- this.debugLog(`Lock: ${this.accessory.displayName} updateCharacteristic LockCurrentState: ${this.LockCurrentState}`);
394
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic LockCurrentState: ${this.LockCurrentState}`);
293
395
  }
294
396
  }
295
397
 
296
- async apiError(e: any): Promise<void> {
297
- if (!this.device.lock?.hide_contactsensor) {
298
- this.contactSensorService?.updateCharacteristic(this.platform.Characteristic.ContactSensorState, e);
398
+ async scan(device: device & devicesConfig): Promise<void> {
399
+ if (device.scanDuration) {
400
+ this.scanDuration = this.accessory.context.scanDuration = device.scanDuration;
401
+ if (this.BLE) {
402
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Config scanDuration: ${this.scanDuration}`);
403
+ }
404
+ } else {
405
+ this.scanDuration = this.accessory.context.scanDuration = 1;
406
+ if (this.BLE) {
407
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Default scanDuration: ${this.scanDuration}`);
408
+ }
299
409
  }
300
- this.lockService.updateCharacteristic(this.platform.Characteristic.LockTargetState, e);
301
- this.lockService.updateCharacteristic(this.platform.Characteristic.LockCurrentState, e);
302
- //throw new this.platform.api.hap.HapStatusError(HAPStatus.SERVICE_COMMUNICATION_FAILURE);
303
410
  }
304
411
 
305
412
  async statusCode({ res }: { res: IncomingMessage }): Promise<void> {
306
413
  switch (res.statusCode) {
307
414
  case 151:
308
- this.errorLog(`Lock: ${this.accessory.displayName} Command not supported by this device type.`);
415
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command not supported by this device type.`);
309
416
  break;
310
417
  case 152:
311
- this.errorLog(`Lock: ${this.accessory.displayName} Device not found.`);
418
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device not found.`);
312
419
  break;
313
420
  case 160:
314
- this.errorLog(`Lock: ${this.accessory.displayName} Command is not supported.`);
421
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command is not supported.`);
315
422
  break;
316
423
  case 161:
317
- this.errorLog(`Lock: ${this.accessory.displayName} Device is offline.`);
424
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device is offline.`);
425
+ this.offlineOff();
318
426
  break;
319
427
  case 171:
320
- this.errorLog(`Lock: ${this.accessory.displayName} Hub Device is offline. Hub: ${this.device.hubDeviceId}`);
428
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Hub Device is offline. Hub: ${this.device.hubDeviceId}`);
429
+ this.offlineOff();
321
430
  break;
322
431
  case 190:
323
432
  this.errorLog(
324
- `Lock: ${this.accessory.displayName} Device internal error due to device states not synchronized with server,` +
325
- ` Or command: ${JSON.stringify(res)} format is invalid`,
433
+ `${this.device.deviceType}: ${this.accessory.displayName} Device internal error due to device states not synchronized with server,` +
434
+ ` Or command: ${superStringify(res)} format is invalid`,
326
435
  );
327
436
  break;
328
437
  case 100:
329
- this.debugLog(`Lock: ${this.accessory.displayName} Command successfully sent.`);
438
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Command successfully sent.`);
330
439
  break;
331
440
  default:
332
- this.debugLog(`Lock: ${this.accessory.displayName} Unknown statusCode.`);
441
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Unknown statusCode.`);
333
442
  }
334
443
  }
335
444
 
336
- /**
337
- * Handle requests to set the value of the "On" characteristic
338
- */
339
- async LockTargetStateSet(value: CharacteristicValue): Promise<void> {
340
- this.debugLog(`Lock: ${this.accessory.displayName} Set LockTargetState: ${value}`);
445
+ async offlineOff(): Promise<void> {
446
+ if (this.device.offline) {
447
+ this.LockCurrentState = this.platform.Characteristic.LockCurrentState.SECURED;
448
+ this.lockService.getCharacteristic(this.platform.Characteristic.LockCurrentState).updateValue(this.LockCurrentState);
449
+ await this.updateHomeKitCharacteristics();
450
+ }
451
+ }
341
452
 
342
- this.LockTargetState = value;
343
- this.doLockUpdate.next();
453
+ async apiError(e: any): Promise<void> {
454
+ if (!this.device.lock?.hide_contactsensor) {
455
+ this.contactSensorService?.updateCharacteristic(this.platform.Characteristic.ContactSensorState, e);
456
+ }
457
+ this.lockService.updateCharacteristic(this.platform.Characteristic.LockTargetState, e);
458
+ this.lockService.updateCharacteristic(this.platform.Characteristic.LockCurrentState, e);
459
+ }
460
+
461
+ FirmwareRevision(accessory: PlatformAccessory<Context>, device: device & devicesConfig): CharacteristicValue {
462
+ let FirmwareRevision: string;
463
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}`
464
+ + ` accessory.context.FirmwareRevision: ${accessory.context.FirmwareRevision}`);
465
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} device.firmware: ${device.firmware}`);
466
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} this.platform.version: ${this.platform.version}`);
467
+ if (accessory.context.FirmwareRevision) {
468
+ FirmwareRevision = accessory.context.FirmwareRevision;
469
+ } else if (device.firmware) {
470
+ FirmwareRevision = device.firmware;
471
+ } else {
472
+ FirmwareRevision = this.platform.version;
473
+ }
474
+ return FirmwareRevision;
475
+ }
476
+
477
+ private conext() {
478
+ if (this.LockTargetState === undefined) {
479
+ this.LockTargetState = false;
480
+ } else {
481
+ this.LockTargetState = this.accessory.context.On;
482
+ }
483
+ }
484
+
485
+ async refreshRate(device: device & devicesConfig): Promise<void> {
486
+ if (device.refreshRate) {
487
+ this.deviceRefreshRate = this.accessory.context.refreshRate = device.refreshRate;
488
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Config refreshRate: ${this.deviceRefreshRate}`);
489
+ } else if (this.platform.config.options!.refreshRate) {
490
+ this.deviceRefreshRate = this.accessory.context.refreshRate = this.platform.config.options!.refreshRate;
491
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Platform Config refreshRate: ${this.deviceRefreshRate}`);
492
+ }
344
493
  }
345
494
 
346
495
  async config(device: device & devicesConfig): Promise<void> {
@@ -348,8 +497,8 @@ export class Lock {
348
497
  if (device.lock) {
349
498
  config = device.lock;
350
499
  }
351
- if (device.ble !== undefined) {
352
- config['ble'] = device.ble;
500
+ if (device.connectionType !== undefined) {
501
+ config['connectionType'] = device.connectionType;
353
502
  }
354
503
  if (device.logging !== undefined) {
355
504
  config['logging'] = device.logging;
@@ -361,65 +510,26 @@ export class Lock {
361
510
  config['scanDuration'] = device.scanDuration;
362
511
  }
363
512
  if (Object.entries(config).length !== 0) {
364
- this.infoLog(`Lock: ${this.accessory.displayName} Config: ${JSON.stringify(config)}`);
365
- }
366
- }
367
-
368
- async refreshRate(device: device & devicesConfig): Promise<void> {
369
- if (device.refreshRate) {
370
- this.deviceRefreshRate = this.accessory.context.refreshRate = device.refreshRate;
371
- this.debugLog(`Lock: ${this.accessory.displayName} Using Device Config refreshRate: ${this.deviceRefreshRate}`);
372
- } else if (this.platform.config.options!.refreshRate) {
373
- this.deviceRefreshRate = this.accessory.context.refreshRate = this.platform.config.options!.refreshRate;
374
- this.debugLog(`Lock: ${this.accessory.displayName} Using Platform Config refreshRate: ${this.deviceRefreshRate}`);
375
- }
376
- }
377
-
378
- async scan(device: device & devicesConfig): Promise<void> {
379
- if (device.scanDuration) {
380
- this.scanDuration = this.accessory.context.scanDuration = device.scanDuration;
381
- if (device.ble) {
382
- this.debugLog(`Lock: ${this.accessory.displayName} Using Device Config scanDuration: ${this.scanDuration}`);
383
- }
384
- } else {
385
- this.scanDuration = this.accessory.context.scanDuration = 1;
386
- if (this.device.ble) {
387
- this.debugLog(`Lock: ${this.accessory.displayName} Using Default scanDuration: ${this.scanDuration}`);
388
- }
513
+ this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Config: ${superStringify(config)}`);
389
514
  }
390
515
  }
391
516
 
392
517
  async logs(device: device & devicesConfig): Promise<void> {
393
518
  if (this.platform.debugMode) {
394
519
  this.deviceLogging = this.accessory.context.logging = 'debugMode';
395
- this.debugLog(`Lock: ${this.accessory.displayName} Using Debug Mode Logging: ${this.deviceLogging}`);
520
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Debug Mode Logging: ${this.deviceLogging}`);
396
521
  } else if (device.logging) {
397
522
  this.deviceLogging = this.accessory.context.logging = device.logging;
398
- this.debugLog(`Lock: ${this.accessory.displayName} Using Device Config Logging: ${this.deviceLogging}`);
523
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Config Logging: ${this.deviceLogging}`);
399
524
  } else if (this.platform.config.options?.logging) {
400
525
  this.deviceLogging = this.accessory.context.logging = this.platform.config.options?.logging;
401
- this.debugLog(`Lock: ${this.accessory.displayName} Using Platform Config Logging: ${this.deviceLogging}`);
526
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Platform Config Logging: ${this.deviceLogging}`);
402
527
  } else {
403
528
  this.deviceLogging = this.accessory.context.logging = 'standard';
404
- this.debugLog(`Lock: ${this.accessory.displayName} Logging Not Set, Using: ${this.deviceLogging}`);
529
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Logging Not Set, Using: ${this.deviceLogging}`);
405
530
  }
406
531
  }
407
532
 
408
- FirmwareRevision(accessory: PlatformAccessory<Context>, device: device & devicesConfig): CharacteristicValue {
409
- let FirmwareRevision: string;
410
- this.debugLog(`Lock: ${this.accessory.displayName} accessory.context.FirmwareRevision: ${accessory.context.FirmwareRevision}`);
411
- this.debugLog(`Lock: ${this.accessory.displayName} device.firmware: ${device.firmware}`);
412
- this.debugLog(`Lock: ${this.accessory.displayName} this.platform.version: ${this.platform.version}`);
413
- if (accessory.context.FirmwareRevision) {
414
- FirmwareRevision = accessory.context.FirmwareRevision;
415
- } else if (device.firmware) {
416
- FirmwareRevision = device.firmware;
417
- } else {
418
- FirmwareRevision = this.platform.version;
419
- }
420
- return FirmwareRevision;
421
- }
422
-
423
533
  /**
424
534
  * Logging for Device
425
535
  */