@switchbot/homebridge-switchbot 2.0.0-beta.8 → 2.0.0

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