@switchbot/homebridge-switchbot 2.0.0-beta.8 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +10 -1
- package/README.md +3 -2
- package/config.schema.json +91 -19
- package/dist/device/bot.d.ts +34 -28
- package/dist/device/bot.d.ts.map +1 -1
- package/dist/device/bot.js +657 -648
- package/dist/device/bot.js.map +1 -1
- package/dist/device/ceilinglight.d.ts +137 -0
- package/dist/device/ceilinglight.d.ts.map +1 -0
- package/dist/device/ceilinglight.js +1127 -0
- package/dist/device/ceilinglight.js.map +1 -0
- package/dist/device/colorbulb.d.ts +36 -19
- package/dist/device/colorbulb.d.ts.map +1 -1
- package/dist/device/colorbulb.js +486 -309
- package/dist/device/colorbulb.js.map +1 -1
- package/dist/device/contact.d.ts +18 -8
- package/dist/device/contact.d.ts.map +1 -1
- package/dist/device/contact.js +306 -237
- package/dist/device/contact.js.map +1 -1
- package/dist/device/curtain.d.ts +23 -16
- package/dist/device/curtain.d.ts.map +1 -1
- package/dist/device/curtain.js +566 -502
- package/dist/device/curtain.js.map +1 -1
- package/dist/device/humidifier.d.ts +24 -18
- package/dist/device/humidifier.d.ts.map +1 -1
- package/dist/device/humidifier.js +453 -369
- package/dist/device/humidifier.js.map +1 -1
- package/dist/device/lock.d.ts +27 -8
- package/dist/device/lock.d.ts.map +1 -1
- package/dist/device/lock.js +305 -148
- package/dist/device/lock.js.map +1 -1
- package/dist/device/meter.d.ts +22 -16
- package/dist/device/meter.d.ts.map +1 -1
- package/dist/device/meter.js +367 -267
- package/dist/device/meter.js.map +1 -1
- package/dist/device/meterplus.d.ts +24 -12
- package/dist/device/meterplus.d.ts.map +1 -1
- package/dist/device/meterplus.js +381 -213
- package/dist/device/meterplus.js.map +1 -1
- package/dist/device/motion.d.ts +18 -8
- package/dist/device/motion.d.ts.map +1 -1
- package/dist/device/motion.js +279 -216
- package/dist/device/motion.js.map +1 -1
- package/dist/device/plug.d.ts +27 -17
- package/dist/device/plug.d.ts.map +1 -1
- package/dist/device/plug.js +295 -251
- package/dist/device/plug.js.map +1 -1
- package/dist/device/striplight.d.ts +43 -19
- package/dist/device/striplight.d.ts.map +1 -1
- package/dist/device/striplight.js +506 -262
- package/dist/device/striplight.js.map +1 -1
- package/dist/irdevice/airconditioner.d.ts +9 -12
- package/dist/irdevice/airconditioner.d.ts.map +1 -1
- package/dist/irdevice/airconditioner.js +278 -230
- package/dist/irdevice/airconditioner.js.map +1 -1
- package/dist/irdevice/airpurifier.d.ts +5 -3
- package/dist/irdevice/airpurifier.d.ts.map +1 -1
- package/dist/irdevice/airpurifier.js +154 -104
- package/dist/irdevice/airpurifier.js.map +1 -1
- package/dist/irdevice/camera.d.ts +11 -8
- package/dist/irdevice/camera.d.ts.map +1 -1
- package/dist/irdevice/camera.js +133 -86
- package/dist/irdevice/camera.js.map +1 -1
- package/dist/irdevice/fan.d.ts +10 -7
- package/dist/irdevice/fan.d.ts.map +1 -1
- package/dist/irdevice/fan.js +160 -109
- package/dist/irdevice/fan.js.map +1 -1
- package/dist/irdevice/light.d.ts +11 -8
- package/dist/irdevice/light.d.ts.map +1 -1
- package/dist/irdevice/light.js +137 -103
- package/dist/irdevice/light.js.map +1 -1
- package/dist/irdevice/other.d.ts +11 -8
- package/dist/irdevice/other.d.ts.map +1 -1
- package/dist/irdevice/other.js +145 -98
- package/dist/irdevice/other.js.map +1 -1
- package/dist/irdevice/tv.d.ts +12 -9
- package/dist/irdevice/tv.d.ts.map +1 -1
- package/dist/irdevice/tv.js +143 -93
- package/dist/irdevice/tv.js.map +1 -1
- package/dist/irdevice/vacuumcleaner.d.ts +9 -10
- package/dist/irdevice/vacuumcleaner.d.ts.map +1 -1
- package/dist/irdevice/vacuumcleaner.js +132 -89
- package/dist/irdevice/vacuumcleaner.js.map +1 -1
- package/dist/irdevice/waterheater.d.ts +8 -9
- package/dist/irdevice/waterheater.d.ts.map +1 -1
- package/dist/irdevice/waterheater.js +132 -89
- package/dist/irdevice/waterheater.js.map +1 -1
- package/dist/platform.d.ts +13 -12
- package/dist/platform.d.ts.map +1 -1
- package/dist/platform.js +524 -418
- package/dist/platform.js.map +1 -1
- package/dist/settings.d.ts +19 -11
- package/dist/settings.d.ts.map +1 -1
- package/dist/settings.js.map +1 -1
- package/homebridge-ui/public/index.html +1 -0
- package/package.json +11 -9
- package/src/device/bot.ts +656 -659
- package/src/device/ceilinglight.ts +1208 -0
- package/src/device/colorbulb.ts +490 -344
- package/src/device/contact.ts +309 -241
- package/src/device/curtain.ts +571 -516
- package/src/device/humidifier.ts +456 -403
- package/src/device/lock.ts +314 -149
- package/src/device/meter.ts +378 -280
- package/src/device/meterplus.ts +391 -219
- package/src/device/motion.ts +285 -222
- package/src/device/plug.ts +299 -260
- package/src/device/striplight.ts +522 -289
- package/src/irdevice/airconditioner.ts +282 -241
- package/src/irdevice/airpurifier.ts +151 -103
- package/src/irdevice/camera.ts +131 -85
- package/src/irdevice/fan.ts +157 -106
- package/src/irdevice/light.ts +135 -103
- package/src/irdevice/other.ts +143 -97
- package/src/irdevice/tv.ts +142 -93
- package/src/irdevice/vacuumcleaner.ts +131 -89
- package/src/irdevice/waterheater.ts +130 -89
- package/src/platform.ts +522 -446
- package/src/settings.ts +20 -11
- package/.github/npm-version-script.js +0 -81
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 === '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.
|
|
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,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.
|
|
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
|
-
|
|
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(
|
|
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(
|
|
166
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} CurrentPosition ${this.CurrentPosition}`);
|
|
194
167
|
if (this.setNewTarget) {
|
|
195
|
-
this.infoLog(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
182
|
+
this.debugLog(`${this.device.deviceType}: ${this.CurrentPosition} DECREASING PositionState: ${this.PositionState}`);
|
|
210
183
|
}
|
|
211
184
|
else {
|
|
212
|
-
this.debugLog(
|
|
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(
|
|
188
|
+
this.debugLog(`${this.device.deviceType}: ${this.CurrentPosition} STOPPED PositionState: ${this.PositionState}`);
|
|
216
189
|
}
|
|
217
190
|
}
|
|
218
191
|
else {
|
|
219
|
-
this.debugLog(
|
|
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(
|
|
195
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Stopped`);
|
|
223
196
|
}
|
|
224
|
-
this.debugLog(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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,83 +255,83 @@ class Curtain {
|
|
|
281
255
|
else {
|
|
282
256
|
this.StatusLowBattery = this.platform.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
|
|
283
257
|
}
|
|
284
|
-
this.debugLog(
|
|
258
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.BatteryLevel},`
|
|
259
|
+
+ ` StatusLowBattery: ${this.StatusLowBattery}`);
|
|
285
260
|
}
|
|
286
261
|
async openAPIparseStatus() {
|
|
287
|
-
|
|
288
|
-
|
|
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.
|
|
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
|
-
|
|
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
|
-
}
|
|
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(
|
|
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.
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
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.
|
|
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(
|
|
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(
|
|
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
337
|
if (switchbot !== false) {
|
|
@@ -370,27 +344,23 @@ class Curtain {
|
|
|
370
344
|
// Set an event hander
|
|
371
345
|
switchbot.onadvertisement = (ad) => {
|
|
372
346
|
this.address = ad.address;
|
|
373
|
-
|
|
374
|
-
this.
|
|
375
|
-
this.infoLog(this.device.bleMac);
|
|
376
|
-
this.infoLog(`Curtain: ${this.accessory.displayName} BLE Address Found: ${this.address}`);
|
|
377
|
-
this.infoLog(`Curtain: ${this.accessory.displayName} Config BLE Address: ${this.device.bleMac}`);
|
|
378
|
-
}
|
|
347
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Config BLE Address: ${this.device.bleMac},`
|
|
348
|
+
+ ` BLE Address Found: ${this.address}`);
|
|
379
349
|
this.serviceData = ad.serviceData;
|
|
380
350
|
this.calibration = ad.serviceData.calibration;
|
|
381
351
|
this.battery = ad.serviceData.battery;
|
|
382
352
|
this.position = ad.serviceData.position;
|
|
383
353
|
this.lightLevel = ad.serviceData.lightLevel;
|
|
384
|
-
this.debugLog(
|
|
385
|
-
this.debugLog(
|
|
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}, ` +
|
|
386
356
|
`position: ${ad.serviceData.position}, lightLevel: ${ad.serviceData.lightLevel}, battery: ${ad.serviceData.battery}`);
|
|
387
357
|
if (this.serviceData) {
|
|
388
358
|
this.connected = true;
|
|
389
|
-
this.debugLog(
|
|
359
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} connected: ${this.connected}`);
|
|
390
360
|
}
|
|
391
361
|
else {
|
|
392
362
|
this.connected = false;
|
|
393
|
-
this.debugLog(
|
|
363
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} connected: ${this.connected}`);
|
|
394
364
|
}
|
|
395
365
|
};
|
|
396
366
|
// Wait 2 seconds
|
|
@@ -400,162 +370,107 @@ class Curtain {
|
|
|
400
370
|
// Stop to monitor
|
|
401
371
|
switchbot.stopScan();
|
|
402
372
|
if (this.connected) {
|
|
403
|
-
this.
|
|
373
|
+
this.BLEparseStatus();
|
|
404
374
|
this.updateHomeKitCharacteristics();
|
|
405
375
|
}
|
|
406
376
|
else {
|
|
407
|
-
this.
|
|
408
|
-
if (this.platform.config.credentials?.token) {
|
|
409
|
-
this.warnLog(`Curtain: ${this.accessory.displayName} Using OpenAPI Connection`);
|
|
410
|
-
this.SwitchToOpenAPI = true;
|
|
411
|
-
await this.openAPIRefreshStatus();
|
|
412
|
-
}
|
|
377
|
+
await this.BLERefreshConnection(switchbot);
|
|
413
378
|
}
|
|
414
379
|
})
|
|
415
380
|
.catch(async (e) => {
|
|
416
|
-
this.errorLog(`Curtain: ${this.accessory.displayName} failed refreshStatus with BLE Connection`);
|
|
417
|
-
if (this.deviceLogging.includes('debug')) {
|
|
418
|
-
this.errorLog(`Curtain: ${this.accessory.displayName} failed refreshStatus with BLE Connection,` + ` Error Message: ${JSON.stringify(e.message)}`);
|
|
419
|
-
}
|
|
420
|
-
if (this.platform.config.credentials?.token) {
|
|
421
|
-
this.warnLog(`Curtain: ${this.accessory.displayName} Using OpenAPI Connection`);
|
|
422
|
-
this.SwitchToOpenAPI = true;
|
|
423
|
-
await this.openAPIRefreshStatus();
|
|
424
|
-
}
|
|
425
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);
|
|
426
385
|
});
|
|
427
386
|
}
|
|
428
387
|
else {
|
|
429
|
-
await this.
|
|
430
|
-
}
|
|
431
|
-
}
|
|
432
|
-
async getCustomBLEAddress(switchbot) {
|
|
433
|
-
if (this.device.customBLEaddress && this.deviceLogging.includes('debug')) {
|
|
434
|
-
(async () => {
|
|
435
|
-
// Start to monitor advertisement packets
|
|
436
|
-
await switchbot.startScan({
|
|
437
|
-
model: 'c',
|
|
438
|
-
});
|
|
439
|
-
// Set an event handler
|
|
440
|
-
switchbot.onadvertisement = (ad) => {
|
|
441
|
-
this.warnLog(`Curtain: ${this.accessory.displayName} ad: ${JSON.stringify(ad, null, ' ')}`);
|
|
442
|
-
};
|
|
443
|
-
await switchbot.wait(10000);
|
|
444
|
-
// Stop to monitor
|
|
445
|
-
switchbot.stopScan();
|
|
446
|
-
})();
|
|
447
|
-
}
|
|
448
|
-
}
|
|
449
|
-
async BLEconnection(switchbot) {
|
|
450
|
-
this.errorLog(`Curtain: ${this.accessory.displayName} wasn't able to establish BLE Connection, node-switchbot: ${switchbot}`);
|
|
451
|
-
if (this.platform.config.credentials?.token) {
|
|
452
|
-
this.warnLog(`Curtain: ${this.accessory.displayName} Using OpenAPI Connection`);
|
|
453
|
-
this.SwitchToOpenAPI = true;
|
|
454
|
-
await this.openAPIRefreshStatus();
|
|
388
|
+
await this.BLERefreshConnection(switchbot);
|
|
455
389
|
}
|
|
456
390
|
}
|
|
457
391
|
async openAPIRefreshStatus() {
|
|
458
|
-
|
|
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
|
-
this.debugLog(`Curtain: ${this.accessory.displayName} d: ${d}`);
|
|
486
|
-
});
|
|
487
|
-
res.on('end', () => {
|
|
488
|
-
try {
|
|
489
|
-
this.deviceStatus = JSON.parse(rawData);
|
|
490
|
-
this.debugLog(`Curtain: ${this.accessory.displayName} refreshStatus: ${JSON.stringify(this.deviceStatus)}`);
|
|
491
|
-
this.slidePosition = this.deviceStatus.body.slidePosition;
|
|
492
|
-
this.moving = this.deviceStatus.body.moving;
|
|
493
|
-
this.brightness = this.deviceStatus.body.brightness;
|
|
494
|
-
this.parseStatus();
|
|
495
|
-
this.updateHomeKitCharacteristics();
|
|
496
|
-
}
|
|
497
|
-
catch (e) {
|
|
498
|
-
this.errorLog(`Curtain: ${this.accessory.displayName} error message: ${e.message}`);
|
|
499
|
-
}
|
|
500
|
-
});
|
|
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}`);
|
|
501
419
|
});
|
|
502
|
-
|
|
503
|
-
|
|
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
|
+
}
|
|
504
433
|
});
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
}
|
|
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)}`);
|
|
514
444
|
}
|
|
515
445
|
}
|
|
516
446
|
async pushChanges() {
|
|
517
|
-
if (this.
|
|
447
|
+
if (this.BLE) {
|
|
518
448
|
await this.BLEpushChanges();
|
|
519
449
|
}
|
|
520
|
-
else {
|
|
450
|
+
else if (this.OpenAPI && this.platform.config.credentials?.token) {
|
|
521
451
|
await this.openAPIpushChanges();
|
|
522
452
|
}
|
|
453
|
+
else {
|
|
454
|
+
this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:`
|
|
455
|
+
+ ` ${this.device.connectionType}, pushChanges will not happen.`);
|
|
456
|
+
}
|
|
523
457
|
(0, rxjs_1.interval)(this.updateRate * 1000)
|
|
524
|
-
.pipe((0, operators_1.take)(
|
|
458
|
+
.pipe((0, operators_1.take)(1))
|
|
525
459
|
.subscribe(async () => {
|
|
526
460
|
await this.refreshStatus();
|
|
527
461
|
});
|
|
528
462
|
}
|
|
529
463
|
async BLEpushChanges() {
|
|
464
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLEpushChanges`);
|
|
530
465
|
if (this.TargetPosition !== this.CurrentPosition) {
|
|
531
|
-
this.debugLog(`Curtain: ${this.accessory.displayName} BLE pushChanges`);
|
|
532
466
|
const switchbot = await this.platform.connectBLE();
|
|
533
467
|
// Convert to BLE Address
|
|
534
468
|
this.device.bleMac = this.device
|
|
535
469
|
.deviceId.match(/.{1,2}/g)
|
|
536
470
|
.join(':')
|
|
537
471
|
.toLowerCase();
|
|
538
|
-
this.debugLog(
|
|
539
|
-
|
|
540
|
-
if (this.device.curtain?.setOpenMode === '1') {
|
|
541
|
-
this.setPositionMode = 1;
|
|
542
|
-
this.Mode = 'Silent Mode';
|
|
543
|
-
}
|
|
544
|
-
else {
|
|
545
|
-
this.setPositionMode = 0;
|
|
546
|
-
this.Mode = 'Performance Mode';
|
|
547
|
-
}
|
|
548
|
-
}
|
|
549
|
-
else {
|
|
550
|
-
if (this.device.curtain?.setCloseMode === '1') {
|
|
551
|
-
this.setPositionMode = 1;
|
|
552
|
-
this.Mode = 'Silent Mode';
|
|
553
|
-
}
|
|
554
|
-
else {
|
|
555
|
-
this.setPositionMode = 0;
|
|
556
|
-
this.Mode = 'Performance Mode';
|
|
557
|
-
}
|
|
558
|
-
}
|
|
472
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
|
|
473
|
+
this.SilentPerformance();
|
|
559
474
|
const adjustedMode = this.setPositionMode || null;
|
|
560
475
|
if (adjustedMode === null) {
|
|
561
476
|
this.Mode = 'Default Mode';
|
|
@@ -569,248 +484,304 @@ class Curtain {
|
|
|
569
484
|
return device_list[0].runToPos(100 - Number(this.TargetPosition), adjustedMode);
|
|
570
485
|
})
|
|
571
486
|
.then(() => {
|
|
572
|
-
this.debugLog(
|
|
487
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Done.`);
|
|
573
488
|
})
|
|
574
489
|
.catch(async (e) => {
|
|
575
|
-
this.errorLog(`Curtain: ${this.accessory.displayName} failed pushChanges with BLE Connection`);
|
|
576
|
-
if (this.deviceLogging.includes('debug')) {
|
|
577
|
-
this.errorLog(`Curtain: ${this.accessory.displayName} failed pushChanges with BLE Connection,` + ` Error Message: ${JSON.stringify(e.message)}`);
|
|
578
|
-
}
|
|
579
|
-
if (this.platform.config.credentials?.token) {
|
|
580
|
-
this.warnLog(`Curtain: ${this.accessory.displayName} Using OpenAPI Connection`);
|
|
581
|
-
await this.openAPIpushChanges();
|
|
582
|
-
}
|
|
583
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();
|
|
584
494
|
});
|
|
585
495
|
}
|
|
586
496
|
else {
|
|
587
|
-
this.errorLog(
|
|
588
|
-
|
|
589
|
-
this.warnLog(`Curtain: ${this.accessory.displayName} Using OpenAPI Connection`);
|
|
590
|
-
await this.openAPIpushChanges();
|
|
591
|
-
}
|
|
497
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} wasn't able to establish BLE Connection`);
|
|
498
|
+
await this.BLEPushConnection();
|
|
592
499
|
}
|
|
593
500
|
}
|
|
594
501
|
else {
|
|
595
|
-
this.debugLog(
|
|
502
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} No BLEpushChanges, CurrentPosition & TargetPosition Are the Same.` +
|
|
596
503
|
` CurrentPosition: ${this.CurrentPosition}, TargetPosition ${this.TargetPosition}`);
|
|
597
504
|
}
|
|
598
505
|
}
|
|
599
506
|
async openAPIpushChanges() {
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
this.setPositionMode = this.device.curtain?.setOpenMode;
|
|
617
|
-
}
|
|
618
|
-
else {
|
|
619
|
-
this.setPositionMode = this.device.curtain?.setCloseMode;
|
|
620
|
-
}
|
|
621
|
-
if (this.setPositionMode === '1') {
|
|
622
|
-
this.Mode = 'Silent Mode';
|
|
623
|
-
}
|
|
624
|
-
else if (this.setPositionMode === '0') {
|
|
625
|
-
this.Mode = 'Performance Mode';
|
|
626
|
-
}
|
|
627
|
-
else {
|
|
628
|
-
this.Mode = 'Default Mode';
|
|
629
|
-
}
|
|
630
|
-
this.debugLog(`${this.accessory.displayName} Mode: ${this.Mode}`);
|
|
631
|
-
const adjustedMode = this.setPositionMode || 'ff';
|
|
632
|
-
const body = JSON.stringify({
|
|
633
|
-
'command': 'setPosition',
|
|
634
|
-
'parameter': `0,${adjustedMode},${adjustedTargetPosition}`,
|
|
635
|
-
'commandType': 'command',
|
|
636
|
-
});
|
|
637
|
-
this.infoLog(`Curtain: ${this.accessory.displayName} Sending request to SwitchBot API. body: ${body},`);
|
|
638
|
-
const options = {
|
|
639
|
-
hostname: settings_1.HostDomain,
|
|
640
|
-
port: 443,
|
|
641
|
-
path: `${settings_1.DevicePath}/${this.device.deviceId}/commands`,
|
|
642
|
-
method: 'POST',
|
|
643
|
-
headers: {
|
|
644
|
-
'Authorization': this.platform.config.credentials?.token,
|
|
645
|
-
'sign': sign,
|
|
646
|
-
'nonce': nonce,
|
|
647
|
-
't': t,
|
|
648
|
-
'Content-Type': 'application/json',
|
|
649
|
-
'Content-Length': body.length,
|
|
650
|
-
},
|
|
651
|
-
};
|
|
652
|
-
const req = https_1.default.request(options, res => {
|
|
653
|
-
this.debugLog(`Curtain: ${this.accessory.displayName} statusCode: ${res.statusCode}`);
|
|
654
|
-
this.statusCode({ res });
|
|
655
|
-
res.on('data', d => {
|
|
656
|
-
this.debugLog(`Curtain: ${this.accessory.displayName} d: ${d}`);
|
|
657
|
-
});
|
|
658
|
-
});
|
|
659
|
-
req.on('error', (e) => {
|
|
660
|
-
this.errorLog(`Curtain: ${this.accessory.displayName} error message: ${e.message}`);
|
|
661
|
-
});
|
|
662
|
-
req.write(body);
|
|
663
|
-
req.end();
|
|
664
|
-
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;
|
|
665
523
|
}
|
|
666
524
|
else {
|
|
667
|
-
this.
|
|
668
|
-
` CurrentPosition: ${this.CurrentPosition}, TargetPosition ${this.TargetPosition}`);
|
|
525
|
+
this.setPositionMode = this.device.curtain?.setCloseMode;
|
|
669
526
|
}
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
this.errorLog(`Curtain: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection`);
|
|
673
|
-
if (this.deviceLogging.includes('debug')) {
|
|
674
|
-
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';
|
|
675
529
|
}
|
|
676
|
-
this.
|
|
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)}`);
|
|
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}`);
|
|
677
575
|
}
|
|
678
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
|
+
if (this.device.mqttURL) {
|
|
595
|
+
this.mqttPublish('TargetPosition', this.TargetPosition);
|
|
596
|
+
}
|
|
597
|
+
await this.setMinMax();
|
|
598
|
+
if (value > this.CurrentPosition) {
|
|
599
|
+
this.PositionState = this.platform.Characteristic.PositionState.INCREASING;
|
|
600
|
+
this.setNewTarget = true;
|
|
601
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} value: ${value}, CurrentPosition: ${this.CurrentPosition}`);
|
|
602
|
+
}
|
|
603
|
+
else if (value < this.CurrentPosition) {
|
|
604
|
+
this.PositionState = this.platform.Characteristic.PositionState.DECREASING;
|
|
605
|
+
this.setNewTarget = true;
|
|
606
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} value: ${value}, CurrentPosition: ${this.CurrentPosition}`);
|
|
607
|
+
}
|
|
608
|
+
else {
|
|
609
|
+
this.PositionState = this.platform.Characteristic.PositionState.STOPPED;
|
|
610
|
+
this.setNewTarget = false;
|
|
611
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} value: ${value}, CurrentPosition: ${this.CurrentPosition}`);
|
|
612
|
+
}
|
|
613
|
+
this.windowCoveringService.setCharacteristic(this.platform.Characteristic.PositionState, this.PositionState);
|
|
614
|
+
this.windowCoveringService.getCharacteristic(this.platform.Characteristic.PositionState).updateValue(this.PositionState);
|
|
615
|
+
/**
|
|
616
|
+
* If Curtain movement time is short, the moving flag from backend is always false.
|
|
617
|
+
* The minimum time depends on the network control latency.
|
|
618
|
+
*/
|
|
619
|
+
clearTimeout(this.setNewTargetTimer);
|
|
620
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateRate: ${this.updateRate}`);
|
|
621
|
+
if (this.setNewTarget) {
|
|
622
|
+
this.setNewTargetTimer = setTimeout(() => {
|
|
623
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} setNewTarget ${this.setNewTarget} timeout`);
|
|
624
|
+
this.setNewTarget = false;
|
|
625
|
+
}, this.updateRate * 1000);
|
|
626
|
+
}
|
|
627
|
+
this.doCurtainUpdate.next();
|
|
679
628
|
}
|
|
680
629
|
async updateHomeKitCharacteristics() {
|
|
681
630
|
await this.setMinMax();
|
|
682
631
|
if (this.CurrentPosition === undefined || Number.isNaN(this.CurrentPosition)) {
|
|
683
|
-
this.debugLog(
|
|
632
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} CurrentPosition: ${this.CurrentPosition}`);
|
|
684
633
|
}
|
|
685
634
|
else {
|
|
635
|
+
if (this.device.mqttURL) {
|
|
636
|
+
this.mqttPublish('CurrentPosition', this.CurrentPosition);
|
|
637
|
+
}
|
|
638
|
+
this.accessory.context.CurrentPosition = this.CurrentPosition;
|
|
686
639
|
this.windowCoveringService.updateCharacteristic(this.platform.Characteristic.CurrentPosition, Number(this.CurrentPosition));
|
|
687
|
-
this.debugLog(
|
|
688
|
-
this.mqttPublish('CurrentPosition', this.CurrentPosition);
|
|
640
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic CurrentPosition: ${this.CurrentPosition}`);
|
|
689
641
|
}
|
|
690
642
|
if (this.PositionState === undefined) {
|
|
691
|
-
this.debugLog(
|
|
643
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} PositionState: ${this.PositionState}`);
|
|
692
644
|
}
|
|
693
645
|
else {
|
|
646
|
+
if (this.device.mqttURL) {
|
|
647
|
+
this.mqttPublish('PositionState', this.PositionState);
|
|
648
|
+
}
|
|
649
|
+
this.accessory.context.PositionState = this.PositionState;
|
|
694
650
|
this.windowCoveringService.updateCharacteristic(this.platform.Characteristic.PositionState, Number(this.PositionState));
|
|
695
|
-
this.debugLog(
|
|
696
|
-
this.mqttPublish('PositionState', this.PositionState);
|
|
651
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic PositionState: ${this.PositionState}`);
|
|
697
652
|
}
|
|
698
653
|
if (this.TargetPosition === undefined || Number.isNaN(this.TargetPosition)) {
|
|
699
|
-
this.debugLog(
|
|
654
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} TargetPosition: ${this.TargetPosition}`);
|
|
700
655
|
}
|
|
701
656
|
else {
|
|
657
|
+
if (this.device.mqttURL) {
|
|
658
|
+
this.mqttPublish('TargetPosition', this.TargetPosition);
|
|
659
|
+
}
|
|
660
|
+
this.accessory.context.TargetPosition = this.TargetPosition;
|
|
702
661
|
this.windowCoveringService.updateCharacteristic(this.platform.Characteristic.TargetPosition, Number(this.TargetPosition));
|
|
703
|
-
this.debugLog(
|
|
704
|
-
this.mqttPublish('TargetPosition', this.TargetPosition);
|
|
662
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic TargetPosition: ${this.TargetPosition}`);
|
|
705
663
|
}
|
|
706
664
|
if (!this.device.curtain?.hide_lightsensor) {
|
|
707
665
|
if (this.CurrentAmbientLightLevel === undefined || Number.isNaN(this.CurrentAmbientLightLevel)) {
|
|
708
|
-
this.debugLog(
|
|
666
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`);
|
|
709
667
|
}
|
|
710
668
|
else {
|
|
669
|
+
if (this.device.mqttURL) {
|
|
670
|
+
this.mqttPublish('CurrentAmbientLightLevel', this.CurrentAmbientLightLevel);
|
|
671
|
+
}
|
|
672
|
+
this.accessory.context.CurrentAmbientLightLevel = this.CurrentAmbientLightLevel;
|
|
711
673
|
this.lightSensorService?.updateCharacteristic(this.platform.Characteristic.CurrentAmbientLightLevel, this.CurrentAmbientLightLevel);
|
|
712
|
-
this.debugLog(
|
|
713
|
-
|
|
674
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}`
|
|
675
|
+
+ ` updateCharacteristic CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`);
|
|
714
676
|
}
|
|
715
677
|
}
|
|
716
|
-
if (this.
|
|
678
|
+
if (this.BLE) {
|
|
717
679
|
if (this.BatteryLevel === undefined) {
|
|
718
|
-
this.debugLog(
|
|
680
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.BatteryLevel}`);
|
|
719
681
|
}
|
|
720
682
|
else {
|
|
683
|
+
if (this.device.mqttURL) {
|
|
684
|
+
this.mqttPublish('BatteryLevel', this.BatteryLevel);
|
|
685
|
+
}
|
|
686
|
+
this.accessory.context.BatteryLevel = this.BatteryLevel;
|
|
721
687
|
this.batteryService?.updateCharacteristic(this.platform.Characteristic.BatteryLevel, this.BatteryLevel);
|
|
722
|
-
this.debugLog(
|
|
723
|
-
this.mqttPublish('BatteryLevel', this.BatteryLevel);
|
|
688
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic BatteryLevel: ${this.BatteryLevel}`);
|
|
724
689
|
}
|
|
725
690
|
if (this.StatusLowBattery === undefined) {
|
|
726
|
-
this.debugLog(
|
|
691
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} StatusLowBattery: ${this.StatusLowBattery}`);
|
|
727
692
|
}
|
|
728
693
|
else {
|
|
694
|
+
if (this.device.mqttURL) {
|
|
695
|
+
this.mqttPublish('StatusLowBattery', this.StatusLowBattery);
|
|
696
|
+
}
|
|
697
|
+
this.accessory.context.StatusLowBattery = this.StatusLowBattery;
|
|
729
698
|
this.batteryService?.updateCharacteristic(this.platform.Characteristic.StatusLowBattery, this.StatusLowBattery);
|
|
730
|
-
this.debugLog(
|
|
731
|
-
this.mqttPublish('StatusLowBattery', this.StatusLowBattery);
|
|
699
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic StatusLowBattery: ${this.StatusLowBattery}`);
|
|
732
700
|
}
|
|
733
701
|
}
|
|
734
702
|
}
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
703
|
+
/*
|
|
704
|
+
* Publish MQTT message for topics of
|
|
705
|
+
* 'homebridge-switchbot/curtain/xx:xx:xx:xx:xx:xx'
|
|
706
|
+
*/
|
|
707
|
+
mqttPublish(topic, message) {
|
|
708
|
+
const mac = this.device.deviceId
|
|
709
|
+
?.toLowerCase()
|
|
710
|
+
.match(/[\s\S]{1,2}/g)
|
|
711
|
+
?.join(':');
|
|
712
|
+
const options = this.device.mqttPubOptions || {};
|
|
713
|
+
this.mqttClient?.publish(`homebridge-switchbot/curtain/${mac}/${topic}`, `${message}`, options);
|
|
714
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} MQTT message: ${topic}/${message} options:${(0, super_stringify_1.default)(options)}`);
|
|
715
|
+
}
|
|
716
|
+
/*
|
|
717
|
+
* Setup MQTT hadler if URL is specifed.
|
|
718
|
+
*/
|
|
719
|
+
async setupMqtt(device) {
|
|
720
|
+
if (device.mqttURL) {
|
|
721
|
+
try {
|
|
722
|
+
this.mqttClient = await (0, async_mqtt_1.connectAsync)(device.mqttURL, device.mqttOptions || {});
|
|
723
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} MQTT connection has been established successfully.`);
|
|
724
|
+
this.mqttClient.on('error', (e) => {
|
|
725
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Failed to publish MQTT messages. ${e}`);
|
|
726
|
+
});
|
|
727
|
+
}
|
|
728
|
+
catch (e) {
|
|
729
|
+
this.mqttClient = null;
|
|
730
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Failed to establish MQTT connection. ${e}`);
|
|
731
|
+
}
|
|
741
732
|
}
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
733
|
+
}
|
|
734
|
+
async getCustomBLEAddress(switchbot) {
|
|
735
|
+
if (this.device.customBLEaddress && this.deviceLogging.includes('debug')) {
|
|
736
|
+
(async () => {
|
|
737
|
+
// Start to monitor advertisement packets
|
|
738
|
+
await switchbot.startScan({
|
|
739
|
+
model: 'c',
|
|
740
|
+
});
|
|
741
|
+
// Set an event handler
|
|
742
|
+
switchbot.onadvertisement = (ad) => {
|
|
743
|
+
this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} ad: ${(0, super_stringify_1.default)(ad, null, ' ')}`);
|
|
744
|
+
};
|
|
745
|
+
await switchbot.wait(10000);
|
|
746
|
+
// Stop to monitor
|
|
747
|
+
switchbot.stopScan();
|
|
748
|
+
})();
|
|
745
749
|
}
|
|
746
|
-
//throw new this.platform.api.hap.HapStatusError(HAPStatus.SERVICE_COMMUNICATION_FAILURE);
|
|
747
750
|
}
|
|
748
|
-
async
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
break;
|
|
753
|
-
case 152:
|
|
754
|
-
this.errorLog(`Curtain: ${this.accessory.displayName} Device not found.`);
|
|
755
|
-
break;
|
|
756
|
-
case 160:
|
|
757
|
-
this.errorLog(`Curtain: ${this.accessory.displayName} Command is not supported.`);
|
|
758
|
-
break;
|
|
759
|
-
case 161:
|
|
760
|
-
this.errorLog(`Curtain: ${this.accessory.displayName} Device is offline.`);
|
|
761
|
-
break;
|
|
762
|
-
case 171:
|
|
763
|
-
this.errorLog(`Curtain: ${this.accessory.displayName} Hub Device is offline. Hub: ${this.device.hubDeviceId}`);
|
|
764
|
-
break;
|
|
765
|
-
case 190:
|
|
766
|
-
this.errorLog(`Curtain: ${this.accessory.displayName} Device internal error due to device states not synchronized with server,` +
|
|
767
|
-
` Or command: ${JSON.stringify(res)} format is invalid`);
|
|
768
|
-
break;
|
|
769
|
-
case 100:
|
|
770
|
-
this.debugLog(`Curtain: ${this.accessory.displayName} Command successfully sent.`);
|
|
771
|
-
break;
|
|
772
|
-
default:
|
|
773
|
-
this.debugLog(`Curtain: ${this.accessory.displayName} Unknown statusCode.`);
|
|
751
|
+
async BLEPushConnection() {
|
|
752
|
+
if (this.platform.config.credentials?.token && this.device.connectionType === 'BLE/OpenAPI') {
|
|
753
|
+
this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} Using OpenAPI Connection to Push Changes`);
|
|
754
|
+
await this.openAPIpushChanges();
|
|
774
755
|
}
|
|
775
756
|
}
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
this.TargetPosition = value;
|
|
782
|
-
this.mqttPublish('TargetPosition', this.TargetPosition);
|
|
783
|
-
await this.setMinMax();
|
|
784
|
-
if (value > this.CurrentPosition) {
|
|
785
|
-
this.PositionState = this.platform.Characteristic.PositionState.INCREASING;
|
|
786
|
-
this.setNewTarget = true;
|
|
787
|
-
this.debugLog(`Curtain: ${this.accessory.displayName} value: ${value}, CurrentPosition: ${this.CurrentPosition}`);
|
|
757
|
+
async BLERefreshConnection(switchbot) {
|
|
758
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} wasn't able to establish BLE Connection, node-switchbot: ${switchbot}`);
|
|
759
|
+
if (this.platform.config.credentials?.token && this.device.connectionType === 'BLE/OpenAPI') {
|
|
760
|
+
this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} Using OpenAPI Connection to Refresh Status`);
|
|
761
|
+
await this.openAPIRefreshStatus();
|
|
788
762
|
}
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
763
|
+
}
|
|
764
|
+
async SilentPerformance() {
|
|
765
|
+
if (this.TargetPosition > 50) {
|
|
766
|
+
if (this.device.curtain?.setOpenMode === '1') {
|
|
767
|
+
this.setPositionMode = 1;
|
|
768
|
+
this.Mode = 'Silent Mode';
|
|
769
|
+
}
|
|
770
|
+
else {
|
|
771
|
+
this.setPositionMode = 0;
|
|
772
|
+
this.Mode = 'Performance Mode';
|
|
773
|
+
}
|
|
793
774
|
}
|
|
794
775
|
else {
|
|
795
|
-
this.
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
* The minimum time depends on the network control latency.
|
|
804
|
-
*/
|
|
805
|
-
clearTimeout(this.setNewTargetTimer);
|
|
806
|
-
this.debugLog(`Curtain: ${this.accessory.displayName} updateRate: ${this.updateRate}`);
|
|
807
|
-
if (this.setNewTarget) {
|
|
808
|
-
this.setNewTargetTimer = setTimeout(() => {
|
|
809
|
-
this.debugLog(`Curtain: ${this.accessory.displayName} setNewTarget ${this.setNewTarget} timeout`);
|
|
810
|
-
this.setNewTarget = false;
|
|
811
|
-
}, this.updateRate * 1000);
|
|
776
|
+
if (this.device.curtain?.setCloseMode === '1') {
|
|
777
|
+
this.setPositionMode = 1;
|
|
778
|
+
this.Mode = 'Silent Mode';
|
|
779
|
+
}
|
|
780
|
+
else {
|
|
781
|
+
this.setPositionMode = 0;
|
|
782
|
+
this.Mode = 'Performance Mode';
|
|
783
|
+
}
|
|
812
784
|
}
|
|
813
|
-
this.doCurtainUpdate.next();
|
|
814
785
|
}
|
|
815
786
|
async setMinMax() {
|
|
816
787
|
if (this.device.curtain?.set_min) {
|
|
@@ -824,96 +795,117 @@ class Curtain {
|
|
|
824
795
|
}
|
|
825
796
|
}
|
|
826
797
|
}
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
config = device.curtain;
|
|
831
|
-
}
|
|
832
|
-
if (device.ble) {
|
|
833
|
-
config['ble'] = device.ble;
|
|
834
|
-
}
|
|
835
|
-
if (device.logging !== undefined) {
|
|
836
|
-
config['logging'] = device.logging;
|
|
837
|
-
}
|
|
838
|
-
if (device.refreshRate !== undefined) {
|
|
839
|
-
config['refreshRate'] = device.refreshRate;
|
|
840
|
-
}
|
|
841
|
-
if (device.scanDuration !== undefined) {
|
|
842
|
-
config['scanDuration'] = device.scanDuration;
|
|
798
|
+
minStep(device) {
|
|
799
|
+
if (device.curtain?.set_minStep) {
|
|
800
|
+
this.set_minStep = device.curtain?.set_minStep;
|
|
843
801
|
}
|
|
844
|
-
|
|
845
|
-
this.
|
|
802
|
+
else {
|
|
803
|
+
this.set_minStep = 1;
|
|
846
804
|
}
|
|
805
|
+
return this.set_minStep;
|
|
847
806
|
}
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
this.deviceRefreshRate = this.accessory.context.refreshRate = device.refreshRate;
|
|
852
|
-
this.debugLog(`Curtain: ${this.accessory.displayName} Using Device Config refreshRate: ${this.deviceRefreshRate}`);
|
|
807
|
+
minLux() {
|
|
808
|
+
if (this.device.curtain?.set_minLux) {
|
|
809
|
+
this.set_minLux = this.device.curtain?.set_minLux;
|
|
853
810
|
}
|
|
854
|
-
else
|
|
855
|
-
this.
|
|
856
|
-
this.debugLog(`Curtain: ${this.accessory.displayName} Using Platform Config refreshRate: ${this.deviceRefreshRate}`);
|
|
811
|
+
else {
|
|
812
|
+
this.set_minLux = 1;
|
|
857
813
|
}
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
814
|
+
return this.set_minLux;
|
|
815
|
+
}
|
|
816
|
+
maxLux() {
|
|
817
|
+
if (this.device.curtain?.set_maxLux) {
|
|
818
|
+
this.set_maxLux = this.device.curtain?.set_maxLux;
|
|
862
819
|
}
|
|
863
820
|
else {
|
|
864
|
-
this.
|
|
865
|
-
this.debugLog(`Curtain: ${this.accessory.displayName} Using Default Curtain Refresh Rate.`);
|
|
821
|
+
this.set_maxLux = 6001;
|
|
866
822
|
}
|
|
823
|
+
return this.set_maxLux;
|
|
867
824
|
}
|
|
868
825
|
async scan(device) {
|
|
869
826
|
if (device.scanDuration) {
|
|
870
827
|
if (this.updateRate > device.scanDuration) {
|
|
871
828
|
this.scanDuration = this.updateRate;
|
|
872
|
-
this.warnLog(
|
|
829
|
+
this.warnLog(`${this.device.deviceType}: `
|
|
830
|
+
+ `${this.accessory.displayName} scanDuration is less then updateRate, overriding scanDuration with updateRate`);
|
|
873
831
|
}
|
|
874
832
|
else {
|
|
875
833
|
this.scanDuration = this.accessory.context.scanDuration = device.scanDuration;
|
|
876
834
|
}
|
|
877
|
-
if (
|
|
878
|
-
this.debugLog(
|
|
835
|
+
if (this.BLE) {
|
|
836
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Config scanDuration: ${this.scanDuration}`);
|
|
879
837
|
}
|
|
880
838
|
}
|
|
881
839
|
else {
|
|
882
840
|
if (this.updateRate > 1) {
|
|
883
841
|
this.scanDuration = this.updateRate;
|
|
884
|
-
this.warnLog(
|
|
842
|
+
this.warnLog(`${this.device.deviceType}: `
|
|
843
|
+
+ `${this.accessory.displayName} scanDuration is less then updateRate, overriding scanDuration with updateRate`);
|
|
885
844
|
}
|
|
886
845
|
else {
|
|
887
846
|
this.scanDuration = this.accessory.context.scanDuration = 1;
|
|
888
847
|
}
|
|
889
|
-
if (this.
|
|
890
|
-
this.debugLog(
|
|
848
|
+
if (this.BLE) {
|
|
849
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Default scanDuration: ${this.scanDuration}`);
|
|
891
850
|
}
|
|
892
851
|
}
|
|
893
852
|
}
|
|
894
|
-
async
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
853
|
+
async statusCode({ res }) {
|
|
854
|
+
switch (res.statusCode) {
|
|
855
|
+
case 151:
|
|
856
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command not supported by this device type.`);
|
|
857
|
+
break;
|
|
858
|
+
case 152:
|
|
859
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device not found.`);
|
|
860
|
+
break;
|
|
861
|
+
case 160:
|
|
862
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command is not supported.`);
|
|
863
|
+
break;
|
|
864
|
+
case 161:
|
|
865
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device is offline.`);
|
|
866
|
+
this.offlineOff();
|
|
867
|
+
break;
|
|
868
|
+
case 171:
|
|
869
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Hub Device is offline. Hub: ${this.device.hubDeviceId}`);
|
|
870
|
+
this.offlineOff();
|
|
871
|
+
break;
|
|
872
|
+
case 190:
|
|
873
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device internal error due to device states not synchronized with server,` +
|
|
874
|
+
` Or command: ${(0, super_stringify_1.default)(res)} format is invalid`);
|
|
875
|
+
break;
|
|
876
|
+
case 100:
|
|
877
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Command successfully sent.`);
|
|
878
|
+
break;
|
|
879
|
+
default:
|
|
880
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Unknown statusCode.`);
|
|
898
881
|
}
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
882
|
+
}
|
|
883
|
+
async offlineOff() {
|
|
884
|
+
if (this.device.offline) {
|
|
885
|
+
this.CurrentPosition = 100;
|
|
886
|
+
this.windowCoveringService.getCharacteristic(this.platform.Characteristic.On).updateValue(this.CurrentPosition);
|
|
887
|
+
await this.updateHomeKitCharacteristics();
|
|
902
888
|
}
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
889
|
+
}
|
|
890
|
+
async apiError(e) {
|
|
891
|
+
this.windowCoveringService.updateCharacteristic(this.platform.Characteristic.CurrentPosition, e);
|
|
892
|
+
this.windowCoveringService.updateCharacteristic(this.platform.Characteristic.PositionState, e);
|
|
893
|
+
this.windowCoveringService.updateCharacteristic(this.platform.Characteristic.TargetPosition, e);
|
|
894
|
+
if (!this.device.curtain?.hide_lightsensor) {
|
|
895
|
+
this.lightSensorService?.updateCharacteristic(this.platform.Characteristic.CurrentAmbientLightLevel, e);
|
|
906
896
|
}
|
|
907
|
-
|
|
908
|
-
this.
|
|
909
|
-
this.
|
|
897
|
+
if (this.BLE) {
|
|
898
|
+
this.batteryService?.updateCharacteristic(this.platform.Characteristic.BatteryLevel, e);
|
|
899
|
+
this.batteryService?.updateCharacteristic(this.platform.Characteristic.StatusLowBattery, e);
|
|
910
900
|
}
|
|
901
|
+
//throw new this.platform.api.hap.HapStatusError(HAPStatus.SERVICE_COMMUNICATION_FAILURE);
|
|
911
902
|
}
|
|
912
903
|
FirmwareRevision(accessory, device) {
|
|
913
904
|
let FirmwareRevision;
|
|
914
|
-
this.debugLog(
|
|
915
|
-
|
|
916
|
-
this.debugLog(
|
|
905
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}`
|
|
906
|
+
+ ` accessory.context.FirmwareRevision: ${accessory.context.FirmwareRevision}`);
|
|
907
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} device.firmware: ${device.firmware}`);
|
|
908
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} this.platform.version: ${this.platform.version}`);
|
|
917
909
|
if (accessory.context.FirmwareRevision) {
|
|
918
910
|
FirmwareRevision = accessory.context.FirmwareRevision;
|
|
919
911
|
}
|
|
@@ -925,32 +917,90 @@ class Curtain {
|
|
|
925
917
|
}
|
|
926
918
|
return FirmwareRevision;
|
|
927
919
|
}
|
|
928
|
-
|
|
929
|
-
if (
|
|
930
|
-
this.
|
|
920
|
+
async context() {
|
|
921
|
+
if (this.CurrentPosition === undefined) {
|
|
922
|
+
this.CurrentPosition = 0;
|
|
931
923
|
}
|
|
932
924
|
else {
|
|
933
|
-
this.
|
|
925
|
+
this.CurrentPosition = this.accessory.context.CurrentPosition;
|
|
926
|
+
}
|
|
927
|
+
if (this.TargetPosition === undefined) {
|
|
928
|
+
this.TargetPosition = 0;
|
|
929
|
+
}
|
|
930
|
+
else {
|
|
931
|
+
this.TargetPosition = this.accessory.context.TargetPosition;
|
|
932
|
+
}
|
|
933
|
+
if (this.PositionState === undefined) {
|
|
934
|
+
this.PositionState = this.platform.Characteristic.PositionState.STOPPED;
|
|
935
|
+
}
|
|
936
|
+
else {
|
|
937
|
+
this.PositionState = this.accessory.context.PositionState;
|
|
934
938
|
}
|
|
935
|
-
return this.set_minStep;
|
|
936
939
|
}
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
+
async refreshRate(device) {
|
|
941
|
+
// refreshRate
|
|
942
|
+
if (device.refreshRate) {
|
|
943
|
+
this.deviceRefreshRate = this.accessory.context.refreshRate = device.refreshRate;
|
|
944
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Config refreshRate: ${this.deviceRefreshRate}`);
|
|
945
|
+
}
|
|
946
|
+
else if (this.platform.config.options.refreshRate) {
|
|
947
|
+
this.deviceRefreshRate = this.accessory.context.refreshRate = this.platform.config.options.refreshRate;
|
|
948
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Platform Config refreshRate: ${this.deviceRefreshRate}`);
|
|
949
|
+
}
|
|
950
|
+
// updateRate
|
|
951
|
+
if (device?.curtain?.updateRate) {
|
|
952
|
+
this.updateRate = device?.curtain?.updateRate;
|
|
953
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Config Curtain refreshRate: ${this.deviceRefreshRate}`);
|
|
940
954
|
}
|
|
941
955
|
else {
|
|
942
|
-
this.
|
|
956
|
+
this.updateRate = 7;
|
|
957
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Default Curtain Refresh Rate.`);
|
|
943
958
|
}
|
|
944
|
-
return this.set_minLux;
|
|
945
959
|
}
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
960
|
+
async config(device) {
|
|
961
|
+
let config = {};
|
|
962
|
+
if (device.curtain) {
|
|
963
|
+
config = device.curtain;
|
|
964
|
+
}
|
|
965
|
+
if (device.connectionType !== undefined) {
|
|
966
|
+
config['connectionType'] = device.connectionType;
|
|
967
|
+
}
|
|
968
|
+
if (device.external !== undefined) {
|
|
969
|
+
config['external'] = device.external;
|
|
970
|
+
}
|
|
971
|
+
if (device.mqttURL !== undefined) {
|
|
972
|
+
config['mqttURL'] = device.mqttURL;
|
|
973
|
+
}
|
|
974
|
+
if (device.logging !== undefined) {
|
|
975
|
+
config['logging'] = device.logging;
|
|
976
|
+
}
|
|
977
|
+
if (device.refreshRate !== undefined) {
|
|
978
|
+
config['refreshRate'] = device.refreshRate;
|
|
979
|
+
}
|
|
980
|
+
if (device.scanDuration !== undefined) {
|
|
981
|
+
config['scanDuration'] = device.scanDuration;
|
|
982
|
+
}
|
|
983
|
+
if (Object.entries(config).length !== 0) {
|
|
984
|
+
this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Config: ${(0, super_stringify_1.default)(config)}`);
|
|
985
|
+
}
|
|
986
|
+
}
|
|
987
|
+
async logs(device) {
|
|
988
|
+
if (this.platform.debugMode) {
|
|
989
|
+
this.deviceLogging = this.accessory.context.logging = 'debugMode';
|
|
990
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Debug Mode Logging: ${this.deviceLogging}`);
|
|
991
|
+
}
|
|
992
|
+
else if (device.logging) {
|
|
993
|
+
this.deviceLogging = this.accessory.context.logging = device.logging;
|
|
994
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Config Logging: ${this.deviceLogging}`);
|
|
995
|
+
}
|
|
996
|
+
else if (this.platform.config.options?.logging) {
|
|
997
|
+
this.deviceLogging = this.accessory.context.logging = this.platform.config.options?.logging;
|
|
998
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Platform Config Logging: ${this.deviceLogging}`);
|
|
949
999
|
}
|
|
950
1000
|
else {
|
|
951
|
-
this.
|
|
1001
|
+
this.deviceLogging = this.accessory.context.logging = 'standard';
|
|
1002
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Logging Not Set, Using: ${this.deviceLogging}`);
|
|
952
1003
|
}
|
|
953
|
-
return this.set_maxLux;
|
|
954
1004
|
}
|
|
955
1005
|
/**
|
|
956
1006
|
* Logging for Device
|
|
@@ -965,11 +1015,25 @@ class Curtain {
|
|
|
965
1015
|
this.platform.log.warn(String(...log));
|
|
966
1016
|
}
|
|
967
1017
|
}
|
|
1018
|
+
debugWarnLog(...log) {
|
|
1019
|
+
if (this.enablingDeviceLogging()) {
|
|
1020
|
+
if (this.deviceLogging?.includes('debug')) {
|
|
1021
|
+
this.platform.log.warn('[DEBUG]', String(...log));
|
|
1022
|
+
}
|
|
1023
|
+
}
|
|
1024
|
+
}
|
|
968
1025
|
errorLog(...log) {
|
|
969
1026
|
if (this.enablingDeviceLogging()) {
|
|
970
1027
|
this.platform.log.error(String(...log));
|
|
971
1028
|
}
|
|
972
1029
|
}
|
|
1030
|
+
debugErrorLog(...log) {
|
|
1031
|
+
if (this.enablingDeviceLogging()) {
|
|
1032
|
+
if (this.deviceLogging?.includes('debug')) {
|
|
1033
|
+
this.platform.log.error('[DEBUG]', String(...log));
|
|
1034
|
+
}
|
|
1035
|
+
}
|
|
1036
|
+
}
|
|
973
1037
|
debugLog(...log) {
|
|
974
1038
|
if (this.enablingDeviceLogging()) {
|
|
975
1039
|
if (this.deviceLogging === 'debug') {
|