@switchbot/homebridge-switchbot 2.0.0-beta.3 → 2.0.0-beta.30

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 +10 -1
  2. package/README.md +1 -2
  3. package/config.schema.json +102 -20
  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 +655 -649
  7. package/dist/device/bot.js.map +1 -1
  8. package/dist/device/colorbulb.d.ts +36 -19
  9. package/dist/device/colorbulb.d.ts.map +1 -1
  10. package/dist/device/colorbulb.js +483 -309
  11. package/dist/device/colorbulb.js.map +1 -1
  12. package/dist/device/contact.d.ts +18 -8
  13. package/dist/device/contact.d.ts.map +1 -1
  14. package/dist/device/contact.js +303 -237
  15. package/dist/device/contact.js.map +1 -1
  16. package/dist/device/curtain.d.ts +23 -16
  17. package/dist/device/curtain.d.ts.map +1 -1
  18. package/dist/device/curtain.js +541 -498
  19. package/dist/device/curtain.js.map +1 -1
  20. package/dist/device/humidifier.d.ts +24 -18
  21. package/dist/device/humidifier.d.ts.map +1 -1
  22. package/dist/device/humidifier.js +450 -369
  23. package/dist/device/humidifier.js.map +1 -1
  24. package/dist/device/lock.d.ts +27 -8
  25. package/dist/device/lock.d.ts.map +1 -1
  26. package/dist/device/lock.js +302 -148
  27. package/dist/device/lock.js.map +1 -1
  28. package/dist/device/meter.d.ts +22 -16
  29. package/dist/device/meter.d.ts.map +1 -1
  30. package/dist/device/meter.js +340 -262
  31. package/dist/device/meter.js.map +1 -1
  32. package/dist/device/meterplus.d.ts +24 -12
  33. package/dist/device/meterplus.d.ts.map +1 -1
  34. package/dist/device/meterplus.js +359 -213
  35. package/dist/device/meterplus.js.map +1 -1
  36. package/dist/device/motion.d.ts +18 -8
  37. package/dist/device/motion.d.ts.map +1 -1
  38. package/dist/device/motion.js +276 -216
  39. package/dist/device/motion.js.map +1 -1
  40. package/dist/device/plug.d.ts +27 -17
  41. package/dist/device/plug.d.ts.map +1 -1
  42. package/dist/device/plug.js +292 -251
  43. package/dist/device/plug.js.map +1 -1
  44. package/dist/device/striplight.d.ts +43 -19
  45. package/dist/device/striplight.d.ts.map +1 -1
  46. package/dist/device/striplight.js +503 -262
  47. package/dist/device/striplight.js.map +1 -1
  48. package/dist/irdevice/airconditioner.d.ts +9 -12
  49. package/dist/irdevice/airconditioner.d.ts.map +1 -1
  50. package/dist/irdevice/airconditioner.js +275 -230
  51. package/dist/irdevice/airconditioner.js.map +1 -1
  52. package/dist/irdevice/airpurifier.d.ts +5 -3
  53. package/dist/irdevice/airpurifier.d.ts.map +1 -1
  54. package/dist/irdevice/airpurifier.js +151 -104
  55. package/dist/irdevice/airpurifier.js.map +1 -1
  56. package/dist/irdevice/camera.d.ts +11 -8
  57. package/dist/irdevice/camera.d.ts.map +1 -1
  58. package/dist/irdevice/camera.js +130 -86
  59. package/dist/irdevice/camera.js.map +1 -1
  60. package/dist/irdevice/fan.d.ts +10 -7
  61. package/dist/irdevice/fan.d.ts.map +1 -1
  62. package/dist/irdevice/fan.js +157 -109
  63. package/dist/irdevice/fan.js.map +1 -1
  64. package/dist/irdevice/light.d.ts +11 -8
  65. package/dist/irdevice/light.d.ts.map +1 -1
  66. package/dist/irdevice/light.js +134 -103
  67. package/dist/irdevice/light.js.map +1 -1
  68. package/dist/irdevice/other.d.ts +11 -8
  69. package/dist/irdevice/other.d.ts.map +1 -1
  70. package/dist/irdevice/other.js +142 -98
  71. package/dist/irdevice/other.js.map +1 -1
  72. package/dist/irdevice/tv.d.ts +12 -9
  73. package/dist/irdevice/tv.d.ts.map +1 -1
  74. package/dist/irdevice/tv.js +140 -93
  75. package/dist/irdevice/tv.js.map +1 -1
  76. package/dist/irdevice/vacuumcleaner.d.ts +9 -10
  77. package/dist/irdevice/vacuumcleaner.d.ts.map +1 -1
  78. package/dist/irdevice/vacuumcleaner.js +129 -89
  79. package/dist/irdevice/vacuumcleaner.js.map +1 -1
  80. package/dist/irdevice/waterheater.d.ts +8 -9
  81. package/dist/irdevice/waterheater.d.ts.map +1 -1
  82. package/dist/irdevice/waterheater.js +129 -89
  83. package/dist/irdevice/waterheater.js.map +1 -1
  84. package/dist/platform.d.ts +14 -12
  85. package/dist/platform.d.ts.map +1 -1
  86. package/dist/platform.js +479 -434
  87. package/dist/platform.js.map +1 -1
  88. package/dist/settings.d.ts +18 -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 +654 -660
  93. package/src/device/colorbulb.ts +487 -344
  94. package/src/device/contact.ts +306 -241
  95. package/src/device/curtain.ts +546 -512
  96. package/src/device/humidifier.ts +453 -403
  97. package/src/device/lock.ts +311 -149
  98. package/src/device/meter.ts +351 -275
  99. package/src/device/meterplus.ts +369 -219
  100. package/src/device/motion.ts +282 -222
  101. package/src/device/plug.ts +296 -260
  102. package/src/device/striplight.ts +519 -289
  103. package/src/irdevice/airconditioner.ts +279 -241
  104. package/src/irdevice/airpurifier.ts +148 -103
  105. package/src/irdevice/camera.ts +128 -85
  106. package/src/irdevice/fan.ts +154 -106
  107. package/src/irdevice/light.ts +132 -103
  108. package/src/irdevice/other.ts +140 -97
  109. package/src/irdevice/tv.ts +139 -93
  110. package/src/irdevice/vacuumcleaner.ts +128 -89
  111. package/src/irdevice/waterheater.ts +127 -89
  112. package/src/platform.ts +469 -456
  113. package/src/settings.ts +18 -11
@@ -8,6 +8,7 @@ const https_1 = __importDefault(require("https"));
8
8
  const crypto_1 = __importDefault(require("crypto"));
9
9
  const rxjs_1 = require("rxjs");
10
10
  const async_mqtt_1 = require("async-mqtt");
11
+ const super_stringify_1 = __importDefault(require("super-stringify"));
11
12
  const operators_1 = require("rxjs/operators");
12
13
  const settings_1 = require("../settings");
13
14
  class Curtain {
@@ -17,15 +18,16 @@ class Curtain {
17
18
  this.device = device;
18
19
  //MQTT stuff
19
20
  this.mqttClient = null;
21
+ // Connection
22
+ this.BLE = (this.device.connectionType === 'BLE' || this.device.connectionType === 'BLE/OpenAPI');
23
+ this.OpenAPI = (this.device.connectionType === 'OpenAPI' || this.device.connectionType === 'BLE/OpenAPI');
20
24
  // default placeholders
21
25
  this.logs(device);
22
26
  this.refreshRate(device);
23
27
  this.scan(device);
24
28
  this.config(device);
25
29
  this.setupMqtt(device);
26
- this.CurrentPosition = 0;
27
- this.TargetPosition = 0;
28
- this.PositionState = this.platform.Characteristic.PositionState.STOPPED;
30
+ this.context();
29
31
  // this is subject we use to track when we need to POST changes to the SwitchBot API
30
32
  this.doCurtainUpdate = new rxjs_1.Subject();
31
33
  this.curtainUpdateInProgress = false;
@@ -76,34 +78,34 @@ class Curtain {
76
78
  .onSet(this.TargetPositionSet.bind(this));
77
79
  // Light Sensor Service
78
80
  if (device.curtain?.hide_lightsensor) {
79
- this.debugLog(`Curtain: ${accessory.displayName} Removing Light Sensor Service`);
81
+ this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Removing Light Sensor Service`);
80
82
  this.lightSensorService = this.accessory.getService(this.platform.Service.LightSensor);
81
83
  accessory.removeService(this.lightSensorService);
82
84
  }
83
85
  else if (!this.lightSensorService) {
84
- this.debugLog(`Curtain: ${accessory.displayName} Add Light Sensor Service`);
86
+ this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Add Light Sensor Service`);
85
87
  (this.lightSensorService =
86
88
  this.accessory.getService(this.platform.Service.LightSensor) || this.accessory.addService(this.platform.Service.LightSensor)),
87
89
  `${accessory.displayName} Light Sensor`;
88
90
  this.lightSensorService.setCharacteristic(this.platform.Characteristic.Name, `${accessory.displayName} Light Sensor`);
89
91
  }
90
92
  else {
91
- this.debugLog(`Curtain: ${accessory.displayName} Light Sensor Service Not Added`);
93
+ this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Light Sensor Service Not Added`);
92
94
  }
93
95
  // Battery Service
94
- if (!device.ble) {
95
- this.debugLog(`Curtain: ${accessory.displayName} Removing Battery Service`);
96
+ if (!this.BLE) {
97
+ this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Removing Battery Service`);
96
98
  this.batteryService = this.accessory.getService(this.platform.Service.Battery);
97
99
  accessory.removeService(this.batteryService);
98
100
  }
99
- else if (device.ble && !this.batteryService) {
100
- this.debugLog(`Curtain: ${accessory.displayName} Add Battery Service`);
101
+ else if (this.BLE && !this.batteryService) {
102
+ this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Add Battery Service`);
101
103
  (this.batteryService = this.accessory.getService(this.platform.Service.Battery) || this.accessory.addService(this.platform.Service.Battery)),
102
104
  `${accessory.displayName} Battery`;
103
105
  this.batteryService.setCharacteristic(this.platform.Characteristic.Name, `${accessory.displayName} Battery`);
104
106
  }
105
107
  else {
106
- this.debugLog(`Curtain: ${accessory.displayName} Battery Service Not Added`);
108
+ this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Battery Service Not Added`);
107
109
  }
108
110
  // Update Homekit
109
111
  this.updateHomeKitCharacteristics();
@@ -120,7 +122,7 @@ class Curtain {
120
122
  if (this.PositionState === this.platform.Characteristic.PositionState.STOPPED) {
121
123
  return;
122
124
  }
123
- this.debugLog(`Curtain: ${accessory.displayName} Refresh Status When Moving, PositionState: ${this.PositionState}`);
125
+ this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Refresh Status When Moving, PositionState: ${this.PositionState}`);
124
126
  await this.refreshStatus();
125
127
  });
126
128
  // Watch for Curtain change events
@@ -134,94 +136,65 @@ class Curtain {
134
136
  await this.pushChanges();
135
137
  }
136
138
  catch (e) {
137
- this.errorLog(`Curtain: ${this.accessory.displayName} failed pushChanges`);
138
- if (this.deviceLogging.includes('debug')) {
139
- this.errorLog(`Curtain: ${this.accessory.displayName} failed pushChanges,` + ` Error Message: ${JSON.stringify(e.message)}`);
140
- }
141
139
  this.apiError(e);
140
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed pushChanges with ${this.device.connectionType} Connection,`
141
+ + ` Error Message: ${(0, super_stringify_1.default)(e.message)}`);
142
142
  }
143
143
  this.curtainUpdateInProgress = false;
144
144
  });
145
145
  }
146
- /*
147
- * Publish MQTT message for topics of
148
- * 'homebridge-switchbot/curtain/xx:xx:xx:xx:xx:xx'
149
- */
150
- mqttPublish(topic, message) {
151
- const mac = this.device.deviceId
152
- ?.toLowerCase()
153
- .match(/[\s\S]{1,2}/g)
154
- ?.join(':');
155
- const options = this.device.mqttPubOptions || {};
156
- this.mqttClient?.publish(`homebridge-switchbot/curtain/${mac}/${topic}`, `${message}`, options);
157
- this.debugLog(`Meter: ${this.accessory.displayName} MQTT message: ${topic}/${message} options:${JSON.stringify(options)}`);
158
- }
159
- /*
160
- * Setup MQTT hadler if URL is specifed.
161
- */
162
- async setupMqtt(device) {
163
- if (device.mqttURL) {
164
- try {
165
- this.mqttClient = await (0, async_mqtt_1.connectAsync)(device.mqttURL, device.mqttOptions || {});
166
- this.debugLog(`Meter: ${this.accessory.displayName} MQTT connection has been established successfully.`);
167
- this.mqttClient.on('error', (e) => {
168
- this.errorLog(`Meter: ${this.accessory.displayName} Failed to publish MQTT messages. ${e}`);
169
- });
170
- }
171
- catch (e) {
172
- this.mqttClient = null;
173
- this.errorLog(`Meter: ${this.accessory.displayName} Failed to establish MQTT connection. ${e}`);
174
- }
175
- }
176
- }
177
146
  /**
178
147
  * Parse the device status from the SwitchBot api
179
148
  */
180
149
  async parseStatus() {
181
- if (this.SwitchToOpenAPI || !this.device.ble) {
150
+ if (this.BLE) {
151
+ await this.BLEparseStatus();
152
+ }
153
+ else if (this.OpenAPI && this.platform.config.credentials?.token) {
182
154
  await this.openAPIparseStatus();
183
155
  }
184
156
  else {
185
- await this.BLEparseStatus();
157
+ this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:`
158
+ + ` ${this.device.connectionType}, parseStatus will not happen.`);
186
159
  }
187
160
  }
188
161
  async BLEparseStatus() {
189
- this.debugLog(`Curtain: ${this.accessory.displayName} BLE parseStatus`);
162
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLEparseStatus`);
190
163
  // CurrentPosition
191
164
  this.CurrentPosition = 100 - Number(this.position);
192
165
  await this.setMinMax();
193
- this.debugLog(`Curtain: ${this.accessory.displayName} CurrentPosition ${this.CurrentPosition}`);
166
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} CurrentPosition ${this.CurrentPosition}`);
194
167
  if (this.setNewTarget) {
195
- this.infoLog(`Curtain: ${this.accessory.displayName} Checking Status ...`);
168
+ this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Checking Status ...`);
196
169
  }
197
170
  if (this.setNewTarget) {
198
171
  await this.setMinMax();
199
172
  if (this.TargetPosition > this.CurrentPosition) {
200
- this.debugLog(`Curtain: ${this.accessory.displayName} Closing, CurrentPosition: ${this.CurrentPosition}`);
173
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Closing, CurrentPosition: ${this.CurrentPosition}`);
201
174
  this.PositionState = this.platform.Characteristic.PositionState.INCREASING;
202
175
  this.windowCoveringService.getCharacteristic(this.platform.Characteristic.PositionState).updateValue(this.PositionState);
203
- this.debugLog(`Curtain: ${this.CurrentPosition} INCREASING PositionState: ${this.PositionState}`);
176
+ this.debugLog(`${this.device.deviceType}: ${this.CurrentPosition} INCREASING PositionState: ${this.PositionState}`);
204
177
  }
205
178
  else if (this.TargetPosition < this.CurrentPosition) {
206
- this.debugLog(`Curtain: ${this.accessory.displayName} Opening, CurrentPosition: ${this.CurrentPosition}`);
179
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Opening, CurrentPosition: ${this.CurrentPosition}`);
207
180
  this.PositionState = this.platform.Characteristic.PositionState.DECREASING;
208
181
  this.windowCoveringService.getCharacteristic(this.platform.Characteristic.PositionState).updateValue(this.PositionState);
209
- this.debugLog(`Curtain: ${this.CurrentPosition} DECREASING PositionState: ${this.PositionState}`);
182
+ this.debugLog(`${this.device.deviceType}: ${this.CurrentPosition} DECREASING PositionState: ${this.PositionState}`);
210
183
  }
211
184
  else {
212
- this.debugLog(`Curtain: ${this.CurrentPosition} Standby, CurrentPosition: ${this.CurrentPosition}`);
185
+ this.debugLog(`${this.device.deviceType}: ${this.CurrentPosition} Standby, CurrentPosition: ${this.CurrentPosition}`);
213
186
  this.PositionState = this.platform.Characteristic.PositionState.STOPPED;
214
187
  this.windowCoveringService.getCharacteristic(this.platform.Characteristic.PositionState).updateValue(this.PositionState);
215
- this.debugLog(`Curtain: ${this.CurrentPosition} STOPPED PositionState: ${this.PositionState}`);
188
+ this.debugLog(`${this.device.deviceType}: ${this.CurrentPosition} STOPPED PositionState: ${this.PositionState}`);
216
189
  }
217
190
  }
218
191
  else {
219
- this.debugLog(`Curtain: ${this.accessory.displayName} Standby, CurrentPosition: ${this.CurrentPosition}`);
192
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Standby, CurrentPosition: ${this.CurrentPosition}`);
220
193
  this.TargetPosition = this.CurrentPosition;
221
194
  this.PositionState = this.platform.Characteristic.PositionState.STOPPED;
222
- this.debugLog(`Curtain: ${this.accessory.displayName} Stopped`);
195
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Stopped`);
223
196
  }
224
- this.debugLog(`Curtain: ${this.accessory.displayName} CurrentPosition: ${this.CurrentPosition},` +
197
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} CurrentPosition: ${this.CurrentPosition},` +
225
198
  ` TargetPosition: ${this.TargetPosition}, PositionState: ${this.PositionState},`);
226
199
  if (!this.device.curtain?.hide_lightsensor) {
227
200
  this.set_minLux = this.minLux();
@@ -231,47 +204,48 @@ class Curtain {
231
204
  switch (this.lightLevel) {
232
205
  case 1:
233
206
  this.CurrentAmbientLightLevel = this.set_minLux;
234
- this.debugLog(`Curtain: ${this.accessory.displayName} LightLevel: ${this.lightLevel}`);
207
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${this.lightLevel}`);
235
208
  break;
236
209
  case 2:
237
210
  this.CurrentAmbientLightLevel = (this.set_maxLux - this.set_minLux) / this.spaceBetweenLevels;
238
- this.debugLog(`Curtain: ${this.accessory.displayName} LightLevel: ${this.lightLevel},` +
211
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${this.lightLevel},` +
239
212
  ` Calculation: ${(this.set_maxLux - this.set_minLux) / this.spaceBetweenLevels}`);
240
213
  break;
241
214
  case 3:
242
215
  this.CurrentAmbientLightLevel = ((this.set_maxLux - this.set_minLux) / this.spaceBetweenLevels) * 2;
243
- this.debugLog(`Curtain: ${this.accessory.displayName} LightLevel: ${this.lightLevel}`);
216
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${this.lightLevel}`);
244
217
  break;
245
218
  case 4:
246
219
  this.CurrentAmbientLightLevel = ((this.set_maxLux - this.set_minLux) / this.spaceBetweenLevels) * 3;
247
- this.debugLog(`Curtain: ${this.accessory.displayName} LightLevel: ${this.lightLevel}`);
220
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${this.lightLevel}`);
248
221
  break;
249
222
  case 5:
250
223
  this.CurrentAmbientLightLevel = ((this.set_maxLux - this.set_minLux) / this.spaceBetweenLevels) * 4;
251
- this.debugLog(`Curtain: ${this.accessory.displayName} LightLevel: ${this.lightLevel}`);
224
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${this.lightLevel}`);
252
225
  break;
253
226
  case 6:
254
227
  this.CurrentAmbientLightLevel = ((this.set_maxLux - this.set_minLux) / this.spaceBetweenLevels) * 5;
255
- this.debugLog(`Curtain: ${this.accessory.displayName} LightLevel: ${this.lightLevel}`);
228
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${this.lightLevel}`);
256
229
  break;
257
230
  case 7:
258
231
  this.CurrentAmbientLightLevel = ((this.set_maxLux - this.set_minLux) / this.spaceBetweenLevels) * 6;
259
- this.debugLog(`Curtain: ${this.accessory.displayName} LightLevel: ${this.lightLevel}`);
232
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${this.lightLevel}`);
260
233
  break;
261
234
  case 8:
262
235
  this.CurrentAmbientLightLevel = ((this.set_maxLux - this.set_minLux) / this.spaceBetweenLevels) * 7;
263
- this.debugLog(`Curtain: ${this.accessory.displayName} LightLevel: ${this.lightLevel}`);
236
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${this.lightLevel}`);
264
237
  break;
265
238
  case 9:
266
239
  this.CurrentAmbientLightLevel = ((this.set_maxLux - this.set_minLux) / this.spaceBetweenLevels) * 8;
267
- this.debugLog(`Curtain: ${this.accessory.displayName} LightLevel: ${this.lightLevel}`);
240
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${this.lightLevel}`);
268
241
  break;
269
242
  case 10:
270
243
  default:
271
244
  this.CurrentAmbientLightLevel = this.set_maxLux;
272
245
  this.debugLog();
273
246
  }
274
- this.debugLog(`Curtain: ${this.accessory.displayName} LightLevel: ${this.lightLevel},` + ` CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`);
247
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${this.lightLevel},`
248
+ + ` CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`);
275
249
  }
276
250
  // Battery
277
251
  this.BatteryLevel = Number(this.battery);
@@ -281,86 +255,85 @@ class Curtain {
281
255
  else {
282
256
  this.StatusLowBattery = this.platform.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
283
257
  }
284
- this.debugLog(`Curtain: ${this.accessory.displayName} BatteryLevel: ${this.BatteryLevel}, StatusLowBattery: ${this.StatusLowBattery}`);
258
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.BatteryLevel},`
259
+ + ` StatusLowBattery: ${this.StatusLowBattery}`);
285
260
  }
286
261
  async openAPIparseStatus() {
287
- if (this.device.ble) {
288
- this.SwitchToOpenAPI = false;
262
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIparseStatus`);
263
+ // CurrentPosition
264
+ this.CurrentPosition = 100 - Number(this.slidePosition);
265
+ await this.setMinMax();
266
+ this.debugLog(`Curtain ${this.accessory.displayName} CurrentPosition: ${this.CurrentPosition}`);
267
+ if (this.setNewTarget) {
268
+ this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Checking Status ...`);
289
269
  }
290
- if (this.platform.config.credentials?.token) {
291
- this.debugLog(`Curtain: ${this.accessory.displayName} OpenAPI parseStatus`);
292
- // CurrentPosition
293
- this.CurrentPosition = 100 - Number(this.slidePosition);
270
+ if (this.setNewTarget && this.moving) {
294
271
  await this.setMinMax();
295
- this.debugLog(`Curtain ${this.accessory.displayName} CurrentPosition: ${this.CurrentPosition}`);
296
- if (this.setNewTarget) {
297
- this.infoLog(`Curtain: ${this.accessory.displayName} Checking Status ...`);
298
- }
299
- if (this.setNewTarget && this.moving) {
300
- await this.setMinMax();
301
- if (this.TargetPosition > this.CurrentPosition) {
302
- this.debugLog(`Curtain: ${this.accessory.displayName} Closing, CurrentPosition: ${this.CurrentPosition} `);
303
- this.PositionState = this.platform.Characteristic.PositionState.INCREASING;
304
- this.windowCoveringService.getCharacteristic(this.platform.Characteristic.PositionState).updateValue(this.PositionState);
305
- this.debugLog(`Curtain: ${this.CurrentPosition} INCREASING PositionState: ${this.PositionState}`);
306
- }
307
- else if (this.TargetPosition < this.CurrentPosition) {
308
- this.debugLog(`Curtain: ${this.accessory.displayName} Opening, CurrentPosition: ${this.CurrentPosition} `);
309
- this.PositionState = this.platform.Characteristic.PositionState.DECREASING;
310
- this.windowCoveringService.getCharacteristic(this.platform.Characteristic.PositionState).updateValue(this.PositionState);
311
- this.debugLog(`Curtain: ${this.CurrentPosition} DECREASING PositionState: ${this.PositionState}`);
312
- }
313
- else {
314
- this.debugLog(`Curtain: ${this.CurrentPosition} Standby, CurrentPosition: ${this.CurrentPosition}`);
315
- this.PositionState = this.platform.Characteristic.PositionState.STOPPED;
316
- this.windowCoveringService.getCharacteristic(this.platform.Characteristic.PositionState).updateValue(this.PositionState);
317
- this.debugLog(`Curtain: ${this.CurrentPosition} STOPPED PositionState: ${this.PositionState}`);
318
- }
272
+ if (this.TargetPosition > this.CurrentPosition) {
273
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Closing, CurrentPosition: ${this.CurrentPosition} `);
274
+ this.PositionState = this.platform.Characteristic.PositionState.INCREASING;
275
+ this.windowCoveringService.getCharacteristic(this.platform.Characteristic.PositionState).updateValue(this.PositionState);
276
+ this.debugLog(`${this.device.deviceType}: ${this.CurrentPosition} INCREASING PositionState: ${this.PositionState}`);
277
+ }
278
+ else if (this.TargetPosition < this.CurrentPosition) {
279
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Opening, CurrentPosition: ${this.CurrentPosition} `);
280
+ this.PositionState = this.platform.Characteristic.PositionState.DECREASING;
281
+ this.windowCoveringService.getCharacteristic(this.platform.Characteristic.PositionState).updateValue(this.PositionState);
282
+ this.debugLog(`${this.device.deviceType}: ${this.CurrentPosition} DECREASING PositionState: ${this.PositionState}`);
319
283
  }
320
284
  else {
321
- this.debugLog(`Curtain: ${this.accessory.displayName} Standby, CurrentPosition: ${this.CurrentPosition}`);
322
- this.TargetPosition = this.CurrentPosition;
285
+ this.debugLog(`${this.device.deviceType}: ${this.CurrentPosition} Standby, CurrentPosition: ${this.CurrentPosition}`);
323
286
  this.PositionState = this.platform.Characteristic.PositionState.STOPPED;
324
- this.debugLog(`Curtain: ${this.accessory.displayName} Stopped`);
325
- }
326
- this.debugLog(`Curtain: ${this.accessory.displayName} CurrentPosition: ${this.CurrentPosition},` +
327
- ` TargetPosition: ${this.TargetPosition}, PositionState: ${this.PositionState},`);
328
- if (!this.device.curtain?.hide_lightsensor) {
329
- this.set_minLux = this.minLux();
330
- this.set_maxLux = this.maxLux();
331
- // Brightness
332
- switch (this.brightness) {
333
- case 'dim':
334
- this.CurrentAmbientLightLevel = this.set_minLux;
335
- break;
336
- case 'bright':
337
- default:
338
- this.CurrentAmbientLightLevel = this.set_maxLux;
339
- }
340
- this.debugLog(`Curtain: ${this.accessory.displayName} CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`);
287
+ this.windowCoveringService.getCharacteristic(this.platform.Characteristic.PositionState).updateValue(this.PositionState);
288
+ this.debugLog(`${this.device.deviceType}: ${this.CurrentPosition} STOPPED PositionState: ${this.PositionState}`);
289
+ }
290
+ }
291
+ else {
292
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Standby, CurrentPosition: ${this.CurrentPosition}`);
293
+ this.TargetPosition = this.CurrentPosition;
294
+ this.PositionState = this.platform.Characteristic.PositionState.STOPPED;
295
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Stopped`);
296
+ }
297
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} CurrentPosition: ${this.CurrentPosition},` +
298
+ ` TargetPosition: ${this.TargetPosition}, PositionState: ${this.PositionState},`);
299
+ if (!this.device.curtain?.hide_lightsensor) {
300
+ this.set_minLux = this.minLux();
301
+ this.set_maxLux = this.maxLux();
302
+ // Brightness
303
+ switch (this.brightness) {
304
+ case 'dim':
305
+ this.CurrentAmbientLightLevel = this.set_minLux;
306
+ break;
307
+ case 'bright':
308
+ default:
309
+ this.CurrentAmbientLightLevel = this.set_maxLux;
341
310
  }
311
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`);
342
312
  }
343
313
  }
344
314
  async refreshStatus() {
345
- if (this.device.ble) {
315
+ if (this.BLE) {
346
316
  await this.BLERefreshStatus();
347
317
  }
348
- else {
318
+ else if (this.OpenAPI && this.platform.config.credentials?.token) {
349
319
  await this.openAPIRefreshStatus();
350
320
  }
321
+ else {
322
+ this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:`
323
+ + ` ${this.device.connectionType}, refreshStatus will not happen.`);
324
+ }
351
325
  }
352
326
  async BLERefreshStatus() {
353
- this.debugLog(`Curtain: ${this.accessory.displayName} BLE refreshStatus`);
327
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLERefreshStatus`);
354
328
  const switchbot = await this.platform.connectBLE();
355
329
  // Convert to BLE Address
356
330
  this.device.bleMac = this.device
357
331
  .deviceId.match(/.{1,2}/g)
358
332
  .join(':')
359
333
  .toLowerCase();
360
- this.debugLog(`Curtain: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
334
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
361
335
  this.getCustomBLEAddress(switchbot);
362
336
  // Start to monitor advertisement packets
363
- this.errorLog(`Color Bulb: ${this.accessory.displayName} switchbot: ${JSON.stringify(switchbot)}`);
364
337
  if (switchbot !== false) {
365
338
  switchbot
366
339
  .startScan({
@@ -371,27 +344,23 @@ class Curtain {
371
344
  // Set an event hander
372
345
  switchbot.onadvertisement = (ad) => {
373
346
  this.address = ad.address;
374
- if (this.deviceLogging.includes('debug')) {
375
- this.infoLog(this.address);
376
- this.infoLog(this.device.bleMac);
377
- this.infoLog(`Curtain: ${this.accessory.displayName} BLE Address Found: ${this.address}`);
378
- this.infoLog(`Curtain: ${this.accessory.displayName} Config BLE Address: ${this.device.bleMac}`);
379
- }
347
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Config BLE Address: ${this.device.bleMac},`
348
+ + ` BLE Address Found: ${this.address}`);
380
349
  this.serviceData = ad.serviceData;
381
350
  this.calibration = ad.serviceData.calibration;
382
351
  this.battery = ad.serviceData.battery;
383
352
  this.position = ad.serviceData.position;
384
353
  this.lightLevel = ad.serviceData.lightLevel;
385
- this.debugLog(`Curtain: ${this.accessory.displayName} serviceData: ${JSON.stringify(ad.serviceData)}`);
386
- this.debugLog(`Curtain: ${this.accessory.displayName} calibration: ${ad.serviceData.calibration}, ` +
354
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${(0, super_stringify_1.default)(ad.serviceData)}`);
355
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} calibration: ${ad.serviceData.calibration}, ` +
387
356
  `position: ${ad.serviceData.position}, lightLevel: ${ad.serviceData.lightLevel}, battery: ${ad.serviceData.battery}`);
388
357
  if (this.serviceData) {
389
358
  this.connected = true;
390
- this.debugLog(`Curtain: ${this.accessory.displayName} connected: ${this.connected}`);
359
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} connected: ${this.connected}`);
391
360
  }
392
361
  else {
393
362
  this.connected = false;
394
- this.debugLog(`Curtain: ${this.accessory.displayName} connected: ${this.connected}`);
363
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} connected: ${this.connected}`);
395
364
  }
396
365
  };
397
366
  // Wait 2 seconds
@@ -401,162 +370,107 @@ class Curtain {
401
370
  // Stop to monitor
402
371
  switchbot.stopScan();
403
372
  if (this.connected) {
404
- this.parseStatus();
373
+ this.BLEparseStatus();
405
374
  this.updateHomeKitCharacteristics();
406
375
  }
407
376
  else {
408
- this.errorLog(`Curtain: ${this.accessory.displayName} wasn't able to establish BLE Connection`);
409
- if (this.platform.config.credentials?.token) {
410
- this.warnLog(`Curtain: ${this.accessory.displayName} Using OpenAPI Connection`);
411
- this.SwitchToOpenAPI = true;
412
- await this.openAPIRefreshStatus();
413
- }
377
+ await this.BLERefreshConnection(switchbot);
414
378
  }
415
379
  })
416
380
  .catch(async (e) => {
417
- this.errorLog(`Curtain: ${this.accessory.displayName} failed refreshStatus with BLE Connection`);
418
- if (this.deviceLogging.includes('debug')) {
419
- this.errorLog(`Curtain: ${this.accessory.displayName} failed refreshStatus with BLE Connection,` + ` Error Message: ${JSON.stringify(e.message)}`);
420
- }
421
- if (this.platform.config.credentials?.token) {
422
- this.warnLog(`Curtain: ${this.accessory.displayName} Using OpenAPI Connection`);
423
- this.SwitchToOpenAPI = true;
424
- await this.openAPIRefreshStatus();
425
- }
426
381
  this.apiError(e);
382
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed BLERefreshStatus with ${this.device.connectionType}`
383
+ + ` Connection, Error Message: ${(0, super_stringify_1.default)(e.message)}`);
384
+ await this.BLERefreshConnection(switchbot);
427
385
  });
428
386
  }
429
387
  else {
430
- await this.BLEconnection(switchbot);
431
- }
432
- }
433
- async getCustomBLEAddress(switchbot) {
434
- if (this.device.customBLEaddress && this.deviceLogging.includes('debug')) {
435
- (async () => {
436
- // Start to monitor advertisement packets
437
- await switchbot.startScan({
438
- model: 'c',
439
- });
440
- // Set an event handler
441
- switchbot.onadvertisement = (ad) => {
442
- this.warnLog(`Curtain: ${this.accessory.displayName} ad: ${JSON.stringify(ad, null, ' ')}`);
443
- };
444
- await switchbot.wait(10000);
445
- // Stop to monitor
446
- switchbot.stopScan();
447
- })();
448
- }
449
- }
450
- async BLEconnection(switchbot) {
451
- this.errorLog(`Curtain: ${this.accessory.displayName} wasn't able to establish BLE Connection, node-switchbot: ${switchbot}`);
452
- if (this.platform.config.credentials?.token) {
453
- this.warnLog(`Curtain: ${this.accessory.displayName} Using OpenAPI Connection`);
454
- this.SwitchToOpenAPI = true;
455
- await this.openAPIRefreshStatus();
388
+ await this.BLERefreshConnection(switchbot);
456
389
  }
457
390
  }
458
391
  async openAPIRefreshStatus() {
459
- if (this.platform.config.credentials?.token) {
460
- this.debugLog(`Curtain: ${this.accessory.displayName} OpenAPI refreshStatus`);
461
- try {
462
- const t = Date.now();
463
- const nonce = 'requestID';
464
- const data = this.platform.config.credentials?.token + t + nonce;
465
- const signTerm = crypto_1.default.createHmac('sha256', this.platform.config.credentials?.secret).update(Buffer.from(data, 'utf-8')).digest();
466
- const sign = signTerm.toString('base64');
467
- this.debugLog(`Curtain: ${this.accessory.displayName} sign: ${sign}`);
468
- const options = {
469
- hostname: settings_1.HostDomain,
470
- port: 443,
471
- path: `${settings_1.DevicePath}/${this.device.deviceId}/status`,
472
- method: 'GET',
473
- headers: {
474
- Authorization: this.platform.config.credentials?.token,
475
- sign: sign,
476
- nonce: nonce,
477
- t: t,
478
- 'Content-Type': 'application/json',
479
- },
480
- };
481
- const req = https_1.default.request(options, (res) => {
482
- this.debugLog(`Curtain: ${this.accessory.displayName} statusCode: ${res.statusCode}`);
483
- let rawData = '';
484
- res.on('data', (d) => {
485
- rawData += d;
486
- this.debugLog(`Curtain: ${this.accessory.displayName} d: ${d}`);
487
- });
488
- res.on('end', () => {
489
- try {
490
- this.deviceStatus = JSON.parse(rawData);
491
- this.debugLog(`Curtain: ${this.accessory.displayName} refreshStatus: ${JSON.stringify(this.deviceStatus)}`);
492
- this.slidePosition = this.deviceStatus.body.slidePosition;
493
- this.moving = this.deviceStatus.body.moving;
494
- this.brightness = this.deviceStatus.body.brightness;
495
- this.parseStatus();
496
- this.updateHomeKitCharacteristics();
497
- }
498
- catch (e) {
499
- this.errorLog(`Curtain: ${this.accessory.displayName} error message: ${e.message}`);
500
- }
501
- });
392
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus`);
393
+ try {
394
+ const t = Date.now();
395
+ const nonce = 'requestID';
396
+ const data = this.platform.config.credentials?.token + t + nonce;
397
+ const signTerm = crypto_1.default.createHmac('sha256', this.platform.config.credentials?.secret).update(Buffer.from(data, 'utf-8')).digest();
398
+ const sign = signTerm.toString('base64');
399
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} sign: ${sign}`);
400
+ const options = {
401
+ hostname: settings_1.HostDomain,
402
+ port: 443,
403
+ path: `${settings_1.DevicePath}/${this.device.deviceId}/status`,
404
+ method: 'GET',
405
+ headers: {
406
+ Authorization: this.platform.config.credentials?.token,
407
+ sign: sign,
408
+ nonce: nonce,
409
+ t: t,
410
+ 'Content-Type': 'application/json',
411
+ },
412
+ };
413
+ const req = https_1.default.request(options, (res) => {
414
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} statusCode: ${res.statusCode}`);
415
+ let rawData = '';
416
+ res.on('data', (d) => {
417
+ rawData += d;
418
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} d: ${d}`);
502
419
  });
503
- req.on('error', (e) => {
504
- this.errorLog(`Curtain: ${this.accessory.displayName} error message: ${e.message}`);
420
+ res.on('end', () => {
421
+ try {
422
+ this.deviceStatus = JSON.parse(rawData);
423
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} refreshStatus: ${(0, super_stringify_1.default)(this.deviceStatus)}`);
424
+ this.slidePosition = this.deviceStatus.body.slidePosition;
425
+ this.moving = this.deviceStatus.body.moving;
426
+ this.brightness = this.deviceStatus.body.brightness;
427
+ this.openAPIparseStatus();
428
+ this.updateHomeKitCharacteristics();
429
+ }
430
+ catch (e) {
431
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} error message: ${e.message}`);
432
+ }
505
433
  });
506
- req.end();
507
- }
508
- catch (e) {
509
- this.errorLog(`Curtain: ${this.accessory.displayName} failed refreshStatus with OpenAPI Connection`);
510
- if (this.deviceLogging.includes('debug')) {
511
- this.errorLog(`Curtain: ${this.accessory.displayName} failed refreshStatus with OpenAPI Connection,` + ` Error Message: ${JSON.stringify(e.message)}`);
512
- }
513
- this.apiError(e);
514
- }
434
+ });
435
+ req.on('error', (e) => {
436
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} error message: ${e.message}`);
437
+ });
438
+ req.end();
439
+ }
440
+ catch (e) {
441
+ this.apiError(e);
442
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed openAPIRefreshStatus with ${this.device.connectionType}`
443
+ + ` Connection, Error Message: ${(0, super_stringify_1.default)(e.message)}`);
515
444
  }
516
445
  }
517
446
  async pushChanges() {
518
- if (this.device.ble) {
519
- await this.BLEpushChanges();
447
+ if (this.BLE) {
448
+ await this.BLERefreshStatus();
520
449
  }
521
- else {
450
+ else if (this.OpenAPI && this.platform.config.credentials?.token) {
522
451
  await this.openAPIpushChanges();
523
452
  }
453
+ else {
454
+ this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:`
455
+ + ` ${this.device.connectionType}, pushChanges will not happen.`);
456
+ }
524
457
  (0, rxjs_1.interval)(this.updateRate * 1000)
525
- .pipe((0, operators_1.take)(2))
458
+ .pipe((0, operators_1.take)(1))
526
459
  .subscribe(async () => {
527
460
  await this.refreshStatus();
528
461
  });
529
462
  }
530
463
  async BLEpushChanges() {
464
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLEpushChanges`);
531
465
  if (this.TargetPosition !== this.CurrentPosition) {
532
- this.debugLog(`Curtain: ${this.accessory.displayName} BLE pushChanges`);
533
466
  const switchbot = await this.platform.connectBLE();
534
467
  // Convert to BLE Address
535
468
  this.device.bleMac = this.device
536
469
  .deviceId.match(/.{1,2}/g)
537
470
  .join(':')
538
471
  .toLowerCase();
539
- this.debugLog(`Curtain: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
540
- if (this.TargetPosition > 50) {
541
- if (this.device.curtain?.setOpenMode === '1') {
542
- this.setPositionMode = 1;
543
- this.Mode = 'Silent Mode';
544
- }
545
- else {
546
- this.setPositionMode = 0;
547
- this.Mode = 'Performance Mode';
548
- }
549
- }
550
- else {
551
- if (this.device.curtain?.setCloseMode === '1') {
552
- this.setPositionMode = 1;
553
- this.Mode = 'Silent Mode';
554
- }
555
- else {
556
- this.setPositionMode = 0;
557
- this.Mode = 'Performance Mode';
558
- }
559
- }
472
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
473
+ this.SilentPerformance();
560
474
  const adjustedMode = this.setPositionMode || null;
561
475
  if (adjustedMode === null) {
562
476
  this.Mode = 'Default Mode';
@@ -570,248 +484,290 @@ class Curtain {
570
484
  return device_list[0].runToPos(100 - Number(this.TargetPosition), adjustedMode);
571
485
  })
572
486
  .then(() => {
573
- this.debugLog(`Curtain: ${this.accessory.displayName} Done.`);
487
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Done.`);
574
488
  })
575
489
  .catch(async (e) => {
576
- this.errorLog(`Curtain: ${this.accessory.displayName} failed pushChanges with BLE Connection`);
577
- if (this.deviceLogging.includes('debug')) {
578
- this.errorLog(`Curtain: ${this.accessory.displayName} failed pushChanges with BLE Connection,` + ` Error Message: ${JSON.stringify(e.message)}`);
579
- }
580
- if (this.platform.config.credentials?.token) {
581
- this.warnLog(`Curtain: ${this.accessory.displayName} Using OpenAPI Connection`);
582
- await this.openAPIpushChanges();
583
- }
584
490
  this.apiError(e);
491
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed BLEpushChanges with ${this.device.connectionType}`
492
+ + ` Connection, Error Message: ${(0, super_stringify_1.default)(e.message)}`);
493
+ await this.BLEPushConnection();
585
494
  });
586
495
  }
587
496
  else {
588
- this.errorLog(`Curtain: ${this.accessory.displayName} wasn't able to establish BLE Connection`);
589
- if (this.platform.config.credentials?.token) {
590
- this.warnLog(`Curtain: ${this.accessory.displayName} Using OpenAPI Connection`);
591
- await this.openAPIpushChanges();
592
- }
497
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} wasn't able to establish BLE Connection`);
498
+ await this.BLEPushConnection();
593
499
  }
594
500
  }
595
501
  else {
596
- this.debugLog(`Curtain: ${this.accessory.displayName} No BLE Changes, CurrentPosition & TargetPosition Are the Same.` +
502
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} No BLEpushChanges, CurrentPosition & TargetPosition Are the Same.` +
597
503
  ` CurrentPosition: ${this.CurrentPosition}, TargetPosition ${this.TargetPosition}`);
598
504
  }
599
505
  }
600
506
  async openAPIpushChanges() {
601
- if (this.platform.config.credentials?.token) {
602
- try {
603
- this.debugLog(`Curtain: ${this.accessory.displayName} OpenAPI pushChanges`);
604
- if (this.TargetPosition !== this.CurrentPosition) {
605
- // Make Push On request to the API
606
- const t = Date.now();
607
- const nonce = 'requestID';
608
- const data = this.platform.config.credentials?.token + t + nonce;
609
- const signTerm = crypto_1.default.createHmac('sha256', this.platform.config.credentials?.secret)
610
- .update(Buffer.from(data, 'utf-8'))
611
- .digest();
612
- const sign = signTerm.toString('base64');
613
- this.debugLog(`Curtain: ${this.accessory.displayName} sign: ${sign}`);
614
- this.debugLog(`Pushing ${this.TargetPosition}`);
615
- const adjustedTargetPosition = 100 - Number(this.TargetPosition);
616
- if (this.TargetPosition > 50) {
617
- this.setPositionMode = this.device.curtain?.setOpenMode;
618
- }
619
- else {
620
- this.setPositionMode = this.device.curtain?.setCloseMode;
621
- }
622
- if (this.setPositionMode === '1') {
623
- this.Mode = 'Silent Mode';
624
- }
625
- else if (this.setPositionMode === '0') {
626
- this.Mode = 'Performance Mode';
627
- }
628
- else {
629
- this.Mode = 'Default Mode';
630
- }
631
- this.debugLog(`${this.accessory.displayName} Mode: ${this.Mode}`);
632
- const adjustedMode = this.setPositionMode || 'ff';
633
- const body = JSON.stringify({
634
- 'command': 'setPosition',
635
- 'parameter': `0,${adjustedMode},${adjustedTargetPosition}`,
636
- 'commandType': 'command',
637
- });
638
- this.infoLog(`Curtain: ${this.accessory.displayName} Sending request to SwitchBot API. body: ${body},`);
639
- const options = {
640
- hostname: settings_1.HostDomain,
641
- port: 443,
642
- path: `${settings_1.DevicePath}/${this.device.deviceId}/commands`,
643
- method: 'POST',
644
- headers: {
645
- 'Authorization': this.platform.config.credentials?.token,
646
- 'sign': sign,
647
- 'nonce': nonce,
648
- 't': t,
649
- 'Content-Type': 'application/json',
650
- 'Content-Length': body.length,
651
- },
652
- };
653
- const req = https_1.default.request(options, res => {
654
- this.debugLog(`Curtain: ${this.accessory.displayName} statusCode: ${res.statusCode}`);
655
- this.statusCode({ res });
656
- res.on('data', d => {
657
- this.debugLog(`Curtain: ${this.accessory.displayName} d: ${d}`);
658
- });
659
- });
660
- req.on('error', (e) => {
661
- this.errorLog(`Curtain: ${this.accessory.displayName} error message: ${e.message}`);
662
- });
663
- req.write(body);
664
- req.end();
665
- this.debugLog(`Curtain: ${this.accessory.displayName} openAPIpushChanges: ${JSON.stringify(req)}`);
507
+ try {
508
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} OpenAPI pushChanges`);
509
+ if (this.TargetPosition !== this.CurrentPosition) {
510
+ // Make Push On request to the API
511
+ const t = Date.now();
512
+ const nonce = 'requestID';
513
+ const data = this.platform.config.credentials?.token + t + nonce;
514
+ const signTerm = crypto_1.default.createHmac('sha256', this.platform.config.credentials?.secret)
515
+ .update(Buffer.from(data, 'utf-8'))
516
+ .digest();
517
+ const sign = signTerm.toString('base64');
518
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} sign: ${sign}`);
519
+ this.debugLog(`Pushing ${this.TargetPosition}`);
520
+ const adjustedTargetPosition = 100 - Number(this.TargetPosition);
521
+ if (this.TargetPosition > 50) {
522
+ this.setPositionMode = this.device.curtain?.setOpenMode;
666
523
  }
667
524
  else {
668
- this.debugLog(`Curtain: ${this.accessory.displayName} No OpenAPI Changes, CurrentPosition & TargetPosition Are the Same.` +
669
- ` CurrentPosition: ${this.CurrentPosition}, TargetPosition ${this.TargetPosition}`);
525
+ this.setPositionMode = this.device.curtain?.setCloseMode;
670
526
  }
671
- }
672
- catch (e) {
673
- this.errorLog(`Curtain: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection`);
674
- if (this.deviceLogging.includes('debug')) {
675
- this.errorLog(`Curtain: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection,` + ` Error Message: ${JSON.stringify(e.message)}`);
527
+ if (this.setPositionMode === '1') {
528
+ this.Mode = 'Silent Mode';
676
529
  }
677
- this.apiError(e);
530
+ else if (this.setPositionMode === '0') {
531
+ this.Mode = 'Performance Mode';
532
+ }
533
+ else {
534
+ this.Mode = 'Default Mode';
535
+ }
536
+ this.debugLog(`${this.accessory.displayName} Mode: ${this.Mode}`);
537
+ const adjustedMode = this.setPositionMode || 'ff';
538
+ const body = (0, super_stringify_1.default)({
539
+ 'command': 'setPosition',
540
+ 'parameter': `0,${adjustedMode},${adjustedTargetPosition}`,
541
+ 'commandType': 'command',
542
+ });
543
+ this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Sending request to SwitchBot API. body: ${body},`);
544
+ const options = {
545
+ hostname: settings_1.HostDomain,
546
+ port: 443,
547
+ path: `${settings_1.DevicePath}/${this.device.deviceId}/commands`,
548
+ method: 'POST',
549
+ headers: {
550
+ 'Authorization': this.platform.config.credentials?.token,
551
+ 'sign': sign,
552
+ 'nonce': nonce,
553
+ 't': t,
554
+ 'Content-Type': 'application/json',
555
+ 'Content-Length': body.length,
556
+ },
557
+ };
558
+ const req = https_1.default.request(options, res => {
559
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIpushChanges statusCode: ${res.statusCode}`);
560
+ this.statusCode({ res });
561
+ res.on('data', d => {
562
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} d: ${d}`);
563
+ });
564
+ });
565
+ req.on('error', (e) => {
566
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} error message: ${e.message}`);
567
+ });
568
+ req.write(body);
569
+ req.end();
570
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIpushChanges: ${(0, super_stringify_1.default)(req)}`);
678
571
  }
572
+ else {
573
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} No OpenAPI Changes, CurrentPosition & TargetPosition Are the Same.`
574
+ + ` CurrentPosition: ${this.CurrentPosition}, TargetPosition ${this.TargetPosition}`);
575
+ }
576
+ }
577
+ catch (e) {
578
+ this.apiError(e);
579
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed pushBrightnessChanges with ${this.device.connectionType}`
580
+ + ` Connection, Error Message: ${(0, super_stringify_1.default)(e.message)}`);
581
+ }
582
+ }
583
+ /**
584
+ * Handle requests to set the value of the "Target Position" characteristic
585
+ */
586
+ async TargetPositionSet(value) {
587
+ if (this.TargetPosition === this.accessory.context.TargetPosition) {
588
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} No Changes, Set TargetPosition: ${value}`);
589
+ }
590
+ else {
591
+ this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Set TargetPosition: ${value}`);
592
+ }
593
+ this.TargetPosition = value;
594
+ this.mqttPublish('TargetPosition', this.TargetPosition);
595
+ await this.setMinMax();
596
+ if (value > this.CurrentPosition) {
597
+ this.PositionState = this.platform.Characteristic.PositionState.INCREASING;
598
+ this.setNewTarget = true;
599
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} value: ${value}, CurrentPosition: ${this.CurrentPosition}`);
600
+ }
601
+ else if (value < this.CurrentPosition) {
602
+ this.PositionState = this.platform.Characteristic.PositionState.DECREASING;
603
+ this.setNewTarget = true;
604
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} value: ${value}, CurrentPosition: ${this.CurrentPosition}`);
605
+ }
606
+ else {
607
+ this.PositionState = this.platform.Characteristic.PositionState.STOPPED;
608
+ this.setNewTarget = false;
609
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} value: ${value}, CurrentPosition: ${this.CurrentPosition}`);
610
+ }
611
+ this.windowCoveringService.setCharacteristic(this.platform.Characteristic.PositionState, this.PositionState);
612
+ this.windowCoveringService.getCharacteristic(this.platform.Characteristic.PositionState).updateValue(this.PositionState);
613
+ /**
614
+ * If Curtain movement time is short, the moving flag from backend is always false.
615
+ * The minimum time depends on the network control latency.
616
+ */
617
+ clearTimeout(this.setNewTargetTimer);
618
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateRate: ${this.updateRate}`);
619
+ if (this.setNewTarget) {
620
+ this.setNewTargetTimer = setTimeout(() => {
621
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} setNewTarget ${this.setNewTarget} timeout`);
622
+ this.setNewTarget = false;
623
+ }, this.updateRate * 1000);
679
624
  }
625
+ this.doCurtainUpdate.next();
680
626
  }
681
627
  async updateHomeKitCharacteristics() {
682
628
  await this.setMinMax();
683
629
  if (this.CurrentPosition === undefined || Number.isNaN(this.CurrentPosition)) {
684
- this.debugLog(`Curtain: ${this.accessory.displayName} CurrentPosition: ${this.CurrentPosition}`);
630
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} CurrentPosition: ${this.CurrentPosition}`);
685
631
  }
686
632
  else {
633
+ this.accessory.context.CurrentPosition = this.CurrentPosition;
687
634
  this.windowCoveringService.updateCharacteristic(this.platform.Characteristic.CurrentPosition, Number(this.CurrentPosition));
688
- this.debugLog(`Curtain: ${this.accessory.displayName} updateCharacteristic CurrentPosition: ${this.CurrentPosition}`);
635
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic CurrentPosition: ${this.CurrentPosition}`);
689
636
  this.mqttPublish('CurrentPosition', this.CurrentPosition);
690
637
  }
691
638
  if (this.PositionState === undefined) {
692
- this.debugLog(`Curtain: ${this.accessory.displayName} PositionState: ${this.PositionState}`);
639
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} PositionState: ${this.PositionState}`);
693
640
  }
694
641
  else {
642
+ this.accessory.context.PositionState = this.PositionState;
695
643
  this.windowCoveringService.updateCharacteristic(this.platform.Characteristic.PositionState, Number(this.PositionState));
696
- this.debugLog(`Curtain: ${this.accessory.displayName} updateCharacteristic PositionState: ${this.PositionState}`);
644
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic PositionState: ${this.PositionState}`);
697
645
  this.mqttPublish('PositionState', this.PositionState);
698
646
  }
699
647
  if (this.TargetPosition === undefined || Number.isNaN(this.TargetPosition)) {
700
- this.debugLog(`Curtain: ${this.accessory.displayName} TargetPosition: ${this.TargetPosition}`);
648
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} TargetPosition: ${this.TargetPosition}`);
701
649
  }
702
650
  else {
651
+ this.accessory.context.TargetPosition = this.TargetPosition;
703
652
  this.windowCoveringService.updateCharacteristic(this.platform.Characteristic.TargetPosition, Number(this.TargetPosition));
704
- this.debugLog(`Curtain: ${this.accessory.displayName} updateCharacteristic TargetPosition: ${this.TargetPosition}`);
653
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic TargetPosition: ${this.TargetPosition}`);
705
654
  this.mqttPublish('TargetPosition', this.TargetPosition);
706
655
  }
707
656
  if (!this.device.curtain?.hide_lightsensor) {
708
657
  if (this.CurrentAmbientLightLevel === undefined || Number.isNaN(this.CurrentAmbientLightLevel)) {
709
- this.debugLog(`Curtain: ${this.accessory.displayName} CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`);
658
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`);
710
659
  }
711
660
  else {
661
+ this.accessory.context.CurrentAmbientLightLevel = this.CurrentAmbientLightLevel;
712
662
  this.lightSensorService?.updateCharacteristic(this.platform.Characteristic.CurrentAmbientLightLevel, this.CurrentAmbientLightLevel);
713
- this.debugLog(`Curtain: ${this.accessory.displayName}` + ` updateCharacteristic CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`);
663
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}`
664
+ + ` updateCharacteristic CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`);
714
665
  this.mqttPublish('CurrentAmbientLightLevel', this.CurrentAmbientLightLevel);
715
666
  }
716
667
  }
717
- if (this.device.ble) {
668
+ if (this.BLE) {
718
669
  if (this.BatteryLevel === undefined) {
719
- this.debugLog(`Curtain: ${this.accessory.displayName} BatteryLevel: ${this.BatteryLevel}`);
670
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.BatteryLevel}`);
720
671
  }
721
672
  else {
673
+ this.accessory.context.BatteryLevel = this.BatteryLevel;
722
674
  this.batteryService?.updateCharacteristic(this.platform.Characteristic.BatteryLevel, this.BatteryLevel);
723
- this.debugLog(`Curtain: ${this.accessory.displayName} updateCharacteristic BatteryLevel: ${this.BatteryLevel}`);
675
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic BatteryLevel: ${this.BatteryLevel}`);
724
676
  this.mqttPublish('BatteryLevel', this.BatteryLevel);
725
677
  }
726
678
  if (this.StatusLowBattery === undefined) {
727
- this.debugLog(`Curtain: ${this.accessory.displayName} StatusLowBattery: ${this.StatusLowBattery}`);
679
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} StatusLowBattery: ${this.StatusLowBattery}`);
728
680
  }
729
681
  else {
682
+ this.accessory.context.StatusLowBattery = this.StatusLowBattery;
730
683
  this.batteryService?.updateCharacteristic(this.platform.Characteristic.StatusLowBattery, this.StatusLowBattery);
731
- this.debugLog(`Curtain: ${this.accessory.displayName} updateCharacteristic StatusLowBattery: ${this.StatusLowBattery}`);
684
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic StatusLowBattery: ${this.StatusLowBattery}`);
732
685
  this.mqttPublish('StatusLowBattery', this.StatusLowBattery);
733
686
  }
734
687
  }
735
688
  }
736
- async apiError(e) {
737
- this.windowCoveringService.updateCharacteristic(this.platform.Characteristic.CurrentPosition, e);
738
- this.windowCoveringService.updateCharacteristic(this.platform.Characteristic.PositionState, e);
739
- this.windowCoveringService.updateCharacteristic(this.platform.Characteristic.TargetPosition, e);
740
- if (!this.device.curtain?.hide_lightsensor) {
741
- this.lightSensorService?.updateCharacteristic(this.platform.Characteristic.CurrentAmbientLightLevel, e);
689
+ /*
690
+ * Publish MQTT message for topics of
691
+ * 'homebridge-switchbot/curtain/xx:xx:xx:xx:xx:xx'
692
+ */
693
+ mqttPublish(topic, message) {
694
+ const mac = this.device.deviceId
695
+ ?.toLowerCase()
696
+ .match(/[\s\S]{1,2}/g)
697
+ ?.join(':');
698
+ const options = this.device.mqttPubOptions || {};
699
+ this.mqttClient?.publish(`homebridge-switchbot/curtain/${mac}/${topic}`, `${message}`, options);
700
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} MQTT message: ${topic}/${message} options:${(0, super_stringify_1.default)(options)}`);
701
+ }
702
+ /*
703
+ * Setup MQTT hadler if URL is specifed.
704
+ */
705
+ async setupMqtt(device) {
706
+ if (device.mqttURL) {
707
+ try {
708
+ this.mqttClient = await (0, async_mqtt_1.connectAsync)(device.mqttURL, device.mqttOptions || {});
709
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} MQTT connection has been established successfully.`);
710
+ this.mqttClient.on('error', (e) => {
711
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Failed to publish MQTT messages. ${e}`);
712
+ });
713
+ }
714
+ catch (e) {
715
+ this.mqttClient = null;
716
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Failed to establish MQTT connection. ${e}`);
717
+ }
742
718
  }
743
- if (this.device.ble) {
744
- this.batteryService?.updateCharacteristic(this.platform.Characteristic.BatteryLevel, e);
745
- this.batteryService?.updateCharacteristic(this.platform.Characteristic.StatusLowBattery, e);
719
+ }
720
+ async getCustomBLEAddress(switchbot) {
721
+ if (this.device.customBLEaddress && this.deviceLogging.includes('debug')) {
722
+ (async () => {
723
+ // Start to monitor advertisement packets
724
+ await switchbot.startScan({
725
+ model: 'c',
726
+ });
727
+ // Set an event handler
728
+ switchbot.onadvertisement = (ad) => {
729
+ this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} ad: ${(0, super_stringify_1.default)(ad, null, ' ')}`);
730
+ };
731
+ await switchbot.wait(10000);
732
+ // Stop to monitor
733
+ switchbot.stopScan();
734
+ })();
746
735
  }
747
- //throw new this.platform.api.hap.HapStatusError(HAPStatus.SERVICE_COMMUNICATION_FAILURE);
748
736
  }
749
- async statusCode({ res }) {
750
- switch (res.statusCode) {
751
- case 151:
752
- this.errorLog(`Curtain: ${this.accessory.displayName} Command not supported by this device type.`);
753
- break;
754
- case 152:
755
- this.errorLog(`Curtain: ${this.accessory.displayName} Device not found.`);
756
- break;
757
- case 160:
758
- this.errorLog(`Curtain: ${this.accessory.displayName} Command is not supported.`);
759
- break;
760
- case 161:
761
- this.errorLog(`Curtain: ${this.accessory.displayName} Device is offline.`);
762
- break;
763
- case 171:
764
- this.errorLog(`Curtain: ${this.accessory.displayName} Hub Device is offline. Hub: ${this.device.hubDeviceId}`);
765
- break;
766
- case 190:
767
- this.errorLog(`Curtain: ${this.accessory.displayName} Device internal error due to device states not synchronized with server,` +
768
- ` Or command: ${JSON.stringify(res)} format is invalid`);
769
- break;
770
- case 100:
771
- this.debugLog(`Curtain: ${this.accessory.displayName} Command successfully sent.`);
772
- break;
773
- default:
774
- this.debugLog(`Curtain: ${this.accessory.displayName} Unknown statusCode.`);
737
+ async BLEPushConnection() {
738
+ if (this.platform.config.credentials?.token && this.device.connectionType === 'BLE/OpenAPI') {
739
+ this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} Using OpenAPI Connection to Push Changes`);
740
+ await this.openAPIpushChanges();
775
741
  }
776
742
  }
777
- /**
778
- * Handle requests to set the value of the "Target Position" characteristic
779
- */
780
- async TargetPositionSet(value) {
781
- this.debugLog(`Curtain: ${this.accessory.displayName} TargetPosition: ${value}`);
782
- this.TargetPosition = value;
783
- this.mqttPublish('TargetPosition', this.TargetPosition);
784
- await this.setMinMax();
785
- if (value > this.CurrentPosition) {
786
- this.PositionState = this.platform.Characteristic.PositionState.INCREASING;
787
- this.setNewTarget = true;
788
- this.debugLog(`Curtain: ${this.accessory.displayName} value: ${value}, CurrentPosition: ${this.CurrentPosition}`);
743
+ async BLERefreshConnection(switchbot) {
744
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} wasn't able to establish BLE Connection, node-switchbot: ${switchbot}`);
745
+ if (this.platform.config.credentials?.token && this.device.connectionType === 'BLE/OpenAPI') {
746
+ this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} Using OpenAPI Connection to Refresh Status`);
747
+ await this.openAPIRefreshStatus();
789
748
  }
790
- else if (value < this.CurrentPosition) {
791
- this.PositionState = this.platform.Characteristic.PositionState.DECREASING;
792
- this.setNewTarget = true;
793
- this.debugLog(`Curtain: ${this.accessory.displayName} value: ${value}, CurrentPosition: ${this.CurrentPosition}`);
749
+ }
750
+ async SilentPerformance() {
751
+ if (this.TargetPosition > 50) {
752
+ if (this.device.curtain?.setOpenMode === '1') {
753
+ this.setPositionMode = 1;
754
+ this.Mode = 'Silent Mode';
755
+ }
756
+ else {
757
+ this.setPositionMode = 0;
758
+ this.Mode = 'Performance Mode';
759
+ }
794
760
  }
795
761
  else {
796
- this.PositionState = this.platform.Characteristic.PositionState.STOPPED;
797
- this.setNewTarget = false;
798
- this.debugLog(`Curtain: ${this.accessory.displayName} value: ${value}, CurrentPosition: ${this.CurrentPosition}`);
799
- }
800
- this.windowCoveringService.setCharacteristic(this.platform.Characteristic.PositionState, this.PositionState);
801
- this.windowCoveringService.getCharacteristic(this.platform.Characteristic.PositionState).updateValue(this.PositionState);
802
- /**
803
- * If Curtain movement time is short, the moving flag from backend is always false.
804
- * The minimum time depends on the network control latency.
805
- */
806
- clearTimeout(this.setNewTargetTimer);
807
- this.debugLog(`Curtain: ${this.accessory.displayName} updateRate: ${this.updateRate}`);
808
- if (this.setNewTarget) {
809
- this.setNewTargetTimer = setTimeout(() => {
810
- this.debugLog(`Curtain: ${this.accessory.displayName} setNewTarget ${this.setNewTarget} timeout`);
811
- this.setNewTarget = false;
812
- }, this.updateRate * 1000);
762
+ if (this.device.curtain?.setCloseMode === '1') {
763
+ this.setPositionMode = 1;
764
+ this.Mode = 'Silent Mode';
765
+ }
766
+ else {
767
+ this.setPositionMode = 0;
768
+ this.Mode = 'Performance Mode';
769
+ }
813
770
  }
814
- this.doCurtainUpdate.next();
815
771
  }
816
772
  async setMinMax() {
817
773
  if (this.device.curtain?.set_min) {
@@ -825,96 +781,117 @@ class Curtain {
825
781
  }
826
782
  }
827
783
  }
828
- async config(device) {
829
- let config = {};
830
- if (device.curtain) {
831
- config = device.curtain;
832
- }
833
- if (device.ble) {
834
- config['ble'] = device.ble;
835
- }
836
- if (device.logging !== undefined) {
837
- config['logging'] = device.logging;
838
- }
839
- if (device.refreshRate !== undefined) {
840
- config['refreshRate'] = device.refreshRate;
841
- }
842
- if (device.scanDuration !== undefined) {
843
- config['scanDuration'] = device.scanDuration;
784
+ minStep(device) {
785
+ if (device.curtain?.set_minStep) {
786
+ this.set_minStep = device.curtain?.set_minStep;
844
787
  }
845
- if (Object.entries(config).length !== 0) {
846
- this.infoLog(`Curtain: ${this.accessory.displayName} Config: ${JSON.stringify(config)}`);
788
+ else {
789
+ this.set_minStep = 1;
847
790
  }
791
+ return this.set_minStep;
848
792
  }
849
- async refreshRate(device) {
850
- // refreshRate
851
- if (device.refreshRate) {
852
- this.deviceRefreshRate = this.accessory.context.refreshRate = device.refreshRate;
853
- this.debugLog(`Curtain: ${this.accessory.displayName} Using Device Config refreshRate: ${this.deviceRefreshRate}`);
793
+ minLux() {
794
+ if (this.device.curtain?.set_minLux) {
795
+ this.set_minLux = this.device.curtain?.set_minLux;
854
796
  }
855
- else if (this.platform.config.options.refreshRate) {
856
- this.deviceRefreshRate = this.accessory.context.refreshRate = this.platform.config.options.refreshRate;
857
- this.debugLog(`Curtain: ${this.accessory.displayName} Using Platform Config refreshRate: ${this.deviceRefreshRate}`);
797
+ else {
798
+ this.set_minLux = 1;
858
799
  }
859
- // updateRate
860
- if (device?.curtain?.updateRate) {
861
- this.updateRate = device?.curtain?.updateRate;
862
- this.debugLog(`Curtain: ${this.accessory.displayName} Using Device Config Curtain refreshRate: ${this.deviceRefreshRate}`);
800
+ return this.set_minLux;
801
+ }
802
+ maxLux() {
803
+ if (this.device.curtain?.set_maxLux) {
804
+ this.set_maxLux = this.device.curtain?.set_maxLux;
863
805
  }
864
806
  else {
865
- this.updateRate = 7;
866
- this.debugLog(`Curtain: ${this.accessory.displayName} Using Default Curtain Refresh Rate.`);
807
+ this.set_maxLux = 6001;
867
808
  }
809
+ return this.set_maxLux;
868
810
  }
869
811
  async scan(device) {
870
812
  if (device.scanDuration) {
871
813
  if (this.updateRate > device.scanDuration) {
872
814
  this.scanDuration = this.updateRate;
873
- this.warnLog(`Curtain: ${this.accessory.displayName} scanDuration is less then updateRate, overriding scanDuration with updateRate`);
815
+ this.warnLog(`${this.device.deviceType}: `
816
+ + `${this.accessory.displayName} scanDuration is less then updateRate, overriding scanDuration with updateRate`);
874
817
  }
875
818
  else {
876
819
  this.scanDuration = this.accessory.context.scanDuration = device.scanDuration;
877
820
  }
878
- if (device.ble) {
879
- this.debugLog(`Curtain: ${this.accessory.displayName} Using Device Config scanDuration: ${this.scanDuration}`);
821
+ if (this.BLE) {
822
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Config scanDuration: ${this.scanDuration}`);
880
823
  }
881
824
  }
882
825
  else {
883
826
  if (this.updateRate > 1) {
884
827
  this.scanDuration = this.updateRate;
885
- this.warnLog(`Curtain: ${this.accessory.displayName} scanDuration is less then updateRate, overriding scanDuration with updateRate`);
828
+ this.warnLog(`${this.device.deviceType}: `
829
+ + `${this.accessory.displayName} scanDuration is less then updateRate, overriding scanDuration with updateRate`);
886
830
  }
887
831
  else {
888
832
  this.scanDuration = this.accessory.context.scanDuration = 1;
889
833
  }
890
- if (this.device.ble) {
891
- this.debugLog(`Curtain: ${this.accessory.displayName} Using Default scanDuration: ${this.scanDuration}`);
834
+ if (this.BLE) {
835
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Default scanDuration: ${this.scanDuration}`);
892
836
  }
893
837
  }
894
838
  }
895
- async logs(device) {
896
- if (this.platform.debugMode) {
897
- this.deviceLogging = this.accessory.context.logging = 'debugMode';
898
- this.debugLog(`Curtain: ${this.accessory.displayName} Using Debug Mode Logging: ${this.deviceLogging}`);
839
+ async statusCode({ res }) {
840
+ switch (res.statusCode) {
841
+ case 151:
842
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command not supported by this device type.`);
843
+ break;
844
+ case 152:
845
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device not found.`);
846
+ break;
847
+ case 160:
848
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command is not supported.`);
849
+ break;
850
+ case 161:
851
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device is offline.`);
852
+ this.offlineOff();
853
+ break;
854
+ case 171:
855
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Hub Device is offline. Hub: ${this.device.hubDeviceId}`);
856
+ this.offlineOff();
857
+ break;
858
+ case 190:
859
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device internal error due to device states not synchronized with server,` +
860
+ ` Or command: ${(0, super_stringify_1.default)(res)} format is invalid`);
861
+ break;
862
+ case 100:
863
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Command successfully sent.`);
864
+ break;
865
+ default:
866
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Unknown statusCode.`);
899
867
  }
900
- else if (device.logging) {
901
- this.deviceLogging = this.accessory.context.logging = device.logging;
902
- this.debugLog(`Curtain: ${this.accessory.displayName} Using Device Config Logging: ${this.deviceLogging}`);
868
+ }
869
+ async offlineOff() {
870
+ if (this.device.offline) {
871
+ this.CurrentPosition = 100;
872
+ this.windowCoveringService.getCharacteristic(this.platform.Characteristic.On).updateValue(this.CurrentPosition);
873
+ await this.updateHomeKitCharacteristics();
903
874
  }
904
- else if (this.platform.config.options?.logging) {
905
- this.deviceLogging = this.accessory.context.logging = this.platform.config.options?.logging;
906
- this.debugLog(`Curtain: ${this.accessory.displayName} Using Platform Config Logging: ${this.deviceLogging}`);
875
+ }
876
+ async apiError(e) {
877
+ this.windowCoveringService.updateCharacteristic(this.platform.Characteristic.CurrentPosition, e);
878
+ this.windowCoveringService.updateCharacteristic(this.platform.Characteristic.PositionState, e);
879
+ this.windowCoveringService.updateCharacteristic(this.platform.Characteristic.TargetPosition, e);
880
+ if (!this.device.curtain?.hide_lightsensor) {
881
+ this.lightSensorService?.updateCharacteristic(this.platform.Characteristic.CurrentAmbientLightLevel, e);
907
882
  }
908
- else {
909
- this.deviceLogging = this.accessory.context.logging = 'standard';
910
- this.debugLog(`Curtain: ${this.accessory.displayName} Logging Not Set, Using: ${this.deviceLogging}`);
883
+ if (this.BLE) {
884
+ this.batteryService?.updateCharacteristic(this.platform.Characteristic.BatteryLevel, e);
885
+ this.batteryService?.updateCharacteristic(this.platform.Characteristic.StatusLowBattery, e);
911
886
  }
887
+ //throw new this.platform.api.hap.HapStatusError(HAPStatus.SERVICE_COMMUNICATION_FAILURE);
912
888
  }
913
889
  FirmwareRevision(accessory, device) {
914
890
  let FirmwareRevision;
915
- this.debugLog(`Curtain: ${this.accessory.displayName} accessory.context.FirmwareRevision: ${accessory.context.FirmwareRevision}`);
916
- this.debugLog(`Curtain: ${this.accessory.displayName} device.firmware: ${device.firmware}`);
917
- this.debugLog(`Curtain: ${this.accessory.displayName} this.platform.version: ${this.platform.version}`);
891
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}`
892
+ + ` accessory.context.FirmwareRevision: ${accessory.context.FirmwareRevision}`);
893
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} device.firmware: ${device.firmware}`);
894
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} this.platform.version: ${this.platform.version}`);
918
895
  if (accessory.context.FirmwareRevision) {
919
896
  FirmwareRevision = accessory.context.FirmwareRevision;
920
897
  }
@@ -926,32 +903,84 @@ class Curtain {
926
903
  }
927
904
  return FirmwareRevision;
928
905
  }
929
- minStep(device) {
930
- if (device.curtain?.set_minStep) {
931
- this.set_minStep = device.curtain?.set_minStep;
906
+ async context() {
907
+ if (this.CurrentPosition === undefined) {
908
+ this.CurrentPosition = 0;
932
909
  }
933
910
  else {
934
- this.set_minStep = 1;
911
+ this.CurrentPosition = this.accessory.context.CurrentPosition;
912
+ }
913
+ if (this.TargetPosition === undefined) {
914
+ this.TargetPosition = 0;
915
+ }
916
+ else {
917
+ this.TargetPosition = this.accessory.context.TargetPosition;
918
+ }
919
+ if (this.PositionState === undefined) {
920
+ this.PositionState = this.platform.Characteristic.PositionState.STOPPED;
921
+ }
922
+ else {
923
+ this.PositionState = this.accessory.context.PositionState;
935
924
  }
936
- return this.set_minStep;
937
925
  }
938
- minLux() {
939
- if (this.device.curtain?.set_minLux) {
940
- this.set_minLux = this.device.curtain?.set_minLux;
926
+ async refreshRate(device) {
927
+ // refreshRate
928
+ if (device.refreshRate) {
929
+ this.deviceRefreshRate = this.accessory.context.refreshRate = device.refreshRate;
930
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Config refreshRate: ${this.deviceRefreshRate}`);
931
+ }
932
+ else if (this.platform.config.options.refreshRate) {
933
+ this.deviceRefreshRate = this.accessory.context.refreshRate = this.platform.config.options.refreshRate;
934
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Platform Config refreshRate: ${this.deviceRefreshRate}`);
935
+ }
936
+ // updateRate
937
+ if (device?.curtain?.updateRate) {
938
+ this.updateRate = device?.curtain?.updateRate;
939
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Config Curtain refreshRate: ${this.deviceRefreshRate}`);
941
940
  }
942
941
  else {
943
- this.set_minLux = 1;
942
+ this.updateRate = 7;
943
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Default Curtain Refresh Rate.`);
944
944
  }
945
- return this.set_minLux;
946
945
  }
947
- maxLux() {
948
- if (this.device.curtain?.set_maxLux) {
949
- this.set_maxLux = this.device.curtain?.set_maxLux;
946
+ async config(device) {
947
+ let config = {};
948
+ if (device.curtain) {
949
+ config = device.curtain;
950
+ }
951
+ if (device.connectionType !== undefined) {
952
+ config['connectionType'] = device.connectionType;
953
+ }
954
+ if (device.logging !== undefined) {
955
+ config['logging'] = device.logging;
956
+ }
957
+ if (device.refreshRate !== undefined) {
958
+ config['refreshRate'] = device.refreshRate;
959
+ }
960
+ if (device.scanDuration !== undefined) {
961
+ config['scanDuration'] = device.scanDuration;
962
+ }
963
+ if (Object.entries(config).length !== 0) {
964
+ this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Config: ${(0, super_stringify_1.default)(config)}`);
965
+ }
966
+ }
967
+ async logs(device) {
968
+ if (this.platform.debugMode) {
969
+ this.deviceLogging = this.accessory.context.logging = 'debugMode';
970
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Debug Mode Logging: ${this.deviceLogging}`);
971
+ }
972
+ else if (device.logging) {
973
+ this.deviceLogging = this.accessory.context.logging = device.logging;
974
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Config Logging: ${this.deviceLogging}`);
975
+ }
976
+ else if (this.platform.config.options?.logging) {
977
+ this.deviceLogging = this.accessory.context.logging = this.platform.config.options?.logging;
978
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Platform Config Logging: ${this.deviceLogging}`);
950
979
  }
951
980
  else {
952
- this.set_maxLux = 6001;
981
+ this.deviceLogging = this.accessory.context.logging = 'standard';
982
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Logging Not Set, Using: ${this.deviceLogging}`);
953
983
  }
954
- return this.set_maxLux;
955
984
  }
956
985
  /**
957
986
  * Logging for Device
@@ -966,11 +995,25 @@ class Curtain {
966
995
  this.platform.log.warn(String(...log));
967
996
  }
968
997
  }
998
+ debugWarnLog(...log) {
999
+ if (this.enablingDeviceLogging()) {
1000
+ if (this.deviceLogging?.includes('debug')) {
1001
+ this.platform.log.warn('[DEBUG]', String(...log));
1002
+ }
1003
+ }
1004
+ }
969
1005
  errorLog(...log) {
970
1006
  if (this.enablingDeviceLogging()) {
971
1007
  this.platform.log.error(String(...log));
972
1008
  }
973
1009
  }
1010
+ debugErrorLog(...log) {
1011
+ if (this.enablingDeviceLogging()) {
1012
+ if (this.deviceLogging?.includes('debug')) {
1013
+ this.platform.log.error('[DEBUG]', String(...log));
1014
+ }
1015
+ }
1016
+ }
974
1017
  debugLog(...log) {
975
1018
  if (this.enablingDeviceLogging()) {
976
1019
  if (this.deviceLogging === 'debug') {