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