@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/motion.js
CHANGED
|
@@ -1,121 +1,97 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
import {
|
|
1
|
+
/* Copyright(C) 2021-2024, donavanbecker (https://github.com/donavanbecker). All rights reserved.
|
|
2
|
+
*
|
|
3
|
+
* motion.ts: @switchbot/homebridge-switchbot.
|
|
4
|
+
*/
|
|
5
|
+
import { deviceBase } from './device.js';
|
|
6
|
+
import { Subject, interval, skipWhile } from 'rxjs';
|
|
6
7
|
/**
|
|
7
8
|
* Platform Accessory
|
|
8
9
|
* An instance of this class is created for each accessory your platform registers
|
|
9
10
|
* Each accessory may expose multiple services of different service types.
|
|
10
11
|
*/
|
|
11
|
-
export class Motion {
|
|
12
|
+
export class Motion extends deviceBase {
|
|
12
13
|
platform;
|
|
13
|
-
accessory;
|
|
14
|
-
device;
|
|
15
|
-
api;
|
|
16
|
-
log;
|
|
17
|
-
config;
|
|
18
|
-
hap;
|
|
19
14
|
// Services
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
// Characteristic Values
|
|
24
|
-
BatteryLevel;
|
|
25
|
-
MotionDetected;
|
|
26
|
-
StatusLowBattery;
|
|
27
|
-
FirmwareRevision;
|
|
28
|
-
CurrentAmbientLightLevel;
|
|
29
|
-
// OpenAPI Others
|
|
30
|
-
OpenAPI_BatteryLevel;
|
|
31
|
-
OpenAPI_FirmwareRevision;
|
|
32
|
-
OpenAPI_MotionDetected;
|
|
33
|
-
OpenAPI_CurrentAmbientLightLevel;
|
|
34
|
-
// Status
|
|
35
|
-
BLE_BatteryLevel;
|
|
36
|
-
BLE_MotionDetected;
|
|
37
|
-
BLE_CurrentAmbientLightLevel;
|
|
38
|
-
// BLE Others
|
|
39
|
-
scanning;
|
|
40
|
-
BLE_IsConnected;
|
|
41
|
-
// Config
|
|
42
|
-
set_minLux;
|
|
43
|
-
set_maxLux;
|
|
44
|
-
scanDuration;
|
|
45
|
-
deviceLogging;
|
|
46
|
-
deviceRefreshRate;
|
|
15
|
+
Battery;
|
|
16
|
+
MotionSensor;
|
|
17
|
+
LightSensor;
|
|
47
18
|
// Updates
|
|
48
19
|
motionUbpdateInProgress;
|
|
49
20
|
doMotionUpdate;
|
|
50
|
-
// Connection
|
|
51
|
-
OpenAPI;
|
|
52
|
-
BLE;
|
|
53
21
|
constructor(platform, accessory, device) {
|
|
22
|
+
super(platform, accessory, device);
|
|
54
23
|
this.platform = platform;
|
|
55
|
-
this.accessory = accessory;
|
|
56
|
-
this.device = device;
|
|
57
|
-
this.api = this.platform.api;
|
|
58
|
-
this.log = this.platform.log;
|
|
59
|
-
this.config = this.platform.config;
|
|
60
|
-
this.hap = this.api.hap;
|
|
61
|
-
// Connection
|
|
62
|
-
this.BLE = this.device.connectionType === 'BLE' || this.device.connectionType === 'BLE/OpenAPI';
|
|
63
|
-
this.OpenAPI = this.device.connectionType === 'OpenAPI' || this.device.connectionType === 'BLE/OpenAPI';
|
|
64
|
-
// default placeholders
|
|
65
|
-
this.deviceLogs(device);
|
|
66
|
-
this.scan(device);
|
|
67
|
-
this.refreshRate(device);
|
|
68
|
-
this.deviceContext();
|
|
69
|
-
this.deviceConfig(device);
|
|
70
24
|
// this is subject we use to track when we need to POST changes to the SwitchBot API
|
|
71
25
|
this.doMotionUpdate = new Subject();
|
|
72
26
|
this.motionUbpdateInProgress = false;
|
|
73
|
-
//
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
.getService(this.hap.Service.
|
|
78
|
-
.
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
27
|
+
// Initialize Motion Sensor property
|
|
28
|
+
accessory.context.MotionSensor = accessory.context.MotionSensor ?? {};
|
|
29
|
+
this.MotionSensor = {
|
|
30
|
+
Name: accessory.context.MotionSensor.Name ?? `${accessory.displayName} Motion Sensor`,
|
|
31
|
+
Service: accessory.getService(this.hap.Service.MotionSensor) ?? accessory.addService(this.hap.Service.MotionSensor),
|
|
32
|
+
MotionDetected: accessory.context.MotionDetected ?? false,
|
|
33
|
+
};
|
|
34
|
+
accessory.context.MotionSensor = this.MotionSensor;
|
|
35
|
+
// Initialize Motion Sensor Characteristics
|
|
36
|
+
this.MotionSensor.Service
|
|
37
|
+
.setCharacteristic(this.hap.Characteristic.Name, accessory.displayName)
|
|
38
|
+
.setCharacteristic(this.hap.Characteristic.StatusActive, true)
|
|
39
|
+
.getCharacteristic(this.hap.Characteristic.MotionDetected)
|
|
40
|
+
.onGet(() => {
|
|
41
|
+
return this.MotionSensor.MotionDetected;
|
|
42
|
+
});
|
|
43
|
+
accessory.context.MotionSensorName = this.MotionSensor.Name;
|
|
44
|
+
// Initialize Battery Service
|
|
45
|
+
accessory.context.Battery = accessory.context.Battery ?? {};
|
|
46
|
+
this.Battery = {
|
|
47
|
+
Name: accessory.context.Battery.Name ?? `${accessory.displayName} Battery`,
|
|
48
|
+
Service: accessory.getService(this.hap.Service.Battery) ?? accessory.addService(this.hap.Service.Battery),
|
|
49
|
+
BatteryLevel: accessory.context.BatteryLevel ?? 100,
|
|
50
|
+
StatusLowBattery: accessory.context.StatusLowBattery ?? this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL,
|
|
51
|
+
};
|
|
52
|
+
accessory.context.Battery = this.Battery;
|
|
53
|
+
// Initialize Battery Characteristics
|
|
54
|
+
this.Battery.Service
|
|
55
|
+
.setCharacteristic(this.hap.Characteristic.Name, this.Battery.Name)
|
|
56
|
+
.setCharacteristic(this.hap.Characteristic.ChargingState, this.hap.Characteristic.ChargingState.NOT_CHARGEABLE)
|
|
57
|
+
.getCharacteristic(this.hap.Characteristic.BatteryLevel)
|
|
58
|
+
.onGet(() => {
|
|
59
|
+
return this.Battery.BatteryLevel;
|
|
60
|
+
});
|
|
61
|
+
this.Battery.Service
|
|
62
|
+
.setCharacteristic(this.hap.Characteristic.StatusLowBattery, this.Battery.StatusLowBattery)
|
|
63
|
+
.getCharacteristic(this.hap.Characteristic.StatusLowBattery)
|
|
64
|
+
.onGet(() => {
|
|
65
|
+
return this.Battery.StatusLowBattery;
|
|
66
|
+
});
|
|
67
|
+
// Initialize Light Sensor Service
|
|
94
68
|
if (device.motion?.hide_lightsensor) {
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Add Light Sensor Service`);
|
|
101
|
-
const lightSensorService = `${accessory.displayName} Light Sensor`;
|
|
102
|
-
(this.lightSensorService = this.accessory.getService(this.hap.Service.LightSensor)
|
|
103
|
-
|| this.accessory.addService(this.hap.Service.LightSensor)), lightSensorService;
|
|
104
|
-
this.lightSensorService.setCharacteristic(this.hap.Characteristic.Name, `${accessory.displayName} Light Sensor`);
|
|
105
|
-
this.lightSensorService.setCharacteristic(this.hap.Characteristic.ConfiguredName, `${accessory.displayName} Light Sensor`);
|
|
69
|
+
if (this.LightSensor) {
|
|
70
|
+
this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Removing Light Sensor Service`);
|
|
71
|
+
this.LightSensor.Service = this.accessory.getService(this.hap.Service.LightSensor);
|
|
72
|
+
accessory.removeService(this.LightSensor.Service);
|
|
73
|
+
}
|
|
106
74
|
}
|
|
107
75
|
else {
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
this.
|
|
76
|
+
accessory.context.LightSensor = accessory.context.LightSensor ?? {};
|
|
77
|
+
this.LightSensor = {
|
|
78
|
+
Name: accessory.context.LightSensor.Name ?? `${accessory.displayName} Light Sensor`,
|
|
79
|
+
Service: accessory.getService(this.hap.Service.LightSensor) ?? this.accessory.addService(this.hap.Service.LightSensor),
|
|
80
|
+
CurrentAmbientLightLevel: accessory.context.CurrentAmbientLightLevel ?? 0.0001,
|
|
81
|
+
};
|
|
82
|
+
accessory.context.LightSensor = this.LightSensor;
|
|
83
|
+
// Initialize LightSensor Characteristics
|
|
84
|
+
this.LightSensor.Service
|
|
85
|
+
.setCharacteristic(this.hap.Characteristic.Name, this.LightSensor.Name)
|
|
86
|
+
.setCharacteristic(this.hap.Characteristic.StatusActive, true)
|
|
87
|
+
.getCharacteristic(this.hap.Characteristic.CurrentAmbientLightLevel)
|
|
88
|
+
.onGet(() => {
|
|
89
|
+
return this.LightSensor.CurrentAmbientLightLevel;
|
|
90
|
+
});
|
|
117
91
|
}
|
|
118
|
-
|
|
92
|
+
;
|
|
93
|
+
// Retrieve initial values and updateHomekit
|
|
94
|
+
this.refreshStatus();
|
|
119
95
|
// Retrieve initial values and updateHomekit
|
|
120
96
|
this.updateHomeKitCharacteristics();
|
|
121
97
|
// Start an update interval
|
|
@@ -125,119 +101,96 @@ export class Motion {
|
|
|
125
101
|
await this.refreshStatus();
|
|
126
102
|
});
|
|
127
103
|
//regisiter webhook event handler
|
|
128
|
-
|
|
129
|
-
this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} is listening webhook.`);
|
|
130
|
-
this.platform.webhookEventHandler[this.device.deviceId] = async (context) => {
|
|
131
|
-
try {
|
|
132
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} received Webhook: ${JSON.stringify(context)}`);
|
|
133
|
-
const { detectionState } = context;
|
|
134
|
-
const { MotionDetected } = this;
|
|
135
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} ` +
|
|
136
|
-
'(detectionState) = ' +
|
|
137
|
-
`Webhook:(${detectionState}), ` +
|
|
138
|
-
`current:(${MotionDetected})`);
|
|
139
|
-
this.MotionDetected = detectionState === 'DETECTED' ? true : false;
|
|
140
|
-
this.updateHomeKitCharacteristics();
|
|
141
|
-
}
|
|
142
|
-
catch (e) {
|
|
143
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} `
|
|
144
|
-
+ `failed to handle webhook. Received: ${JSON.stringify(context)} Error: ${e}`);
|
|
145
|
-
}
|
|
146
|
-
};
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
/**
|
|
150
|
-
* Parse the device status from the SwitchBot api
|
|
151
|
-
*/
|
|
152
|
-
async parseStatus() {
|
|
153
|
-
if (!this.device.enableCloudService && this.OpenAPI) {
|
|
154
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} parseStatus enableCloudService: ${this.device.enableCloudService}`);
|
|
155
|
-
}
|
|
156
|
-
else if (this.BLE) {
|
|
157
|
-
await this.BLEparseStatus();
|
|
158
|
-
}
|
|
159
|
-
else if (this.OpenAPI && this.platform.config.credentials?.token) {
|
|
160
|
-
await this.openAPIparseStatus();
|
|
161
|
-
}
|
|
162
|
-
else {
|
|
163
|
-
await this.offlineOff();
|
|
164
|
-
this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:` + ` ${this.device.connectionType}, parseStatus will not happen.`);
|
|
165
|
-
}
|
|
104
|
+
this.registerWebhook(accessory, device);
|
|
166
105
|
}
|
|
167
|
-
async BLEparseStatus() {
|
|
106
|
+
async BLEparseStatus(serviceData) {
|
|
168
107
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLEparseStatus`);
|
|
169
108
|
// Movement
|
|
170
|
-
this.MotionDetected =
|
|
171
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} MotionDetected: ${this.MotionDetected}`);
|
|
172
|
-
if (this.MotionDetected !== this.accessory.context.MotionDetected && this.MotionDetected) {
|
|
109
|
+
this.MotionSensor.MotionDetected = serviceData.movement;
|
|
110
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} MotionDetected: ${this.MotionSensor.MotionDetected}`);
|
|
111
|
+
if (this.MotionSensor.MotionDetected !== this.accessory.context.MotionDetected && this.MotionSensor.MotionDetected) {
|
|
173
112
|
this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Detected Motion`);
|
|
174
113
|
}
|
|
175
114
|
// Light Level
|
|
176
115
|
if (!this.device.motion?.hide_lightsensor) {
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
switch (
|
|
116
|
+
const set_minLux = this.device.motion?.set_minLux ?? 1;
|
|
117
|
+
const set_maxLux = this.device.motion?.set_maxLux ?? 6001;
|
|
118
|
+
switch (serviceData.lightLevel) {
|
|
180
119
|
case 'dark':
|
|
181
120
|
case 1:
|
|
182
|
-
this.CurrentAmbientLightLevel =
|
|
121
|
+
this.LightSensor.CurrentAmbientLightLevel = set_minLux;
|
|
183
122
|
break;
|
|
184
123
|
default:
|
|
185
|
-
this.CurrentAmbientLightLevel =
|
|
124
|
+
this.LightSensor.CurrentAmbientLightLevel = set_maxLux;
|
|
186
125
|
}
|
|
187
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${
|
|
188
|
-
` CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`);
|
|
189
|
-
if (this.CurrentAmbientLightLevel !== this.accessory.context.CurrentAmbientLightLevel) {
|
|
190
|
-
this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName}
|
|
126
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${serviceData.lightLevel},`
|
|
127
|
+
+ ` CurrentAmbientLightLevel: ${this.LightSensor.CurrentAmbientLightLevel}`);
|
|
128
|
+
if (this.LightSensor.CurrentAmbientLightLevel !== this.accessory.context.CurrentAmbientLightLevel) {
|
|
129
|
+
this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName}`
|
|
130
|
+
+ ` CurrentAmbientLightLevel: ${this.LightSensor.CurrentAmbientLightLevel}`);
|
|
191
131
|
}
|
|
192
132
|
}
|
|
193
133
|
// Battery
|
|
194
|
-
if (
|
|
195
|
-
|
|
134
|
+
if (serviceData.battery === undefined) {
|
|
135
|
+
serviceData.battery = 100;
|
|
196
136
|
}
|
|
197
|
-
this.BatteryLevel =
|
|
198
|
-
if (this.BatteryLevel < 10) {
|
|
199
|
-
this.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW;
|
|
137
|
+
this.Battery.BatteryLevel = serviceData.battery;
|
|
138
|
+
if (this.Battery.BatteryLevel < 10) {
|
|
139
|
+
this.Battery.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW;
|
|
200
140
|
}
|
|
201
141
|
else {
|
|
202
|
-
this.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
|
|
142
|
+
this.Battery.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
|
|
203
143
|
}
|
|
204
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.BatteryLevel},`
|
|
144
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.Battery.BatteryLevel},`
|
|
145
|
+
+ ` StatusLowBattery: ${this.Battery.StatusLowBattery}`);
|
|
205
146
|
}
|
|
206
|
-
async openAPIparseStatus() {
|
|
147
|
+
async openAPIparseStatus(deviceStatus) {
|
|
207
148
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIparseStatus`);
|
|
208
149
|
// Motion State
|
|
209
|
-
this.MotionDetected =
|
|
210
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} MotionDetected: ${this.MotionDetected}`);
|
|
150
|
+
this.MotionSensor.MotionDetected = deviceStatus.body.moveDetected;
|
|
151
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} MotionDetected: ${this.MotionSensor.MotionDetected}`);
|
|
211
152
|
// Light Level
|
|
212
153
|
if (!this.device.motion?.hide_lightsensor) {
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
switch (
|
|
154
|
+
const set_minLux = this.device.motion?.set_minLux ?? 1;
|
|
155
|
+
const set_maxLux = this.device.motion?.set_maxLux ?? 6001;
|
|
156
|
+
switch (deviceStatus.body.brightness) {
|
|
216
157
|
case 'dim':
|
|
217
|
-
this.CurrentAmbientLightLevel =
|
|
158
|
+
this.LightSensor.CurrentAmbientLightLevel = set_minLux;
|
|
218
159
|
break;
|
|
219
160
|
case 'bright':
|
|
220
161
|
default:
|
|
221
|
-
this.CurrentAmbientLightLevel =
|
|
162
|
+
this.LightSensor.CurrentAmbientLightLevel = set_maxLux;
|
|
222
163
|
}
|
|
223
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}
|
|
164
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}`
|
|
165
|
+
+ ` CurrentAmbientLightLevel: ${this.LightSensor.CurrentAmbientLightLevel}`);
|
|
224
166
|
}
|
|
225
167
|
// Battery
|
|
226
|
-
this.BatteryLevel = Number(
|
|
227
|
-
if (this.BatteryLevel < 10) {
|
|
228
|
-
this.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW;
|
|
168
|
+
this.Battery.BatteryLevel = Number(deviceStatus.body.battery);
|
|
169
|
+
if (this.Battery.BatteryLevel < 10) {
|
|
170
|
+
this.Battery.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW;
|
|
229
171
|
}
|
|
230
172
|
else {
|
|
231
|
-
this.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
|
|
232
|
-
}
|
|
233
|
-
if (Number.isNaN(this.BatteryLevel)) {
|
|
234
|
-
this.BatteryLevel = 100;
|
|
173
|
+
this.Battery.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
|
|
174
|
+
}
|
|
175
|
+
if (Number.isNaN(this.Battery.BatteryLevel)) {
|
|
176
|
+
this.Battery.BatteryLevel = 100;
|
|
177
|
+
}
|
|
178
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.Battery.BatteryLevel},`
|
|
179
|
+
+ ` StatusLowBattery: ${this.Battery.StatusLowBattery}`);
|
|
180
|
+
// Firmware Version
|
|
181
|
+
const version = deviceStatus.body.version?.toString();
|
|
182
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Firmware Version: ${version?.replace(/^V|-.*$/g, '')}`);
|
|
183
|
+
if (deviceStatus.body.version) {
|
|
184
|
+
const deviceVersion = version?.replace(/^V|-.*$/g, '') ?? '0.0.0';
|
|
185
|
+
this.accessory
|
|
186
|
+
.getService(this.hap.Service.AccessoryInformation)
|
|
187
|
+
.setCharacteristic(this.hap.Characteristic.HardwareRevision, deviceVersion)
|
|
188
|
+
.setCharacteristic(this.hap.Characteristic.FirmwareRevision, deviceVersion)
|
|
189
|
+
.getCharacteristic(this.hap.Characteristic.FirmwareRevision)
|
|
190
|
+
.updateValue(deviceVersion);
|
|
191
|
+
this.accessory.context.deviceVersion = deviceVersion;
|
|
192
|
+
this.debugSuccessLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceVersion: ${this.accessory.context.deviceVersion}`);
|
|
235
193
|
}
|
|
236
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.BatteryLevel},`
|
|
237
|
-
+ ` StatusLowBattery: ${this.StatusLowBattery}`);
|
|
238
|
-
// FirmwareRevision
|
|
239
|
-
this.FirmwareRevision = this.OpenAPI_FirmwareRevision;
|
|
240
|
-
this.accessory.context.FirmwareRevision = this.FirmwareRevision;
|
|
241
194
|
}
|
|
242
195
|
/**
|
|
243
196
|
* Asks the SwitchBot API for the latest device information
|
|
@@ -254,214 +207,120 @@ export class Motion {
|
|
|
254
207
|
}
|
|
255
208
|
else {
|
|
256
209
|
await this.offlineOff();
|
|
257
|
-
this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:`
|
|
258
|
-
` ${this.device.connectionType}, refreshStatus will not happen.`);
|
|
210
|
+
this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:`
|
|
211
|
+
+ ` ${this.device.connectionType}, refreshStatus will not happen.`);
|
|
259
212
|
}
|
|
260
213
|
}
|
|
261
214
|
async BLERefreshStatus() {
|
|
262
215
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLERefreshStatus`);
|
|
263
|
-
const switchbot = await this.
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
.deviceId.match(/.{1,2}/g)
|
|
269
|
-
.join(':')
|
|
270
|
-
.toLowerCase();
|
|
271
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
|
|
272
|
-
this.getCustomBLEAddress(switchbot);
|
|
273
|
-
// Start to monitor advertisement packets
|
|
274
|
-
(async () => {
|
|
216
|
+
const switchbot = await this.switchbotBLE();
|
|
217
|
+
if (switchbot === undefined) {
|
|
218
|
+
await this.BLERefreshConnection(switchbot);
|
|
219
|
+
}
|
|
220
|
+
else {
|
|
275
221
|
// Start to monitor advertisement packets
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} address: ${ad.address}, model: ${ad.serviceData.model}`);
|
|
284
|
-
if (this.device.bleMac === ad.address && ad.serviceData.model === 's') {
|
|
285
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${JSON.stringify(ad.serviceData)}`);
|
|
286
|
-
this.BLE_MotionDetected = ad.serviceData.movement;
|
|
287
|
-
this.BLE_BatteryLevel = ad.serviceData.battery;
|
|
288
|
-
this.BLE_CurrentAmbientLightLevel = ad.serviceData.lightLevel;
|
|
222
|
+
(async () => {
|
|
223
|
+
// Start to monitor advertisement packets
|
|
224
|
+
const serviceData = await this.monitorAdvertisementPackets(switchbot);
|
|
225
|
+
// Update HomeKit
|
|
226
|
+
if (serviceData.model !== '' && serviceData.modelName !== '') {
|
|
227
|
+
await this.BLEparseStatus(serviceData);
|
|
228
|
+
await this.updateHomeKitCharacteristics();
|
|
289
229
|
}
|
|
290
230
|
else {
|
|
291
|
-
this.
|
|
231
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed to get serviceData, serviceData: ${serviceData}`);
|
|
232
|
+
await this.BLERefreshConnection(switchbot);
|
|
292
233
|
}
|
|
293
|
-
};
|
|
294
|
-
|
|
295
|
-
await switchbot.wait(this.scanDuration * 1000);
|
|
296
|
-
// Stop to monitor
|
|
297
|
-
await switchbot.stopScan();
|
|
298
|
-
// Update HomeKit
|
|
299
|
-
await this.BLEparseStatus();
|
|
300
|
-
await this.updateHomeKitCharacteristics();
|
|
301
|
-
})();
|
|
302
|
-
/*if (switchbot !== false) {
|
|
303
|
-
await switchbot
|
|
304
|
-
.startScan({
|
|
305
|
-
model: 's',
|
|
306
|
-
id: this.device.bleMac,
|
|
307
|
-
})
|
|
308
|
-
.then(async () => {
|
|
309
|
-
return await this.retry({
|
|
310
|
-
max: this.maxRetry(),
|
|
311
|
-
fn: async () => {
|
|
312
|
-
// Set an event handler
|
|
313
|
-
this.scanning = true;
|
|
314
|
-
switchbot.onadvertisement = async (ad: ad) => {
|
|
315
|
-
this.debugLog(
|
|
316
|
-
`${this.device.deviceType}: ${this.accessory.displayName} Config BLE Address: ${this.device.bleMac},` +
|
|
317
|
-
` BLE Address Found: ${ad.address}`,
|
|
318
|
-
);
|
|
319
|
-
this.BLE_MotionDetected = ad.serviceData.movement;
|
|
320
|
-
this.BLE_BatteryLevel = ad.serviceData.battery;
|
|
321
|
-
this.BLE_CurrentAmbientLightLevel = ad.serviceData.lightLevel;
|
|
322
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${JSON.stringify(ad.serviceData)}`);
|
|
323
|
-
this.debugLog(
|
|
324
|
-
`${this.device.deviceType}: ${this.accessory.displayName} movement: ${ad.serviceData.movement},`
|
|
325
|
-
+ ` lightLevel: ${ad.serviceData.lightLevel}, battery: ${ad.serviceData.battery}`,
|
|
326
|
-
);
|
|
327
|
-
|
|
328
|
-
if (ad.serviceData) {
|
|
329
|
-
this.BLE_IsConnected = true;
|
|
330
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} connected: ${this.BLE_IsConnected}`);
|
|
331
|
-
this.debugErrorLog('1');
|
|
332
|
-
await this.stopScanning(switchbot);
|
|
333
|
-
this.scanning = false;
|
|
334
|
-
this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} scanning: ${this.scanning}`);
|
|
335
|
-
} else {
|
|
336
|
-
this.BLE_IsConnected = false;
|
|
337
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} connected: ${this.BLE_IsConnected}`);
|
|
338
|
-
}
|
|
339
|
-
};
|
|
340
|
-
// Wait
|
|
341
|
-
return await sleep(this.scanDuration * 1000);
|
|
342
|
-
},
|
|
343
|
-
});
|
|
344
|
-
})
|
|
345
|
-
.then(async () => {
|
|
346
|
-
// Stop to monitor
|
|
347
|
-
this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} scanning: ${this.scanning}`);
|
|
348
|
-
if (this.scanning) {
|
|
349
|
-
this.debugErrorLog('2');
|
|
350
|
-
await this.stopScanning(switchbot);
|
|
351
|
-
}
|
|
352
|
-
})
|
|
353
|
-
.catch(async (e: any) => {
|
|
354
|
-
this.apiError(e);
|
|
355
|
-
this.errorLog(
|
|
356
|
-
`${this.device.deviceType}: ${this.accessory.displayName} failed BLERefreshStatus with ${this.device.connectionType}` +
|
|
357
|
-
` Connection, Error Message: ${JSON.stringify(e.message)}`,
|
|
358
|
-
);
|
|
359
|
-
this.debugErrorLog('3');
|
|
360
|
-
await this.BLERefreshConnection(switchbot);
|
|
361
|
-
});
|
|
362
|
-
} else {
|
|
363
|
-
this.debugErrorLog('4');
|
|
364
|
-
await this.BLERefreshConnection(switchbot);
|
|
365
|
-
}*/
|
|
234
|
+
})();
|
|
235
|
+
}
|
|
366
236
|
}
|
|
367
237
|
async openAPIRefreshStatus() {
|
|
368
238
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus`);
|
|
369
239
|
try {
|
|
370
|
-
const { body, statusCode } = await
|
|
371
|
-
headers: this.platform.generateHeaders(),
|
|
372
|
-
});
|
|
373
|
-
this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} statusCode: ${statusCode}`);
|
|
240
|
+
const { body, statusCode } = await this.deviceRefreshStatus();
|
|
374
241
|
const deviceStatus = await body.json();
|
|
375
|
-
this.
|
|
376
|
-
|
|
242
|
+
await this.refreshStatusCodes(statusCode, deviceStatus);
|
|
243
|
+
;
|
|
377
244
|
if ((statusCode === 200 || statusCode === 100) && (deviceStatus.statusCode === 200 || deviceStatus.statusCode === 100)) {
|
|
378
|
-
this.
|
|
379
|
-
|
|
380
|
-
this.
|
|
381
|
-
this.OpenAPI_CurrentAmbientLightLevel = deviceStatus.body.brightness;
|
|
382
|
-
this.OpenAPI_BatteryLevel = deviceStatus.body.battery;
|
|
383
|
-
this.OpenAPI_FirmwareRevision = deviceStatus.body.version;
|
|
384
|
-
this.openAPIparseStatus();
|
|
385
|
-
this.updateHomeKitCharacteristics();
|
|
245
|
+
await this.successfulRefreshStatus(statusCode, deviceStatus);
|
|
246
|
+
await this.openAPIparseStatus(deviceStatus);
|
|
247
|
+
await this.updateHomeKitCharacteristics();
|
|
386
248
|
}
|
|
387
249
|
else {
|
|
388
|
-
this.
|
|
389
|
-
this.statusCode(deviceStatus.statusCode);
|
|
250
|
+
await this.statusCodes(statusCode, deviceStatus);
|
|
390
251
|
}
|
|
391
252
|
}
|
|
392
253
|
catch (e) {
|
|
393
254
|
this.apiError(e);
|
|
394
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed openAPIRefreshStatus with ${this.device.connectionType}`
|
|
395
|
-
` Connection, Error Message: ${JSON.stringify(e.message)}`);
|
|
255
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed openAPIRefreshStatus with ${this.device.connectionType}`
|
|
256
|
+
+ ` Connection, Error Message: ${JSON.stringify(e.message)}`);
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
async registerWebhook(accessory, device) {
|
|
260
|
+
if (device.webhook) {
|
|
261
|
+
this.debugLog(`${device.deviceType}: ${accessory.displayName} is listening webhook.`);
|
|
262
|
+
this.platform.webhookEventHandler[device.deviceId] = async (context) => {
|
|
263
|
+
try {
|
|
264
|
+
this.debugLog(`${device.deviceType}: ${accessory.displayName} received Webhook: ${JSON.stringify(context)}`);
|
|
265
|
+
const { detectionState } = context;
|
|
266
|
+
const { MotionDetected } = this.MotionSensor;
|
|
267
|
+
this.debugLog(`${device.deviceType}: ${accessory.displayName} (detectionState) = Webhook: (${detectionState}),`
|
|
268
|
+
+ ` current: (${MotionDetected})`);
|
|
269
|
+
this.MotionSensor.MotionDetected = detectionState === 'DETECTED' ? true : false;
|
|
270
|
+
this.updateHomeKitCharacteristics();
|
|
271
|
+
}
|
|
272
|
+
catch (e) {
|
|
273
|
+
this.errorLog(`${device.deviceType}: ${accessory.displayName} failed to handle webhook. Received: ${JSON.stringify(context)} Error: ${e}`);
|
|
274
|
+
}
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
else {
|
|
278
|
+
this.debugLog(`${device.deviceType}: ${accessory.displayName} is not listening webhook.`);
|
|
396
279
|
}
|
|
397
280
|
}
|
|
398
281
|
/**
|
|
399
282
|
* Updates the status for each of the HomeKit Characteristics
|
|
400
283
|
*/
|
|
401
284
|
async updateHomeKitCharacteristics() {
|
|
402
|
-
if (this.MotionDetected === undefined) {
|
|
403
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} MotionDetected: ${this.MotionDetected}`);
|
|
285
|
+
if (this.MotionSensor.MotionDetected === undefined) {
|
|
286
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} MotionDetected: ${this.MotionSensor.MotionDetected}`);
|
|
404
287
|
}
|
|
405
288
|
else {
|
|
406
|
-
this.accessory.context.MotionDetected = this.MotionDetected;
|
|
407
|
-
this.
|
|
408
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic
|
|
289
|
+
this.accessory.context.MotionDetected = this.MotionSensor.MotionDetected;
|
|
290
|
+
this.MotionSensor.Service.updateCharacteristic(this.hap.Characteristic.MotionDetected, this.MotionSensor.MotionDetected);
|
|
291
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic`
|
|
292
|
+
+ ` MotionDetected: ${this.MotionSensor.MotionDetected}`);
|
|
409
293
|
}
|
|
410
|
-
if (this.BatteryLevel === undefined) {
|
|
411
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.BatteryLevel}`);
|
|
294
|
+
if (this.Battery.BatteryLevel === undefined) {
|
|
295
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.Battery.BatteryLevel}`);
|
|
412
296
|
}
|
|
413
297
|
else {
|
|
414
|
-
this.accessory.context.BatteryLevel = this.BatteryLevel;
|
|
415
|
-
this.
|
|
416
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic BatteryLevel: ${this.BatteryLevel}`);
|
|
298
|
+
this.accessory.context.BatteryLevel = this.Battery.BatteryLevel;
|
|
299
|
+
this.Battery.Service.updateCharacteristic(this.hap.Characteristic.BatteryLevel, this.Battery.BatteryLevel);
|
|
300
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic BatteryLevel: ${this.Battery.BatteryLevel}`);
|
|
417
301
|
}
|
|
418
|
-
if (this.StatusLowBattery === undefined) {
|
|
419
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} StatusLowBattery: ${this.StatusLowBattery}`);
|
|
302
|
+
if (this.Battery.StatusLowBattery === undefined) {
|
|
303
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} StatusLowBattery: ${this.Battery.StatusLowBattery}`);
|
|
420
304
|
}
|
|
421
305
|
else {
|
|
422
|
-
this.accessory.context.StatusLowBattery = this.StatusLowBattery;
|
|
423
|
-
this.
|
|
424
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic
|
|
306
|
+
this.accessory.context.StatusLowBattery = this.Battery.StatusLowBattery;
|
|
307
|
+
this.Battery.Service.updateCharacteristic(this.hap.Characteristic.StatusLowBattery, this.Battery.StatusLowBattery);
|
|
308
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic`
|
|
309
|
+
+ ` StatusLowBattery: ${this.Battery.StatusLowBattery}`);
|
|
425
310
|
}
|
|
426
311
|
if (this.BLE) {
|
|
427
|
-
if (this.CurrentAmbientLightLevel === undefined) {
|
|
428
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}
|
|
312
|
+
if (this.LightSensor.CurrentAmbientLightLevel === undefined) {
|
|
313
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}`
|
|
314
|
+
+ ` CurrentAmbientLightLevel: ${this.LightSensor.CurrentAmbientLightLevel}`);
|
|
429
315
|
}
|
|
430
316
|
else {
|
|
431
|
-
this.accessory.context.CurrentAmbientLightLevel = this.CurrentAmbientLightLevel;
|
|
432
|
-
this.
|
|
433
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}`
|
|
434
|
-
` updateCharacteristic CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`);
|
|
317
|
+
this.accessory.context.CurrentAmbientLightLevel = this.LightSensor.CurrentAmbientLightLevel;
|
|
318
|
+
this.LightSensor.Service.updateCharacteristic(this.hap.Characteristic.CurrentAmbientLightLevel, this.LightSensor.CurrentAmbientLightLevel);
|
|
319
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}`
|
|
320
|
+
+ ` updateCharacteristic CurrentAmbientLightLevel: ${this.LightSensor.CurrentAmbientLightLevel}`);
|
|
435
321
|
}
|
|
436
322
|
}
|
|
437
323
|
}
|
|
438
|
-
async stopScanning(switchbot) {
|
|
439
|
-
switchbot.stopScan();
|
|
440
|
-
if (this.BLE_IsConnected) {
|
|
441
|
-
await this.BLEparseStatus();
|
|
442
|
-
await this.updateHomeKitCharacteristics();
|
|
443
|
-
}
|
|
444
|
-
else {
|
|
445
|
-
await this.BLERefreshConnection(switchbot);
|
|
446
|
-
}
|
|
447
|
-
}
|
|
448
|
-
async getCustomBLEAddress(switchbot) {
|
|
449
|
-
if (this.device.customBLEaddress && this.deviceLogging.includes('debug')) {
|
|
450
|
-
(async () => {
|
|
451
|
-
// Start to monitor advertisement packets
|
|
452
|
-
await switchbot.startScan({
|
|
453
|
-
model: 's',
|
|
454
|
-
});
|
|
455
|
-
// Set an event handler
|
|
456
|
-
switchbot.onadvertisement = (ad) => {
|
|
457
|
-
this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} ad: ${JSON.stringify(ad, null, ' ')}`);
|
|
458
|
-
};
|
|
459
|
-
await sleep(10000);
|
|
460
|
-
// Stop to monitor
|
|
461
|
-
switchbot.stopScan();
|
|
462
|
-
})();
|
|
463
|
-
}
|
|
464
|
-
}
|
|
465
324
|
async BLERefreshConnection(switchbot) {
|
|
466
325
|
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} wasn't able to establish BLE Connection, node-switchbot:`
|
|
467
326
|
+ ` ${JSON.stringify(switchbot)}`);
|
|
@@ -470,256 +329,18 @@ export class Motion {
|
|
|
470
329
|
await this.openAPIRefreshStatus();
|
|
471
330
|
}
|
|
472
331
|
}
|
|
473
|
-
async retry({ max, fn }) {
|
|
474
|
-
return fn().catch(async (e) => {
|
|
475
|
-
if (max === 0) {
|
|
476
|
-
throw e;
|
|
477
|
-
}
|
|
478
|
-
this.infoLog(e);
|
|
479
|
-
this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Retrying`);
|
|
480
|
-
await sleep(1000);
|
|
481
|
-
return this.retry({ max: max - 1, fn });
|
|
482
|
-
});
|
|
483
|
-
}
|
|
484
|
-
maxRetry() {
|
|
485
|
-
if (this.device.maxRetry) {
|
|
486
|
-
return this.device.maxRetry;
|
|
487
|
-
}
|
|
488
|
-
else {
|
|
489
|
-
return 5;
|
|
490
|
-
}
|
|
491
|
-
}
|
|
492
|
-
minLux() {
|
|
493
|
-
if (this.device.motion?.set_minLux) {
|
|
494
|
-
this.set_minLux = this.device.motion.set_minLux;
|
|
495
|
-
}
|
|
496
|
-
else {
|
|
497
|
-
this.set_minLux = 1;
|
|
498
|
-
}
|
|
499
|
-
return this.set_minLux;
|
|
500
|
-
}
|
|
501
|
-
maxLux() {
|
|
502
|
-
if (this.device.motion?.set_maxLux) {
|
|
503
|
-
this.set_maxLux = this.device.motion.set_maxLux;
|
|
504
|
-
}
|
|
505
|
-
else {
|
|
506
|
-
this.set_maxLux = 6001;
|
|
507
|
-
}
|
|
508
|
-
return this.set_maxLux;
|
|
509
|
-
}
|
|
510
|
-
async scan(device) {
|
|
511
|
-
if (device.scanDuration) {
|
|
512
|
-
this.scanDuration = this.accessory.context.scanDuration = device.scanDuration;
|
|
513
|
-
if (this.BLE) {
|
|
514
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Config scanDuration: ${this.scanDuration}`);
|
|
515
|
-
}
|
|
516
|
-
}
|
|
517
|
-
else {
|
|
518
|
-
this.scanDuration = this.accessory.context.scanDuration = 1;
|
|
519
|
-
if (this.BLE) {
|
|
520
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Default scanDuration: ${this.scanDuration}`);
|
|
521
|
-
}
|
|
522
|
-
}
|
|
523
|
-
}
|
|
524
|
-
async statusCode(statusCode) {
|
|
525
|
-
switch (statusCode) {
|
|
526
|
-
case 151:
|
|
527
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command not supported by this deviceType, statusCode: ${statusCode}`);
|
|
528
|
-
break;
|
|
529
|
-
case 152:
|
|
530
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device not found, statusCode: ${statusCode}`);
|
|
531
|
-
break;
|
|
532
|
-
case 160:
|
|
533
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command is not supported, statusCode: ${statusCode}`);
|
|
534
|
-
break;
|
|
535
|
-
case 161:
|
|
536
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device is offline, statusCode: ${statusCode}`);
|
|
537
|
-
this.offlineOff();
|
|
538
|
-
break;
|
|
539
|
-
case 171:
|
|
540
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Hub Device is offline, statusCode: ${statusCode}. ` +
|
|
541
|
-
`Hub: ${this.device.hubDeviceId}`);
|
|
542
|
-
this.offlineOff();
|
|
543
|
-
break;
|
|
544
|
-
case 190:
|
|
545
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device internal error due to device states not synchronized with server,` +
|
|
546
|
-
` Or command format is invalid, statusCode: ${statusCode}`);
|
|
547
|
-
break;
|
|
548
|
-
case 100:
|
|
549
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Command successfully sent, statusCode: ${statusCode}`);
|
|
550
|
-
break;
|
|
551
|
-
case 200:
|
|
552
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Request successful, statusCode: ${statusCode}`);
|
|
553
|
-
break;
|
|
554
|
-
case 400:
|
|
555
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Bad Request, The client has issued an invalid request. `
|
|
556
|
-
+ `This is commonly used to specify validation errors in a request payload, statusCode: ${statusCode}`);
|
|
557
|
-
break;
|
|
558
|
-
case 401:
|
|
559
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Unauthorized, Authorization for the API is required, `
|
|
560
|
-
+ `but the request has not been authenticated, statusCode: ${statusCode}`);
|
|
561
|
-
break;
|
|
562
|
-
case 403:
|
|
563
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Forbidden, The request has been authenticated but does not `
|
|
564
|
-
+ `have appropriate permissions, or a requested resource is not found, statusCode: ${statusCode}`);
|
|
565
|
-
break;
|
|
566
|
-
case 404:
|
|
567
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Not Found, Specifies the requested path does not exist, `
|
|
568
|
-
+ `statusCode: ${statusCode}`);
|
|
569
|
-
break;
|
|
570
|
-
case 406:
|
|
571
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Not Acceptable, The client has requested a MIME type via `
|
|
572
|
-
+ `the Accept header for a value not supported by the server, statusCode: ${statusCode}`);
|
|
573
|
-
break;
|
|
574
|
-
case 415:
|
|
575
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Unsupported Media Type, The client has defined a contentType `
|
|
576
|
-
+ `header that is not supported by the server, statusCode: ${statusCode}`);
|
|
577
|
-
break;
|
|
578
|
-
case 422:
|
|
579
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Unprocessable Entity, The client has made a valid request, `
|
|
580
|
-
+ `but the server cannot process it. This is often used for APIs for which certain limits have been exceeded, statusCode: ${statusCode}`);
|
|
581
|
-
break;
|
|
582
|
-
case 429:
|
|
583
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Too Many Requests, The client has exceeded the number of `
|
|
584
|
-
+ `requests allowed for a given time window, statusCode: ${statusCode}`);
|
|
585
|
-
break;
|
|
586
|
-
case 500:
|
|
587
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Internal Server Error, An unexpected error on the SmartThings `
|
|
588
|
-
+ `servers has occurred. These errors should be rare, statusCode: ${statusCode}`);
|
|
589
|
-
break;
|
|
590
|
-
default:
|
|
591
|
-
this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Unknown statusCode: ` +
|
|
592
|
-
`${statusCode}, Submit Bugs Here: ' + 'https://tinyurl.com/SwitchBotBug`);
|
|
593
|
-
}
|
|
594
|
-
}
|
|
595
332
|
async offlineOff() {
|
|
596
333
|
if (this.device.offline) {
|
|
597
|
-
|
|
598
|
-
await this.updateHomeKitCharacteristics();
|
|
334
|
+
this.MotionSensor.Service.updateCharacteristic(this.hap.Characteristic.MotionDetected, false);
|
|
599
335
|
}
|
|
600
336
|
}
|
|
601
337
|
async apiError(e) {
|
|
602
|
-
this.
|
|
603
|
-
this.
|
|
604
|
-
this.
|
|
338
|
+
this.MotionSensor.Service.updateCharacteristic(this.hap.Characteristic.MotionDetected, e);
|
|
339
|
+
this.Battery.Service.updateCharacteristic(this.hap.Characteristic.BatteryLevel, e);
|
|
340
|
+
this.Battery.Service.updateCharacteristic(this.hap.Characteristic.StatusLowBattery, e);
|
|
605
341
|
if (this.BLE) {
|
|
606
|
-
this.
|
|
607
|
-
}
|
|
608
|
-
}
|
|
609
|
-
async deviceContext() {
|
|
610
|
-
if (this.MotionDetected === undefined) {
|
|
611
|
-
this.MotionDetected = false;
|
|
612
|
-
}
|
|
613
|
-
else {
|
|
614
|
-
this.MotionDetected = this.accessory.context.MotionDetected;
|
|
615
|
-
}
|
|
616
|
-
if (this.FirmwareRevision === undefined) {
|
|
617
|
-
this.FirmwareRevision = this.platform.version;
|
|
618
|
-
this.accessory.context.FirmwareRevision = this.FirmwareRevision;
|
|
619
|
-
}
|
|
620
|
-
}
|
|
621
|
-
async refreshRate(device) {
|
|
622
|
-
if (device.refreshRate) {
|
|
623
|
-
this.deviceRefreshRate = this.accessory.context.refreshRate = device.refreshRate;
|
|
624
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Config refreshRate: ${this.deviceRefreshRate}`);
|
|
625
|
-
}
|
|
626
|
-
else if (this.platform.config.options.refreshRate) {
|
|
627
|
-
this.deviceRefreshRate = this.accessory.context.refreshRate = this.platform.config.options.refreshRate;
|
|
628
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Platform Config refreshRate: ${this.deviceRefreshRate}`);
|
|
629
|
-
}
|
|
630
|
-
}
|
|
631
|
-
async deviceConfig(device) {
|
|
632
|
-
let config = {};
|
|
633
|
-
if (device.motion) {
|
|
634
|
-
config = device.motion;
|
|
635
|
-
}
|
|
636
|
-
if (device.connectionType !== undefined) {
|
|
637
|
-
config['connectionType'] = device.connectionType;
|
|
342
|
+
this.LightSensor.Service.updateCharacteristic(this.hap.Characteristic.CurrentAmbientLightLevel, e);
|
|
638
343
|
}
|
|
639
|
-
if (device.external !== undefined) {
|
|
640
|
-
config['external'] = device.external;
|
|
641
|
-
}
|
|
642
|
-
if (device.logging !== undefined) {
|
|
643
|
-
config['logging'] = device.logging;
|
|
644
|
-
}
|
|
645
|
-
if (device.refreshRate !== undefined) {
|
|
646
|
-
config['refreshRate'] = device.refreshRate;
|
|
647
|
-
}
|
|
648
|
-
if (device.scanDuration !== undefined) {
|
|
649
|
-
config['scanDuration'] = device.scanDuration;
|
|
650
|
-
}
|
|
651
|
-
if (device.offline !== undefined) {
|
|
652
|
-
config['offline'] = device.offline;
|
|
653
|
-
}
|
|
654
|
-
if (device.webhook !== undefined) {
|
|
655
|
-
config['webhook'] = device.webhook;
|
|
656
|
-
}
|
|
657
|
-
if (Object.entries(config).length !== 0) {
|
|
658
|
-
this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} Config: ${JSON.stringify(config)}`);
|
|
659
|
-
}
|
|
660
|
-
}
|
|
661
|
-
async deviceLogs(device) {
|
|
662
|
-
if (this.platform.debugMode) {
|
|
663
|
-
this.deviceLogging = this.accessory.context.logging = 'debugMode';
|
|
664
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Debug Mode Logging: ${this.deviceLogging}`);
|
|
665
|
-
}
|
|
666
|
-
else if (device.logging) {
|
|
667
|
-
this.deviceLogging = this.accessory.context.logging = device.logging;
|
|
668
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Config Logging: ${this.deviceLogging}`);
|
|
669
|
-
}
|
|
670
|
-
else if (this.platform.config.options?.logging) {
|
|
671
|
-
this.deviceLogging = this.accessory.context.logging = this.platform.config.options?.logging;
|
|
672
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Platform Config Logging: ${this.deviceLogging}`);
|
|
673
|
-
}
|
|
674
|
-
else {
|
|
675
|
-
this.deviceLogging = this.accessory.context.logging = 'standard';
|
|
676
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Logging Not Set, Using: ${this.deviceLogging}`);
|
|
677
|
-
}
|
|
678
|
-
}
|
|
679
|
-
/**
|
|
680
|
-
* Logging for Device
|
|
681
|
-
*/
|
|
682
|
-
infoLog(...log) {
|
|
683
|
-
if (this.enablingDeviceLogging()) {
|
|
684
|
-
this.platform.log.info(String(...log));
|
|
685
|
-
}
|
|
686
|
-
}
|
|
687
|
-
warnLog(...log) {
|
|
688
|
-
if (this.enablingDeviceLogging()) {
|
|
689
|
-
this.platform.log.warn(String(...log));
|
|
690
|
-
}
|
|
691
|
-
}
|
|
692
|
-
debugWarnLog(...log) {
|
|
693
|
-
if (this.enablingDeviceLogging()) {
|
|
694
|
-
if (this.deviceLogging?.includes('debug')) {
|
|
695
|
-
this.platform.log.warn('[DEBUG]', String(...log));
|
|
696
|
-
}
|
|
697
|
-
}
|
|
698
|
-
}
|
|
699
|
-
errorLog(...log) {
|
|
700
|
-
if (this.enablingDeviceLogging()) {
|
|
701
|
-
this.platform.log.error(String(...log));
|
|
702
|
-
}
|
|
703
|
-
}
|
|
704
|
-
debugErrorLog(...log) {
|
|
705
|
-
if (this.enablingDeviceLogging()) {
|
|
706
|
-
if (this.deviceLogging?.includes('debug')) {
|
|
707
|
-
this.platform.log.error('[DEBUG]', String(...log));
|
|
708
|
-
}
|
|
709
|
-
}
|
|
710
|
-
}
|
|
711
|
-
debugLog(...log) {
|
|
712
|
-
if (this.enablingDeviceLogging()) {
|
|
713
|
-
if (this.deviceLogging === 'debug') {
|
|
714
|
-
this.platform.log.info('[DEBUG]', String(...log));
|
|
715
|
-
}
|
|
716
|
-
else {
|
|
717
|
-
this.platform.log.debug(String(...log));
|
|
718
|
-
}
|
|
719
|
-
}
|
|
720
|
-
}
|
|
721
|
-
enablingDeviceLogging() {
|
|
722
|
-
return this.deviceLogging.includes('debug') || this.deviceLogging === 'standard';
|
|
723
344
|
}
|
|
724
345
|
}
|
|
725
346
|
//# sourceMappingURL=motion.js.map
|