@switchbot/homebridge-switchbot 3.5.0-beta.23 → 3.5.0-beta.24
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/config.schema.json +23 -2
- package/dist/device/blindtilt.d.ts +21 -98
- package/dist/device/blindtilt.d.ts.map +1 -1
- package/dist/device/blindtilt.js +332 -785
- package/dist/device/blindtilt.js.map +1 -1
- package/dist/device/bot.d.ts +25 -75
- package/dist/device/bot.d.ts.map +1 -1
- package/dist/device/bot.js +566 -778
- package/dist/device/bot.js.map +1 -1
- package/dist/device/ceilinglight.d.ts +13 -71
- package/dist/device/ceilinglight.d.ts.map +1 -1
- package/dist/device/ceilinglight.js +168 -606
- package/dist/device/ceilinglight.js.map +1 -1
- package/dist/device/colorbulb.d.ts +13 -78
- package/dist/device/colorbulb.d.ts.map +1 -1
- package/dist/device/colorbulb.js +218 -655
- package/dist/device/colorbulb.js.map +1 -1
- package/dist/device/contact.d.ts +14 -69
- package/dist/device/contact.d.ts.map +1 -1
- package/dist/device/contact.js +196 -553
- package/dist/device/contact.js.map +1 -1
- package/dist/device/curtain.d.ts +17 -90
- package/dist/device/curtain.d.ts.map +1 -1
- package/dist/device/curtain.js +324 -810
- package/dist/device/curtain.js.map +1 -1
- package/dist/device/device.d.ts +58 -0
- package/dist/device/device.d.ts.map +1 -0
- package/dist/device/device.js +629 -0
- package/dist/device/device.js.map +1 -0
- package/dist/device/hub.d.ts +15 -63
- package/dist/device/hub.d.ts.map +1 -1
- package/dist/device/hub.js +223 -610
- package/dist/device/hub.js.map +1 -1
- package/dist/device/humidifier.d.ts +10 -69
- package/dist/device/humidifier.d.ts.map +1 -1
- package/dist/device/humidifier.js +192 -595
- package/dist/device/humidifier.js.map +1 -1
- package/dist/device/iosensor.d.ts +11 -68
- package/dist/device/iosensor.d.ts.map +1 -1
- package/dist/device/iosensor.js +156 -599
- package/dist/device/iosensor.js.map +1 -1
- package/dist/device/lightstrip.d.ts +10 -72
- package/dist/device/lightstrip.d.ts.map +1 -1
- package/dist/device/lightstrip.js +204 -591
- package/dist/device/lightstrip.js.map +1 -1
- package/dist/device/lock.d.ts +15 -66
- package/dist/device/lock.d.ts.map +1 -1
- package/dist/device/lock.js +199 -566
- package/dist/device/lock.js.map +1 -1
- package/dist/device/meter.d.ts +13 -67
- package/dist/device/meter.d.ts.map +1 -1
- package/dist/device/meter.js +152 -592
- package/dist/device/meter.js.map +1 -1
- package/dist/device/meterplus.d.ts +13 -68
- package/dist/device/meterplus.d.ts.map +1 -1
- package/dist/device/meterplus.js +151 -599
- package/dist/device/meterplus.js.map +1 -1
- package/dist/device/motion.d.ts +13 -73
- package/dist/device/motion.d.ts.map +1 -1
- package/dist/device/motion.js +129 -540
- package/dist/device/motion.js.map +1 -1
- package/dist/device/plug.d.ts +9 -61
- package/dist/device/plug.d.ts.map +1 -1
- package/dist/device/plug.js +71 -476
- package/dist/device/plug.js.map +1 -1
- package/dist/device/robotvacuumcleaner.d.ts +11 -66
- package/dist/device/robotvacuumcleaner.d.ts.map +1 -1
- package/dist/device/robotvacuumcleaner.js +122 -471
- package/dist/device/robotvacuumcleaner.js.map +1 -1
- package/dist/device/waterdetector.d.ts +9 -66
- package/dist/device/waterdetector.d.ts.map +1 -1
- package/dist/device/waterdetector.js +105 -478
- package/dist/device/waterdetector.js.map +1 -1
- package/dist/irdevice/airconditioner.d.ts +5 -36
- package/dist/irdevice/airconditioner.d.ts.map +1 -1
- package/dist/irdevice/airconditioner.js +228 -337
- package/dist/irdevice/airconditioner.js.map +1 -1
- package/dist/irdevice/airpurifier.d.ts +5 -34
- package/dist/irdevice/airpurifier.d.ts.map +1 -1
- package/dist/irdevice/airpurifier.js +19 -267
- package/dist/irdevice/airpurifier.js.map +1 -1
- package/dist/irdevice/camera.d.ts +5 -34
- package/dist/irdevice/camera.d.ts.map +1 -1
- package/dist/irdevice/camera.js +13 -261
- package/dist/irdevice/camera.js.map +1 -1
- package/dist/irdevice/fan.d.ts +5 -34
- package/dist/irdevice/fan.d.ts.map +1 -1
- package/dist/irdevice/fan.js +13 -260
- package/dist/irdevice/fan.js.map +1 -1
- package/dist/irdevice/irdevice.d.ts +39 -0
- package/dist/irdevice/irdevice.d.ts.map +1 -0
- package/dist/irdevice/irdevice.js +502 -0
- package/dist/irdevice/irdevice.js.map +1 -0
- package/dist/irdevice/light.d.ts +5 -34
- package/dist/irdevice/light.d.ts.map +1 -1
- package/dist/irdevice/light.js +13 -267
- package/dist/irdevice/light.js.map +1 -1
- package/dist/irdevice/other.d.ts +18 -48
- package/dist/irdevice/other.d.ts.map +1 -1
- package/dist/irdevice/other.js +349 -551
- package/dist/irdevice/other.js.map +1 -1
- package/dist/irdevice/tv.d.ts +7 -40
- package/dist/irdevice/tv.d.ts.map +1 -1
- package/dist/irdevice/tv.js +79 -325
- package/dist/irdevice/tv.js.map +1 -1
- package/dist/irdevice/vacuumcleaner.d.ts +6 -36
- package/dist/irdevice/vacuumcleaner.d.ts.map +1 -1
- package/dist/irdevice/vacuumcleaner.js +38 -288
- package/dist/irdevice/vacuumcleaner.js.map +1 -1
- package/dist/irdevice/waterheater.d.ts +6 -36
- package/dist/irdevice/waterheater.d.ts.map +1 -1
- package/dist/irdevice/waterheater.js +39 -291
- package/dist/irdevice/waterheater.js.map +1 -1
- package/dist/settings.d.ts +15 -2
- package/dist/settings.d.ts.map +1 -1
- package/dist/utils.d.ts +68 -0
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +71 -0
- package/dist/utils.js.map +1 -1
- package/package.json +8 -8
- package/src/device/blindtilt.ts +356 -809
- package/src/device/bot.ts +601 -865
- package/src/device/ceilinglight.ts +182 -628
- package/src/device/colorbulb.ts +235 -683
- package/src/device/contact.ts +220 -575
- package/src/device/curtain.ts +344 -836
- package/src/device/device.ts +655 -0
- package/src/device/hub.ts +246 -636
- package/src/device/humidifier.ts +224 -645
- package/src/device/iosensor.ts +181 -625
- package/src/device/lightstrip.ts +230 -622
- package/src/device/lock.ts +236 -607
- package/src/device/meter.ts +177 -616
- package/src/device/meterplus.ts +175 -624
- package/src/device/motion.ts +147 -563
- package/src/device/plug.ts +81 -505
- package/src/device/robotvacuumcleaner.ts +139 -494
- package/src/device/waterdetector.ts +126 -506
- package/src/irdevice/airconditioner.ts +228 -353
- package/src/irdevice/airpurifier.ts +23 -282
- package/src/irdevice/camera.ts +18 -277
- package/src/irdevice/fan.ts +18 -275
- package/src/irdevice/irdevice.ts +518 -0
- package/src/irdevice/light.ts +18 -283
- package/src/irdevice/other.ts +394 -621
- package/src/irdevice/tv.ts +97 -344
- package/src/irdevice/vacuumcleaner.ts +46 -310
- package/src/irdevice/waterheater.ts +47 -315
- package/src/settings.ts +20 -3
- package/src/utils.ts +71 -0
package/src/device/curtain.ts
CHANGED
|
@@ -1,108 +1,53 @@
|
|
|
1
|
+
/* Copyright(C) 2021-2024, donavanbecker (https://github.com/donavanbecker). All rights reserved.
|
|
2
|
+
*
|
|
3
|
+
* curtain.ts: @switchbot/homebridge-switchbot.
|
|
4
|
+
*/
|
|
5
|
+
import { hostname } from 'os';
|
|
1
6
|
import { request } from 'undici';
|
|
2
|
-
import { sleep } from '../utils.js';
|
|
3
|
-
import { MqttClient } from 'mqtt';
|
|
4
7
|
import { interval, Subject } from 'rxjs';
|
|
5
|
-
import
|
|
8
|
+
import { deviceBase } from './device.js';
|
|
6
9
|
import { SwitchBotPlatform } from '../platform.js';
|
|
7
10
|
import { debounceTime, skipWhile, take, tap } from 'rxjs/operators';
|
|
8
|
-
import { Service, PlatformAccessory, CharacteristicValue, CharacteristicChange
|
|
9
|
-
import { device, devicesConfig, serviceData, deviceStatus, Devices
|
|
10
|
-
import { hostname } from 'os';
|
|
11
|
+
import { Service, PlatformAccessory, CharacteristicValue, CharacteristicChange } from 'homebridge';
|
|
12
|
+
import { device, devicesConfig, serviceData, deviceStatus, Devices } from '../settings.js';
|
|
11
13
|
|
|
12
|
-
export class Curtain {
|
|
13
|
-
public readonly api: API;
|
|
14
|
-
public readonly log: Logging;
|
|
15
|
-
public readonly config!: SwitchBotPlatformConfig;
|
|
16
|
-
protected readonly hap: HAP;
|
|
14
|
+
export class Curtain extends deviceBase {
|
|
17
15
|
// Services
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
OpenAPI_CurrentPosition: deviceStatus['slidePosition'];
|
|
37
|
-
OpenAPI_CurrentAmbientLightLevel: deviceStatus['brightness'];
|
|
38
|
-
|
|
39
|
-
// Others
|
|
40
|
-
Mode!: string;
|
|
41
|
-
setPositionMode?: string;
|
|
42
|
-
|
|
43
|
-
// BLE Status
|
|
44
|
-
BLE_InMotion: serviceData['inMotion'];
|
|
45
|
-
BLE_BatteryLevel: serviceData['battery'];
|
|
46
|
-
BLE_Calibration: serviceData['calibration'];
|
|
47
|
-
BLE_CurrentPosition: serviceData['position'];
|
|
48
|
-
BLE_CurrentAmbientLightLevel: serviceData['lightLevel'];
|
|
49
|
-
|
|
50
|
-
// BLE Others
|
|
51
|
-
BLE_IsConnected?: boolean;
|
|
52
|
-
spaceBetweenLevels!: number;
|
|
16
|
+
private WindowCovering!: {
|
|
17
|
+
Service: Service;
|
|
18
|
+
PositionState: CharacteristicValue;
|
|
19
|
+
TargetPosition: CharacteristicValue;
|
|
20
|
+
CurrentPosition: CharacteristicValue;
|
|
21
|
+
HoldPosition: CharacteristicValue;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
private Battery!: {
|
|
25
|
+
Service: Service;
|
|
26
|
+
BatteryLevel: CharacteristicValue;
|
|
27
|
+
StatusLowBattery: CharacteristicValue;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
private LightSensor?: {
|
|
31
|
+
Service: Service;
|
|
32
|
+
CurrentAmbientLightLevel?: CharacteristicValue;
|
|
33
|
+
};
|
|
53
34
|
|
|
54
35
|
// Target
|
|
55
36
|
setNewTarget!: boolean;
|
|
56
37
|
setNewTargetTimer!: NodeJS.Timeout;
|
|
57
38
|
|
|
58
|
-
//MQTT stuff
|
|
59
|
-
mqttClient: MqttClient | null = null;
|
|
60
|
-
|
|
61
|
-
// Config
|
|
62
|
-
updateRate!: number;
|
|
63
|
-
set_minLux!: number;
|
|
64
|
-
set_maxLux!: number;
|
|
65
|
-
set_minStep!: number;
|
|
66
|
-
setOpenMode!: string;
|
|
67
|
-
setCloseMode!: string;
|
|
68
|
-
scanDuration!: number;
|
|
69
|
-
deviceLogging!: string;
|
|
70
|
-
deviceRefreshRate!: number;
|
|
71
|
-
maxRetries!: number;
|
|
72
|
-
delayBetweenRetries!: number;
|
|
73
|
-
|
|
74
39
|
// Updates
|
|
75
40
|
curtainUpdateInProgress!: boolean;
|
|
76
41
|
doCurtainUpdate!: Subject<void>;
|
|
77
42
|
|
|
78
|
-
// Connection
|
|
79
|
-
private readonly OpenAPI: boolean;
|
|
80
|
-
private readonly BLE: boolean;
|
|
81
|
-
|
|
82
|
-
// EVE history service handler
|
|
83
|
-
historyService: any = null;
|
|
84
|
-
|
|
85
43
|
constructor(
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
44
|
+
readonly platform: SwitchBotPlatform,
|
|
45
|
+
accessory: PlatformAccessory,
|
|
46
|
+
device: device & devicesConfig,
|
|
89
47
|
) {
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
this.
|
|
93
|
-
this.hap = this.api.hap;
|
|
94
|
-
// Connection
|
|
95
|
-
this.BLE = this.device.connectionType === 'BLE' || this.device.connectionType === 'BLE/OpenAPI';
|
|
96
|
-
this.OpenAPI = this.device.connectionType === 'OpenAPI' || this.device.connectionType === 'BLE/OpenAPI';
|
|
97
|
-
// default placeholders
|
|
98
|
-
this.deviceLogs(device);
|
|
99
|
-
this.refreshRate(device);
|
|
100
|
-
this.scan(device);
|
|
101
|
-
this.setupMqtt(device);
|
|
102
|
-
this.deviceContext();
|
|
103
|
-
this.deviceRetry(device);
|
|
104
|
-
this.deviceConfig(device);
|
|
105
|
-
|
|
48
|
+
super(platform, accessory, device);
|
|
49
|
+
// default placeholder
|
|
50
|
+
this.history(device);
|
|
106
51
|
// this is subject we use to track when we need to POST changes to the SwitchBot API
|
|
107
52
|
this.doCurtainUpdate = new Subject();
|
|
108
53
|
this.curtainUpdateInProgress = false;
|
|
@@ -110,33 +55,45 @@ export class Curtain {
|
|
|
110
55
|
|
|
111
56
|
// Retrieve initial values and updateHomekit
|
|
112
57
|
this.refreshStatus();
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
.
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
58
|
+
// Initialize LightBulb property
|
|
59
|
+
this.WindowCovering = {
|
|
60
|
+
Service: this.accessory.addService(this.hap.Service.WindowCovering),
|
|
61
|
+
PositionState: this.accessory.context.PositionState || this.hap.Characteristic.PositionState.STOPPED,
|
|
62
|
+
TargetPosition: this.accessory.context.TargetPosition || 100,
|
|
63
|
+
CurrentPosition: this.accessory.context.CurrentPosition || 100,
|
|
64
|
+
HoldPosition: this.accessory.context.HoldPosition || false,
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
// Initialize Battery property
|
|
68
|
+
this.Battery = {
|
|
69
|
+
Service: this.accessory.addService(this.hap.Service.Battery),
|
|
70
|
+
BatteryLevel: this.accessory.context.BatteryLevel || 100,
|
|
71
|
+
StatusLowBattery: this.accessory.context.StatusLowBattery || this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL,
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
// Initialize LightSensor property
|
|
75
|
+
if (!this.device.curtain?.hide_lightsensor) {
|
|
76
|
+
this.LightSensor = {
|
|
77
|
+
Service: this.accessory.addService(this.hap.Service.LightSensor),
|
|
78
|
+
CurrentAmbientLightLevel: this.accessory.context.CurrentAmbientLightLevel || 0,
|
|
79
|
+
};
|
|
80
|
+
}
|
|
121
81
|
|
|
122
82
|
// get the WindowCovering service if it exists, otherwise create a new WindowCovering service
|
|
123
83
|
// you can create multiple services for each accessory
|
|
124
|
-
const
|
|
125
|
-
(this.
|
|
126
|
-
|| accessory.addService(this.hap.Service.WindowCovering)),
|
|
84
|
+
const WindowCoveringService = `${accessory.displayName} ${device.deviceType}`;
|
|
85
|
+
(this.WindowCovering.Service = accessory.getService(this.hap.Service.WindowCovering)
|
|
86
|
+
|| accessory.addService(this.hap.Service.WindowCovering)), WindowCoveringService;
|
|
127
87
|
|
|
128
|
-
this.
|
|
129
|
-
if (!this.windowCoveringService.testCharacteristic(this.hap.Characteristic.ConfiguredName)) {
|
|
130
|
-
this.windowCoveringService.addCharacteristic(this.hap.Characteristic.ConfiguredName, accessory.displayName);
|
|
131
|
-
}
|
|
88
|
+
this.WindowCovering.Service.setCharacteristic(this.hap.Characteristic.Name, accessory.displayName);
|
|
132
89
|
|
|
133
90
|
// each service must implement at-minimum the "required characteristics" for the given service type
|
|
134
91
|
// see https://developers.homebridge.io/#/service/WindowCovering
|
|
135
92
|
|
|
136
93
|
// create handlers for required characteristics
|
|
137
|
-
this.
|
|
94
|
+
this.WindowCovering.Service.setCharacteristic(this.hap.Characteristic.PositionState, this.WindowCovering.PositionState);
|
|
138
95
|
|
|
139
|
-
this.
|
|
96
|
+
this.WindowCovering.Service
|
|
140
97
|
.getCharacteristic(this.hap.Characteristic.CurrentPosition)
|
|
141
98
|
.setProps({
|
|
142
99
|
minStep: this.minStep(device),
|
|
@@ -145,10 +102,10 @@ export class Curtain {
|
|
|
145
102
|
validValueRanges: [0, 100],
|
|
146
103
|
})
|
|
147
104
|
.onGet(() => {
|
|
148
|
-
return this.CurrentPosition;
|
|
105
|
+
return this.WindowCovering.CurrentPosition;
|
|
149
106
|
});
|
|
150
107
|
|
|
151
|
-
this.
|
|
108
|
+
this.WindowCovering.Service
|
|
152
109
|
.getCharacteristic(this.hap.Characteristic.TargetPosition)
|
|
153
110
|
.setProps({
|
|
154
111
|
minStep: this.minStep(device),
|
|
@@ -158,38 +115,32 @@ export class Curtain {
|
|
|
158
115
|
})
|
|
159
116
|
.onSet(this.TargetPositionSet.bind(this));
|
|
160
117
|
|
|
161
|
-
this.
|
|
118
|
+
this.WindowCovering.Service
|
|
162
119
|
.getCharacteristic(this.hap.Characteristic.HoldPosition)
|
|
163
120
|
.onSet(this.HoldPositionSet.bind(this));
|
|
164
121
|
|
|
165
122
|
// Light Sensor Service
|
|
166
123
|
if (device.curtain?.hide_lightsensor) {
|
|
167
124
|
this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Removing Light Sensor Service`);
|
|
168
|
-
this.
|
|
169
|
-
accessory.removeService(this.
|
|
170
|
-
} else if (!this.
|
|
125
|
+
this.LightSensor!.Service = this.accessory.getService(this.hap.Service.LightSensor) as Service;
|
|
126
|
+
accessory.removeService(this.LightSensor!.Service);
|
|
127
|
+
} else if (!this.LightSensor?.Service) {
|
|
171
128
|
this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Add Light Sensor Service`);
|
|
172
|
-
const
|
|
173
|
-
(this.
|
|
174
|
-
|| this.accessory.addService(this.hap.Service.LightSensor)),
|
|
129
|
+
const LightSensorService = `${accessory.displayName} Light Sensor`;
|
|
130
|
+
(this.LightSensor!.Service = this.accessory.getService(this.hap.Service.LightSensor)
|
|
131
|
+
|| this.accessory.addService(this.hap.Service.LightSensor)), LightSensorService;
|
|
175
132
|
|
|
176
|
-
this.
|
|
177
|
-
if (!this.lightSensorService?.testCharacteristic(this.hap.Characteristic.ConfiguredName)) {
|
|
178
|
-
this.lightSensorService.addCharacteristic(this.hap.Characteristic.ConfiguredName, `${accessory.displayName} Light Sensor`);
|
|
179
|
-
}
|
|
133
|
+
this.LightSensor!.Service.setCharacteristic(this.hap.Characteristic.Name, LightSensorService);
|
|
180
134
|
} else {
|
|
181
135
|
this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Light Sensor Service Not Added`);
|
|
182
136
|
}
|
|
183
137
|
|
|
184
138
|
// Battery Service
|
|
185
139
|
const batteryService = `${accessory.displayName} Battery`;
|
|
186
|
-
(this.
|
|
140
|
+
(this.Battery.Service = this.accessory.getService(this.hap.Service.Battery)
|
|
187
141
|
|| accessory.addService(this.hap.Service.Battery)), batteryService;
|
|
188
142
|
|
|
189
|
-
this.
|
|
190
|
-
if (!this.batteryService.testCharacteristic(this.hap.Characteristic.ConfiguredName)) {
|
|
191
|
-
this.batteryService.addCharacteristic(this.hap.Characteristic.ConfiguredName, `${accessory.displayName} Battery`);
|
|
192
|
-
}
|
|
143
|
+
this.Battery.Service.setCharacteristic(this.hap.Characteristic.Name, `${accessory.displayName} Battery`);
|
|
193
144
|
|
|
194
145
|
// Update Homekit
|
|
195
146
|
this.updateHomeKitCharacteristics();
|
|
@@ -208,13 +159,12 @@ export class Curtain {
|
|
|
208
159
|
try {
|
|
209
160
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} received Webhook: ${JSON.stringify(context)}`);
|
|
210
161
|
const { slidePosition, battery } = context;
|
|
211
|
-
const { CurrentPosition, BatteryLevel } = this;
|
|
212
162
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} ` +
|
|
213
163
|
'(slidePosition, battery) = ' +
|
|
214
164
|
`Webhook:(${slidePosition}, ${battery}), ` +
|
|
215
|
-
`current:(${CurrentPosition}, ${BatteryLevel})`);
|
|
216
|
-
this.CurrentPosition = slidePosition;
|
|
217
|
-
this.BatteryLevel = battery;
|
|
165
|
+
`current:(${this.WindowCovering.CurrentPosition}, ${this.Battery.BatteryLevel})`);
|
|
166
|
+
this.WindowCovering.CurrentPosition = slidePosition;
|
|
167
|
+
this.Battery.BatteryLevel = battery;
|
|
218
168
|
this.updateHomeKitCharacteristics();
|
|
219
169
|
} catch (e: any) {
|
|
220
170
|
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} `
|
|
@@ -224,13 +174,14 @@ export class Curtain {
|
|
|
224
174
|
}
|
|
225
175
|
|
|
226
176
|
// update slide progress
|
|
227
|
-
interval(this.
|
|
177
|
+
interval(this.deviceUpdateRate * 1000)
|
|
228
178
|
//.pipe(skipWhile(() => this.curtainUpdateInProgress))
|
|
229
179
|
.subscribe(async () => {
|
|
230
|
-
if (this.PositionState === this.hap.Characteristic.PositionState.STOPPED) {
|
|
180
|
+
if (this.WindowCovering.PositionState === this.hap.Characteristic.PositionState.STOPPED) {
|
|
231
181
|
return;
|
|
232
182
|
}
|
|
233
|
-
this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Refresh Status When Moving
|
|
183
|
+
this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Refresh Status When Moving,`
|
|
184
|
+
+ ` PositionState: ${this.WindowCovering.PositionState}`);
|
|
234
185
|
await this.refreshStatus();
|
|
235
186
|
});
|
|
236
187
|
|
|
@@ -260,6 +211,16 @@ export class Curtain {
|
|
|
260
211
|
this.setupHistoryService(device);
|
|
261
212
|
}
|
|
262
213
|
|
|
214
|
+
private history(device: device & devicesConfig) {
|
|
215
|
+
if (device.history === true) {
|
|
216
|
+
// initialize when this accessory is newly created.
|
|
217
|
+
this.accessory.context.lastActivation = this.accessory.context.lastActivation ?? 0;
|
|
218
|
+
} else {
|
|
219
|
+
// removes cached values if history is turned off
|
|
220
|
+
delete this.accessory.context.lastActivation;
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
263
224
|
/*
|
|
264
225
|
* Setup EVE history features for curtain devices.
|
|
265
226
|
*/
|
|
@@ -307,7 +268,7 @@ export class Curtain {
|
|
|
307
268
|
}
|
|
308
269
|
|
|
309
270
|
async updateHistory(): Promise<void> {
|
|
310
|
-
const motion = Number(this.CurrentPosition) > 0 ? 1 : 0;
|
|
271
|
+
const motion = Number(this.WindowCovering.CurrentPosition) > 0 ? 1 : 0;
|
|
311
272
|
this.historyService.addEntry({
|
|
312
273
|
time: Math.round(new Date().valueOf() / 1000),
|
|
313
274
|
motion: motion,
|
|
@@ -320,198 +281,189 @@ export class Curtain {
|
|
|
320
281
|
);
|
|
321
282
|
}
|
|
322
283
|
|
|
323
|
-
|
|
324
|
-
* Parse the device status from the SwitchBot api
|
|
325
|
-
*/
|
|
326
|
-
async parseStatus(): Promise<void> {
|
|
327
|
-
if (!this.device.enableCloudService && this.OpenAPI) {
|
|
328
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} parseStatus enableCloudService: ${this.device.enableCloudService}`);
|
|
329
|
-
} else if (this.BLE) {
|
|
330
|
-
await this.BLEparseStatus();
|
|
331
|
-
} else if (this.OpenAPI && this.platform.config.credentials?.token) {
|
|
332
|
-
await this.openAPIparseStatus();
|
|
333
|
-
} else {
|
|
334
|
-
await this.offlineOff();
|
|
335
|
-
this.debugWarnLog(
|
|
336
|
-
`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:` + ` ${this.device.connectionType}, parseStatus will not happen.`,
|
|
337
|
-
);
|
|
338
|
-
}
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
async BLEparseStatus(): Promise<void> {
|
|
284
|
+
async BLEparseStatus(serviceData: serviceData): Promise<void> {
|
|
342
285
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLEparseStatus`);
|
|
343
286
|
// CurrentPosition
|
|
344
|
-
this.CurrentPosition = 100 - Number(
|
|
287
|
+
this.WindowCovering.CurrentPosition = 100 - Number(serviceData.position);
|
|
345
288
|
await this.setMinMax();
|
|
346
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} CurrentPosition ${this.CurrentPosition}`);
|
|
289
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} CurrentPosition ${this.WindowCovering.CurrentPosition}`);
|
|
347
290
|
if (this.setNewTarget) {
|
|
348
291
|
this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Checking Status ...`);
|
|
349
292
|
await this.setMinMax();
|
|
350
|
-
if (Number(this.TargetPosition) > this.CurrentPosition) {
|
|
351
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Closing, CurrentPosition: ${this.CurrentPosition}`);
|
|
352
|
-
this.PositionState = this.hap.Characteristic.PositionState.INCREASING;
|
|
353
|
-
this.
|
|
354
|
-
this.debugLog(`${this.device.deviceType}: ${this.CurrentPosition} INCREASING
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
this.
|
|
358
|
-
this.
|
|
359
|
-
this.
|
|
293
|
+
if (Number(this.WindowCovering.TargetPosition) > this.WindowCovering.CurrentPosition) {
|
|
294
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Closing, CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
|
|
295
|
+
this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.INCREASING;
|
|
296
|
+
this.WindowCovering.Service.getCharacteristic(this.hap.Characteristic.PositionState).updateValue(this.WindowCovering.PositionState);
|
|
297
|
+
this.debugLog(`${this.device.deviceType}: ${this.WindowCovering.CurrentPosition} INCREASING`
|
|
298
|
+
+ ` PositionState: ${this.WindowCovering.PositionState}`);
|
|
299
|
+
} else if (Number(this.WindowCovering.TargetPosition) < this.WindowCovering.CurrentPosition) {
|
|
300
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Opening, CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
|
|
301
|
+
this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.DECREASING;
|
|
302
|
+
this.WindowCovering.Service.getCharacteristic(this.hap.Characteristic.PositionState).updateValue(this.WindowCovering.PositionState);
|
|
303
|
+
this.debugLog(`${this.device.deviceType}: ${this.WindowCovering.CurrentPosition} DECREASING`
|
|
304
|
+
+ ` PositionState: ${this.WindowCovering.PositionState}`);
|
|
360
305
|
} else {
|
|
361
|
-
this.debugLog(`${this.device.deviceType}: ${this.CurrentPosition} Standby
|
|
362
|
-
|
|
363
|
-
this.
|
|
364
|
-
this.
|
|
306
|
+
this.debugLog(`${this.device.deviceType}: ${this.WindowCovering.CurrentPosition} Standby,`
|
|
307
|
+
+ ` CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
|
|
308
|
+
this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.STOPPED;
|
|
309
|
+
this.WindowCovering.Service.getCharacteristic(this.hap.Characteristic.PositionState).updateValue(this.WindowCovering.PositionState);
|
|
310
|
+
this.debugLog(`${this.device.deviceType}: ${this.WindowCovering.CurrentPosition} STOPPED`
|
|
311
|
+
+ ` PositionState: ${this.WindowCovering.PositionState}`);
|
|
365
312
|
}
|
|
366
313
|
} else {
|
|
367
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Standby, CurrentPosition: ${this.CurrentPosition}`);
|
|
368
|
-
this.TargetPosition = this.CurrentPosition;
|
|
369
|
-
this.PositionState = this.hap.Characteristic.PositionState.STOPPED;
|
|
314
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Standby, CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
|
|
315
|
+
this.WindowCovering.TargetPosition = this.WindowCovering.CurrentPosition;
|
|
316
|
+
this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.STOPPED;
|
|
370
317
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Stopped`);
|
|
371
318
|
}
|
|
372
319
|
this.debugLog(
|
|
373
|
-
`${this.device.deviceType}: ${this.accessory.displayName} CurrentPosition: ${this.CurrentPosition},` +
|
|
374
|
-
` TargetPosition: ${this.TargetPosition}, PositionState: ${this.PositionState},`,
|
|
320
|
+
`${this.device.deviceType}: ${this.accessory.displayName} CurrentPosition: ${this.WindowCovering.CurrentPosition},` +
|
|
321
|
+
` TargetPosition: ${this.WindowCovering.TargetPosition}, PositionState: ${this.WindowCovering.PositionState},`,
|
|
375
322
|
);
|
|
376
323
|
|
|
377
324
|
if (!this.device.curtain?.hide_lightsensor) {
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
325
|
+
const set_minLux = await this.minLux();
|
|
326
|
+
const set_maxLux = await this.maxLux();
|
|
327
|
+
const spaceBetweenLevels = 9;
|
|
381
328
|
|
|
382
329
|
// Brightness
|
|
383
|
-
switch (
|
|
330
|
+
switch (serviceData.lightLevel) {
|
|
384
331
|
case 1:
|
|
385
|
-
this.CurrentAmbientLightLevel =
|
|
386
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${
|
|
332
|
+
this.LightSensor!.CurrentAmbientLightLevel = set_minLux;
|
|
333
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${serviceData.lightLevel}`);
|
|
387
334
|
break;
|
|
388
335
|
case 2:
|
|
389
|
-
this.CurrentAmbientLightLevel = (
|
|
336
|
+
this.LightSensor!.CurrentAmbientLightLevel = (set_maxLux - set_minLux) / spaceBetweenLevels;
|
|
390
337
|
this.debugLog(
|
|
391
|
-
`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${
|
|
392
|
-
` Calculation: ${(
|
|
338
|
+
`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${serviceData.lightLevel},` +
|
|
339
|
+
` Calculation: ${(set_maxLux - set_minLux) / spaceBetweenLevels}`,
|
|
393
340
|
);
|
|
394
341
|
break;
|
|
395
342
|
case 3:
|
|
396
|
-
this.CurrentAmbientLightLevel = ((
|
|
397
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${
|
|
343
|
+
this.LightSensor!.CurrentAmbientLightLevel = ((set_maxLux - set_minLux) / spaceBetweenLevels) * 2;
|
|
344
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${serviceData.lightLevel}`);
|
|
398
345
|
break;
|
|
399
346
|
case 4:
|
|
400
|
-
this.CurrentAmbientLightLevel = ((
|
|
401
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${
|
|
347
|
+
this.LightSensor!.CurrentAmbientLightLevel = ((set_maxLux - set_minLux) / spaceBetweenLevels) * 3;
|
|
348
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${serviceData.lightLevel}`);
|
|
402
349
|
break;
|
|
403
350
|
case 5:
|
|
404
|
-
this.CurrentAmbientLightLevel = ((
|
|
405
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${
|
|
351
|
+
this.LightSensor!.CurrentAmbientLightLevel = ((set_maxLux - set_minLux) / spaceBetweenLevels) * 4;
|
|
352
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${serviceData.lightLevel}`);
|
|
406
353
|
break;
|
|
407
354
|
case 6:
|
|
408
|
-
this.CurrentAmbientLightLevel = ((
|
|
409
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${
|
|
355
|
+
this.LightSensor!.CurrentAmbientLightLevel = ((set_maxLux - set_minLux) / spaceBetweenLevels) * 5;
|
|
356
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${serviceData.lightLevel}`);
|
|
410
357
|
break;
|
|
411
358
|
case 7:
|
|
412
|
-
this.CurrentAmbientLightLevel = ((
|
|
413
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${
|
|
359
|
+
this.LightSensor!.CurrentAmbientLightLevel = ((set_maxLux - set_minLux) / spaceBetweenLevels) * 6;
|
|
360
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${serviceData.lightLevel}`);
|
|
414
361
|
break;
|
|
415
362
|
case 8:
|
|
416
|
-
this.CurrentAmbientLightLevel = ((
|
|
417
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${
|
|
363
|
+
this.LightSensor!.CurrentAmbientLightLevel = ((set_maxLux - set_minLux) / spaceBetweenLevels) * 7;
|
|
364
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${serviceData.lightLevel}`);
|
|
418
365
|
break;
|
|
419
366
|
case 9:
|
|
420
|
-
this.CurrentAmbientLightLevel = ((
|
|
421
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${
|
|
367
|
+
this.LightSensor!.CurrentAmbientLightLevel = ((set_maxLux - set_minLux) / spaceBetweenLevels) * 8;
|
|
368
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${serviceData.lightLevel}`);
|
|
422
369
|
break;
|
|
423
370
|
case 10:
|
|
424
371
|
default:
|
|
425
|
-
this.CurrentAmbientLightLevel =
|
|
372
|
+
this.LightSensor!.CurrentAmbientLightLevel = set_maxLux;
|
|
426
373
|
this.debugLog();
|
|
427
374
|
}
|
|
428
375
|
this.debugLog(
|
|
429
|
-
`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${
|
|
430
|
-
` CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`,
|
|
376
|
+
`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${serviceData.lightLevel},` +
|
|
377
|
+
` CurrentAmbientLightLevel: ${this.LightSensor!.CurrentAmbientLightLevel}`,
|
|
431
378
|
);
|
|
432
379
|
}
|
|
433
380
|
// Battery
|
|
434
|
-
this.BatteryLevel = Number(
|
|
435
|
-
if (this.BatteryLevel < 10) {
|
|
436
|
-
this.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW;
|
|
381
|
+
this.Battery.BatteryLevel = Number(serviceData.battery);
|
|
382
|
+
if (this.Battery.BatteryLevel < 10) {
|
|
383
|
+
this.Battery.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW;
|
|
437
384
|
} else {
|
|
438
|
-
this.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
|
|
385
|
+
this.Battery.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
|
|
439
386
|
}
|
|
440
387
|
this.debugLog(
|
|
441
|
-
`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.BatteryLevel},`
|
|
388
|
+
`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.Battery.BatteryLevel},`
|
|
389
|
+
+ ` StatusLowBattery: ${this.Battery.StatusLowBattery}`,
|
|
442
390
|
);
|
|
443
391
|
}
|
|
444
392
|
|
|
445
|
-
async openAPIparseStatus(): Promise<void> {
|
|
393
|
+
async openAPIparseStatus(deviceStatus: deviceStatus): Promise<void> {
|
|
446
394
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIparseStatus`);
|
|
447
395
|
// CurrentPosition
|
|
448
|
-
this.CurrentPosition = 100 - Number(
|
|
396
|
+
this.WindowCovering.CurrentPosition = 100 - Number(deviceStatus.body.slidePosition);
|
|
449
397
|
await this.setMinMax();
|
|
450
|
-
this.debugLog(`Curtain ${this.accessory.displayName} CurrentPosition: ${this.CurrentPosition}`);
|
|
398
|
+
this.debugLog(`Curtain ${this.accessory.displayName} CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
|
|
451
399
|
if (this.setNewTarget) {
|
|
452
400
|
this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Checking Status ...`);
|
|
453
401
|
}
|
|
454
402
|
|
|
455
|
-
if (this.setNewTarget &&
|
|
403
|
+
if (this.setNewTarget && deviceStatus.body.moving) {
|
|
456
404
|
await this.setMinMax();
|
|
457
|
-
if (Number(this.TargetPosition) > this.CurrentPosition) {
|
|
458
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Closing, CurrentPosition: ${this.CurrentPosition} `);
|
|
459
|
-
this.PositionState = this.hap.Characteristic.PositionState.INCREASING;
|
|
460
|
-
this.
|
|
461
|
-
this.debugLog(`${this.device.deviceType}: ${this.CurrentPosition} INCREASING
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
this.
|
|
465
|
-
this.
|
|
466
|
-
this.
|
|
405
|
+
if (Number(this.WindowCovering.TargetPosition) > this.WindowCovering.CurrentPosition) {
|
|
406
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Closing, CurrentPosition: ${this.WindowCovering.CurrentPosition} `);
|
|
407
|
+
this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.INCREASING;
|
|
408
|
+
this.WindowCovering.Service.getCharacteristic(this.hap.Characteristic.PositionState).updateValue(this.WindowCovering.PositionState);
|
|
409
|
+
this.debugLog(`${this.device.deviceType}: ${this.WindowCovering.CurrentPosition} INCREASING`
|
|
410
|
+
+ ` PositionState: ${this.WindowCovering.PositionState}`);
|
|
411
|
+
} else if (Number(this.WindowCovering.TargetPosition) < this.WindowCovering.CurrentPosition) {
|
|
412
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Opening, CurrentPosition: ${this.WindowCovering.CurrentPosition} `);
|
|
413
|
+
this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.DECREASING;
|
|
414
|
+
this.WindowCovering.Service.getCharacteristic(this.hap.Characteristic.PositionState).updateValue(this.WindowCovering.PositionState);
|
|
415
|
+
this.debugLog(`${this.device.deviceType}: ${this.WindowCovering.CurrentPosition} DECREASING`
|
|
416
|
+
+ ` PositionState: ${this.WindowCovering.PositionState}`);
|
|
467
417
|
} else {
|
|
468
|
-
this.debugLog(`${this.device.deviceType}: ${this.CurrentPosition} Standby
|
|
469
|
-
|
|
470
|
-
this.
|
|
471
|
-
this.
|
|
418
|
+
this.debugLog(`${this.device.deviceType}: ${this.WindowCovering.CurrentPosition} Standby,`
|
|
419
|
+
+ ` CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
|
|
420
|
+
this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.STOPPED;
|
|
421
|
+
this.WindowCovering.Service.getCharacteristic(this.hap.Characteristic.PositionState).updateValue(this.WindowCovering.PositionState);
|
|
422
|
+
this.debugLog(`${this.device.deviceType}: ${this.WindowCovering.CurrentPosition} STOPPED`
|
|
423
|
+
+ ` PositionState: ${this.WindowCovering.PositionState}`);
|
|
472
424
|
}
|
|
473
425
|
} else {
|
|
474
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Standby, CurrentPosition: ${this.CurrentPosition}`);
|
|
475
|
-
this.TargetPosition = this.CurrentPosition;
|
|
476
|
-
this.PositionState = this.hap.Characteristic.PositionState.STOPPED;
|
|
426
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Standby, CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
|
|
427
|
+
this.WindowCovering.TargetPosition = this.WindowCovering.CurrentPosition;
|
|
428
|
+
this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.STOPPED;
|
|
477
429
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Stopped`);
|
|
478
430
|
}
|
|
479
431
|
this.debugLog(
|
|
480
|
-
`${this.device.deviceType}: ${this.accessory.displayName} CurrentPosition: ${this.CurrentPosition},` +
|
|
481
|
-
` TargetPosition: ${this.TargetPosition}, PositionState: ${this.PositionState},`,
|
|
432
|
+
`${this.device.deviceType}: ${this.accessory.displayName} CurrentPosition: ${this.WindowCovering.CurrentPosition},` +
|
|
433
|
+
` TargetPosition: ${this.WindowCovering.TargetPosition}, PositionState: ${this.WindowCovering.PositionState},`,
|
|
482
434
|
);
|
|
483
435
|
|
|
484
436
|
// Brightness
|
|
485
437
|
if (!this.device.curtain?.hide_lightsensor) {
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
switch (
|
|
438
|
+
const set_minLux = await this.minLux();
|
|
439
|
+
const set_maxLux = await this.maxLux();
|
|
440
|
+
switch (deviceStatus.body.brightness) {
|
|
489
441
|
case 'dim':
|
|
490
|
-
this.CurrentAmbientLightLevel =
|
|
442
|
+
this.LightSensor!.CurrentAmbientLightLevel = set_minLux;
|
|
491
443
|
break;
|
|
492
444
|
case 'bright':
|
|
493
445
|
default:
|
|
494
|
-
this.CurrentAmbientLightLevel =
|
|
446
|
+
this.LightSensor!.CurrentAmbientLightLevel = set_maxLux;
|
|
495
447
|
}
|
|
496
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}
|
|
448
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}`
|
|
449
|
+
+ ` CurrentAmbientLightLevel: ${this.LightSensor!.CurrentAmbientLightLevel}`);
|
|
497
450
|
}
|
|
498
451
|
|
|
499
452
|
// BatteryLevel
|
|
500
|
-
this.BatteryLevel = Number(
|
|
501
|
-
if (this.BatteryLevel < 10) {
|
|
502
|
-
this.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW;
|
|
453
|
+
this.Battery.BatteryLevel = Number(deviceStatus.body.battery);
|
|
454
|
+
if (this.Battery.BatteryLevel < 10) {
|
|
455
|
+
this.Battery.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW;
|
|
503
456
|
} else {
|
|
504
|
-
this.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
|
|
457
|
+
this.Battery.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
|
|
505
458
|
}
|
|
506
|
-
if (Number.isNaN(this.BatteryLevel)) {
|
|
507
|
-
this.BatteryLevel = 100;
|
|
459
|
+
if (Number.isNaN(this.Battery.BatteryLevel)) {
|
|
460
|
+
this.Battery.BatteryLevel = 100;
|
|
508
461
|
}
|
|
509
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.BatteryLevel},`
|
|
510
|
-
+ ` StatusLowBattery: ${this.StatusLowBattery}`);
|
|
462
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.Battery.BatteryLevel},`
|
|
463
|
+
+ ` StatusLowBattery: ${this.Battery.StatusLowBattery}`);
|
|
511
464
|
|
|
512
465
|
// FirmwareRevision
|
|
513
|
-
this.FirmwareRevision =
|
|
514
|
-
this.accessory.context.FirmwareRevision = this.FirmwareRevision;
|
|
466
|
+
this.accessory.context.FirmwareRevision = deviceStatus.body.version;
|
|
515
467
|
}
|
|
516
468
|
|
|
517
469
|
async refreshStatus(): Promise<void> {
|
|
@@ -541,106 +493,37 @@ export class Curtain {
|
|
|
541
493
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
|
|
542
494
|
this.getCustomBLEAddress(switchbot);
|
|
543
495
|
// Start to monitor advertisement packets
|
|
544
|
-
let model: string;
|
|
545
|
-
switch (this.device.configDeviceType) {
|
|
546
|
-
case 'Curtain3':
|
|
547
|
-
model = '{';
|
|
548
|
-
break;
|
|
549
|
-
default:
|
|
550
|
-
model = 'c';
|
|
551
|
-
}
|
|
552
496
|
(async () => {
|
|
553
497
|
// Start to monitor advertisement packets
|
|
554
|
-
await switchbot.startScan({
|
|
555
|
-
model: model,
|
|
556
|
-
id: this.device.bleMac,
|
|
557
|
-
});
|
|
498
|
+
await switchbot.startScan({ model: this.device.bleModel, id: this.device.bleMac });
|
|
558
499
|
// Set an event handler
|
|
559
500
|
switchbot.onadvertisement = (ad: any) => {
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
501
|
+
if (this.device.bleMac === ad.address && ad.model === this.device.bleModel) {
|
|
502
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} ${JSON.stringify(ad, null, ' ')}`);
|
|
503
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} address: ${ad.address}, model: ${ad.model}`);
|
|
563
504
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${JSON.stringify(ad.serviceData)}`);
|
|
564
|
-
this.BLE_Calibration = ad.serviceData.calibration;
|
|
565
|
-
this.BLE_BatteryLevel = ad.serviceData.battery;
|
|
566
|
-
this.BLE_InMotion = ad.serviceData.inMotion;
|
|
567
|
-
this.BLE_CurrentPosition = ad.serviceData.position;
|
|
568
|
-
this.BLE_CurrentAmbientLightLevel = ad.serviceData.lightLevel;
|
|
569
505
|
} else {
|
|
570
506
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${JSON.stringify(ad.serviceData)}`);
|
|
571
507
|
}
|
|
572
508
|
};
|
|
573
|
-
// Wait
|
|
509
|
+
// Wait 10 seconds
|
|
574
510
|
await switchbot.wait(this.scanDuration * 1000);
|
|
575
511
|
// Stop to monitor
|
|
576
512
|
await switchbot.stopScan();
|
|
577
513
|
// Update HomeKit
|
|
578
|
-
await this.BLEparseStatus();
|
|
514
|
+
await this.BLEparseStatus(switchbot.onadvertisement.serviceData);
|
|
579
515
|
await this.updateHomeKitCharacteristics();
|
|
580
516
|
})();
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
/*if (switchbot !== false) {
|
|
584
|
-
switchbot
|
|
585
|
-
.startScan({
|
|
586
|
-
model: model,
|
|
587
|
-
id: this.device.bleMac,
|
|
588
|
-
})
|
|
589
|
-
.then(async () => {
|
|
590
|
-
// Set an event handler
|
|
591
|
-
switchbot.onadvertisement = async (ad: ad) => {
|
|
592
|
-
this.debugLog(
|
|
593
|
-
`${this.device.deviceType}: ${this.accessory.displayName} Config BLE Address: ${this.device.bleMac},` +
|
|
594
|
-
` BLE Address Found: ${ad.address}`,
|
|
595
|
-
);
|
|
596
|
-
this.BLE_Calibration = ad.serviceData.calibration;
|
|
597
|
-
this.BLE_BatteryLevel = ad.serviceData.battery;
|
|
598
|
-
this.BLE_InMotion = ad.serviceData.inMotion;
|
|
599
|
-
this.BLE_CurrentPosition = ad.serviceData.position;
|
|
600
|
-
this.BLE_CurrentAmbientLightLevel = ad.serviceData.lightLevel;
|
|
601
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${JSON.stringify(ad.serviceData)}`);
|
|
602
|
-
this.debugLog(
|
|
603
|
-
`${this.device.deviceType}: ${this.accessory.displayName} calibration: ${ad.serviceData.calibration}, ` +
|
|
604
|
-
`position: ${ad.serviceData.position}, lightLevel: ${ad.serviceData.lightLevel}, battery: ${ad.serviceData.battery}, ` +
|
|
605
|
-
`inMotion: ${ad.serviceData.inMotion}`,
|
|
606
|
-
);
|
|
607
|
-
|
|
608
|
-
if (ad.serviceData) {
|
|
609
|
-
this.BLE_IsConnected = true;
|
|
610
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} connected: ${this.BLE_IsConnected}`);
|
|
611
|
-
await this.stopScanning(switchbot);
|
|
612
|
-
} else {
|
|
613
|
-
this.BLE_IsConnected = false;
|
|
614
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} connected: ${this.BLE_IsConnected}`);
|
|
615
|
-
}
|
|
616
|
-
};
|
|
617
|
-
// Wait
|
|
618
|
-
return await sleep(this.scanDuration * 1000);
|
|
619
|
-
})
|
|
620
|
-
.then(async () => {
|
|
621
|
-
// Stop to monitor
|
|
622
|
-
await this.stopScanning(switchbot);
|
|
623
|
-
})
|
|
624
|
-
.catch(async (e: any) => {
|
|
625
|
-
this.apiError(e);
|
|
626
|
-
this.errorLog(
|
|
627
|
-
`${this.device.deviceType}: ${this.accessory.displayName} failed BLERefreshStatus with ${this.device.connectionType}` +
|
|
628
|
-
` Connection, Error Message: ${JSON.stringify(e.message)}`,
|
|
629
|
-
);
|
|
630
|
-
await this.BLERefreshConnection(switchbot);
|
|
631
|
-
});
|
|
632
|
-
} else {
|
|
517
|
+
if (switchbot === undefined) {
|
|
633
518
|
await this.BLERefreshConnection(switchbot);
|
|
634
|
-
}
|
|
519
|
+
}
|
|
635
520
|
}
|
|
636
521
|
|
|
637
522
|
async openAPIRefreshStatus(): Promise<void> {
|
|
638
523
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus`);
|
|
639
524
|
try {
|
|
640
|
-
const { body, statusCode } = await this.platform.retryRequest(this.
|
|
641
|
-
`${Devices}/${this.device.deviceId}/status`, {
|
|
642
|
-
headers: this.platform.generateHeaders(),
|
|
643
|
-
});
|
|
525
|
+
const { body, statusCode } = await this.platform.retryRequest(this.deviceMaxRetries, this.deviceDelayBetweenRetries,
|
|
526
|
+
`${Devices}/${this.device.deviceId}/status`, { headers: this.platform.generateHeaders() });
|
|
644
527
|
this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} statusCode: ${statusCode}`);
|
|
645
528
|
const deviceStatus: any = await body.json();
|
|
646
529
|
this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus: ${JSON.stringify(deviceStatus)}`);
|
|
@@ -648,12 +531,7 @@ export class Curtain {
|
|
|
648
531
|
if ((statusCode === 200 || statusCode === 100) && (deviceStatus.statusCode === 200 || deviceStatus.statusCode === 100)) {
|
|
649
532
|
this.debugErrorLog(`${this.device.deviceType}: ${this.accessory.displayName} `
|
|
650
533
|
+ `statusCode: ${statusCode} & deviceStatus StatusCode: ${deviceStatus.statusCode}`);
|
|
651
|
-
this.
|
|
652
|
-
this.OpenAPI_InMotion = deviceStatus.body.moving;
|
|
653
|
-
this.OpenAPI_CurrentAmbientLightLevel = deviceStatus.body.brightness;
|
|
654
|
-
this.OpenAPI_BatteryLevel = deviceStatus.body.battery;
|
|
655
|
-
this.OpenAPI_FirmwareRevision = deviceStatus.body.version;
|
|
656
|
-
this.openAPIparseStatus();
|
|
534
|
+
this.openAPIparseStatus(deviceStatus);
|
|
657
535
|
this.updateHomeKitCharacteristics();
|
|
658
536
|
} else {
|
|
659
537
|
this.statusCode(statusCode);
|
|
@@ -692,7 +570,7 @@ export class Curtain {
|
|
|
692
570
|
|
|
693
571
|
async BLEpushChanges(): Promise<void> {
|
|
694
572
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLEpushChanges`);
|
|
695
|
-
if (this.TargetPosition !== this.CurrentPosition) {
|
|
573
|
+
if (this.WindowCovering.TargetPosition !== this.WindowCovering.CurrentPosition) {
|
|
696
574
|
const switchbot = await this.platform.connectBLE();
|
|
697
575
|
// Convert to BLE Address
|
|
698
576
|
this.device.bleMac = this.device
|
|
@@ -700,29 +578,29 @@ export class Curtain {
|
|
|
700
578
|
.join(':')
|
|
701
579
|
.toLowerCase();
|
|
702
580
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
|
|
703
|
-
this.
|
|
704
|
-
const adjustedMode =
|
|
705
|
-
this.debugLog(`${this.accessory.displayName} Mode: ${
|
|
581
|
+
const { setPositionMode, Mode }: { setPositionMode: number; Mode: string; } = await this.setPerformance();
|
|
582
|
+
const adjustedMode = setPositionMode === 1 ? 0x01 : 0xff;
|
|
583
|
+
this.debugLog(`${this.accessory.displayName} Mode: ${Mode}`);
|
|
706
584
|
if (switchbot !== false) {
|
|
707
585
|
try {
|
|
708
586
|
const device_list = await switchbot.discover({ model: 'c', quick: true, id: this.device.bleMac });
|
|
709
|
-
this.infoLog(`${this.accessory.displayName} Target Position: ${this.TargetPosition}`);
|
|
587
|
+
this.infoLog(`${this.accessory.displayName} Target Position: ${this.WindowCovering.TargetPosition}`);
|
|
710
588
|
|
|
711
|
-
await this.
|
|
712
|
-
max: this.
|
|
589
|
+
await this.retryBLE({
|
|
590
|
+
max: await this.maxRetryBLE(),
|
|
713
591
|
fn: async () => {
|
|
714
|
-
await device_list[0].runToPos(100 - Number(this.TargetPosition), adjustedMode);
|
|
592
|
+
await device_list[0].runToPos(100 - Number(this.WindowCovering.TargetPosition), adjustedMode);
|
|
715
593
|
},
|
|
716
594
|
});
|
|
717
595
|
|
|
718
596
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Done.`);
|
|
719
597
|
this.successLog(`${this.device.deviceType}: ${this.accessory.displayName} `
|
|
720
|
-
|
|
598
|
+
+ `TargetPosition: ${this.WindowCovering.TargetPosition} sent over BLE, sent successfully`);
|
|
721
599
|
} catch (e) {
|
|
722
600
|
this.apiError(e);
|
|
723
601
|
this.errorLog(
|
|
724
602
|
`${this.device.deviceType}: ${this.accessory.displayName} failed BLEpushChanges with ${this.device.connectionType}` +
|
|
725
|
-
|
|
603
|
+
` Connection, Error Message: ${JSON.stringify((e as Error).message)}`,
|
|
726
604
|
);
|
|
727
605
|
await this.BLEPushConnection();
|
|
728
606
|
throw new Error('Connection error');
|
|
@@ -734,54 +612,23 @@ export class Curtain {
|
|
|
734
612
|
} else {
|
|
735
613
|
this.debugLog(
|
|
736
614
|
`${this.device.deviceType}: ${this.accessory.displayName} No BLEpushChanges, CurrentPosition & TargetPosition Are the Same.` +
|
|
737
|
-
` CurrentPosition: ${this.CurrentPosition}, TargetPosition ${this.TargetPosition}`,
|
|
615
|
+
` CurrentPosition: ${this.WindowCovering.CurrentPosition}, TargetPosition ${this.WindowCovering.TargetPosition}`,
|
|
738
616
|
);
|
|
739
617
|
}
|
|
740
618
|
}
|
|
741
619
|
|
|
742
|
-
async retry({ max, fn }: { max: number; fn: { (): any; (): Promise<any> } }): Promise<null> {
|
|
743
|
-
return fn().catch(async (e: any) => {
|
|
744
|
-
if (max === 0) {
|
|
745
|
-
throw e;
|
|
746
|
-
}
|
|
747
|
-
this.infoLog(e);
|
|
748
|
-
this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Retrying`);
|
|
749
|
-
await sleep(1000);
|
|
750
|
-
return this.retry({ max: max - 1, fn });
|
|
751
|
-
});
|
|
752
|
-
}
|
|
753
|
-
|
|
754
|
-
maxRetry(): number {
|
|
755
|
-
if (this.device.maxRetry) {
|
|
756
|
-
return this.device.maxRetry;
|
|
757
|
-
} else {
|
|
758
|
-
return 5;
|
|
759
|
-
}
|
|
760
|
-
}
|
|
761
|
-
|
|
762
620
|
async openAPIpushChanges(): Promise<void> {
|
|
763
621
|
let command: string;
|
|
764
622
|
let parameter: string;
|
|
765
623
|
let commandType: string;
|
|
766
624
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIpushChanges`);
|
|
767
|
-
if (this.TargetPosition !== this.CurrentPosition || this.device.disableCaching) {
|
|
768
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Pushing ${this.TargetPosition}`);
|
|
769
|
-
const adjustedTargetPosition = 100 - Number(this.TargetPosition);
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
}
|
|
775
|
-
if (this.setPositionMode === '1') {
|
|
776
|
-
this.Mode = 'Silent Mode';
|
|
777
|
-
} else if (this.setPositionMode === '0') {
|
|
778
|
-
this.Mode = 'Performance Mode';
|
|
779
|
-
} else {
|
|
780
|
-
this.Mode = 'Default Mode';
|
|
781
|
-
}
|
|
782
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Mode: ${this.Mode}`);
|
|
783
|
-
const adjustedMode = this.setPositionMode || 'ff';
|
|
784
|
-
if (this.HoldPosition) {
|
|
625
|
+
if (this.WindowCovering.TargetPosition !== this.WindowCovering.CurrentPosition || this.device.disableCaching) {
|
|
626
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Pushing ${this.WindowCovering.TargetPosition}`);
|
|
627
|
+
const adjustedTargetPosition = 100 - Number(this.WindowCovering.TargetPosition);
|
|
628
|
+
const { setPositionMode, Mode }: { setPositionMode: number; Mode: string; } = await this.setPerformance();
|
|
629
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Mode: ${Mode}`);
|
|
630
|
+
const adjustedMode = setPositionMode || 'ff';
|
|
631
|
+
if (this.WindowCovering.HoldPosition) {
|
|
785
632
|
command = 'pause';
|
|
786
633
|
parameter = 'default';
|
|
787
634
|
commandType = 'command';
|
|
@@ -811,7 +658,7 @@ export class Curtain {
|
|
|
811
658
|
this.debugErrorLog(`${this.device.deviceType}: ${this.accessory.displayName} `
|
|
812
659
|
+ `statusCode: ${statusCode} & deviceStatus StatusCode: ${deviceStatus.statusCode}`);
|
|
813
660
|
this.successLog(`${this.device.deviceType}: ${this.accessory.displayName} `
|
|
814
|
-
|
|
661
|
+
+ `request to SwitchBot API, body: ${deviceStatus} sent successfully`);
|
|
815
662
|
} else {
|
|
816
663
|
this.statusCode(statusCode);
|
|
817
664
|
this.statusCode(deviceStatus.statusCode);
|
|
@@ -826,7 +673,7 @@ export class Curtain {
|
|
|
826
673
|
} else {
|
|
827
674
|
this.debugLog(
|
|
828
675
|
`${this.device.deviceType}: ${this.accessory.displayName} No OpenAPI Changes, CurrentPosition & TargetPosition Are the Same.` +
|
|
829
|
-
` CurrentPosition: ${this.CurrentPosition}, TargetPosition ${this.TargetPosition}`,
|
|
676
|
+
` CurrentPosition: ${this.WindowCovering.CurrentPosition}, TargetPosition ${this.WindowCovering.TargetPosition}`,
|
|
830
677
|
);
|
|
831
678
|
}
|
|
832
679
|
}
|
|
@@ -835,50 +682,53 @@ export class Curtain {
|
|
|
835
682
|
* Handle requests to set the value of the "Target Position" characteristic
|
|
836
683
|
*/
|
|
837
684
|
async TargetPositionSet(value: CharacteristicValue): Promise<void> {
|
|
838
|
-
if (this.TargetPosition === this.accessory.context.TargetPosition) {
|
|
685
|
+
if (this.WindowCovering.TargetPosition === this.accessory.context.TargetPosition) {
|
|
839
686
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} No Changes, Set TargetPosition: ${value}`);
|
|
840
687
|
} else {
|
|
841
688
|
this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Set TargetPosition: ${value}`);
|
|
842
689
|
}
|
|
843
690
|
|
|
844
691
|
// Set HoldPosition to false when TargetPosition is changed
|
|
845
|
-
this.HoldPosition = false;
|
|
846
|
-
this.
|
|
692
|
+
this.WindowCovering.HoldPosition = false;
|
|
693
|
+
this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.HoldPosition, this.WindowCovering.HoldPosition);
|
|
847
694
|
|
|
848
|
-
this.TargetPosition = value;
|
|
695
|
+
this.WindowCovering.TargetPosition = value;
|
|
849
696
|
if (this.device.mqttURL) {
|
|
850
|
-
this.mqttPublish('TargetPosition', this.TargetPosition);
|
|
851
|
-
this.mqttPublish('HoldPosition', this.HoldPosition);
|
|
697
|
+
this.mqttPublish('TargetPosition', this.WindowCovering.TargetPosition.toString());
|
|
698
|
+
this.mqttPublish('HoldPosition', this.WindowCovering.HoldPosition.toString()); // Convert boolean to string
|
|
852
699
|
}
|
|
853
700
|
|
|
854
701
|
await this.setMinMax();
|
|
855
|
-
if (value > this.CurrentPosition) {
|
|
856
|
-
this.PositionState = this.hap.Characteristic.PositionState.INCREASING;
|
|
702
|
+
if (value > this.WindowCovering.CurrentPosition) {
|
|
703
|
+
this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.INCREASING;
|
|
857
704
|
this.setNewTarget = true;
|
|
858
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} value: ${value}
|
|
859
|
-
|
|
860
|
-
|
|
705
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} value: ${value},`
|
|
706
|
+
+ ` CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
|
|
707
|
+
} else if (value < this.WindowCovering.CurrentPosition) {
|
|
708
|
+
this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.DECREASING;
|
|
861
709
|
this.setNewTarget = true;
|
|
862
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} value: ${value}
|
|
710
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} value: ${value},`
|
|
711
|
+
+ ` CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
|
|
863
712
|
} else {
|
|
864
|
-
this.PositionState = this.hap.Characteristic.PositionState.STOPPED;
|
|
713
|
+
this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.STOPPED;
|
|
865
714
|
this.setNewTarget = false;
|
|
866
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} value: ${value}
|
|
715
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} value: ${value},`
|
|
716
|
+
+ ` CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
|
|
867
717
|
}
|
|
868
|
-
this.
|
|
869
|
-
this.
|
|
718
|
+
this.WindowCovering.Service.setCharacteristic(this.hap.Characteristic.PositionState, this.WindowCovering.PositionState);
|
|
719
|
+
this.WindowCovering.Service.getCharacteristic(this.hap.Characteristic.PositionState).updateValue(this.WindowCovering.PositionState);
|
|
870
720
|
|
|
871
721
|
/**
|
|
872
722
|
* If Curtain movement time is short, the moving flag from backend is always false.
|
|
873
723
|
* The minimum time depends on the network control latency.
|
|
874
724
|
*/
|
|
875
725
|
clearTimeout(this.setNewTargetTimer);
|
|
876
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateRate: ${this.
|
|
726
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateRate: ${this.deviceUpdateRate}`);
|
|
877
727
|
if (this.setNewTarget) {
|
|
878
728
|
this.setNewTargetTimer = setTimeout(() => {
|
|
879
729
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} setNewTarget ${this.setNewTarget} timeout`);
|
|
880
730
|
this.setNewTarget = false;
|
|
881
|
-
}, this.
|
|
731
|
+
}, this.deviceUpdateRate * 1000);
|
|
882
732
|
}
|
|
883
733
|
this.doCurtainUpdate.next();
|
|
884
734
|
}
|
|
@@ -888,153 +738,98 @@ export class Curtain {
|
|
|
888
738
|
*/
|
|
889
739
|
async HoldPositionSet(value: CharacteristicValue): Promise<void> {
|
|
890
740
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} HoldPosition: ${value}`);
|
|
891
|
-
this.HoldPosition = value;
|
|
741
|
+
this.WindowCovering.HoldPosition = value;
|
|
892
742
|
this.doCurtainUpdate.next();
|
|
893
743
|
}
|
|
894
744
|
|
|
895
745
|
async updateHomeKitCharacteristics(): Promise<void> {
|
|
896
746
|
await this.setMinMax();
|
|
897
|
-
if (this.CurrentPosition === undefined || Number.isNaN(this.CurrentPosition)) {
|
|
898
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} CurrentPosition: ${this.CurrentPosition}`);
|
|
747
|
+
if (this.WindowCovering.CurrentPosition === undefined || Number.isNaN(this.WindowCovering.CurrentPosition)) {
|
|
748
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
|
|
899
749
|
} else {
|
|
750
|
+
this.accessory.context.CurrentPosition = this.WindowCovering.CurrentPosition;
|
|
751
|
+
this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.CurrentPosition, Number(this.WindowCovering.CurrentPosition));
|
|
752
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic`
|
|
753
|
+
+ ` CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
|
|
900
754
|
if (this.device.mqttURL) {
|
|
901
|
-
this.mqttPublish('CurrentPosition', this.CurrentPosition);
|
|
755
|
+
this.mqttPublish('CurrentPosition', this.WindowCovering.CurrentPosition.toString()); // Convert to string
|
|
902
756
|
}
|
|
903
|
-
this.accessory.context.CurrentPosition = this.CurrentPosition;
|
|
904
|
-
this.windowCoveringService.updateCharacteristic(this.hap.Characteristic.CurrentPosition, Number(this.CurrentPosition));
|
|
905
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic CurrentPosition: ${this.CurrentPosition}`);
|
|
906
757
|
}
|
|
907
|
-
if (this.PositionState === undefined) {
|
|
908
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} PositionState: ${this.PositionState}`);
|
|
758
|
+
if (this.WindowCovering.PositionState === undefined) {
|
|
759
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} PositionState: ${this.WindowCovering.PositionState}`);
|
|
909
760
|
} else {
|
|
910
761
|
if (this.device.mqttURL) {
|
|
911
|
-
this.mqttPublish('PositionState', this.PositionState);
|
|
762
|
+
this.mqttPublish('PositionState', this.WindowCovering.PositionState.toString());
|
|
912
763
|
}
|
|
913
|
-
this.accessory.context.PositionState = this.PositionState;
|
|
914
|
-
this.
|
|
915
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic
|
|
764
|
+
this.accessory.context.PositionState = this.WindowCovering.PositionState;
|
|
765
|
+
this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.PositionState, Number(this.WindowCovering.PositionState));
|
|
766
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic`
|
|
767
|
+
+ ` PositionState: ${this.WindowCovering.PositionState}`);
|
|
916
768
|
}
|
|
917
|
-
if (this.TargetPosition === undefined || Number.isNaN(this.TargetPosition)) {
|
|
918
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} TargetPosition: ${this.TargetPosition}`);
|
|
769
|
+
if (this.WindowCovering.TargetPosition === undefined || Number.isNaN(this.WindowCovering.TargetPosition)) {
|
|
770
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} TargetPosition: ${this.WindowCovering.TargetPosition}`);
|
|
919
771
|
} else {
|
|
920
772
|
if (this.device.mqttURL) {
|
|
921
|
-
this.mqttPublish('TargetPosition', this.TargetPosition);
|
|
773
|
+
this.mqttPublish('TargetPosition', this.WindowCovering.TargetPosition.toString());
|
|
922
774
|
}
|
|
923
|
-
this.accessory.context.TargetPosition = this.TargetPosition;
|
|
924
|
-
this.
|
|
925
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic
|
|
775
|
+
this.accessory.context.TargetPosition = this.WindowCovering.TargetPosition;
|
|
776
|
+
this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.TargetPosition, Number(this.WindowCovering.TargetPosition));
|
|
777
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic`
|
|
778
|
+
+ ` TargetPosition: ${this.WindowCovering.TargetPosition}`);
|
|
926
779
|
}
|
|
927
|
-
if (this.HoldPosition === undefined) {
|
|
928
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} HoldPosition: ${this.HoldPosition}`);
|
|
780
|
+
if (this.WindowCovering.HoldPosition === undefined) {
|
|
781
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} HoldPosition: ${this.WindowCovering.HoldPosition}`);
|
|
929
782
|
} else {
|
|
930
783
|
if (this.device.mqttURL) {
|
|
931
|
-
this.mqttPublish('HoldPosition', this.HoldPosition);
|
|
784
|
+
this.mqttPublish('HoldPosition', this.WindowCovering.HoldPosition.toString());
|
|
932
785
|
}
|
|
933
|
-
this.accessory.context.HoldPosition = this.HoldPosition;
|
|
934
|
-
this.
|
|
935
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic
|
|
786
|
+
this.accessory.context.HoldPosition = this.WindowCovering.HoldPosition;
|
|
787
|
+
this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.HoldPosition, this.WindowCovering.HoldPosition);
|
|
788
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic`
|
|
789
|
+
+ ` HoldPosition: ${this.WindowCovering.HoldPosition}`);
|
|
936
790
|
}
|
|
937
791
|
if (!this.device.curtain?.hide_lightsensor) {
|
|
938
|
-
if (this.CurrentAmbientLightLevel === undefined || Number.isNaN(this.CurrentAmbientLightLevel)) {
|
|
939
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}
|
|
792
|
+
if (this.LightSensor!.CurrentAmbientLightLevel === undefined || Number.isNaN(this.LightSensor!.CurrentAmbientLightLevel)) {
|
|
793
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}`
|
|
794
|
+
+ ` CurrentAmbientLightLevel: ${this.LightSensor!.CurrentAmbientLightLevel}`);
|
|
940
795
|
} else {
|
|
941
796
|
if (this.device.mqttURL) {
|
|
942
|
-
this.mqttPublish('CurrentAmbientLightLevel', this.CurrentAmbientLightLevel);
|
|
797
|
+
this.mqttPublish('CurrentAmbientLightLevel', this.LightSensor!.CurrentAmbientLightLevel.toString());
|
|
943
798
|
}
|
|
944
|
-
this.accessory.context.CurrentAmbientLightLevel = this.CurrentAmbientLightLevel;
|
|
945
|
-
this.
|
|
799
|
+
this.accessory.context.CurrentAmbientLightLevel = this.LightSensor!.CurrentAmbientLightLevel;
|
|
800
|
+
this.LightSensor!.Service.updateCharacteristic(this.hap.Characteristic.CurrentAmbientLightLevel, this.LightSensor!.CurrentAmbientLightLevel);
|
|
946
801
|
this.debugLog(
|
|
947
802
|
`${this.device.deviceType}: ${this.accessory.displayName}` +
|
|
948
|
-
` updateCharacteristic CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`,
|
|
803
|
+
` updateCharacteristic CurrentAmbientLightLevel: ${this.LightSensor!.CurrentAmbientLightLevel}`,
|
|
949
804
|
);
|
|
950
805
|
if (this.device.history) {
|
|
951
806
|
this.historyService?.addEntry({
|
|
952
807
|
time: Math.round(new Date().valueOf() / 1000),
|
|
953
|
-
lux: this.CurrentAmbientLightLevel,
|
|
808
|
+
lux: this.LightSensor!.CurrentAmbientLightLevel,
|
|
954
809
|
});
|
|
955
810
|
}
|
|
956
811
|
}
|
|
957
812
|
}
|
|
958
|
-
if (this.BatteryLevel === undefined) {
|
|
959
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.BatteryLevel}`);
|
|
813
|
+
if (this.Battery.BatteryLevel === undefined) {
|
|
814
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.Battery.BatteryLevel}`);
|
|
960
815
|
} else {
|
|
961
816
|
if (this.device.mqttURL) {
|
|
962
|
-
this.mqttPublish('BatteryLevel', this.BatteryLevel);
|
|
817
|
+
this.mqttPublish('BatteryLevel', this.Battery.BatteryLevel.toString());
|
|
963
818
|
}
|
|
964
|
-
this.accessory.context.BatteryLevel = this.BatteryLevel;
|
|
965
|
-
this.
|
|
966
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic BatteryLevel: ${this.BatteryLevel}`);
|
|
819
|
+
this.accessory.context.BatteryLevel = this.Battery.BatteryLevel;
|
|
820
|
+
this.Battery.Service.updateCharacteristic(this.hap.Characteristic.BatteryLevel, this.Battery.BatteryLevel);
|
|
821
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic BatteryLevel: ${this.Battery.BatteryLevel}`);
|
|
967
822
|
}
|
|
968
|
-
if (this.StatusLowBattery === undefined) {
|
|
969
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} StatusLowBattery: ${this.StatusLowBattery}`);
|
|
823
|
+
if (this.Battery.StatusLowBattery === undefined) {
|
|
824
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} StatusLowBattery: ${this.Battery.StatusLowBattery}`);
|
|
970
825
|
} else {
|
|
971
826
|
if (this.device.mqttURL) {
|
|
972
|
-
this.mqttPublish('StatusLowBattery', this.StatusLowBattery);
|
|
973
|
-
}
|
|
974
|
-
this.accessory.context.StatusLowBattery = this.StatusLowBattery;
|
|
975
|
-
this.batteryService?.updateCharacteristic(this.hap.Characteristic.StatusLowBattery, this.StatusLowBattery);
|
|
976
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic StatusLowBattery: ${this.StatusLowBattery}`);
|
|
977
|
-
}
|
|
978
|
-
}
|
|
979
|
-
|
|
980
|
-
/*
|
|
981
|
-
* Publish MQTT message for topics of
|
|
982
|
-
* 'homebridge-switchbot/curtain/xx:xx:xx:xx:xx:xx'
|
|
983
|
-
*/
|
|
984
|
-
mqttPublish(topic: string, message: any) {
|
|
985
|
-
const mac = this.device.deviceId
|
|
986
|
-
?.toLowerCase()
|
|
987
|
-
.match(/[\s\S]{1,2}/g)
|
|
988
|
-
?.join(':');
|
|
989
|
-
const options = this.device.mqttPubOptions || {};
|
|
990
|
-
this.mqttClient?.publish(`homebridge-switchbot/curtain/${mac}/${topic}`, `${message}`, options);
|
|
991
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} MQTT message: ${topic}/${message} options:${JSON.stringify(options)}`);
|
|
992
|
-
}
|
|
993
|
-
|
|
994
|
-
/*
|
|
995
|
-
* Setup MQTT hadler if URL is specified.
|
|
996
|
-
*/
|
|
997
|
-
async setupMqtt(device: device & devicesConfig): Promise<void> {
|
|
998
|
-
if (device.mqttURL) {
|
|
999
|
-
try {
|
|
1000
|
-
const { connectAsync } = asyncmqtt;
|
|
1001
|
-
this.mqttClient = await connectAsync(device.mqttURL, device.mqttOptions || {});
|
|
1002
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} MQTT connection has been established successfully.`);
|
|
1003
|
-
this.mqttClient.on('error', (e: Error) => {
|
|
1004
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Failed to publish MQTT messages. ${e}`);
|
|
1005
|
-
});
|
|
1006
|
-
} catch (e) {
|
|
1007
|
-
this.mqttClient = null;
|
|
1008
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Failed to establish MQTT connection. ${e}`);
|
|
827
|
+
this.mqttPublish('StatusLowBattery', this.Battery.StatusLowBattery.toString());
|
|
1009
828
|
}
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
switchbot.stopScan();
|
|
1015
|
-
if (this.BLE_IsConnected) {
|
|
1016
|
-
await this.BLEparseStatus();
|
|
1017
|
-
await this.updateHomeKitCharacteristics();
|
|
1018
|
-
} else {
|
|
1019
|
-
await this.BLERefreshConnection(switchbot);
|
|
1020
|
-
}
|
|
1021
|
-
}
|
|
1022
|
-
|
|
1023
|
-
async getCustomBLEAddress(switchbot: any) {
|
|
1024
|
-
if (this.device.customBLEaddress && this.deviceLogging.includes('debug')) {
|
|
1025
|
-
(async () => {
|
|
1026
|
-
// Start to monitor advertisement packets
|
|
1027
|
-
await switchbot.startScan({
|
|
1028
|
-
model: 'c',
|
|
1029
|
-
});
|
|
1030
|
-
// Set an event handler
|
|
1031
|
-
switchbot.onadvertisement = (ad: any) => {
|
|
1032
|
-
this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} ad: ${JSON.stringify(ad, null, ' ')}`);
|
|
1033
|
-
};
|
|
1034
|
-
await sleep(10000);
|
|
1035
|
-
// Stop to monitor
|
|
1036
|
-
switchbot.stopScan();
|
|
1037
|
-
})();
|
|
829
|
+
this.accessory.context.StatusLowBattery = this.Battery.StatusLowBattery;
|
|
830
|
+
this.Battery.Service.updateCharacteristic(this.hap.Characteristic.StatusLowBattery, this.Battery.StatusLowBattery);
|
|
831
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic`
|
|
832
|
+
+ ` StatusLowBattery: ${this.Battery.StatusLowBattery}`);
|
|
1038
833
|
}
|
|
1039
834
|
}
|
|
1040
835
|
|
|
@@ -1054,387 +849,100 @@ export class Curtain {
|
|
|
1054
849
|
}
|
|
1055
850
|
}
|
|
1056
851
|
|
|
1057
|
-
async
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
852
|
+
async setPerformance() {
|
|
853
|
+
let setPositionMode: number;
|
|
854
|
+
let Mode: string;
|
|
855
|
+
if (Number(this.WindowCovering.TargetPosition) > 50) {
|
|
856
|
+
if (this.device.blindTilt?.setOpenMode === '1') {
|
|
857
|
+
setPositionMode = 1;
|
|
858
|
+
Mode = 'Silent Mode';
|
|
859
|
+
} else if (this.device.blindTilt?.setOpenMode === '0') {
|
|
860
|
+
setPositionMode = 0;
|
|
861
|
+
Mode = 'Performance Mode';
|
|
1062
862
|
} else {
|
|
1063
|
-
|
|
1064
|
-
|
|
863
|
+
setPositionMode = 0;
|
|
864
|
+
Mode = 'Default Mode';
|
|
1065
865
|
}
|
|
1066
866
|
} else {
|
|
1067
|
-
if (this.device.
|
|
1068
|
-
|
|
1069
|
-
|
|
867
|
+
if (this.device.blindTilt?.setCloseMode === '1') {
|
|
868
|
+
setPositionMode = 1;
|
|
869
|
+
Mode = 'Silent Mode';
|
|
870
|
+
} else if (this.device.blindTilt?.setOpenMode === '0') {
|
|
871
|
+
setPositionMode = 0;
|
|
872
|
+
Mode = 'Performance Mode';
|
|
1070
873
|
} else {
|
|
1071
|
-
|
|
1072
|
-
|
|
874
|
+
setPositionMode = 0;
|
|
875
|
+
Mode = 'Default Mode';
|
|
1073
876
|
}
|
|
1074
877
|
}
|
|
878
|
+
return { setPositionMode, Mode };
|
|
1075
879
|
}
|
|
1076
880
|
|
|
1077
881
|
async setMinMax(): Promise<void> {
|
|
1078
882
|
if (this.device.curtain?.set_min) {
|
|
1079
|
-
if (Number(this.CurrentPosition) <= this.device.curtain?.set_min) {
|
|
1080
|
-
this.CurrentPosition = 0;
|
|
883
|
+
if (Number(this.WindowCovering.CurrentPosition) <= this.device.curtain?.set_min) {
|
|
884
|
+
this.WindowCovering.CurrentPosition = 0;
|
|
1081
885
|
}
|
|
1082
886
|
}
|
|
1083
887
|
if (this.device.curtain?.set_max) {
|
|
1084
|
-
if (Number(this.CurrentPosition) >= this.device.curtain?.set_max) {
|
|
1085
|
-
this.CurrentPosition = 100;
|
|
888
|
+
if (Number(this.WindowCovering.CurrentPosition) >= this.device.curtain?.set_max) {
|
|
889
|
+
this.WindowCovering.CurrentPosition = 100;
|
|
1086
890
|
}
|
|
1087
891
|
}
|
|
1088
892
|
if (this.device.history) {
|
|
1089
893
|
const motion = this.accessory.getService(this.hap.Service.MotionSensor);
|
|
1090
|
-
const state = Number(this.CurrentPosition) > 0 ? 1 : 0;
|
|
894
|
+
const state = Number(this.WindowCovering.CurrentPosition) > 0 ? 1 : 0;
|
|
1091
895
|
motion?.updateCharacteristic(this.hap.Characteristic.MotionDetected, state);
|
|
1092
896
|
}
|
|
1093
897
|
}
|
|
1094
898
|
|
|
1095
899
|
minStep(device: device & devicesConfig): number {
|
|
900
|
+
let set_minStep: number;
|
|
1096
901
|
if (device.curtain?.set_minStep) {
|
|
1097
|
-
|
|
902
|
+
set_minStep = device.curtain?.set_minStep;
|
|
1098
903
|
} else {
|
|
1099
|
-
|
|
904
|
+
set_minStep = 1;
|
|
1100
905
|
}
|
|
1101
|
-
return
|
|
906
|
+
return set_minStep;
|
|
1102
907
|
}
|
|
1103
908
|
|
|
1104
|
-
minLux(): number {
|
|
909
|
+
async minLux(): Promise<number> {
|
|
910
|
+
let set_minLux: number;
|
|
1105
911
|
if (this.device.curtain?.set_minLux) {
|
|
1106
|
-
|
|
912
|
+
set_minLux = this.device.curtain?.set_minLux;
|
|
1107
913
|
} else {
|
|
1108
|
-
|
|
914
|
+
set_minLux = 1;
|
|
1109
915
|
}
|
|
1110
|
-
return
|
|
916
|
+
return set_minLux;
|
|
1111
917
|
}
|
|
1112
918
|
|
|
1113
|
-
maxLux(): number {
|
|
919
|
+
async maxLux(): Promise<number> {
|
|
920
|
+
let set_maxLux: number;
|
|
1114
921
|
if (this.device.curtain?.set_maxLux) {
|
|
1115
|
-
|
|
1116
|
-
} else {
|
|
1117
|
-
this.set_maxLux = 6001;
|
|
1118
|
-
}
|
|
1119
|
-
return this.set_maxLux;
|
|
1120
|
-
}
|
|
1121
|
-
|
|
1122
|
-
async scan(device: device & devicesConfig): Promise<void> {
|
|
1123
|
-
if (device.scanDuration) {
|
|
1124
|
-
if (this.updateRate > device.scanDuration) {
|
|
1125
|
-
this.scanDuration = this.updateRate;
|
|
1126
|
-
if (this.BLE) {
|
|
1127
|
-
this.warnLog(
|
|
1128
|
-
`${this.device.deviceType}: ` +
|
|
1129
|
-
`${this.accessory.displayName} scanDuration is less than updateRate, overriding scanDuration with updateRate`,
|
|
1130
|
-
);
|
|
1131
|
-
}
|
|
1132
|
-
} else {
|
|
1133
|
-
this.scanDuration = this.accessory.context.scanDuration = device.scanDuration;
|
|
1134
|
-
}
|
|
1135
|
-
if (this.BLE) {
|
|
1136
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Config scanDuration: ${this.scanDuration}`);
|
|
1137
|
-
}
|
|
922
|
+
set_maxLux = this.device.curtain?.set_maxLux;
|
|
1138
923
|
} else {
|
|
1139
|
-
|
|
1140
|
-
this.scanDuration = this.updateRate;
|
|
1141
|
-
} else {
|
|
1142
|
-
this.scanDuration = this.accessory.context.scanDuration = 1;
|
|
1143
|
-
}
|
|
1144
|
-
if (this.BLE) {
|
|
1145
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Default scanDuration: ${this.scanDuration}`);
|
|
1146
|
-
}
|
|
1147
|
-
}
|
|
1148
|
-
}
|
|
1149
|
-
|
|
1150
|
-
async statusCode(statusCode: number): Promise<void> {
|
|
1151
|
-
switch (statusCode) {
|
|
1152
|
-
case 151:
|
|
1153
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command not supported by this deviceType, statusCode: ${statusCode}`);
|
|
1154
|
-
break;
|
|
1155
|
-
case 152:
|
|
1156
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device not found, statusCode: ${statusCode}`);
|
|
1157
|
-
break;
|
|
1158
|
-
case 160:
|
|
1159
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command is not supported, statusCode: ${statusCode}`);
|
|
1160
|
-
break;
|
|
1161
|
-
case 161:
|
|
1162
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device is offline, statusCode: ${statusCode}`);
|
|
1163
|
-
this.offlineOff();
|
|
1164
|
-
break;
|
|
1165
|
-
case 171:
|
|
1166
|
-
this.errorLog(
|
|
1167
|
-
`${this.device.deviceType}: ${this.accessory.displayName} Hub Device is offline, statusCode: ${statusCode}. ` +
|
|
1168
|
-
`Hub: ${this.device.hubDeviceId}`,
|
|
1169
|
-
);
|
|
1170
|
-
this.offlineOff();
|
|
1171
|
-
break;
|
|
1172
|
-
case 190:
|
|
1173
|
-
this.errorLog(
|
|
1174
|
-
`${this.device.deviceType}: ${this.accessory.displayName} Device internal error due to device states not synchronized with server,` +
|
|
1175
|
-
` Or command format is invalid, statusCode: ${statusCode}`,
|
|
1176
|
-
);
|
|
1177
|
-
break;
|
|
1178
|
-
case 100:
|
|
1179
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Command successfully sent, statusCode: ${statusCode}`);
|
|
1180
|
-
break;
|
|
1181
|
-
case 200:
|
|
1182
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Request successful, statusCode: ${statusCode}`);
|
|
1183
|
-
break;
|
|
1184
|
-
case 400:
|
|
1185
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Bad Request, The client has issued an invalid request. `
|
|
1186
|
-
+ `This is commonly used to specify validation errors in a request payload, statusCode: ${statusCode}`);
|
|
1187
|
-
break;
|
|
1188
|
-
case 401:
|
|
1189
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Unauthorized, Authorization for the API is required, `
|
|
1190
|
-
+ `but the request has not been authenticated, statusCode: ${statusCode}`);
|
|
1191
|
-
break;
|
|
1192
|
-
case 403:
|
|
1193
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Forbidden, The request has been authenticated but does not `
|
|
1194
|
-
+ `have appropriate permissions, or a requested resource is not found, statusCode: ${statusCode}`);
|
|
1195
|
-
break;
|
|
1196
|
-
case 404:
|
|
1197
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Not Found, Specifies the requested path does not exist, `
|
|
1198
|
-
+ `statusCode: ${statusCode}`);
|
|
1199
|
-
break;
|
|
1200
|
-
case 406:
|
|
1201
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Not Acceptable, The client has requested a MIME type via `
|
|
1202
|
-
+ `the Accept header for a value not supported by the server, statusCode: ${statusCode}`);
|
|
1203
|
-
break;
|
|
1204
|
-
case 415:
|
|
1205
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Unsupported Media Type, The client has defined a contentType `
|
|
1206
|
-
+ `header that is not supported by the server, statusCode: ${statusCode}`);
|
|
1207
|
-
break;
|
|
1208
|
-
case 422:
|
|
1209
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Unprocessable Entity, The client has made a valid request, `
|
|
1210
|
-
+ `but the server cannot process it. This is often used for APIs for which certain limits have been exceeded, statusCode: ${statusCode}`);
|
|
1211
|
-
break;
|
|
1212
|
-
case 429:
|
|
1213
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Too Many Requests, The client has exceeded the number of `
|
|
1214
|
-
+ `requests allowed for a given time window, statusCode: ${statusCode}`);
|
|
1215
|
-
break;
|
|
1216
|
-
case 500:
|
|
1217
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Internal Server Error, An unexpected error on the SmartThings `
|
|
1218
|
-
+ `servers has occurred. These errors should be rare, statusCode: ${statusCode}`);
|
|
1219
|
-
break;
|
|
1220
|
-
default:
|
|
1221
|
-
this.infoLog(
|
|
1222
|
-
`${this.device.deviceType}: ${this.accessory.displayName} Unknown statusCode: ` +
|
|
1223
|
-
`${statusCode}, Submit Bugs Here: ' + 'https://tinyurl.com/SwitchBotBug`,
|
|
1224
|
-
);
|
|
924
|
+
set_maxLux = 6001;
|
|
1225
925
|
}
|
|
926
|
+
return set_maxLux;
|
|
1226
927
|
}
|
|
1227
928
|
|
|
1228
929
|
async offlineOff(): Promise<void> {
|
|
1229
930
|
if (this.device.offline) {
|
|
1230
|
-
|
|
1231
|
-
|
|
931
|
+
this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.CurrentPosition, 100);
|
|
932
|
+
this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.TargetPosition, 100);
|
|
933
|
+
this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.PositionState, this.hap.Characteristic.PositionState.STOPPED);
|
|
1232
934
|
}
|
|
1233
935
|
}
|
|
1234
936
|
|
|
1235
937
|
async apiError(e: any): Promise<void> {
|
|
1236
|
-
this.
|
|
1237
|
-
this.
|
|
1238
|
-
this.
|
|
938
|
+
this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.CurrentPosition, e);
|
|
939
|
+
this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.PositionState, e);
|
|
940
|
+
this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.TargetPosition, e);
|
|
1239
941
|
if (!this.device.curtain?.hide_lightsensor) {
|
|
1240
|
-
this.
|
|
942
|
+
this.LightSensor!.Service.updateCharacteristic(this.hap.Characteristic.CurrentAmbientLightLevel, e);
|
|
1241
943
|
}
|
|
1242
|
-
this.
|
|
1243
|
-
this.
|
|
944
|
+
this.Battery.Service.updateCharacteristic(this.hap.Characteristic.BatteryLevel, e);
|
|
945
|
+
this.Battery.Service.updateCharacteristic(this.hap.Characteristic.StatusLowBattery, e);
|
|
1244
946
|
//throw new this.platform.api.hap.HapStatusError(HAPStatus.SERVICE_COMMUNICATION_FAILURE);
|
|
1245
947
|
}
|
|
1246
|
-
|
|
1247
|
-
async deviceContext() {
|
|
1248
|
-
if (this.accessory.context.CurrentPosition === undefined) {
|
|
1249
|
-
this.CurrentPosition = 0;
|
|
1250
|
-
} else {
|
|
1251
|
-
this.CurrentPosition = this.accessory.context.CurrentPosition;
|
|
1252
|
-
}
|
|
1253
|
-
|
|
1254
|
-
if (this.accessory.context.TargetPosition === undefined) {
|
|
1255
|
-
this.TargetPosition = 0;
|
|
1256
|
-
} else {
|
|
1257
|
-
this.TargetPosition = this.accessory.context.TargetPosition;
|
|
1258
|
-
}
|
|
1259
|
-
|
|
1260
|
-
if (this.accessory.context.PositionState === undefined) {
|
|
1261
|
-
this.PositionState = this.hap.Characteristic.PositionState.STOPPED;
|
|
1262
|
-
} else {
|
|
1263
|
-
this.PositionState = this.accessory.context.PositionState;
|
|
1264
|
-
}
|
|
1265
|
-
|
|
1266
|
-
if (!this.device.curtain?.hide_lightsensor) {
|
|
1267
|
-
if (this.accessory.context.CurrentAmbientLightLevel !== undefined) {
|
|
1268
|
-
this.CurrentAmbientLightLevel = this.accessory.context.CurrentAmbientLightLevel;
|
|
1269
|
-
}
|
|
1270
|
-
}
|
|
1271
|
-
|
|
1272
|
-
if (this.BLE) {
|
|
1273
|
-
if (this.accessory.context.BatteryLevel === undefined) {
|
|
1274
|
-
this.BatteryLevel = 100;
|
|
1275
|
-
} else {
|
|
1276
|
-
this.BatteryLevel = this.accessory.context.BatteryLevel;
|
|
1277
|
-
}
|
|
1278
|
-
if (this.accessory.context.StatusLowBattery === undefined) {
|
|
1279
|
-
this.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
|
|
1280
|
-
} else {
|
|
1281
|
-
this.StatusLowBattery = this.accessory.context.StatusLowBattery;
|
|
1282
|
-
}
|
|
1283
|
-
}
|
|
1284
|
-
|
|
1285
|
-
if (this.device.history === true) {
|
|
1286
|
-
// initialize when this accessory is newly created.
|
|
1287
|
-
this.accessory.context.lastActivation = this.accessory.context.lastActivation ?? 0;
|
|
1288
|
-
} else {
|
|
1289
|
-
// removes cached values if history is turned off
|
|
1290
|
-
delete this.accessory.context.lastActivation;
|
|
1291
|
-
}
|
|
1292
|
-
if (this.FirmwareRevision === undefined) {
|
|
1293
|
-
this.FirmwareRevision = this.platform.version;
|
|
1294
|
-
this.accessory.context.FirmwareRevision = this.FirmwareRevision;
|
|
1295
|
-
}
|
|
1296
|
-
}
|
|
1297
|
-
|
|
1298
|
-
async refreshRate(device: device & devicesConfig): Promise<void> {
|
|
1299
|
-
// refreshRate
|
|
1300
|
-
if (device.refreshRate) {
|
|
1301
|
-
this.deviceRefreshRate = this.accessory.context.refreshRate = device.refreshRate;
|
|
1302
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Config refreshRate: ${this.deviceRefreshRate}`);
|
|
1303
|
-
} else if (this.platform.config.options!.refreshRate) {
|
|
1304
|
-
this.deviceRefreshRate = this.accessory.context.refreshRate = this.platform.config.options!.refreshRate;
|
|
1305
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Platform Config refreshRate: ${this.deviceRefreshRate}`);
|
|
1306
|
-
}
|
|
1307
|
-
// updateRate
|
|
1308
|
-
if (device?.curtain?.updateRate) {
|
|
1309
|
-
this.updateRate = device?.curtain?.updateRate;
|
|
1310
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Config Curtain updateRate: ${this.updateRate}`);
|
|
1311
|
-
} else {
|
|
1312
|
-
this.updateRate = 7;
|
|
1313
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Default Curtain updateRate: ${this.updateRate}`);
|
|
1314
|
-
}
|
|
1315
|
-
}
|
|
1316
|
-
|
|
1317
|
-
async deviceRetry(device: device & devicesConfig): Promise<void> {
|
|
1318
|
-
if (!device.maxRetries) {
|
|
1319
|
-
this.maxRetries = 5; // Maximum number of retries
|
|
1320
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Max Retries Not Set, Using: ${this.maxRetries}`);
|
|
1321
|
-
} else {
|
|
1322
|
-
this.maxRetries = device.maxRetries;
|
|
1323
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Max Retries: ${this.maxRetries}`);
|
|
1324
|
-
}
|
|
1325
|
-
if (!device.delayBetweenRetries) {
|
|
1326
|
-
this.delayBetweenRetries = 3000; // Delay between retries in milliseconds
|
|
1327
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Delay Between Retries Not Set, Using: ${this.delayBetweenRetries}`);
|
|
1328
|
-
} else {
|
|
1329
|
-
this.delayBetweenRetries = device.delayBetweenRetries * 1000;
|
|
1330
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Delay Between Retries: ${this.delayBetweenRetries}`);
|
|
1331
|
-
}
|
|
1332
|
-
}
|
|
1333
|
-
|
|
1334
|
-
async deviceConfig(device: device & devicesConfig): Promise<void> {
|
|
1335
|
-
let config = {};
|
|
1336
|
-
if (device.curtain) {
|
|
1337
|
-
config = device.curtain;
|
|
1338
|
-
}
|
|
1339
|
-
if (device.connectionType !== undefined) {
|
|
1340
|
-
config['connectionType'] = device.connectionType;
|
|
1341
|
-
}
|
|
1342
|
-
if (device.external !== undefined) {
|
|
1343
|
-
config['external'] = device.external;
|
|
1344
|
-
}
|
|
1345
|
-
if (device.mqttURL !== undefined) {
|
|
1346
|
-
config['mqttURL'] = device.mqttURL;
|
|
1347
|
-
}
|
|
1348
|
-
if (device.logging !== undefined) {
|
|
1349
|
-
config['logging'] = device.logging;
|
|
1350
|
-
}
|
|
1351
|
-
if (device.refreshRate !== undefined) {
|
|
1352
|
-
config['refreshRate'] = device.refreshRate;
|
|
1353
|
-
}
|
|
1354
|
-
if (device.scanDuration !== undefined) {
|
|
1355
|
-
config['scanDuration'] = device.scanDuration;
|
|
1356
|
-
}
|
|
1357
|
-
if (device.maxRetry !== undefined) {
|
|
1358
|
-
config['maxRetry'] = device.maxRetry;
|
|
1359
|
-
}
|
|
1360
|
-
if (device.webhook !== undefined) {
|
|
1361
|
-
config['webhook'] = device.webhook;
|
|
1362
|
-
}
|
|
1363
|
-
if (Object.entries(config).length !== 0) {
|
|
1364
|
-
this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} Config: ${JSON.stringify(config)}`);
|
|
1365
|
-
}
|
|
1366
|
-
}
|
|
1367
|
-
|
|
1368
|
-
async deviceLogs(device: device & devicesConfig): Promise<void> {
|
|
1369
|
-
if (this.platform.debugMode) {
|
|
1370
|
-
this.deviceLogging = this.accessory.context.logging = 'debugMode';
|
|
1371
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Debug Mode Logging: ${this.deviceLogging}`);
|
|
1372
|
-
} else if (device.logging) {
|
|
1373
|
-
this.deviceLogging = this.accessory.context.logging = device.logging;
|
|
1374
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Config Logging: ${this.deviceLogging}`);
|
|
1375
|
-
} else if (this.platform.config.options?.logging) {
|
|
1376
|
-
this.deviceLogging = this.accessory.context.logging = this.platform.config.options?.logging;
|
|
1377
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Platform Config Logging: ${this.deviceLogging}`);
|
|
1378
|
-
} else {
|
|
1379
|
-
this.deviceLogging = this.accessory.context.logging = 'standard';
|
|
1380
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Logging Not Set, Using: ${this.deviceLogging}`);
|
|
1381
|
-
}
|
|
1382
|
-
}
|
|
1383
|
-
|
|
1384
|
-
/**
|
|
1385
|
-
* Logging for Device
|
|
1386
|
-
*/
|
|
1387
|
-
successLog(...log: any[]): void {
|
|
1388
|
-
if (this.enablingDeviceLogging()) {
|
|
1389
|
-
this.platform.log.success(String(...log));
|
|
1390
|
-
}
|
|
1391
|
-
}
|
|
1392
|
-
|
|
1393
|
-
infoLog(...log: any[]): void {
|
|
1394
|
-
if (this.enablingDeviceLogging()) {
|
|
1395
|
-
this.platform.log.info(String(...log));
|
|
1396
|
-
}
|
|
1397
|
-
}
|
|
1398
|
-
|
|
1399
|
-
warnLog(...log: any[]): void {
|
|
1400
|
-
if (this.enablingDeviceLogging()) {
|
|
1401
|
-
this.platform.log.warn(String(...log));
|
|
1402
|
-
}
|
|
1403
|
-
}
|
|
1404
|
-
|
|
1405
|
-
debugWarnLog(...log: any[]): void {
|
|
1406
|
-
if (this.enablingDeviceLogging()) {
|
|
1407
|
-
if (this.deviceLogging?.includes('debug')) {
|
|
1408
|
-
this.platform.log.warn('[DEBUG]', String(...log));
|
|
1409
|
-
}
|
|
1410
|
-
}
|
|
1411
|
-
}
|
|
1412
|
-
|
|
1413
|
-
errorLog(...log: any[]): void {
|
|
1414
|
-
if (this.enablingDeviceLogging()) {
|
|
1415
|
-
this.platform.log.error(String(...log));
|
|
1416
|
-
}
|
|
1417
|
-
}
|
|
1418
|
-
|
|
1419
|
-
debugErrorLog(...log: any[]): void {
|
|
1420
|
-
if (this.enablingDeviceLogging()) {
|
|
1421
|
-
if (this.deviceLogging?.includes('debug')) {
|
|
1422
|
-
this.platform.log.error('[DEBUG]', String(...log));
|
|
1423
|
-
}
|
|
1424
|
-
}
|
|
1425
|
-
}
|
|
1426
|
-
|
|
1427
|
-
debugLog(...log: any[]): void {
|
|
1428
|
-
if (this.enablingDeviceLogging()) {
|
|
1429
|
-
if (this.deviceLogging === 'debug') {
|
|
1430
|
-
this.platform.log.info('[DEBUG]', String(...log));
|
|
1431
|
-
} else {
|
|
1432
|
-
this.platform.log.debug(String(...log));
|
|
1433
|
-
}
|
|
1434
|
-
}
|
|
1435
|
-
}
|
|
1436
|
-
|
|
1437
|
-
enablingDeviceLogging(): boolean {
|
|
1438
|
-
return this.deviceLogging.includes('debug') || this.deviceLogging === 'standard';
|
|
1439
|
-
}
|
|
1440
948
|
}
|