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