@switchbot/homebridge-switchbot 3.5.0-beta.9 → 3.5.1-beta.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/.vscode/settings.json +4 -1
- package/CHANGELOG.md +4 -1
- package/config.schema.json +164 -22
- package/dist/device/blindtilt.d.ts +21 -96
- package/dist/device/blindtilt.d.ts.map +1 -1
- package/dist/device/blindtilt.js +457 -866
- package/dist/device/blindtilt.js.map +1 -1
- package/dist/device/bot.d.ts +27 -72
- package/dist/device/bot.d.ts.map +1 -1
- package/dist/device/bot.js +851 -913
- package/dist/device/bot.js.map +1 -1
- package/dist/device/ceilinglight.d.ts +15 -69
- package/dist/device/ceilinglight.d.ts.map +1 -1
- package/dist/device/ceilinglight.js +316 -742
- package/dist/device/ceilinglight.js.map +1 -1
- package/dist/device/colorbulb.d.ts +15 -76
- package/dist/device/colorbulb.d.ts.map +1 -1
- package/dist/device/colorbulb.js +380 -833
- package/dist/device/colorbulb.js.map +1 -1
- package/dist/device/contact.d.ts +14 -66
- package/dist/device/contact.d.ts.map +1 -1
- package/dist/device/contact.js +267 -602
- package/dist/device/contact.js.map +1 -1
- package/dist/device/curtain.d.ts +18 -89
- package/dist/device/curtain.d.ts.map +1 -1
- package/dist/device/curtain.js +469 -897
- package/dist/device/curtain.js.map +1 -1
- package/dist/device/device.d.ts +76 -0
- package/dist/device/device.d.ts.map +1 -0
- package/dist/device/device.js +846 -0
- package/dist/device/device.js.map +1 -0
- package/dist/device/fan.d.ts +63 -0
- package/dist/device/fan.d.ts.map +1 -0
- package/dist/device/fan.js +645 -0
- package/dist/device/fan.js.map +1 -0
- package/dist/device/hub.d.ts +19 -58
- package/dist/device/hub.d.ts.map +1 -1
- package/dist/device/hub.js +304 -640
- package/dist/device/hub.js.map +1 -1
- package/dist/device/humidifier.d.ts +11 -66
- package/dist/device/humidifier.d.ts.map +1 -1
- package/dist/device/humidifier.js +300 -710
- package/dist/device/humidifier.js.map +1 -1
- package/dist/device/iosensor.d.ts +12 -64
- package/dist/device/iosensor.d.ts.map +1 -1
- package/dist/device/iosensor.js +225 -643
- package/dist/device/iosensor.js.map +1 -1
- package/dist/device/lightstrip.d.ts +12 -70
- package/dist/device/lightstrip.d.ts.map +1 -1
- package/dist/device/lightstrip.js +371 -742
- package/dist/device/lightstrip.js.map +1 -1
- package/dist/device/lock.d.ts +17 -63
- package/dist/device/lock.d.ts.map +1 -1
- package/dist/device/lock.js +309 -642
- package/dist/device/lock.js.map +1 -1
- package/dist/device/meter.d.ts +15 -64
- package/dist/device/meter.d.ts.map +1 -1
- package/dist/device/meter.js +223 -638
- package/dist/device/meter.js.map +1 -1
- package/dist/device/meterplus.d.ts +15 -65
- package/dist/device/meterplus.d.ts.map +1 -1
- package/dist/device/meterplus.js +216 -644
- package/dist/device/meterplus.js.map +1 -1
- package/dist/device/motion.d.ts +12 -69
- package/dist/device/motion.d.ts.map +1 -1
- package/dist/device/motion.js +209 -588
- package/dist/device/motion.js.map +1 -1
- package/dist/device/plug.d.ts +10 -57
- package/dist/device/plug.d.ts.map +1 -1
- package/dist/device/plug.js +141 -532
- package/dist/device/plug.js.map +1 -1
- package/dist/device/robotvacuumcleaner.d.ts +13 -63
- package/dist/device/robotvacuumcleaner.d.ts.map +1 -1
- package/dist/device/robotvacuumcleaner.js +252 -609
- package/dist/device/robotvacuumcleaner.js.map +1 -1
- package/dist/device/waterdetector.d.ts +11 -63
- package/dist/device/waterdetector.d.ts.map +1 -1
- package/dist/device/waterdetector.js +179 -521
- package/dist/device/waterdetector.js.map +1 -1
- package/dist/homebridge-ui/public/index.html +22 -16
- package/dist/homebridge-ui/server.js +1 -1
- package/dist/homebridge-ui/server.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/irdevice/airconditioner.d.ts +10 -50
- package/dist/irdevice/airconditioner.d.ts.map +1 -1
- package/dist/irdevice/airconditioner.js +337 -482
- package/dist/irdevice/airconditioner.js.map +1 -1
- package/dist/irdevice/airpurifier.d.ts +8 -39
- package/dist/irdevice/airpurifier.d.ts.map +1 -1
- package/dist/irdevice/airpurifier.js +108 -333
- package/dist/irdevice/airpurifier.js.map +1 -1
- package/dist/irdevice/camera.d.ts +7 -36
- package/dist/irdevice/camera.d.ts.map +1 -1
- package/dist/irdevice/camera.js +47 -299
- package/dist/irdevice/camera.js.map +1 -1
- package/dist/irdevice/fan.d.ts +7 -43
- package/dist/irdevice/fan.d.ts.map +1 -1
- package/dist/irdevice/fan.js +95 -364
- package/dist/irdevice/fan.js.map +1 -1
- package/dist/irdevice/irdevice.d.ts +46 -0
- package/dist/irdevice/irdevice.d.ts.map +1 -0
- package/dist/irdevice/irdevice.js +393 -0
- package/dist/irdevice/irdevice.js.map +1 -0
- package/dist/irdevice/light.d.ts +12 -45
- package/dist/irdevice/light.d.ts.map +1 -1
- package/dist/irdevice/light.js +121 -376
- package/dist/irdevice/light.js.map +1 -1
- package/dist/irdevice/other.d.ts +19 -48
- package/dist/irdevice/other.d.ts.map +1 -1
- package/dist/irdevice/other.js +441 -584
- package/dist/irdevice/other.js.map +1 -1
- package/dist/irdevice/tv.d.ts +8 -40
- package/dist/irdevice/tv.d.ts.map +1 -1
- package/dist/irdevice/tv.js +94 -353
- package/dist/irdevice/tv.js.map +1 -1
- package/dist/irdevice/vacuumcleaner.d.ts +7 -36
- package/dist/irdevice/vacuumcleaner.d.ts.map +1 -1
- package/dist/irdevice/vacuumcleaner.js +48 -299
- package/dist/irdevice/vacuumcleaner.js.map +1 -1
- package/dist/irdevice/waterheater.d.ts +7 -36
- package/dist/irdevice/waterheater.d.ts.map +1 -1
- package/dist/irdevice/waterheater.js +50 -305
- package/dist/irdevice/waterheater.js.map +1 -1
- package/dist/platform.d.ts +22 -8
- package/dist/platform.d.ts.map +1 -1
- package/dist/platform.js +342 -191
- package/dist/platform.js.map +1 -1
- package/dist/settings.d.ts +66 -18
- package/dist/settings.d.ts.map +1 -1
- package/dist/settings.js +16 -552
- package/dist/settings.js.map +1 -1
- package/dist/utils.d.ts +95 -0
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +657 -1
- package/dist/utils.js.map +1 -1
- package/eslint.config.js +96 -0
- package/package.json +20 -16
- package/src/custom.d.ts +2 -1
- package/src/device/blindtilt.ts +488 -937
- package/src/device/bot.ts +907 -1016
- package/src/device/ceilinglight.ts +330 -798
- package/src/device/colorbulb.ts +394 -904
- package/src/device/contact.ts +298 -637
- package/src/device/curtain.ts +496 -954
- package/src/device/device.ts +872 -0
- package/src/device/fan.ts +692 -0
- package/src/device/hub.ts +338 -671
- package/src/device/humidifier.ts +330 -777
- package/src/device/iosensor.ts +258 -671
- package/src/device/lightstrip.ts +394 -809
- package/src/device/lock.ts +345 -700
- package/src/device/meter.ts +256 -666
- package/src/device/meterplus.ts +248 -672
- package/src/device/motion.ts +234 -622
- package/src/device/plug.ts +152 -572
- package/src/device/robotvacuumcleaner.ts +273 -653
- package/src/device/waterdetector.ts +198 -549
- package/src/homebridge-ui/public/index.html +22 -16
- package/src/homebridge-ui/server.ts +1 -1
- package/src/index.ts +4 -3
- package/src/irdevice/airconditioner.ts +368 -540
- package/src/irdevice/airpurifier.ts +134 -369
- package/src/irdevice/camera.ts +60 -324
- package/src/irdevice/fan.ts +111 -392
- package/src/irdevice/irdevice.ts +406 -0
- package/src/irdevice/light.ts +159 -425
- package/src/irdevice/other.ts +509 -661
- package/src/irdevice/tv.ts +123 -388
- package/src/irdevice/vacuumcleaner.ts +61 -324
- package/src/irdevice/waterheater.ts +63 -333
- package/src/platform.ts +395 -259
- package/src/settings.ts +120 -610
- package/src/utils.ts +661 -1
- package/src/device/waterdetector.json +0 -11
package/dist/device/lock.js
CHANGED
|
@@ -1,151 +1,117 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
/* Copyright(C) 2021-2024, donavanbecker (https://github.com/donavanbecker). All rights reserved.
|
|
2
|
+
*
|
|
3
|
+
* lock.ts: @switchbot/homebridge-switchbot.
|
|
4
|
+
*/
|
|
5
|
+
import { deviceBase } from './device.js';
|
|
3
6
|
import { interval, Subject } from 'rxjs';
|
|
4
7
|
import { debounceTime, skipWhile, take, tap } from 'rxjs/operators';
|
|
5
|
-
|
|
6
|
-
export class Lock {
|
|
8
|
+
export class Lock extends deviceBase {
|
|
7
9
|
platform;
|
|
8
|
-
accessory;
|
|
9
|
-
device;
|
|
10
|
-
api;
|
|
11
|
-
log;
|
|
12
|
-
config;
|
|
13
|
-
hap;
|
|
14
10
|
// Services
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
// Characteristic Values
|
|
20
|
-
BatteryLevel;
|
|
21
|
-
LockTargetState;
|
|
22
|
-
LockCurrentState;
|
|
23
|
-
FirmwareRevision;
|
|
24
|
-
StatusLowBattery;
|
|
25
|
-
ContactSensorState;
|
|
26
|
-
// OpenAPI Status
|
|
27
|
-
OpenAPI_BatteryLevel;
|
|
28
|
-
OpenAPI_FirmwareRevision;
|
|
29
|
-
OpenAPI_LockCurrentState;
|
|
30
|
-
OpenAPI_ContactSensorState;
|
|
31
|
-
// BLE Status
|
|
32
|
-
BLE_BatteryLevel;
|
|
33
|
-
BLE_LockCurrentState;
|
|
34
|
-
BLE_Calibration;
|
|
35
|
-
BLE_ContactSensorState;
|
|
36
|
-
// BLE Others
|
|
37
|
-
BLE_IsConnected;
|
|
38
|
-
// Config
|
|
39
|
-
scanDuration;
|
|
40
|
-
deviceLogging;
|
|
41
|
-
deviceRefreshRate;
|
|
11
|
+
LockMechanism;
|
|
12
|
+
Battery;
|
|
13
|
+
ContactSensor;
|
|
14
|
+
Switch;
|
|
42
15
|
// Updates
|
|
43
16
|
lockUpdateInProgress;
|
|
44
17
|
doLockUpdate;
|
|
45
|
-
// Connection
|
|
46
|
-
OpenAPI;
|
|
47
|
-
BLE;
|
|
48
18
|
constructor(platform, accessory, device) {
|
|
19
|
+
super(platform, accessory, device);
|
|
49
20
|
this.platform = platform;
|
|
50
|
-
this.accessory = accessory;
|
|
51
|
-
this.device = device;
|
|
52
|
-
this.api = this.platform.api;
|
|
53
|
-
this.log = this.platform.log;
|
|
54
|
-
this.config = this.platform.config;
|
|
55
|
-
this.hap = this.api.hap;
|
|
56
|
-
// Connection
|
|
57
|
-
this.BLE = this.device.connectionType === 'BLE' || this.device.connectionType === 'BLE/OpenAPI';
|
|
58
|
-
this.OpenAPI = this.device.connectionType === 'OpenAPI' || this.device.connectionType === 'BLE/OpenAPI';
|
|
59
|
-
// default placeholders
|
|
60
|
-
this.deviceLogs(device);
|
|
61
|
-
this.scan(device);
|
|
62
|
-
this.refreshRate(device);
|
|
63
|
-
this.deviceContext();
|
|
64
|
-
this.deviceConfig(device);
|
|
65
21
|
// this is subject we use to track when we need to POST changes to the SwitchBot API
|
|
66
22
|
this.doLockUpdate = new Subject();
|
|
67
23
|
this.lockUpdateInProgress = false;
|
|
68
|
-
//
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
.getService(this.hap.Service.
|
|
73
|
-
.
|
|
74
|
-
.
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
//
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
this.
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
this.
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
24
|
+
// Initialize LockMechanism Service
|
|
25
|
+
accessory.context.LockMechanism = accessory.context.LockMechanism ?? {};
|
|
26
|
+
this.LockMechanism = {
|
|
27
|
+
Name: accessory.context.LockMechanism.Name ?? accessory.displayName,
|
|
28
|
+
Service: accessory.getService(this.hap.Service.LockMechanism) ?? accessory.addService(this.hap.Service.LockMechanism),
|
|
29
|
+
LockTargetState: accessory.context.LockTargetState ?? this.hap.Characteristic.LockTargetState.SECURED,
|
|
30
|
+
LockCurrentState: accessory.context.LockCurrentState ?? this.hap.Characteristic.LockCurrentState.SECURED,
|
|
31
|
+
};
|
|
32
|
+
accessory.context.LockMechanism = this.LockMechanism;
|
|
33
|
+
// Initialize LockMechanism Characteristics
|
|
34
|
+
this.LockMechanism.Service
|
|
35
|
+
.setCharacteristic(this.hap.Characteristic.Name, this.LockMechanism.Name)
|
|
36
|
+
.getCharacteristic(this.hap.Characteristic.LockTargetState)
|
|
37
|
+
.onGet(() => {
|
|
38
|
+
return this.LockMechanism.LockTargetState;
|
|
39
|
+
})
|
|
40
|
+
.onSet(this.LockTargetStateSet.bind(this));
|
|
41
|
+
// Initialize Battery property
|
|
42
|
+
accessory.context.Battery = accessory.context.Battery ?? {};
|
|
43
|
+
this.Battery = {
|
|
44
|
+
Name: accessory.context.Battery.Name ?? `${accessory.displayName} Battery`,
|
|
45
|
+
Service: accessory.getService(this.hap.Service.Battery) ?? accessory.addService(this.hap.Service.Battery),
|
|
46
|
+
BatteryLevel: accessory.context.BatteryLevel ?? 100,
|
|
47
|
+
StatusLowBattery: accessory.context.StatusLowBattery ?? this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL,
|
|
48
|
+
};
|
|
49
|
+
accessory.context.Battery = this.Battery;
|
|
50
|
+
// Initialize Battery Characteristics
|
|
51
|
+
this.Battery.Service
|
|
52
|
+
.setCharacteristic(this.hap.Characteristic.Name, this.Battery.Name)
|
|
53
|
+
.setCharacteristic(this.hap.Characteristic.ChargingState, this.hap.Characteristic.ChargingState.NOT_CHARGEABLE)
|
|
54
|
+
.getCharacteristic(this.hap.Characteristic.BatteryLevel)
|
|
55
|
+
.onGet(() => {
|
|
56
|
+
return this.Battery.BatteryLevel;
|
|
57
|
+
});
|
|
58
|
+
this.Battery.Service
|
|
59
|
+
.getCharacteristic(this.hap.Characteristic.StatusLowBattery)
|
|
60
|
+
.onGet(() => {
|
|
61
|
+
return this.Battery.StatusLowBattery;
|
|
62
|
+
});
|
|
63
|
+
// Contact Sensor Service
|
|
64
|
+
if (device.lock?.hide_contactsensor) {
|
|
65
|
+
if (this.ContactSensor) {
|
|
66
|
+
this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Removing Contact Sensor Service`);
|
|
67
|
+
this.ContactSensor.Service = this.accessory.getService(this.hap.Service.ContactSensor);
|
|
68
|
+
accessory.removeService(this.ContactSensor.Service);
|
|
107
69
|
}
|
|
108
|
-
this.latchButtonService.getCharacteristic(this.hap.Characteristic.On)
|
|
109
|
-
.on('set', (value, callback) => {
|
|
110
|
-
if (typeof value === 'boolean') {
|
|
111
|
-
this.handleLatchCharacteristic(value, callback);
|
|
112
|
-
}
|
|
113
|
-
else {
|
|
114
|
-
callback(new Error('Wrong characteristic value type'));
|
|
115
|
-
}
|
|
116
|
-
});
|
|
117
70
|
}
|
|
118
71
|
else {
|
|
119
|
-
|
|
72
|
+
accessory.context.ContactSensor = accessory.context.ContactSensor ?? {};
|
|
73
|
+
this.ContactSensor = {
|
|
74
|
+
Name: accessory.context.ContactSensor.Name ?? `${accessory.displayName} Contact Sensor`,
|
|
75
|
+
Service: accessory.getService(this.hap.Service.ContactSensor) ?? this.accessory.addService(this.hap.Service.ContactSensor),
|
|
76
|
+
ContactSensorState: accessory.context.ContactSensorState ?? this.hap.Characteristic.ContactSensorState.CONTACT_DETECTED,
|
|
77
|
+
};
|
|
78
|
+
accessory.context.ContactSensor = this.ContactSensor;
|
|
79
|
+
// Initialize Contact Sensor Characteristics
|
|
80
|
+
this.ContactSensor.Service
|
|
81
|
+
.setCharacteristic(this.hap.Characteristic.Name, this.ContactSensor.Name)
|
|
82
|
+
.setCharacteristic(this.hap.Characteristic.StatusActive, true)
|
|
83
|
+
.getCharacteristic(this.hap.Characteristic.ContactSensorState)
|
|
84
|
+
.onGet(() => {
|
|
85
|
+
return this.ContactSensor.ContactSensorState;
|
|
86
|
+
});
|
|
120
87
|
}
|
|
121
|
-
//
|
|
122
|
-
if (device.lock?.
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
else if (!this.contactSensorService) {
|
|
128
|
-
this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Add Contact Sensor Service`);
|
|
129
|
-
const contactSensorService = `${accessory.displayName} Contact Sensor`;
|
|
130
|
-
(this.contactSensorService = this.accessory.getService(this.hap.Service.ContactSensor)
|
|
131
|
-
|| this.accessory.addService(this.hap.Service.ContactSensor)), contactSensorService;
|
|
132
|
-
this.contactSensorService.setCharacteristic(this.hap.Characteristic.Name, `${accessory.displayName} Contact Sensor`);
|
|
133
|
-
if (!this.contactSensorService.testCharacteristic(this.hap.Characteristic.ConfiguredName)) {
|
|
134
|
-
this.contactSensorService.addCharacteristic(this.hap.Characteristic.ConfiguredName, `${accessory.displayName} Contact Sensor`);
|
|
88
|
+
// Initialize Latch Button Service
|
|
89
|
+
if (device.lock?.activate_latchbutton === false) {
|
|
90
|
+
if (this.Switch) {
|
|
91
|
+
this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Removing Latch Button Service`);
|
|
92
|
+
this.Switch.Service = accessory.getService(this.hap.Service.Switch);
|
|
93
|
+
accessory.removeService(this.Switch.Service);
|
|
135
94
|
}
|
|
136
95
|
}
|
|
137
96
|
else {
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
this.
|
|
97
|
+
accessory.context.Switch = accessory.context.Switch ?? {};
|
|
98
|
+
this.Switch = {
|
|
99
|
+
Name: accessory.context.Switch.Name ?? `${accessory.displayName} Latch`,
|
|
100
|
+
Service: accessory.getService(this.hap.Service.Switch) ?? accessory.addService(this.hap.Service.Switch),
|
|
101
|
+
On: accessory.context.On ?? false,
|
|
102
|
+
};
|
|
103
|
+
accessory.context.Switch = this.Switch;
|
|
104
|
+
// Initialize Latch Button Characteristics
|
|
105
|
+
this.Switch.Service
|
|
106
|
+
.setCharacteristic(this.hap.Characteristic.Name, this.Switch.Name)
|
|
107
|
+
.getCharacteristic(this.hap.Characteristic.On)
|
|
108
|
+
.onGet(() => {
|
|
109
|
+
return this.Switch.On;
|
|
110
|
+
})
|
|
111
|
+
.onSet(this.OnSet.bind(this));
|
|
147
112
|
}
|
|
148
|
-
|
|
113
|
+
// Retrieve initial values and updateHomekit
|
|
114
|
+
this.refreshStatus();
|
|
149
115
|
// Update Homekit
|
|
150
116
|
this.updateHomeKitCharacteristics();
|
|
151
117
|
// Start an update interval
|
|
@@ -155,161 +121,107 @@ export class Lock {
|
|
|
155
121
|
await this.refreshStatus();
|
|
156
122
|
});
|
|
157
123
|
//regisiter webhook event handler
|
|
158
|
-
|
|
159
|
-
this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} is listening webhook.`);
|
|
160
|
-
this.platform.webhookEventHandler[this.device.deviceId] = async (context) => {
|
|
161
|
-
try {
|
|
162
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} received Webhook: ${JSON.stringify(context)}`);
|
|
163
|
-
const { lockState } = context;
|
|
164
|
-
const { LockCurrentState } = this;
|
|
165
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} ` +
|
|
166
|
-
'(lockState) = ' +
|
|
167
|
-
`Webhook:(${lockState}), ` +
|
|
168
|
-
`current:(${LockCurrentState})`);
|
|
169
|
-
this.LockCurrentState = lockState === 'LOCKED' ? 1 : 0;
|
|
170
|
-
this.updateHomeKitCharacteristics();
|
|
171
|
-
}
|
|
172
|
-
catch (e) {
|
|
173
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} `
|
|
174
|
-
+ `failed to handle webhook. Received: ${JSON.stringify(context)} Error: ${e}`);
|
|
175
|
-
}
|
|
176
|
-
};
|
|
177
|
-
}
|
|
124
|
+
this.registerWebhook(accessory, device);
|
|
178
125
|
// Watch for Lock change events
|
|
179
126
|
// We put in a debounce of 100ms so we don't make duplicate calls
|
|
180
127
|
this.doLockUpdate
|
|
181
128
|
.pipe(tap(() => {
|
|
182
129
|
this.lockUpdateInProgress = true;
|
|
183
|
-
}), debounceTime(this.
|
|
130
|
+
}), debounceTime(this.devicePushRate * 1000))
|
|
184
131
|
.subscribe(async () => {
|
|
185
132
|
try {
|
|
186
133
|
await this.pushChanges();
|
|
187
134
|
}
|
|
188
135
|
catch (e) {
|
|
189
136
|
this.apiError(e);
|
|
190
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed pushChanges with ${this.device.connectionType} Connection,`
|
|
191
|
-
` Error Message: ${JSON.stringify(e.message)}`);
|
|
137
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed pushChanges with ${this.device.connectionType} Connection,`
|
|
138
|
+
+ ` Error Message: ${JSON.stringify(e.message)}`);
|
|
192
139
|
}
|
|
193
140
|
this.lockUpdateInProgress = false;
|
|
194
141
|
});
|
|
195
142
|
}
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
*/
|
|
199
|
-
async handleLatchCharacteristic(value, callback) {
|
|
200
|
-
this.debugLog(`handleLatchCharacteristic called with value: ${value}`);
|
|
201
|
-
if (value) {
|
|
202
|
-
this.debugLog('Attempting to open the latch');
|
|
203
|
-
this.openAPIpushChanges(value).then(() => {
|
|
204
|
-
this.debugLog('Latch opened successfully');
|
|
205
|
-
this.debugLog(`LatchButtonService is: ${this.latchButtonService ? 'available' : 'not available'}`);
|
|
206
|
-
// simulate button press to turn the switch back off
|
|
207
|
-
if (this.latchButtonService) {
|
|
208
|
-
const latchButtonService = this.latchButtonService;
|
|
209
|
-
// Simulate a button press by waiting a short period before turning the switch off
|
|
210
|
-
setTimeout(() => {
|
|
211
|
-
latchButtonService.getCharacteristic(this.hap.Characteristic.On).updateValue(false);
|
|
212
|
-
this.debugLog('Latch button switched off automatically.');
|
|
213
|
-
}, 500); // 500 ms delay
|
|
214
|
-
}
|
|
215
|
-
callback(null);
|
|
216
|
-
}).catch((error) => {
|
|
217
|
-
// Log the error if the operation failed
|
|
218
|
-
this.debugLog(`Error opening latch: ${error}`);
|
|
219
|
-
// Ensure we turn the switch back off even in case of an error
|
|
220
|
-
if (this.latchButtonService) {
|
|
221
|
-
this.latchButtonService.getCharacteristic(this.hap.Characteristic.On).updateValue(false);
|
|
222
|
-
this.debugLog('Latch button switched off after an error.');
|
|
223
|
-
}
|
|
224
|
-
callback(error);
|
|
225
|
-
});
|
|
226
|
-
}
|
|
227
|
-
else {
|
|
228
|
-
this.debugLog('Switch is off, nothing to do');
|
|
229
|
-
callback(null);
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
/**
|
|
233
|
-
* Parse the device status from the SwitchBot api
|
|
234
|
-
*/
|
|
235
|
-
async parseStatus() {
|
|
236
|
-
if (!this.device.enableCloudService && this.OpenAPI) {
|
|
237
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} parseStatus enableCloudService: ${this.device.enableCloudService}`);
|
|
238
|
-
/* } else if (this.BLE) {
|
|
239
|
-
await this.BLEparseStatus();*/
|
|
240
|
-
}
|
|
241
|
-
else if (this.OpenAPI && this.platform.config.credentials?.token) {
|
|
242
|
-
await this.openAPIparseStatus();
|
|
243
|
-
}
|
|
244
|
-
else {
|
|
245
|
-
await this.offlineOff();
|
|
246
|
-
this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:` + ` ${this.device.connectionType}, parseStatus will not happen.`);
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
async BLEparseStatus() {
|
|
143
|
+
async BLEparseStatus(serviceData) {
|
|
144
|
+
// BLE Status
|
|
250
145
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLEparseStatus`);
|
|
251
|
-
switch (
|
|
146
|
+
switch (serviceData.status) {
|
|
252
147
|
case 'locked':
|
|
253
|
-
this.LockCurrentState = this.hap.Characteristic.LockCurrentState.SECURED;
|
|
254
|
-
this.LockTargetState = this.hap.Characteristic.LockTargetState.SECURED;
|
|
148
|
+
this.LockMechanism.LockCurrentState = this.hap.Characteristic.LockCurrentState.SECURED;
|
|
149
|
+
this.LockMechanism.LockTargetState = this.hap.Characteristic.LockTargetState.SECURED;
|
|
255
150
|
break;
|
|
256
151
|
default:
|
|
257
|
-
this.LockCurrentState = this.hap.Characteristic.LockCurrentState.UNSECURED;
|
|
258
|
-
this.LockTargetState = this.hap.Characteristic.LockTargetState.UNSECURED;
|
|
152
|
+
this.LockMechanism.LockCurrentState = this.hap.Characteristic.LockCurrentState.UNSECURED;
|
|
153
|
+
this.LockMechanism.LockTargetState = this.hap.Characteristic.LockTargetState.UNSECURED;
|
|
259
154
|
}
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
155
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}`
|
|
156
|
+
+ ` LockTargetState: ${this.LockMechanism.LockTargetState}, LockCurrentState: ${this.LockMechanism.LockCurrentState}`);
|
|
157
|
+
// Contact Sensor
|
|
158
|
+
if (!this.device.lock?.hide_contactsensor) {
|
|
159
|
+
switch (serviceData.door_open) {
|
|
160
|
+
case 'opened':
|
|
161
|
+
this.ContactSensor.ContactSensorState = this.hap.Characteristic.ContactSensorState.CONTACT_NOT_DETECTED;
|
|
162
|
+
break;
|
|
163
|
+
default:
|
|
164
|
+
this.ContactSensor.ContactSensorState = this.hap.Characteristic.ContactSensorState.CONTACT_DETECTED;
|
|
165
|
+
}
|
|
166
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} ContactSensorState: ${this.ContactSensor.ContactSensorState}`);
|
|
266
167
|
}
|
|
267
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.LockTargetState}`);
|
|
268
168
|
// Battery
|
|
269
|
-
this.BatteryLevel = Number(
|
|
270
|
-
if (this.BatteryLevel < 10) {
|
|
271
|
-
this.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW;
|
|
169
|
+
this.Battery.BatteryLevel = Number(serviceData.battery);
|
|
170
|
+
if (this.Battery.BatteryLevel < 10) {
|
|
171
|
+
this.Battery.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW;
|
|
272
172
|
}
|
|
273
173
|
else {
|
|
274
|
-
this.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
|
|
174
|
+
this.Battery.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
|
|
275
175
|
}
|
|
276
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}
|
|
176
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}`
|
|
177
|
+
+ ` BatteryLevel: ${this.Battery.BatteryLevel}, StatusLowBattery: ${this.Battery.StatusLowBattery}`);
|
|
277
178
|
}
|
|
278
|
-
async openAPIparseStatus() {
|
|
179
|
+
async openAPIparseStatus(deviceStatus) {
|
|
279
180
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIparseStatus`);
|
|
280
|
-
switch (
|
|
181
|
+
switch (deviceStatus.body.lockState) {
|
|
281
182
|
case 'locked':
|
|
282
|
-
this.LockCurrentState = this.hap.Characteristic.LockCurrentState.SECURED;
|
|
283
|
-
this.LockTargetState = this.hap.Characteristic.LockTargetState.SECURED;
|
|
183
|
+
this.LockMechanism.LockCurrentState = this.hap.Characteristic.LockCurrentState.SECURED;
|
|
184
|
+
this.LockMechanism.LockTargetState = this.hap.Characteristic.LockTargetState.SECURED;
|
|
284
185
|
break;
|
|
285
186
|
default:
|
|
286
|
-
this.LockCurrentState = this.hap.Characteristic.LockCurrentState.UNSECURED;
|
|
287
|
-
this.LockTargetState = this.hap.Characteristic.LockTargetState.UNSECURED;
|
|
187
|
+
this.LockMechanism.LockCurrentState = this.hap.Characteristic.LockCurrentState.UNSECURED;
|
|
188
|
+
this.LockMechanism.LockTargetState = this.hap.Characteristic.LockTargetState.UNSECURED;
|
|
288
189
|
}
|
|
289
|
-
switch (
|
|
190
|
+
switch (deviceStatus.body.doorState) {
|
|
290
191
|
case 'opened':
|
|
291
|
-
this.ContactSensorState = this.hap.Characteristic.ContactSensorState.CONTACT_NOT_DETECTED;
|
|
192
|
+
this.ContactSensor.ContactSensorState = this.hap.Characteristic.ContactSensorState.CONTACT_NOT_DETECTED;
|
|
292
193
|
break;
|
|
293
194
|
default:
|
|
294
|
-
this.ContactSensorState = this.hap.Characteristic.ContactSensorState.CONTACT_DETECTED;
|
|
195
|
+
this.ContactSensor.ContactSensorState = this.hap.Characteristic.ContactSensorState.CONTACT_DETECTED;
|
|
295
196
|
}
|
|
296
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.LockTargetState}`);
|
|
197
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.LockMechanism.LockTargetState}`);
|
|
297
198
|
// Battery
|
|
298
|
-
this.BatteryLevel = Number(
|
|
299
|
-
if (this.BatteryLevel < 10) {
|
|
300
|
-
this.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW;
|
|
199
|
+
this.Battery.BatteryLevel = Number(deviceStatus.body.battery);
|
|
200
|
+
if (this.Battery.BatteryLevel < 10) {
|
|
201
|
+
this.Battery.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW;
|
|
301
202
|
}
|
|
302
203
|
else {
|
|
303
|
-
this.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
|
|
304
|
-
}
|
|
305
|
-
if (Number.isNaN(this.BatteryLevel)) {
|
|
306
|
-
this.BatteryLevel = 100;
|
|
204
|
+
this.Battery.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
|
|
205
|
+
}
|
|
206
|
+
if (Number.isNaN(this.Battery.BatteryLevel)) {
|
|
207
|
+
this.Battery.BatteryLevel = 100;
|
|
208
|
+
}
|
|
209
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.Battery.BatteryLevel},`
|
|
210
|
+
+ ` StatusLowBattery: ${this.Battery.StatusLowBattery}`);
|
|
211
|
+
// Firmware Version
|
|
212
|
+
const version = deviceStatus.body.version?.toString();
|
|
213
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Firmware Version: ${version?.replace(/^V|-.*$/g, '')}`);
|
|
214
|
+
if (deviceStatus.body.version) {
|
|
215
|
+
const deviceVersion = version?.replace(/^V|-.*$/g, '') ?? '0.0.0';
|
|
216
|
+
this.accessory
|
|
217
|
+
.getService(this.hap.Service.AccessoryInformation)
|
|
218
|
+
.setCharacteristic(this.hap.Characteristic.HardwareRevision, deviceVersion)
|
|
219
|
+
.setCharacteristic(this.hap.Characteristic.FirmwareRevision, deviceVersion)
|
|
220
|
+
.getCharacteristic(this.hap.Characteristic.FirmwareRevision)
|
|
221
|
+
.updateValue(deviceVersion);
|
|
222
|
+
this.accessory.context.deviceVersion = deviceVersion;
|
|
223
|
+
this.debugSuccessLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceVersion: ${this.accessory.context.deviceVersion}`);
|
|
307
224
|
}
|
|
308
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.BatteryLevel},`
|
|
309
|
-
+ ` StatusLowBattery: ${this.StatusLowBattery}`);
|
|
310
|
-
// FirmwareRevision
|
|
311
|
-
this.FirmwareRevision = this.OpenAPI_FirmwareRevision;
|
|
312
|
-
this.accessory.context.FirmwareRevision = this.FirmwareRevision;
|
|
313
225
|
}
|
|
314
226
|
/**
|
|
315
227
|
* Asks the SwitchBot API for the latest device information
|
|
@@ -326,131 +238,74 @@ export class Lock {
|
|
|
326
238
|
}
|
|
327
239
|
else {
|
|
328
240
|
await this.offlineOff();
|
|
329
|
-
this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:`
|
|
330
|
-
` ${this.device.connectionType}, refreshStatus will not happen.`);
|
|
241
|
+
this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:`
|
|
242
|
+
+ ` ${this.device.connectionType}, refreshStatus will not happen.`);
|
|
331
243
|
}
|
|
332
244
|
}
|
|
333
245
|
async BLERefreshStatus() {
|
|
334
246
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLERefreshStatus`);
|
|
335
|
-
const switchbot = await this.
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
.toLowerCase();
|
|
341
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
|
|
342
|
-
this.getCustomBLEAddress(switchbot);
|
|
343
|
-
// Start to monitor advertisement packets
|
|
344
|
-
(async () => {
|
|
247
|
+
const switchbot = await this.switchbotBLE();
|
|
248
|
+
if (switchbot === undefined) {
|
|
249
|
+
await this.BLERefreshConnection(switchbot);
|
|
250
|
+
}
|
|
251
|
+
else {
|
|
345
252
|
// Start to monitor advertisement packets
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} address: ${ad.address}, model: ${ad.serviceData.model}`);
|
|
354
|
-
if (this.device.bleMac === ad.address && ad.serviceData.model === 'o') {
|
|
355
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${JSON.stringify(ad.serviceData)}`);
|
|
356
|
-
this.BLE_BatteryLevel = ad.serviceData.battery;
|
|
357
|
-
this.BLE_Calibration = ad.serviceData.calibration;
|
|
358
|
-
this.BLE_LockCurrentState = ad.serviceData.status;
|
|
359
|
-
this.BLE_ContactSensorState = ad.serviceData.door_open;
|
|
253
|
+
(async () => {
|
|
254
|
+
// Start to monitor advertisement packets
|
|
255
|
+
const serviceData = await this.monitorAdvertisementPackets(switchbot);
|
|
256
|
+
// Update HomeKit
|
|
257
|
+
if (serviceData.model !== '' && serviceData.modelName !== '') {
|
|
258
|
+
await this.BLEparseStatus(serviceData);
|
|
259
|
+
await this.updateHomeKitCharacteristics();
|
|
360
260
|
}
|
|
361
261
|
else {
|
|
362
|
-
this.
|
|
363
|
-
|
|
364
|
-
};
|
|
365
|
-
// Wait 1 seconds
|
|
366
|
-
await switchbot.wait(this.scanDuration * 1000);
|
|
367
|
-
// Stop to monitor
|
|
368
|
-
await switchbot.stopScan();
|
|
369
|
-
// Update HomeKit
|
|
370
|
-
await this.BLEparseStatus();
|
|
371
|
-
await this.updateHomeKitCharacteristics();
|
|
372
|
-
})();
|
|
373
|
-
/*if (switchbot !== false) {
|
|
374
|
-
switchbot
|
|
375
|
-
.startScan({
|
|
376
|
-
model: 'o',
|
|
377
|
-
id: this.device.bleMac,
|
|
378
|
-
})
|
|
379
|
-
.then(async () => {
|
|
380
|
-
// Set an event handler
|
|
381
|
-
switchbot.onadvertisement = async (ad: ad) => {
|
|
382
|
-
this.debugLog(
|
|
383
|
-
`${this.device.deviceType}: ${this.accessory.displayName} Config BLE Address: ${this.device.bleMac},` +
|
|
384
|
-
` BLE Address Found: ${ad.address}`,
|
|
385
|
-
);
|
|
386
|
-
this.BLE_BatteryLevel = ad.serviceData.battery;
|
|
387
|
-
this.BLE_Calibration = ad.serviceData.calibration;
|
|
388
|
-
this.BLE_LockCurrentState = ad.serviceData.status;
|
|
389
|
-
this.BLE_ContactSensorState = ad.serviceData.door_open;
|
|
390
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${JSON.stringify(ad.serviceData)}`);
|
|
391
|
-
this.debugLog(
|
|
392
|
-
`${this.device.deviceType}: ${this.accessory.displayName} battery: ${ad.serviceData.battery}, ` +
|
|
393
|
-
`calibration: ${ad.serviceData.calibration}, status: ${ad.serviceData.status}, battery: ${ad.serviceData.battery}, ` +
|
|
394
|
-
`door_open: ${ad.serviceData.door_open}`,
|
|
395
|
-
);
|
|
396
|
-
|
|
397
|
-
if (ad.serviceData) {
|
|
398
|
-
this.BLE_IsConnected = true;
|
|
399
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} connected: ${this.BLE_IsConnected}`);
|
|
400
|
-
await this.stopScanning(switchbot);
|
|
401
|
-
} else {
|
|
402
|
-
this.BLE_IsConnected = false;
|
|
403
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} connected: ${this.BLE_IsConnected}`);
|
|
262
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed to get serviceData, serviceData: ${serviceData}`);
|
|
263
|
+
await this.BLERefreshConnection(switchbot);
|
|
404
264
|
}
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
return await sleep(this.scanDuration * 1000);
|
|
408
|
-
})
|
|
409
|
-
.then(async () => {
|
|
410
|
-
// Stop to monitor
|
|
411
|
-
await this.stopScanning(switchbot);
|
|
412
|
-
})
|
|
413
|
-
.catch(async (e: any) => {
|
|
414
|
-
this.apiError(e);
|
|
415
|
-
this.errorLog(
|
|
416
|
-
`${this.device.deviceType}: ${this.accessory.displayName} failed BLERefreshStatus with ${this.device.connectionType}` +
|
|
417
|
-
` Connection, Error Message: ${JSON.stringify(e.message)}`,
|
|
418
|
-
);
|
|
419
|
-
await this.BLERefreshConnection(switchbot);
|
|
420
|
-
});
|
|
421
|
-
} else {
|
|
422
|
-
await this.BLERefreshConnection(switchbot);
|
|
423
|
-
}*/
|
|
265
|
+
})();
|
|
266
|
+
}
|
|
424
267
|
}
|
|
425
268
|
async openAPIRefreshStatus() {
|
|
426
269
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus`);
|
|
427
270
|
try {
|
|
428
|
-
const { body, statusCode } = await
|
|
429
|
-
headers: this.platform.generateHeaders(),
|
|
430
|
-
});
|
|
431
|
-
this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} statusCode: ${statusCode}`);
|
|
271
|
+
const { body, statusCode } = await this.deviceRefreshStatus();
|
|
432
272
|
const deviceStatus = await body.json();
|
|
433
|
-
this.
|
|
434
|
-
|
|
273
|
+
await this.refreshStatusCodes(statusCode, deviceStatus);
|
|
274
|
+
;
|
|
435
275
|
if ((statusCode === 200 || statusCode === 100) && (deviceStatus.statusCode === 200 || deviceStatus.statusCode === 100)) {
|
|
436
|
-
this.
|
|
437
|
-
|
|
438
|
-
this.
|
|
439
|
-
this.OpenAPI_ContactSensorState = deviceStatus.body.doorState;
|
|
440
|
-
this.OpenAPI_BatteryLevel = deviceStatus.body.battery;
|
|
441
|
-
this.OpenAPI_FirmwareRevision = deviceStatus.body.version;
|
|
442
|
-
this.openAPIparseStatus();
|
|
443
|
-
this.updateHomeKitCharacteristics();
|
|
276
|
+
await this.successfulRefreshStatus(statusCode, deviceStatus);
|
|
277
|
+
await this.openAPIparseStatus(deviceStatus);
|
|
278
|
+
await this.updateHomeKitCharacteristics();
|
|
444
279
|
}
|
|
445
280
|
else {
|
|
446
|
-
this.
|
|
447
|
-
this.statusCode(deviceStatus.statusCode);
|
|
281
|
+
await this.statusCodes(statusCode, deviceStatus);
|
|
448
282
|
}
|
|
449
283
|
}
|
|
450
284
|
catch (e) {
|
|
451
285
|
this.apiError(e);
|
|
452
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed openAPIRefreshStatus with ${this.device.connectionType}`
|
|
453
|
-
` Connection, Error Message: ${JSON.stringify(e.message)}`);
|
|
286
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed openAPIRefreshStatus with ${this.device.connectionType}`
|
|
287
|
+
+ ` Connection, Error Message: ${JSON.stringify(e.message)}`);
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
async registerWebhook(accessory, device) {
|
|
291
|
+
if (device.webhook) {
|
|
292
|
+
this.debugLog(`${device.deviceType}: ${accessory.displayName} is listening webhook.`);
|
|
293
|
+
this.platform.webhookEventHandler[device.deviceId] = async (context) => {
|
|
294
|
+
try {
|
|
295
|
+
this.debugLog(`${device.deviceType}: ${accessory.displayName} received Webhook: ${JSON.stringify(context)}`);
|
|
296
|
+
const { lockState } = context;
|
|
297
|
+
const { LockCurrentState } = this.LockMechanism;
|
|
298
|
+
this.debugLog(`${device.deviceType}: ${accessory.displayName} (lockState) = Webhook:(${lockState}), current:(${LockCurrentState})`);
|
|
299
|
+
this.LockMechanism.LockCurrentState = lockState === 'LOCKED' ? 1 : 0;
|
|
300
|
+
this.updateHomeKitCharacteristics();
|
|
301
|
+
}
|
|
302
|
+
catch (e) {
|
|
303
|
+
this.errorLog(`${device.deviceType}: ${accessory.displayName} failed to handle webhook. Received: ${JSON.stringify(context)} Error: ${e}`);
|
|
304
|
+
}
|
|
305
|
+
};
|
|
306
|
+
}
|
|
307
|
+
else {
|
|
308
|
+
this.debugLog(`${device.deviceType}: ${accessory.displayName} is not listening webhook.`);
|
|
454
309
|
}
|
|
455
310
|
}
|
|
456
311
|
/**
|
|
@@ -462,15 +317,17 @@ export class Lock {
|
|
|
462
317
|
async pushChanges() {
|
|
463
318
|
if (!this.device.enableCloudService && this.OpenAPI) {
|
|
464
319
|
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} pushChanges enableCloudService: ${this.device.enableCloudService}`);
|
|
465
|
-
|
|
466
|
-
|
|
320
|
+
}
|
|
321
|
+
else if (this.BLE) {
|
|
322
|
+
await this.BLEpushChanges();
|
|
467
323
|
}
|
|
468
324
|
else if (this.OpenAPI && this.platform.config.credentials?.token) {
|
|
469
325
|
await this.openAPIpushChanges();
|
|
470
326
|
}
|
|
471
327
|
else {
|
|
472
328
|
await this.offlineOff();
|
|
473
|
-
this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:`
|
|
329
|
+
this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:`
|
|
330
|
+
+ ` ${this.device.connectionType}, pushChanges will not happen.`);
|
|
474
331
|
}
|
|
475
332
|
// Refresh the status from the API
|
|
476
333
|
interval(15000)
|
|
@@ -482,16 +339,12 @@ export class Lock {
|
|
|
482
339
|
}
|
|
483
340
|
async BLEpushChanges() {
|
|
484
341
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLEpushChanges`);
|
|
485
|
-
if (this.LockTargetState !== this.accessory.context.LockTargetState) {
|
|
486
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLEpushChanges LockTargetState: ${this.LockTargetState}`
|
|
487
|
-
` LockTargetStateCached: ${this.accessory.context.LockTargetState}`);
|
|
342
|
+
if (this.LockMechanism.LockTargetState !== this.accessory.context.LockTargetState) {
|
|
343
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLEpushChanges LockTargetState: ${this.LockMechanism.LockTargetState}`
|
|
344
|
+
+ ` LockTargetStateCached: ${this.accessory.context.LockTargetState}`);
|
|
488
345
|
const switchbot = await this.platform.connectBLE();
|
|
489
346
|
// Convert to BLE Address
|
|
490
|
-
|
|
491
|
-
.deviceId.match(/.{1,2}/g)
|
|
492
|
-
.join(':')
|
|
493
|
-
.toLowerCase();
|
|
494
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
|
|
347
|
+
await this.convertBLEAddress();
|
|
495
348
|
switchbot
|
|
496
349
|
.discover({
|
|
497
350
|
model: '',
|
|
@@ -499,31 +352,33 @@ export class Lock {
|
|
|
499
352
|
})
|
|
500
353
|
.then(() => {
|
|
501
354
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Done.`);
|
|
502
|
-
this.
|
|
355
|
+
this.successLog(`${this.device.deviceType}: ${this.accessory.displayName} `
|
|
356
|
+
+ `LockTargetState: ${this.LockMechanism.LockTargetState} sent over BLE, sent successfully`);
|
|
357
|
+
this.LockMechanism.LockTargetState = this.hap.Characteristic.LockTargetState.SECURED;
|
|
503
358
|
})
|
|
504
359
|
.catch(async (e) => {
|
|
505
360
|
this.apiError(e);
|
|
506
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed BLEpushChanges with ${this.device.connectionType}`
|
|
507
|
-
` Connection, Error Message: ${JSON.stringify(e.message)}`);
|
|
361
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed BLEpushChanges with ${this.device.connectionType}`
|
|
362
|
+
+ ` Connection, Error Message: ${JSON.stringify(e.message)}`);
|
|
508
363
|
await this.BLEPushConnection();
|
|
509
364
|
});
|
|
510
365
|
}
|
|
511
366
|
else {
|
|
512
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} No BLEpushChanges.`
|
|
513
|
-
`LockTargetState: ${this.LockTargetState}, `
|
|
514
|
-
`LockTargetStateCached: ${this.accessory.context.LockTargetState}`);
|
|
367
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} No BLEpushChanges.`
|
|
368
|
+
+ `LockTargetState: ${this.LockMechanism.LockTargetState}, `
|
|
369
|
+
+ `LockTargetStateCached: ${this.accessory.context.LockTargetState}`);
|
|
515
370
|
}
|
|
516
371
|
}
|
|
517
372
|
async openAPIpushChanges(LatchUnlock) {
|
|
518
373
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIpushChanges`);
|
|
519
|
-
if ((this.LockTargetState !== this.accessory.context.LockTargetState) || LatchUnlock) {
|
|
374
|
+
if ((this.LockMechanism.LockTargetState !== this.accessory.context.LockTargetState) || LatchUnlock) {
|
|
520
375
|
// Determine the command based on the LockTargetState or the forceUnlock parameter
|
|
521
376
|
let command = '';
|
|
522
377
|
if (LatchUnlock) {
|
|
523
378
|
command = 'unlock';
|
|
524
379
|
}
|
|
525
380
|
else {
|
|
526
|
-
command = this.LockTargetState ? 'lock' : 'unlock';
|
|
381
|
+
command = this.LockMechanism.LockTargetState ? 'lock' : 'unlock';
|
|
527
382
|
}
|
|
528
383
|
const bodyChange = JSON.stringify({
|
|
529
384
|
command: `${command}`,
|
|
@@ -532,119 +387,125 @@ export class Lock {
|
|
|
532
387
|
});
|
|
533
388
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Sending request to SwitchBot API, body: ${bodyChange},`);
|
|
534
389
|
try {
|
|
535
|
-
const { body, statusCode } = await
|
|
536
|
-
body: bodyChange,
|
|
537
|
-
method: 'POST',
|
|
538
|
-
headers: this.platform.generateHeaders(),
|
|
539
|
-
});
|
|
540
|
-
this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} statusCode: ${statusCode}`);
|
|
390
|
+
const { body, statusCode } = await this.pushChangeRequest(bodyChange);
|
|
541
391
|
const deviceStatus = await body.json();
|
|
542
|
-
this.
|
|
543
|
-
this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus body: ${JSON.stringify(deviceStatus.body)}`);
|
|
544
|
-
this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus statusCode: ${deviceStatus.statusCode}`);
|
|
392
|
+
await this.pushStatusCodes(statusCode, deviceStatus);
|
|
545
393
|
if ((statusCode === 200 || statusCode === 100) && (deviceStatus.statusCode === 200 || deviceStatus.statusCode === 100)) {
|
|
546
|
-
this.
|
|
547
|
-
|
|
394
|
+
await this.successfulPushChange(statusCode, deviceStatus, bodyChange);
|
|
395
|
+
await this.updateHomeKitCharacteristics();
|
|
548
396
|
}
|
|
549
397
|
else {
|
|
550
|
-
this.statusCode(statusCode);
|
|
551
|
-
this.statusCode(deviceStatus.statusCode);
|
|
398
|
+
await this.statusCode(statusCode);
|
|
399
|
+
await this.statusCode(deviceStatus.statusCode);
|
|
552
400
|
}
|
|
553
401
|
}
|
|
554
402
|
catch (e) {
|
|
555
403
|
this.apiError(e);
|
|
556
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed openAPIpushChanges with ${this.device.connectionType}`
|
|
557
|
-
` Connection, Error Message: ${JSON.stringify(e.message)}`);
|
|
404
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed openAPIpushChanges with ${this.device.connectionType}`
|
|
405
|
+
+ ` Connection, Error Message: ${JSON.stringify(e.message)}`);
|
|
558
406
|
}
|
|
559
407
|
}
|
|
560
408
|
else {
|
|
561
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} No openAPIpushChanges
|
|
562
|
-
|
|
563
|
-
`LockTargetStateCached: ${this.accessory.context.LockTargetState}`);
|
|
409
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} No openAPIpushChanges, LockTargetState: `
|
|
410
|
+
+ `${this.LockMechanism.LockTargetState}, LockTargetStateCached: ${this.accessory.context.LockTargetState}`);
|
|
564
411
|
}
|
|
565
412
|
}
|
|
566
413
|
/**
|
|
567
414
|
* Handle requests to set the value of the "On" characteristic
|
|
568
415
|
*/
|
|
569
416
|
async LockTargetStateSet(value) {
|
|
570
|
-
if (this.LockTargetState === this.accessory.context.LockTargetState) {
|
|
417
|
+
if (this.LockMechanism.LockTargetState === this.accessory.context.LockTargetState) {
|
|
571
418
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} No Changes, Set LockTargetState: ${value}`);
|
|
572
419
|
}
|
|
573
420
|
else {
|
|
574
421
|
this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Set LockTargetState: ${value}`);
|
|
575
422
|
}
|
|
576
|
-
this.LockTargetState = value;
|
|
423
|
+
this.LockMechanism.LockTargetState = value;
|
|
424
|
+
this.doLockUpdate.next();
|
|
425
|
+
}
|
|
426
|
+
/**
|
|
427
|
+
* Handle requests to set the value of the "On" characteristic
|
|
428
|
+
*/
|
|
429
|
+
async OnSet(value) {
|
|
430
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Latch Button Set On: ${value}`);
|
|
431
|
+
if (value) {
|
|
432
|
+
this.debugLog('Attempting to open the latch');
|
|
433
|
+
this.openAPIpushChanges(value).then(() => {
|
|
434
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Latch opened successfully`);
|
|
435
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}`
|
|
436
|
+
+ ` SwitchService is: ${this.Switch.Service ? 'available' : 'not available'}`);
|
|
437
|
+
// simulate button press to turn the switch back off
|
|
438
|
+
if (this.Switch.Service) {
|
|
439
|
+
const SwitchService = this.Switch.Service;
|
|
440
|
+
// Simulate a button press by waiting a short period before turning the switch off
|
|
441
|
+
setTimeout(() => {
|
|
442
|
+
SwitchService.getCharacteristic(this.hap.Characteristic.On).updateValue(false);
|
|
443
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Latch button switched off automatically.`);
|
|
444
|
+
}, 500); // 500 ms delay
|
|
445
|
+
}
|
|
446
|
+
}).catch((e) => {
|
|
447
|
+
// Log the error if the operation failed
|
|
448
|
+
this.debugLog(`Error opening latch: ${e}`);
|
|
449
|
+
// Ensure we turn the switch back off even in case of an error
|
|
450
|
+
if (this.Switch.Service) {
|
|
451
|
+
this.Switch.Service.getCharacteristic(this.hap.Characteristic.On).updateValue(false);
|
|
452
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Latch button switched off after an error.`);
|
|
453
|
+
}
|
|
454
|
+
});
|
|
455
|
+
}
|
|
456
|
+
else {
|
|
457
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Switch is off, nothing to do`);
|
|
458
|
+
}
|
|
459
|
+
this.Switch.On = value;
|
|
577
460
|
this.doLockUpdate.next();
|
|
578
461
|
}
|
|
579
462
|
async updateHomeKitCharacteristics() {
|
|
580
463
|
if (!this.device.lock?.hide_contactsensor) {
|
|
581
|
-
if (this.ContactSensorState === undefined) {
|
|
582
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} ContactSensorState: ${this.ContactSensorState}`);
|
|
464
|
+
if (this.ContactSensor.ContactSensorState === undefined) {
|
|
465
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} ContactSensorState: ${this.ContactSensor.ContactSensorState}`);
|
|
583
466
|
}
|
|
584
467
|
else {
|
|
585
|
-
this.accessory.context.ContactSensorState = this.ContactSensorState;
|
|
586
|
-
this.
|
|
587
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic
|
|
468
|
+
this.accessory.context.ContactSensorState = this.ContactSensor.ContactSensorState;
|
|
469
|
+
this.ContactSensor.Service.updateCharacteristic(this.hap.Characteristic.ContactSensorState, this.ContactSensor.ContactSensorState);
|
|
470
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic`
|
|
471
|
+
+ ` ContactSensorState: ${this.ContactSensor.ContactSensorState}`);
|
|
588
472
|
}
|
|
589
473
|
}
|
|
590
|
-
if (this.LockTargetState === undefined) {
|
|
591
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LockTargetState: ${this.LockTargetState}`);
|
|
592
|
-
}
|
|
593
|
-
else {
|
|
594
|
-
this.accessory.context.LockTargetState = this.LockTargetState;
|
|
595
|
-
this.lockService.updateCharacteristic(this.hap.Characteristic.LockTargetState, this.LockTargetState);
|
|
596
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic LockTargetState: ${this.LockTargetState}`);
|
|
597
|
-
}
|
|
598
|
-
if (this.LockCurrentState === undefined) {
|
|
599
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LockCurrentState: ${this.LockCurrentState}`);
|
|
474
|
+
if (this.LockMechanism.LockTargetState === undefined) {
|
|
475
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LockTargetState: ${this.LockMechanism.LockTargetState}`);
|
|
600
476
|
}
|
|
601
477
|
else {
|
|
602
|
-
this.accessory.context.
|
|
603
|
-
this.
|
|
604
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic
|
|
478
|
+
this.accessory.context.LockTargetState = this.LockMechanism.LockTargetState;
|
|
479
|
+
this.LockMechanism.Service.updateCharacteristic(this.hap.Characteristic.LockTargetState, this.LockMechanism.LockTargetState);
|
|
480
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic`
|
|
481
|
+
+ ` LockTargetState: ${this.LockMechanism.LockTargetState}`);
|
|
605
482
|
}
|
|
606
|
-
if (this.
|
|
607
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}
|
|
483
|
+
if (this.LockMechanism.LockCurrentState === undefined) {
|
|
484
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LockCurrentState: ${this.LockMechanism.LockCurrentState}`);
|
|
608
485
|
}
|
|
609
486
|
else {
|
|
610
|
-
this.accessory.context.
|
|
611
|
-
this.
|
|
612
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic
|
|
487
|
+
this.accessory.context.LockCurrentState = this.LockMechanism.LockCurrentState;
|
|
488
|
+
this.LockMechanism.Service.updateCharacteristic(this.hap.Characteristic.LockCurrentState, this.LockMechanism.LockCurrentState);
|
|
489
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic`
|
|
490
|
+
+ ` LockCurrentState: ${this.LockMechanism.LockCurrentState}`);
|
|
613
491
|
}
|
|
614
|
-
if (this.
|
|
615
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}
|
|
492
|
+
if (this.Battery.BatteryLevel === undefined) {
|
|
493
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.Battery.BatteryLevel}`);
|
|
616
494
|
}
|
|
617
495
|
else {
|
|
618
|
-
this.accessory.context.
|
|
619
|
-
this.
|
|
620
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic
|
|
496
|
+
this.accessory.context.BatteryLevel = this.Battery.BatteryLevel;
|
|
497
|
+
this.Battery.Service.updateCharacteristic(this.hap.Characteristic.BatteryLevel, this.Battery.BatteryLevel);
|
|
498
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic`
|
|
499
|
+
+ ` BatteryLevel: ${this.Battery.BatteryLevel}`);
|
|
621
500
|
}
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
switchbot.stopScan();
|
|
625
|
-
if (this.BLE_IsConnected) {
|
|
626
|
-
await this.BLEparseStatus();
|
|
627
|
-
await this.updateHomeKitCharacteristics();
|
|
501
|
+
if (this.Battery.StatusLowBattery === undefined) {
|
|
502
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} StatusLowBattery: ${this.Battery.StatusLowBattery}`);
|
|
628
503
|
}
|
|
629
504
|
else {
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
if (this.device.customBLEaddress && this.deviceLogging.includes('debug')) {
|
|
635
|
-
(async () => {
|
|
636
|
-
// Start to monitor advertisement packets
|
|
637
|
-
await switchbot.startScan({
|
|
638
|
-
model: 'c',
|
|
639
|
-
});
|
|
640
|
-
// Set an event handler
|
|
641
|
-
switchbot.onadvertisement = (ad) => {
|
|
642
|
-
this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} ad: ${JSON.stringify(ad, null, ' ')}`);
|
|
643
|
-
};
|
|
644
|
-
await sleep(10000);
|
|
645
|
-
// Stop to monitor
|
|
646
|
-
switchbot.stopScan();
|
|
647
|
-
})();
|
|
505
|
+
this.accessory.context.StatusLowBattery = this.Battery.StatusLowBattery;
|
|
506
|
+
this.Battery.Service.updateCharacteristic(this.hap.Characteristic.StatusLowBattery, this.Battery.StatusLowBattery);
|
|
507
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic`
|
|
508
|
+
+ ` StatusLowBattery: ${this.Battery.StatusLowBattery}`);
|
|
648
509
|
}
|
|
649
510
|
}
|
|
650
511
|
async BLEPushConnection() {
|
|
@@ -661,215 +522,21 @@ export class Lock {
|
|
|
661
522
|
await this.openAPIRefreshStatus();
|
|
662
523
|
}
|
|
663
524
|
}
|
|
664
|
-
async scan(device) {
|
|
665
|
-
if (device.scanDuration) {
|
|
666
|
-
this.scanDuration = this.accessory.context.scanDuration = device.scanDuration;
|
|
667
|
-
if (this.BLE) {
|
|
668
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Config scanDuration: ${this.scanDuration}`);
|
|
669
|
-
}
|
|
670
|
-
}
|
|
671
|
-
else {
|
|
672
|
-
this.scanDuration = this.accessory.context.scanDuration = 1;
|
|
673
|
-
if (this.BLE) {
|
|
674
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Default scanDuration: ${this.scanDuration}`);
|
|
675
|
-
}
|
|
676
|
-
}
|
|
677
|
-
}
|
|
678
|
-
async statusCode(statusCode) {
|
|
679
|
-
switch (statusCode) {
|
|
680
|
-
case 151:
|
|
681
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command not supported by this deviceType, statusCode: ${statusCode}`);
|
|
682
|
-
break;
|
|
683
|
-
case 152:
|
|
684
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device not found, statusCode: ${statusCode}`);
|
|
685
|
-
break;
|
|
686
|
-
case 160:
|
|
687
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command is not supported, statusCode: ${statusCode}`);
|
|
688
|
-
break;
|
|
689
|
-
case 161:
|
|
690
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device is offline, statusCode: ${statusCode}`);
|
|
691
|
-
this.offlineOff();
|
|
692
|
-
break;
|
|
693
|
-
case 171:
|
|
694
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Hub Device is offline, statusCode: ${statusCode}. ` +
|
|
695
|
-
`Hub: ${this.device.hubDeviceId}`);
|
|
696
|
-
this.offlineOff();
|
|
697
|
-
break;
|
|
698
|
-
case 190:
|
|
699
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device internal error due to device states not synchronized with server,` +
|
|
700
|
-
` Or command format is invalid, statusCode: ${statusCode}`);
|
|
701
|
-
break;
|
|
702
|
-
case 100:
|
|
703
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Command successfully sent, statusCode: ${statusCode}`);
|
|
704
|
-
break;
|
|
705
|
-
case 200:
|
|
706
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Request successful, statusCode: ${statusCode}`);
|
|
707
|
-
break;
|
|
708
|
-
case 400:
|
|
709
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Bad Request, The client has issued an invalid request. `
|
|
710
|
-
+ `This is commonly used to specify validation errors in a request payload, statusCode: ${statusCode}`);
|
|
711
|
-
break;
|
|
712
|
-
case 401:
|
|
713
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Unauthorized, Authorization for the API is required, `
|
|
714
|
-
+ `but the request has not been authenticated, statusCode: ${statusCode}`);
|
|
715
|
-
break;
|
|
716
|
-
case 403:
|
|
717
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Forbidden, The request has been authenticated but does not `
|
|
718
|
-
+ `have appropriate permissions, or a requested resource is not found, statusCode: ${statusCode}`);
|
|
719
|
-
break;
|
|
720
|
-
case 404:
|
|
721
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Not Found, Specifies the requested path does not exist, `
|
|
722
|
-
+ `statusCode: ${statusCode}`);
|
|
723
|
-
break;
|
|
724
|
-
case 406:
|
|
725
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Not Acceptable, The client has requested a MIME type via `
|
|
726
|
-
+ `the Accept header for a value not supported by the server, statusCode: ${statusCode}`);
|
|
727
|
-
break;
|
|
728
|
-
case 415:
|
|
729
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Unsupported Media Type, The client has defined a contentType `
|
|
730
|
-
+ `header that is not supported by the server, statusCode: ${statusCode}`);
|
|
731
|
-
break;
|
|
732
|
-
case 422:
|
|
733
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Unprocessable Entity, The client has made a valid request, `
|
|
734
|
-
+ `but the server cannot process it. This is often used for APIs for which certain limits have been exceeded, statusCode: ${statusCode}`);
|
|
735
|
-
break;
|
|
736
|
-
case 429:
|
|
737
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Too Many Requests, The client has exceeded the number of `
|
|
738
|
-
+ `requests allowed for a given time window, statusCode: ${statusCode}`);
|
|
739
|
-
break;
|
|
740
|
-
case 500:
|
|
741
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Internal Server Error, An unexpected error on the SmartThings `
|
|
742
|
-
+ `servers has occurred. These errors should be rare, statusCode: ${statusCode}`);
|
|
743
|
-
break;
|
|
744
|
-
default:
|
|
745
|
-
this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Unknown statusCode: ` +
|
|
746
|
-
`${statusCode}, Submit Bugs Here: ' + 'https://tinyurl.com/SwitchBotBug`);
|
|
747
|
-
}
|
|
748
|
-
}
|
|
749
525
|
async offlineOff() {
|
|
750
526
|
if (this.device.offline) {
|
|
751
|
-
|
|
752
|
-
|
|
527
|
+
if (!this.device.lock?.hide_contactsensor) {
|
|
528
|
+
this.ContactSensor.Service.updateCharacteristic(this.hap.Characteristic.ContactSensorState, this.hap.Characteristic.ContactSensorState.CONTACT_DETECTED);
|
|
529
|
+
}
|
|
530
|
+
this.LockMechanism.Service.updateCharacteristic(this.hap.Characteristic.LockTargetState, this.hap.Characteristic.LockTargetState.SECURED);
|
|
531
|
+
this.LockMechanism.Service.updateCharacteristic(this.hap.Characteristic.LockCurrentState, this.hap.Characteristic.LockCurrentState.SECURED);
|
|
753
532
|
}
|
|
754
533
|
}
|
|
755
534
|
async apiError(e) {
|
|
756
535
|
if (!this.device.lock?.hide_contactsensor) {
|
|
757
|
-
this.
|
|
758
|
-
}
|
|
759
|
-
this.lockService.updateCharacteristic(this.hap.Characteristic.LockTargetState, e);
|
|
760
|
-
this.lockService.updateCharacteristic(this.hap.Characteristic.LockCurrentState, e);
|
|
761
|
-
}
|
|
762
|
-
async deviceContext() {
|
|
763
|
-
if (this.LockTargetState === undefined) {
|
|
764
|
-
this.LockTargetState = false;
|
|
765
|
-
}
|
|
766
|
-
else {
|
|
767
|
-
this.LockTargetState = this.accessory.context.On;
|
|
768
|
-
}
|
|
769
|
-
if (this.FirmwareRevision === undefined) {
|
|
770
|
-
this.FirmwareRevision = this.platform.version;
|
|
771
|
-
this.accessory.context.FirmwareRevision = this.FirmwareRevision;
|
|
772
|
-
}
|
|
773
|
-
}
|
|
774
|
-
async refreshRate(device) {
|
|
775
|
-
if (device.refreshRate) {
|
|
776
|
-
this.deviceRefreshRate = this.accessory.context.refreshRate = device.refreshRate;
|
|
777
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Config refreshRate: ${this.deviceRefreshRate}`);
|
|
778
|
-
}
|
|
779
|
-
else if (this.platform.config.options.refreshRate) {
|
|
780
|
-
this.deviceRefreshRate = this.accessory.context.refreshRate = this.platform.config.options.refreshRate;
|
|
781
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Platform Config refreshRate: ${this.deviceRefreshRate}`);
|
|
782
|
-
}
|
|
783
|
-
}
|
|
784
|
-
async deviceConfig(device) {
|
|
785
|
-
let config = {};
|
|
786
|
-
if (device.lock) {
|
|
787
|
-
config = device.lock;
|
|
788
|
-
}
|
|
789
|
-
if (device.connectionType !== undefined) {
|
|
790
|
-
config['connectionType'] = device.connectionType;
|
|
791
|
-
}
|
|
792
|
-
if (device.external !== undefined) {
|
|
793
|
-
config['external'] = device.external;
|
|
794
|
-
}
|
|
795
|
-
if (device.logging !== undefined) {
|
|
796
|
-
config['logging'] = device.logging;
|
|
797
|
-
}
|
|
798
|
-
if (device.refreshRate !== undefined) {
|
|
799
|
-
config['refreshRate'] = device.refreshRate;
|
|
800
|
-
}
|
|
801
|
-
if (device.scanDuration !== undefined) {
|
|
802
|
-
config['scanDuration'] = device.scanDuration;
|
|
803
|
-
}
|
|
804
|
-
if (device.webhook !== undefined) {
|
|
805
|
-
config['webhook'] = device.webhook;
|
|
806
|
-
}
|
|
807
|
-
if (Object.entries(config).length !== 0) {
|
|
808
|
-
this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} Config: ${JSON.stringify(config)}`);
|
|
809
|
-
}
|
|
810
|
-
}
|
|
811
|
-
async deviceLogs(device) {
|
|
812
|
-
if (this.platform.debugMode) {
|
|
813
|
-
this.deviceLogging = this.accessory.context.logging = 'debugMode';
|
|
814
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Debug Mode Logging: ${this.deviceLogging}`);
|
|
536
|
+
this.ContactSensor.Service.updateCharacteristic(this.hap.Characteristic.ContactSensorState, e);
|
|
815
537
|
}
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Config Logging: ${this.deviceLogging}`);
|
|
819
|
-
}
|
|
820
|
-
else if (this.platform.config.options?.logging) {
|
|
821
|
-
this.deviceLogging = this.accessory.context.logging = this.platform.config.options?.logging;
|
|
822
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Platform Config Logging: ${this.deviceLogging}`);
|
|
823
|
-
}
|
|
824
|
-
else {
|
|
825
|
-
this.deviceLogging = this.accessory.context.logging = 'standard';
|
|
826
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Logging Not Set, Using: ${this.deviceLogging}`);
|
|
827
|
-
}
|
|
828
|
-
}
|
|
829
|
-
/**
|
|
830
|
-
* Logging for Device
|
|
831
|
-
*/
|
|
832
|
-
infoLog(...log) {
|
|
833
|
-
if (this.enablingDeviceLogging()) {
|
|
834
|
-
this.platform.log.info(String(...log));
|
|
835
|
-
}
|
|
836
|
-
}
|
|
837
|
-
warnLog(...log) {
|
|
838
|
-
if (this.enablingDeviceLogging()) {
|
|
839
|
-
this.platform.log.warn(String(...log));
|
|
840
|
-
}
|
|
841
|
-
}
|
|
842
|
-
debugWarnLog(...log) {
|
|
843
|
-
if (this.enablingDeviceLogging()) {
|
|
844
|
-
if (this.deviceLogging?.includes('debug')) {
|
|
845
|
-
this.platform.log.warn('[DEBUG]', String(...log));
|
|
846
|
-
}
|
|
847
|
-
}
|
|
848
|
-
}
|
|
849
|
-
errorLog(...log) {
|
|
850
|
-
if (this.enablingDeviceLogging()) {
|
|
851
|
-
this.platform.log.error(String(...log));
|
|
852
|
-
}
|
|
853
|
-
}
|
|
854
|
-
debugErrorLog(...log) {
|
|
855
|
-
if (this.enablingDeviceLogging()) {
|
|
856
|
-
if (this.deviceLogging?.includes('debug')) {
|
|
857
|
-
this.platform.log.error('[DEBUG]', String(...log));
|
|
858
|
-
}
|
|
859
|
-
}
|
|
860
|
-
}
|
|
861
|
-
debugLog(...log) {
|
|
862
|
-
if (this.enablingDeviceLogging()) {
|
|
863
|
-
if (this.deviceLogging === 'debug') {
|
|
864
|
-
this.platform.log.info('[DEBUG]', String(...log));
|
|
865
|
-
}
|
|
866
|
-
else {
|
|
867
|
-
this.platform.log.debug(String(...log));
|
|
868
|
-
}
|
|
869
|
-
}
|
|
870
|
-
}
|
|
871
|
-
enablingDeviceLogging() {
|
|
872
|
-
return this.deviceLogging.includes('debug') || this.deviceLogging === 'standard';
|
|
538
|
+
this.LockMechanism.Service.updateCharacteristic(this.hap.Characteristic.LockTargetState, e);
|
|
539
|
+
this.LockMechanism.Service.updateCharacteristic(this.hap.Characteristic.LockCurrentState, e);
|
|
873
540
|
}
|
|
874
541
|
}
|
|
875
542
|
//# sourceMappingURL=lock.js.map
|