@switchbot/homebridge-switchbot 3.5.0-beta.9 → 3.5.1-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.vscode/settings.json +4 -1
- package/CHANGELOG.md +4 -1
- package/config.schema.json +164 -22
- package/dist/device/blindtilt.d.ts +21 -96
- package/dist/device/blindtilt.d.ts.map +1 -1
- package/dist/device/blindtilt.js +457 -866
- package/dist/device/blindtilt.js.map +1 -1
- package/dist/device/bot.d.ts +27 -72
- package/dist/device/bot.d.ts.map +1 -1
- package/dist/device/bot.js +851 -913
- package/dist/device/bot.js.map +1 -1
- package/dist/device/ceilinglight.d.ts +15 -69
- package/dist/device/ceilinglight.d.ts.map +1 -1
- package/dist/device/ceilinglight.js +316 -742
- package/dist/device/ceilinglight.js.map +1 -1
- package/dist/device/colorbulb.d.ts +15 -76
- package/dist/device/colorbulb.d.ts.map +1 -1
- package/dist/device/colorbulb.js +380 -833
- package/dist/device/colorbulb.js.map +1 -1
- package/dist/device/contact.d.ts +14 -66
- package/dist/device/contact.d.ts.map +1 -1
- package/dist/device/contact.js +267 -602
- package/dist/device/contact.js.map +1 -1
- package/dist/device/curtain.d.ts +18 -89
- package/dist/device/curtain.d.ts.map +1 -1
- package/dist/device/curtain.js +469 -897
- package/dist/device/curtain.js.map +1 -1
- package/dist/device/device.d.ts +76 -0
- package/dist/device/device.d.ts.map +1 -0
- package/dist/device/device.js +846 -0
- package/dist/device/device.js.map +1 -0
- package/dist/device/fan.d.ts +63 -0
- package/dist/device/fan.d.ts.map +1 -0
- package/dist/device/fan.js +645 -0
- package/dist/device/fan.js.map +1 -0
- package/dist/device/hub.d.ts +19 -58
- package/dist/device/hub.d.ts.map +1 -1
- package/dist/device/hub.js +304 -640
- package/dist/device/hub.js.map +1 -1
- package/dist/device/humidifier.d.ts +11 -66
- package/dist/device/humidifier.d.ts.map +1 -1
- package/dist/device/humidifier.js +300 -710
- package/dist/device/humidifier.js.map +1 -1
- package/dist/device/iosensor.d.ts +12 -64
- package/dist/device/iosensor.d.ts.map +1 -1
- package/dist/device/iosensor.js +225 -643
- package/dist/device/iosensor.js.map +1 -1
- package/dist/device/lightstrip.d.ts +12 -70
- package/dist/device/lightstrip.d.ts.map +1 -1
- package/dist/device/lightstrip.js +371 -742
- package/dist/device/lightstrip.js.map +1 -1
- package/dist/device/lock.d.ts +17 -63
- package/dist/device/lock.d.ts.map +1 -1
- package/dist/device/lock.js +309 -642
- package/dist/device/lock.js.map +1 -1
- package/dist/device/meter.d.ts +15 -64
- package/dist/device/meter.d.ts.map +1 -1
- package/dist/device/meter.js +223 -638
- package/dist/device/meter.js.map +1 -1
- package/dist/device/meterplus.d.ts +15 -65
- package/dist/device/meterplus.d.ts.map +1 -1
- package/dist/device/meterplus.js +216 -644
- package/dist/device/meterplus.js.map +1 -1
- package/dist/device/motion.d.ts +12 -69
- package/dist/device/motion.d.ts.map +1 -1
- package/dist/device/motion.js +209 -588
- package/dist/device/motion.js.map +1 -1
- package/dist/device/plug.d.ts +10 -57
- package/dist/device/plug.d.ts.map +1 -1
- package/dist/device/plug.js +141 -532
- package/dist/device/plug.js.map +1 -1
- package/dist/device/robotvacuumcleaner.d.ts +13 -63
- package/dist/device/robotvacuumcleaner.d.ts.map +1 -1
- package/dist/device/robotvacuumcleaner.js +252 -609
- package/dist/device/robotvacuumcleaner.js.map +1 -1
- package/dist/device/waterdetector.d.ts +11 -63
- package/dist/device/waterdetector.d.ts.map +1 -1
- package/dist/device/waterdetector.js +179 -521
- package/dist/device/waterdetector.js.map +1 -1
- package/dist/homebridge-ui/public/index.html +22 -16
- package/dist/homebridge-ui/server.js +1 -1
- package/dist/homebridge-ui/server.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/irdevice/airconditioner.d.ts +10 -50
- package/dist/irdevice/airconditioner.d.ts.map +1 -1
- package/dist/irdevice/airconditioner.js +337 -482
- package/dist/irdevice/airconditioner.js.map +1 -1
- package/dist/irdevice/airpurifier.d.ts +8 -39
- package/dist/irdevice/airpurifier.d.ts.map +1 -1
- package/dist/irdevice/airpurifier.js +108 -333
- package/dist/irdevice/airpurifier.js.map +1 -1
- package/dist/irdevice/camera.d.ts +7 -36
- package/dist/irdevice/camera.d.ts.map +1 -1
- package/dist/irdevice/camera.js +47 -299
- package/dist/irdevice/camera.js.map +1 -1
- package/dist/irdevice/fan.d.ts +7 -43
- package/dist/irdevice/fan.d.ts.map +1 -1
- package/dist/irdevice/fan.js +95 -364
- package/dist/irdevice/fan.js.map +1 -1
- package/dist/irdevice/irdevice.d.ts +46 -0
- package/dist/irdevice/irdevice.d.ts.map +1 -0
- package/dist/irdevice/irdevice.js +393 -0
- package/dist/irdevice/irdevice.js.map +1 -0
- package/dist/irdevice/light.d.ts +12 -45
- package/dist/irdevice/light.d.ts.map +1 -1
- package/dist/irdevice/light.js +121 -376
- package/dist/irdevice/light.js.map +1 -1
- package/dist/irdevice/other.d.ts +19 -48
- package/dist/irdevice/other.d.ts.map +1 -1
- package/dist/irdevice/other.js +441 -584
- package/dist/irdevice/other.js.map +1 -1
- package/dist/irdevice/tv.d.ts +8 -40
- package/dist/irdevice/tv.d.ts.map +1 -1
- package/dist/irdevice/tv.js +94 -353
- package/dist/irdevice/tv.js.map +1 -1
- package/dist/irdevice/vacuumcleaner.d.ts +7 -36
- package/dist/irdevice/vacuumcleaner.d.ts.map +1 -1
- package/dist/irdevice/vacuumcleaner.js +48 -299
- package/dist/irdevice/vacuumcleaner.js.map +1 -1
- package/dist/irdevice/waterheater.d.ts +7 -36
- package/dist/irdevice/waterheater.d.ts.map +1 -1
- package/dist/irdevice/waterheater.js +50 -305
- package/dist/irdevice/waterheater.js.map +1 -1
- package/dist/platform.d.ts +22 -8
- package/dist/platform.d.ts.map +1 -1
- package/dist/platform.js +342 -191
- package/dist/platform.js.map +1 -1
- package/dist/settings.d.ts +66 -18
- package/dist/settings.d.ts.map +1 -1
- package/dist/settings.js +16 -552
- package/dist/settings.js.map +1 -1
- package/dist/utils.d.ts +95 -0
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +657 -1
- package/dist/utils.js.map +1 -1
- package/eslint.config.js +96 -0
- package/package.json +20 -16
- package/src/custom.d.ts +2 -1
- package/src/device/blindtilt.ts +488 -937
- package/src/device/bot.ts +907 -1016
- package/src/device/ceilinglight.ts +330 -798
- package/src/device/colorbulb.ts +394 -904
- package/src/device/contact.ts +298 -637
- package/src/device/curtain.ts +496 -954
- package/src/device/device.ts +872 -0
- package/src/device/fan.ts +692 -0
- package/src/device/hub.ts +338 -671
- package/src/device/humidifier.ts +330 -777
- package/src/device/iosensor.ts +258 -671
- package/src/device/lightstrip.ts +394 -809
- package/src/device/lock.ts +345 -700
- package/src/device/meter.ts +256 -666
- package/src/device/meterplus.ts +248 -672
- package/src/device/motion.ts +234 -622
- package/src/device/plug.ts +152 -572
- package/src/device/robotvacuumcleaner.ts +273 -653
- package/src/device/waterdetector.ts +198 -549
- package/src/homebridge-ui/public/index.html +22 -16
- package/src/homebridge-ui/server.ts +1 -1
- package/src/index.ts +4 -3
- package/src/irdevice/airconditioner.ts +368 -540
- package/src/irdevice/airpurifier.ts +134 -369
- package/src/irdevice/camera.ts +60 -324
- package/src/irdevice/fan.ts +111 -392
- package/src/irdevice/irdevice.ts +406 -0
- package/src/irdevice/light.ts +159 -425
- package/src/irdevice/other.ts +509 -661
- package/src/irdevice/tv.ts +123 -388
- package/src/irdevice/vacuumcleaner.ts +61 -324
- package/src/irdevice/waterheater.ts +63 -333
- package/src/platform.ts +395 -259
- package/src/settings.ts +120 -610
- package/src/utils.ts +661 -1
- package/src/device/waterdetector.json +0 -11
package/src/device/curtain.ts
CHANGED
|
@@ -1,193 +1,179 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
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';
|
|
4
6
|
import { interval, Subject } from 'rxjs';
|
|
5
|
-
import
|
|
6
|
-
import { SwitchBotPlatform } from '../platform.js';
|
|
7
|
+
import { deviceBase } from './device.js';
|
|
7
8
|
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
9
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
PositionState!: CharacteristicValue;
|
|
26
|
-
TargetPosition!: CharacteristicValue;
|
|
27
|
-
CurrentPosition!: CharacteristicValue;
|
|
28
|
-
FirmwareRevision!: CharacteristicValue;
|
|
29
|
-
StatusLowBattery!: CharacteristicValue;
|
|
30
|
-
CurrentAmbientLightLevel?: CharacteristicValue;
|
|
10
|
+
import type { SwitchBotPlatform } from '../platform.js';
|
|
11
|
+
import type { device, devicesConfig, serviceData, deviceStatus } from '../settings.js';
|
|
12
|
+
import type { Service, PlatformAccessory, CharacteristicValue, CharacteristicChange } from 'homebridge';
|
|
31
13
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
14
|
+
export class Curtain extends deviceBase {
|
|
15
|
+
// Services
|
|
16
|
+
private WindowCovering: {
|
|
17
|
+
Name: CharacteristicValue;
|
|
18
|
+
Service: Service;
|
|
19
|
+
PositionState: CharacteristicValue;
|
|
20
|
+
TargetPosition: CharacteristicValue;
|
|
21
|
+
CurrentPosition: CharacteristicValue;
|
|
22
|
+
HoldPosition: CharacteristicValue;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
private Battery: {
|
|
26
|
+
Name: CharacteristicValue;
|
|
27
|
+
Service: Service;
|
|
28
|
+
BatteryLevel: CharacteristicValue;
|
|
29
|
+
StatusLowBattery: CharacteristicValue;
|
|
30
|
+
ChargingState: CharacteristicValue;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
private LightSensor?: {
|
|
34
|
+
Name: CharacteristicValue;
|
|
35
|
+
Service: Service;
|
|
36
|
+
CurrentAmbientLightLevel?: CharacteristicValue;
|
|
37
|
+
};
|
|
53
38
|
|
|
54
39
|
// Target
|
|
55
40
|
setNewTarget!: boolean;
|
|
56
41
|
setNewTargetTimer!: NodeJS.Timeout;
|
|
57
42
|
|
|
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
43
|
// Updates
|
|
73
44
|
curtainUpdateInProgress!: boolean;
|
|
74
45
|
doCurtainUpdate!: Subject<void>;
|
|
75
46
|
|
|
76
|
-
// Connection
|
|
77
|
-
private readonly OpenAPI: boolean;
|
|
78
|
-
private readonly BLE: boolean;
|
|
79
|
-
|
|
80
|
-
// EVE history service handler
|
|
81
|
-
historyService: any = null;
|
|
82
|
-
|
|
83
47
|
constructor(
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
48
|
+
readonly platform: SwitchBotPlatform,
|
|
49
|
+
accessory: PlatformAccessory,
|
|
50
|
+
device: device & devicesConfig,
|
|
87
51
|
) {
|
|
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
|
-
|
|
52
|
+
super(platform, accessory, device);
|
|
53
|
+
// default placeholder
|
|
54
|
+
this.history(device);
|
|
103
55
|
// this is subject we use to track when we need to POST changes to the SwitchBot API
|
|
104
56
|
this.doCurtainUpdate = new Subject();
|
|
105
57
|
this.curtainUpdateInProgress = false;
|
|
106
58
|
this.setNewTarget = false;
|
|
107
59
|
|
|
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);
|
|
60
|
+
// Initialize WindowCovering Service
|
|
61
|
+
accessory.context.WindowCovering = accessory.context.WindowCovering ?? {};
|
|
62
|
+
this.WindowCovering = {
|
|
63
|
+
Name: accessory.context.WindowCovering.Name ?? accessory.displayName,
|
|
64
|
+
Service: accessory.getService(this.hap.Service.WindowCovering) ?? accessory.addService(this.hap.Service.WindowCovering) as Service,
|
|
65
|
+
PositionState: accessory.context.PositionState ?? this.hap.Characteristic.PositionState.STOPPED,
|
|
66
|
+
TargetPosition: accessory.context.TargetPosition ?? 100,
|
|
67
|
+
CurrentPosition: accessory.context.CurrentPosition ?? 100,
|
|
68
|
+
HoldPosition: accessory.context.HoldPosition ?? false,
|
|
69
|
+
};
|
|
70
|
+
accessory.context.WindowCovering = this.WindowCovering as object;
|
|
71
|
+
|
|
72
|
+
// Initialize WindowCovering Service
|
|
73
|
+
this.WindowCovering.Service.
|
|
74
|
+
setCharacteristic(this.hap.Characteristic.Name, this.WindowCovering.Name)
|
|
75
|
+
.setCharacteristic(this.hap.Characteristic.ObstructionDetected, false)
|
|
76
|
+
.getCharacteristic(this.hap.Characteristic.PositionState)
|
|
77
|
+
.onGet(() => {
|
|
78
|
+
return this.WindowCovering.PositionState;
|
|
79
|
+
});
|
|
135
80
|
|
|
136
|
-
|
|
81
|
+
// Initialize WindowCovering CurrentPosition
|
|
82
|
+
this.WindowCovering.Service
|
|
137
83
|
.getCharacteristic(this.hap.Characteristic.CurrentPosition)
|
|
138
84
|
.setProps({
|
|
139
|
-
minStep:
|
|
85
|
+
minStep: device.curtain?.set_minStep ?? 1,
|
|
140
86
|
minValue: 0,
|
|
141
87
|
maxValue: 100,
|
|
142
88
|
validValueRanges: [0, 100],
|
|
143
89
|
})
|
|
144
90
|
.onGet(() => {
|
|
145
|
-
return this.CurrentPosition;
|
|
91
|
+
return this.WindowCovering.CurrentPosition;
|
|
146
92
|
});
|
|
147
93
|
|
|
148
|
-
|
|
94
|
+
// Initialize WindowCovering TargetPosition
|
|
95
|
+
this.WindowCovering.Service
|
|
149
96
|
.getCharacteristic(this.hap.Characteristic.TargetPosition)
|
|
150
97
|
.setProps({
|
|
151
|
-
minStep:
|
|
98
|
+
minStep: device.curtain?.set_minStep ?? 1,
|
|
152
99
|
minValue: 0,
|
|
153
100
|
maxValue: 100,
|
|
154
101
|
validValueRanges: [0, 100],
|
|
155
102
|
})
|
|
103
|
+
.onGet(() => {
|
|
104
|
+
return this.WindowCovering.TargetPosition;
|
|
105
|
+
})
|
|
156
106
|
.onSet(this.TargetPositionSet.bind(this));
|
|
157
107
|
|
|
158
|
-
|
|
108
|
+
// Initialize WindowCovering TargetPosition
|
|
109
|
+
this.WindowCovering.Service
|
|
159
110
|
.getCharacteristic(this.hap.Characteristic.HoldPosition)
|
|
111
|
+
.onGet(() => {
|
|
112
|
+
return this.WindowCovering.HoldPosition;
|
|
113
|
+
})
|
|
160
114
|
.onSet(this.HoldPositionSet.bind(this));
|
|
161
115
|
|
|
162
|
-
//
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
accessory.
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
116
|
+
// Initialize Battery Service
|
|
117
|
+
accessory.context.Battery = accessory.context.Battery ?? {};
|
|
118
|
+
this.Battery = {
|
|
119
|
+
Name: accessory.context.Battery.Name ?? `${accessory.displayName} Battery`,
|
|
120
|
+
Service: accessory.getService(this.hap.Service.Battery) ?? accessory.addService(this.hap.Service.Battery) as Service,
|
|
121
|
+
BatteryLevel: accessory.context.BatteryLevel ?? 100,
|
|
122
|
+
StatusLowBattery: accessory.context.StatusLowBattery ?? this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL,
|
|
123
|
+
ChargingState: accessory.context.ChargingState ?? this.hap.Characteristic.ChargingState.NOT_CHARGING,
|
|
124
|
+
};
|
|
125
|
+
accessory.context.Battery = this.Battery as object;
|
|
126
|
+
|
|
127
|
+
// Initialize Battery Service
|
|
128
|
+
this.Battery.Service
|
|
129
|
+
.setCharacteristic(this.hap.Characteristic.Name, this.Battery.Name)
|
|
130
|
+
.getCharacteristic(this.hap.Characteristic.BatteryLevel)
|
|
131
|
+
.onGet(() => {
|
|
132
|
+
return this.Battery.BatteryLevel;
|
|
133
|
+
});
|
|
172
134
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Light Sensor Service Not Added`);
|
|
179
|
-
}
|
|
135
|
+
this.Battery.Service
|
|
136
|
+
.getCharacteristic(this.hap.Characteristic.StatusLowBattery)
|
|
137
|
+
.onGet(() => {
|
|
138
|
+
return this.Battery.StatusLowBattery;
|
|
139
|
+
});
|
|
180
140
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
141
|
+
this.Battery.Service
|
|
142
|
+
.getCharacteristic(this.hap.Characteristic.ChargingState)
|
|
143
|
+
.onGet(() => {
|
|
144
|
+
return this.Battery.ChargingState;
|
|
145
|
+
});
|
|
185
146
|
|
|
186
|
-
|
|
187
|
-
if (
|
|
188
|
-
|
|
147
|
+
// Initialize LightSensor Service
|
|
148
|
+
if (device.curtain?.hide_lightsensor) {
|
|
149
|
+
if (this.LightSensor?.Service) {
|
|
150
|
+
this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Removing Light Sensor Service`);
|
|
151
|
+
this.LightSensor.Service = this.accessory.getService(this.hap.Service.LightSensor) as Service;
|
|
152
|
+
accessory.removeService(this.LightSensor.Service);
|
|
153
|
+
accessory.context.LightSensor = {};
|
|
154
|
+
}
|
|
155
|
+
} else {
|
|
156
|
+
accessory.context.LightSensor = accessory.context.LightSensor ?? {};
|
|
157
|
+
this.LightSensor = {
|
|
158
|
+
Name: accessory.context.LightSensor.Name ?? `${accessory.displayName} Light Sensor`,
|
|
159
|
+
Service: accessory.getService(this.hap.Service.LightSensor) ?? this.accessory.addService(this.hap.Service.LightSensor) as Service,
|
|
160
|
+
CurrentAmbientLightLevel: accessory.context.CurrentAmbientLightLevel ?? 0.0001,
|
|
161
|
+
};
|
|
162
|
+
accessory.context.LightSensor = this.LightSensor as object;
|
|
163
|
+
|
|
164
|
+
// Initialize LightSensor Characteristic
|
|
165
|
+
this.LightSensor.Service
|
|
166
|
+
.setCharacteristic(this.hap.Characteristic.Name, this.LightSensor.Name)
|
|
167
|
+
.setCharacteristic(this.hap.Characteristic.StatusActive, true)
|
|
168
|
+
.getCharacteristic(this.hap.Characteristic.CurrentAmbientLightLevel)
|
|
169
|
+
.onGet(() => {
|
|
170
|
+
return this.LightSensor!.CurrentAmbientLightLevel!;
|
|
171
|
+
});
|
|
189
172
|
}
|
|
190
173
|
|
|
174
|
+
// Retrieve initial values and updateHomekit
|
|
175
|
+
this.refreshStatus();
|
|
176
|
+
|
|
191
177
|
// Update Homekit
|
|
192
178
|
this.updateHomeKitCharacteristics();
|
|
193
179
|
|
|
@@ -199,35 +185,17 @@ export class Curtain {
|
|
|
199
185
|
});
|
|
200
186
|
|
|
201
187
|
//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
|
-
}
|
|
188
|
+
this.registerWebhook(accessory, device);
|
|
222
189
|
|
|
223
190
|
// update slide progress
|
|
224
|
-
interval(this.
|
|
191
|
+
interval(this.deviceUpdateRate * 1000)
|
|
225
192
|
//.pipe(skipWhile(() => this.curtainUpdateInProgress))
|
|
226
193
|
.subscribe(async () => {
|
|
227
|
-
if (this.PositionState === this.hap.Characteristic.PositionState.STOPPED) {
|
|
194
|
+
if (this.WindowCovering.PositionState === this.hap.Characteristic.PositionState.STOPPED) {
|
|
228
195
|
return;
|
|
229
196
|
}
|
|
230
|
-
this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Refresh Status When Moving
|
|
197
|
+
this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Refresh Status When Moving,`
|
|
198
|
+
+ ` PositionState: ${this.WindowCovering.PositionState}`);
|
|
231
199
|
await this.refreshStatus();
|
|
232
200
|
});
|
|
233
201
|
|
|
@@ -238,29 +206,37 @@ export class Curtain {
|
|
|
238
206
|
tap(() => {
|
|
239
207
|
this.curtainUpdateInProgress = true;
|
|
240
208
|
}),
|
|
241
|
-
debounceTime(this.
|
|
209
|
+
debounceTime(this.devicePushRate * 1000),
|
|
242
210
|
)
|
|
243
211
|
.subscribe(async () => {
|
|
244
212
|
try {
|
|
245
213
|
await this.pushChanges();
|
|
246
214
|
} catch (e: any) {
|
|
247
215
|
this.apiError(e);
|
|
248
|
-
this.errorLog(
|
|
249
|
-
|
|
250
|
-
` Error Message: ${JSON.stringify(e.message)}`,
|
|
251
|
-
);
|
|
216
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed pushChanges with ${this.device.connectionType} Connection,`
|
|
217
|
+
+ ` Error Message: ${JSON.stringify(e.message)}`);
|
|
252
218
|
}
|
|
253
219
|
this.curtainUpdateInProgress = false;
|
|
254
220
|
});
|
|
255
221
|
|
|
256
222
|
// Setup EVE history features
|
|
257
|
-
this.setupHistoryService(device);
|
|
223
|
+
this.setupHistoryService(accessory, device);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
private history(device: device & devicesConfig) {
|
|
227
|
+
if (device.history === true) {
|
|
228
|
+
// initialize when this accessory is newly created.
|
|
229
|
+
this.accessory.context.lastActivation = this.accessory.context.lastActivation ?? 0;
|
|
230
|
+
} else {
|
|
231
|
+
// removes cached values if history is turned off
|
|
232
|
+
delete this.accessory.context.lastActivation;
|
|
233
|
+
}
|
|
258
234
|
}
|
|
259
235
|
|
|
260
236
|
/*
|
|
261
237
|
* Setup EVE history features for curtain devices.
|
|
262
238
|
*/
|
|
263
|
-
async setupHistoryService(device: device & devicesConfig): Promise<void> {
|
|
239
|
+
async setupHistoryService(accessory: PlatformAccessory, device: device & devicesConfig): Promise<void> {
|
|
264
240
|
if (device.history !== true) {
|
|
265
241
|
return;
|
|
266
242
|
}
|
|
@@ -295,8 +271,7 @@ export class Curtain {
|
|
|
295
271
|
this.accessory.context.lastActivation = entry.time;
|
|
296
272
|
sensor?.updateCharacteristic(
|
|
297
273
|
this.platform.eve.Characteristics.LastActivation,
|
|
298
|
-
Math.max(0, this.accessory.context.lastActivation - this.historyService.getInitialTime())
|
|
299
|
-
);
|
|
274
|
+
Math.max(0, this.accessory.context.lastActivation - this.historyService.getInitialTime()));
|
|
300
275
|
this.historyService.addEntry(entry);
|
|
301
276
|
}
|
|
302
277
|
});
|
|
@@ -304,7 +279,7 @@ export class Curtain {
|
|
|
304
279
|
}
|
|
305
280
|
|
|
306
281
|
async updateHistory(): Promise<void> {
|
|
307
|
-
const motion = Number(this.CurrentPosition) > 0 ? 1 : 0;
|
|
282
|
+
const motion = Number(this.WindowCovering.CurrentPosition) > 0 ? 1 : 0;
|
|
308
283
|
this.historyService.addEntry({
|
|
309
284
|
time: Math.round(new Date().valueOf() / 1000),
|
|
310
285
|
motion: motion,
|
|
@@ -317,198 +292,220 @@ export class Curtain {
|
|
|
317
292
|
);
|
|
318
293
|
}
|
|
319
294
|
|
|
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> {
|
|
295
|
+
async BLEparseStatus(serviceData: serviceData): Promise<void> {
|
|
339
296
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLEparseStatus`);
|
|
297
|
+
this.debugSuccessLog(`${this.device.deviceType}: ${this.accessory.displayName} ${JSON.stringify(serviceData)}`);
|
|
340
298
|
// CurrentPosition
|
|
341
|
-
this.CurrentPosition = 100 - Number(
|
|
299
|
+
this.WindowCovering.CurrentPosition = 100 - Number(serviceData.position!);
|
|
342
300
|
await this.setMinMax();
|
|
343
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} CurrentPosition ${this.CurrentPosition}`);
|
|
301
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} CurrentPosition ${this.WindowCovering.CurrentPosition}`);
|
|
344
302
|
if (this.setNewTarget) {
|
|
345
303
|
this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Checking Status ...`);
|
|
346
304
|
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.
|
|
305
|
+
if (Number(this.WindowCovering.TargetPosition) > this.WindowCovering.CurrentPosition) {
|
|
306
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Closing, CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
|
|
307
|
+
this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.INCREASING;
|
|
308
|
+
this.WindowCovering.Service.getCharacteristic(this.hap.Characteristic.PositionState).updateValue(this.WindowCovering.PositionState);
|
|
309
|
+
this.debugLog(`${this.device.deviceType}: ${this.WindowCovering.CurrentPosition} INCREASING`
|
|
310
|
+
+ ` PositionState: ${this.WindowCovering.PositionState}`);
|
|
311
|
+
} else if (Number(this.WindowCovering.TargetPosition) < this.WindowCovering.CurrentPosition) {
|
|
312
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Opening, CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
|
|
313
|
+
this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.DECREASING;
|
|
314
|
+
this.WindowCovering.Service.getCharacteristic(this.hap.Characteristic.PositionState).updateValue(this.WindowCovering.PositionState);
|
|
315
|
+
this.debugLog(`${this.device.deviceType}: ${this.WindowCovering.CurrentPosition} DECREASING`
|
|
316
|
+
+ ` PositionState: ${this.WindowCovering.PositionState}`);
|
|
357
317
|
} else {
|
|
358
|
-
this.debugLog(`${this.device.deviceType}: ${this.CurrentPosition} Standby
|
|
359
|
-
|
|
360
|
-
this.
|
|
361
|
-
this.
|
|
318
|
+
this.debugLog(`${this.device.deviceType}: ${this.WindowCovering.CurrentPosition} Standby,`
|
|
319
|
+
+ ` CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
|
|
320
|
+
this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.STOPPED;
|
|
321
|
+
this.WindowCovering.Service.getCharacteristic(this.hap.Characteristic.PositionState).updateValue(this.WindowCovering.PositionState);
|
|
322
|
+
this.debugLog(`${this.device.deviceType}: ${this.WindowCovering.CurrentPosition} STOPPED`
|
|
323
|
+
+ ` PositionState: ${this.WindowCovering.PositionState}`);
|
|
362
324
|
}
|
|
363
325
|
} 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;
|
|
326
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Standby, CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
|
|
327
|
+
this.WindowCovering.TargetPosition = this.WindowCovering.CurrentPosition;
|
|
328
|
+
this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.STOPPED;
|
|
367
329
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Stopped`);
|
|
368
330
|
}
|
|
369
|
-
this.debugLog(
|
|
370
|
-
|
|
371
|
-
` TargetPosition: ${this.TargetPosition}, PositionState: ${this.PositionState},`,
|
|
372
|
-
);
|
|
331
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} CurrentPosition: ${this.WindowCovering.CurrentPosition},`
|
|
332
|
+
+ ` TargetPosition: ${this.WindowCovering.TargetPosition}, PositionState: ${this.WindowCovering.PositionState},`);
|
|
373
333
|
|
|
374
334
|
if (!this.device.curtain?.hide_lightsensor) {
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
335
|
+
const set_minLux = this.device.curtain?.set_minLux ?? 1;
|
|
336
|
+
const set_maxLux = this.device.curtain?.set_maxLux ?? 6001;
|
|
337
|
+
const spaceBetweenLevels = 9;
|
|
378
338
|
|
|
339
|
+
serviceData.lightLevel = 1;
|
|
379
340
|
// Brightness
|
|
380
|
-
switch (
|
|
341
|
+
switch (serviceData.lightLevel) {
|
|
381
342
|
case 1:
|
|
382
|
-
this.CurrentAmbientLightLevel =
|
|
383
|
-
|
|
343
|
+
this.LightSensor!.CurrentAmbientLightLevel = ((set_maxLux - set_minLux) / spaceBetweenLevels) * (serviceData.lightLevel === 1
|
|
344
|
+
? set_minLux : 2);
|
|
345
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} 1 LightLevel: ${serviceData.lightLevel},`
|
|
346
|
+
+ ` CurrentAmbientLightLevel: ${this.LightSensor!.CurrentAmbientLightLevel}`);
|
|
347
|
+
this.LightSensor!.CurrentAmbientLightLevel = set_minLux;
|
|
348
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} 2 LightLevel: ${serviceData.lightLevel},`
|
|
349
|
+
+ ` CurrentAmbientLightLevel: ${this.LightSensor!.CurrentAmbientLightLevel}`);
|
|
384
350
|
break;
|
|
385
351
|
case 2:
|
|
386
|
-
this.CurrentAmbientLightLevel = (
|
|
387
|
-
this.debugLog(
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
352
|
+
this.LightSensor!.CurrentAmbientLightLevel = ((set_maxLux - set_minLux) / spaceBetweenLevels) * (Number(serviceData.lightLevel) - 1);
|
|
353
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} 1 LightLevel: ${serviceData.lightLevel},`
|
|
354
|
+
+ ` CurrentAmbientLightLevel: ${this.LightSensor!.CurrentAmbientLightLevel}`);
|
|
355
|
+
this.LightSensor!.CurrentAmbientLightLevel = (set_maxLux - set_minLux) / spaceBetweenLevels;
|
|
356
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} 2 LightLevel: ${serviceData.lightLevel},`
|
|
357
|
+
+ ` CurrentAmbientLightLevel: ${this.LightSensor!.CurrentAmbientLightLevel}`);
|
|
358
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} 3 LightLevel: ${serviceData.lightLevel},`
|
|
359
|
+
+ ` Calculation: ${(set_maxLux - set_minLux) / spaceBetweenLevels}`);
|
|
391
360
|
break;
|
|
392
361
|
case 3:
|
|
393
|
-
this.CurrentAmbientLightLevel = ((
|
|
394
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${
|
|
362
|
+
this.LightSensor!.CurrentAmbientLightLevel = ((set_maxLux - set_minLux) / spaceBetweenLevels) * (Number(serviceData.lightLevel) - 1);
|
|
363
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} 1 LightLevel: ${serviceData.lightLevel},`
|
|
364
|
+
+ ` CurrentAmbientLightLevel: ${this.LightSensor!.CurrentAmbientLightLevel}`);
|
|
365
|
+
this.LightSensor!.CurrentAmbientLightLevel = ((set_maxLux - set_minLux) / spaceBetweenLevels) * 2;
|
|
366
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} 2 LightLevel: ${serviceData.lightLevel},`
|
|
367
|
+
+ ` CurrentAmbientLightLevel: ${this.LightSensor!.CurrentAmbientLightLevel}`);
|
|
368
|
+
this.Battery.ChargingState = this.hap.Characteristic.ChargingState.CHARGING;
|
|
395
369
|
break;
|
|
396
370
|
case 4:
|
|
397
|
-
this.CurrentAmbientLightLevel = ((
|
|
398
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${
|
|
371
|
+
this.LightSensor!.CurrentAmbientLightLevel = ((set_maxLux - set_minLux) / spaceBetweenLevels) * 3;
|
|
372
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${serviceData.lightLevel}`);
|
|
373
|
+
this.Battery.ChargingState = this.hap.Characteristic.ChargingState.CHARGING;
|
|
399
374
|
break;
|
|
400
375
|
case 5:
|
|
401
|
-
this.CurrentAmbientLightLevel = ((
|
|
402
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${
|
|
376
|
+
this.LightSensor!.CurrentAmbientLightLevel = ((set_maxLux - set_minLux) / spaceBetweenLevels) * 4;
|
|
377
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${serviceData.lightLevel}`);
|
|
378
|
+
this.Battery.ChargingState = this.hap.Characteristic.ChargingState.CHARGING;
|
|
403
379
|
break;
|
|
404
380
|
case 6:
|
|
405
|
-
this.CurrentAmbientLightLevel = ((
|
|
406
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${
|
|
381
|
+
this.LightSensor!.CurrentAmbientLightLevel = ((set_maxLux - set_minLux) / spaceBetweenLevels) * 5;
|
|
382
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${serviceData.lightLevel}`);
|
|
383
|
+
this.Battery.ChargingState = this.hap.Characteristic.ChargingState.CHARGING;
|
|
407
384
|
break;
|
|
408
385
|
case 7:
|
|
409
|
-
this.CurrentAmbientLightLevel = ((
|
|
410
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${
|
|
386
|
+
this.LightSensor!.CurrentAmbientLightLevel = ((set_maxLux - set_minLux) / spaceBetweenLevels) * 6;
|
|
387
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${serviceData.lightLevel}`);
|
|
388
|
+
this.Battery.ChargingState = this.hap.Characteristic.ChargingState.CHARGING;
|
|
411
389
|
break;
|
|
412
390
|
case 8:
|
|
413
|
-
this.CurrentAmbientLightLevel = ((
|
|
414
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${
|
|
391
|
+
this.LightSensor!.CurrentAmbientLightLevel = ((set_maxLux - set_minLux) / spaceBetweenLevels) * 7;
|
|
392
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${serviceData.lightLevel}`);
|
|
393
|
+
this.Battery.ChargingState = this.hap.Characteristic.ChargingState.CHARGING;
|
|
415
394
|
break;
|
|
416
395
|
case 9:
|
|
417
|
-
this.CurrentAmbientLightLevel = ((
|
|
418
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${
|
|
396
|
+
this.LightSensor!.CurrentAmbientLightLevel = ((set_maxLux - set_minLux) / spaceBetweenLevels) * 8;
|
|
397
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${serviceData.lightLevel}`);
|
|
398
|
+
this.Battery.ChargingState = this.hap.Characteristic.ChargingState.CHARGING;
|
|
419
399
|
break;
|
|
420
400
|
case 10:
|
|
421
401
|
default:
|
|
422
|
-
this.CurrentAmbientLightLevel =
|
|
402
|
+
this.LightSensor!.CurrentAmbientLightLevel = ((set_maxLux - set_minLux) / spaceBetweenLevels) * (Number(serviceData.lightLevel) - 1);
|
|
403
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} 1 LightLevel: ${serviceData.lightLevel},`
|
|
404
|
+
+ ` CurrentAmbientLightLevel: ${this.LightSensor!.CurrentAmbientLightLevel}`);
|
|
405
|
+
this.LightSensor!.CurrentAmbientLightLevel = set_maxLux;
|
|
406
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} 2 LightLevel: ${serviceData.lightLevel},`
|
|
407
|
+
+ ` CurrentAmbientLightLevel: ${this.LightSensor!.CurrentAmbientLightLevel}`);
|
|
423
408
|
this.debugLog();
|
|
424
409
|
}
|
|
425
|
-
this.debugLog(
|
|
426
|
-
|
|
427
|
-
` CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`,
|
|
428
|
-
);
|
|
410
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${serviceData.lightLevel},`
|
|
411
|
+
+ ` CurrentAmbientLightLevel: ${this.LightSensor!.CurrentAmbientLightLevel}`);
|
|
429
412
|
}
|
|
430
413
|
// Battery
|
|
431
|
-
this.BatteryLevel = Number(
|
|
432
|
-
if (this.BatteryLevel < 10) {
|
|
433
|
-
this.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW;
|
|
414
|
+
this.Battery.BatteryLevel = Number(serviceData.battery);
|
|
415
|
+
if (this.Battery.BatteryLevel < 10) {
|
|
416
|
+
this.Battery.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW;
|
|
434
417
|
} else {
|
|
435
|
-
this.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
|
|
418
|
+
this.Battery.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
|
|
436
419
|
}
|
|
437
|
-
this.debugLog(
|
|
438
|
-
|
|
439
|
-
);
|
|
420
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.Battery.BatteryLevel},`
|
|
421
|
+
+ ` StatusLowBattery: ${this.Battery.StatusLowBattery}`);
|
|
440
422
|
}
|
|
441
423
|
|
|
442
|
-
async openAPIparseStatus(): Promise<void> {
|
|
424
|
+
async openAPIparseStatus(deviceStatus: deviceStatus): Promise<void> {
|
|
443
425
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIparseStatus`);
|
|
444
426
|
// CurrentPosition
|
|
445
|
-
this.CurrentPosition = 100 - Number(
|
|
427
|
+
this.WindowCovering!.CurrentPosition = 100 - Number(deviceStatus.body.slidePosition);
|
|
446
428
|
await this.setMinMax();
|
|
447
|
-
this.debugLog(`Curtain ${this.accessory.displayName} CurrentPosition: ${this.CurrentPosition}`);
|
|
429
|
+
this.debugLog(`Curtain ${this.accessory.displayName} CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
|
|
448
430
|
if (this.setNewTarget) {
|
|
449
431
|
this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Checking Status ...`);
|
|
450
432
|
}
|
|
451
433
|
|
|
452
|
-
if (this.setNewTarget &&
|
|
434
|
+
if (this.setNewTarget && deviceStatus.body.moving) {
|
|
453
435
|
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.
|
|
436
|
+
if (Number(this.WindowCovering.TargetPosition) > this.WindowCovering.CurrentPosition) {
|
|
437
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Closing, CurrentPosition: ${this.WindowCovering.CurrentPosition} `);
|
|
438
|
+
this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.INCREASING;
|
|
439
|
+
this.WindowCovering.Service.getCharacteristic(this.hap.Characteristic.PositionState).updateValue(this.WindowCovering.PositionState);
|
|
440
|
+
this.debugLog(`${this.device.deviceType}: ${this.WindowCovering.CurrentPosition} INCREASING`
|
|
441
|
+
+ ` PositionState: ${this.WindowCovering.PositionState}`);
|
|
442
|
+
} else if (Number(this.WindowCovering.TargetPosition) < this.WindowCovering.CurrentPosition) {
|
|
443
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Opening, CurrentPosition: ${this.WindowCovering.CurrentPosition} `);
|
|
444
|
+
this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.DECREASING;
|
|
445
|
+
this.WindowCovering.Service.getCharacteristic(this.hap.Characteristic.PositionState).updateValue(this.WindowCovering.PositionState);
|
|
446
|
+
this.debugLog(`${this.device.deviceType}: ${this.WindowCovering.CurrentPosition} DECREASING`
|
|
447
|
+
+ ` PositionState: ${this.WindowCovering.PositionState}`);
|
|
464
448
|
} else {
|
|
465
|
-
this.debugLog(`${this.device.deviceType}: ${this.CurrentPosition} Standby
|
|
466
|
-
|
|
467
|
-
this.
|
|
468
|
-
this.
|
|
449
|
+
this.debugLog(`${this.device.deviceType}: ${this.WindowCovering.CurrentPosition} Standby,`
|
|
450
|
+
+ ` CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
|
|
451
|
+
this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.STOPPED;
|
|
452
|
+
this.WindowCovering.Service.getCharacteristic(this.hap.Characteristic.PositionState).updateValue(this.WindowCovering.PositionState);
|
|
453
|
+
this.debugLog(`${this.device.deviceType}: ${this.WindowCovering.CurrentPosition} STOPPED`
|
|
454
|
+
+ ` PositionState: ${this.WindowCovering.PositionState}`);
|
|
469
455
|
}
|
|
470
456
|
} 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;
|
|
457
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Standby, CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
|
|
458
|
+
this.WindowCovering.TargetPosition = this.WindowCovering.CurrentPosition;
|
|
459
|
+
this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.STOPPED;
|
|
474
460
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Stopped`);
|
|
475
461
|
}
|
|
476
|
-
this.debugLog(
|
|
477
|
-
|
|
478
|
-
` TargetPosition: ${this.TargetPosition}, PositionState: ${this.PositionState},`,
|
|
479
|
-
);
|
|
462
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} CurrentPosition: ${this.WindowCovering.CurrentPosition},`
|
|
463
|
+
+ ` TargetPosition: ${this.WindowCovering.TargetPosition}, PositionState: ${this.WindowCovering.PositionState},`);
|
|
480
464
|
|
|
481
465
|
// Brightness
|
|
482
466
|
if (!this.device.curtain?.hide_lightsensor) {
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
switch (
|
|
486
|
-
case 'dim':
|
|
487
|
-
this.CurrentAmbientLightLevel = this.set_minLux;
|
|
488
|
-
break;
|
|
467
|
+
const set_minLux = this.device.curtain?.set_minLux ?? 1;
|
|
468
|
+
const set_maxLux = this.device.curtain?.set_maxLux ?? 6001;
|
|
469
|
+
switch (deviceStatus.body.brightness) {
|
|
489
470
|
case 'bright':
|
|
471
|
+
this.LightSensor!.CurrentAmbientLightLevel = set_maxLux;
|
|
472
|
+
this.Battery.ChargingState = this.hap.Characteristic.ChargingState.CHARGING;
|
|
473
|
+
break;
|
|
474
|
+
case 'dim':
|
|
490
475
|
default:
|
|
491
|
-
this.CurrentAmbientLightLevel =
|
|
476
|
+
this.LightSensor!.CurrentAmbientLightLevel = set_minLux;
|
|
492
477
|
}
|
|
493
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}
|
|
478
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}`
|
|
479
|
+
+ ` CurrentAmbientLightLevel: ${this.LightSensor!.CurrentAmbientLightLevel}`);
|
|
494
480
|
}
|
|
495
481
|
|
|
496
482
|
// BatteryLevel
|
|
497
|
-
this.BatteryLevel = Number(
|
|
498
|
-
if (this.BatteryLevel < 10) {
|
|
499
|
-
this.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW;
|
|
483
|
+
this.Battery.BatteryLevel = Number(deviceStatus.body.battery);
|
|
484
|
+
if (this.Battery.BatteryLevel < 10) {
|
|
485
|
+
this.Battery.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW;
|
|
500
486
|
} else {
|
|
501
|
-
this.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
|
|
487
|
+
this.Battery.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
|
|
502
488
|
}
|
|
503
|
-
if (Number.isNaN(this.BatteryLevel)) {
|
|
504
|
-
this.BatteryLevel = 100;
|
|
489
|
+
if (Number.isNaN(this.Battery.BatteryLevel)) {
|
|
490
|
+
this.Battery.BatteryLevel = 100;
|
|
505
491
|
}
|
|
506
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.BatteryLevel},`
|
|
507
|
-
+ ` StatusLowBattery: ${this.StatusLowBattery}`);
|
|
492
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.Battery.BatteryLevel},`
|
|
493
|
+
+ ` StatusLowBattery: ${this.Battery.StatusLowBattery}`);
|
|
508
494
|
|
|
509
|
-
//
|
|
510
|
-
|
|
511
|
-
this.
|
|
495
|
+
// Firmware Version
|
|
496
|
+
const version = deviceStatus.body.version?.toString();
|
|
497
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Firmware Version: ${version?.replace(/^V|-.*$/g, '')}`);
|
|
498
|
+
if (deviceStatus.body.version) {
|
|
499
|
+
const deviceVersion = version?.replace(/^V|-.*$/g, '') ?? '0.0.0';
|
|
500
|
+
this.accessory
|
|
501
|
+
.getService(this.hap.Service.AccessoryInformation)!
|
|
502
|
+
.setCharacteristic(this.hap.Characteristic.HardwareRevision, deviceVersion)
|
|
503
|
+
.setCharacteristic(this.hap.Characteristic.FirmwareRevision, deviceVersion)
|
|
504
|
+
.getCharacteristic(this.hap.Characteristic.FirmwareRevision)
|
|
505
|
+
.updateValue(deviceVersion);
|
|
506
|
+
this.accessory.context.deviceVersion = deviceVersion;
|
|
507
|
+
this.debugSuccessLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceVersion: ${this.accessory.context.deviceVersion}`);
|
|
508
|
+
}
|
|
512
509
|
}
|
|
513
510
|
|
|
514
511
|
async refreshStatus(): Promise<void> {
|
|
@@ -520,147 +517,73 @@ export class Curtain {
|
|
|
520
517
|
await this.openAPIRefreshStatus();
|
|
521
518
|
} else {
|
|
522
519
|
await this.offlineOff();
|
|
523
|
-
this.debugWarnLog(
|
|
524
|
-
|
|
525
|
-
` ${this.device.connectionType}, refreshStatus will not happen.`,
|
|
526
|
-
);
|
|
520
|
+
this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:`
|
|
521
|
+
+ ` ${this.device.connectionType}, refreshStatus will not happen.`);
|
|
527
522
|
}
|
|
528
523
|
}
|
|
529
524
|
|
|
530
525
|
async BLERefreshStatus(): Promise<void> {
|
|
531
526
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLERefreshStatus`);
|
|
532
|
-
const switchbot = await this.
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
.
|
|
536
|
-
|
|
537
|
-
.toLowerCase();
|
|
538
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
|
|
539
|
-
this.getCustomBLEAddress(switchbot);
|
|
527
|
+
const switchbot = await this.switchbotBLE();
|
|
528
|
+
|
|
529
|
+
if (switchbot === undefined) {
|
|
530
|
+
await this.BLERefreshConnection(switchbot);
|
|
531
|
+
} else {
|
|
540
532
|
// Start to monitor advertisement packets
|
|
541
|
-
|
|
542
|
-
switch (this.device.configDeviceType) {
|
|
543
|
-
case 'Curtain3':
|
|
544
|
-
model = '{';
|
|
545
|
-
break;
|
|
546
|
-
default:
|
|
547
|
-
model = 'c';
|
|
548
|
-
}
|
|
549
|
-
(async () => {
|
|
533
|
+
(async () => {
|
|
550
534
|
// Start to monitor advertisement packets
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
switchbot.onadvertisement = (ad: any) => {
|
|
557
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} ${JSON.stringify(ad, null, ' ')}`);
|
|
558
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} address: ${ad.address}, model: ${ad.serviceData.model}`);
|
|
559
|
-
if (this.device.bleMac === ad.address && ad.serviceData.model === 'c') {
|
|
560
|
-
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;
|
|
535
|
+
const serviceData: serviceData = await this.monitorAdvertisementPackets(switchbot);
|
|
536
|
+
// Update HomeKit
|
|
537
|
+
if (serviceData.model !== '' && serviceData.modelName !== '') {
|
|
538
|
+
await this.BLEparseStatus(serviceData);
|
|
539
|
+
await this.updateHomeKitCharacteristics();
|
|
566
540
|
} else {
|
|
567
|
-
this.
|
|
568
|
-
}
|
|
569
|
-
};
|
|
570
|
-
// Wait 1 seconds
|
|
571
|
-
await switchbot.wait(this.scanDuration * 1000);
|
|
572
|
-
// Stop to monitor
|
|
573
|
-
await switchbot.stopScan();
|
|
574
|
-
// Update HomeKit
|
|
575
|
-
await this.BLEparseStatus();
|
|
576
|
-
await this.updateHomeKitCharacteristics();
|
|
577
|
-
})();
|
|
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
|
-
);
|
|
541
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed to get serviceData, serviceData: ${serviceData}`);
|
|
627
542
|
await this.BLERefreshConnection(switchbot);
|
|
628
|
-
}
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
}*/
|
|
543
|
+
}
|
|
544
|
+
})();
|
|
545
|
+
}
|
|
632
546
|
}
|
|
633
547
|
|
|
634
548
|
async openAPIRefreshStatus(): Promise<void> {
|
|
635
549
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus`);
|
|
636
550
|
try {
|
|
637
|
-
const { body, statusCode } = await
|
|
638
|
-
headers: this.platform.generateHeaders(),
|
|
639
|
-
});
|
|
640
|
-
this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} statusCode: ${statusCode}`);
|
|
551
|
+
const { body, statusCode } = await this.deviceRefreshStatus();
|
|
641
552
|
const deviceStatus: any = await body.json();
|
|
642
|
-
this.
|
|
643
|
-
this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus statusCode: ${deviceStatus.statusCode}`);
|
|
553
|
+
await this.refreshStatusCodes(statusCode, deviceStatus);
|
|
644
554
|
if ((statusCode === 200 || statusCode === 100) && (deviceStatus.statusCode === 200 || deviceStatus.statusCode === 100)) {
|
|
645
|
-
this.
|
|
646
|
-
|
|
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();
|
|
653
|
-
this.updateHomeKitCharacteristics();
|
|
555
|
+
await this.successfulRefreshStatus(statusCode, deviceStatus);
|
|
556
|
+
await this.openAPIparseStatus(deviceStatus);
|
|
557
|
+
await this.updateHomeKitCharacteristics();
|
|
654
558
|
} else {
|
|
655
|
-
this.
|
|
656
|
-
this.statusCode(deviceStatus.statusCode);
|
|
559
|
+
await this.statusCodes(statusCode, deviceStatus);
|
|
657
560
|
}
|
|
658
561
|
} catch (e: any) {
|
|
659
562
|
this.apiError(e);
|
|
660
|
-
this.errorLog(
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
563
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed openAPIRefreshStatus with ${this.device.connectionType}`
|
|
564
|
+
+ ` Connection, Error Message: ${JSON.stringify(e.message)}`);
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
async registerWebhook(accessory: PlatformAccessory, device: device & devicesConfig) {
|
|
569
|
+
if (device.webhook) {
|
|
570
|
+
this.debugLog(`${device.deviceType}: ${accessory.displayName} is listening webhook.`);
|
|
571
|
+
this.platform.webhookEventHandler[device.deviceId] = async (context) => {
|
|
572
|
+
try {
|
|
573
|
+
this.debugLog(`${device.deviceType}: ${accessory.displayName} received Webhook: ${JSON.stringify(context)}`);
|
|
574
|
+
const { slidePosition, battery } = context;
|
|
575
|
+
this.debugLog(`${device.deviceType}: ${accessory.displayName} ` +
|
|
576
|
+
'(slidePosition, battery) = ' +
|
|
577
|
+
`Webhook:(${slidePosition}, ${battery}), `
|
|
578
|
+
+ `current:(${this.WindowCovering.CurrentPosition}, ${this.Battery.BatteryLevel})`);
|
|
579
|
+
this.WindowCovering.CurrentPosition = slidePosition;
|
|
580
|
+
this.Battery.BatteryLevel = battery;
|
|
581
|
+
this.updateHomeKitCharacteristics();
|
|
582
|
+
} catch (e: any) {
|
|
583
|
+
this.errorLog(`${device.deviceType}: ${accessory.displayName} `
|
|
584
|
+
+ `failed to handle webhook. Received: ${JSON.stringify(context)} Error: ${e}`);
|
|
585
|
+
}
|
|
586
|
+
};
|
|
664
587
|
}
|
|
665
588
|
}
|
|
666
589
|
|
|
@@ -673,9 +596,8 @@ export class Curtain {
|
|
|
673
596
|
await this.openAPIpushChanges();
|
|
674
597
|
} else {
|
|
675
598
|
await this.offlineOff();
|
|
676
|
-
this.debugWarnLog(
|
|
677
|
-
|
|
678
|
-
);
|
|
599
|
+
this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:`
|
|
600
|
+
+ ` ${this.device.connectionType}, pushChanges will not happen.`);
|
|
679
601
|
}
|
|
680
602
|
// Refresh the status from the API
|
|
681
603
|
interval(15000)
|
|
@@ -688,36 +610,32 @@ export class Curtain {
|
|
|
688
610
|
|
|
689
611
|
async BLEpushChanges(): Promise<void> {
|
|
690
612
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLEpushChanges`);
|
|
691
|
-
if (this.TargetPosition !== this.CurrentPosition) {
|
|
613
|
+
if (this.WindowCovering.TargetPosition !== this.WindowCovering.CurrentPosition) {
|
|
692
614
|
const switchbot = await this.platform.connectBLE();
|
|
693
615
|
// Convert to BLE Address
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
|
|
699
|
-
this.SilentPerformance();
|
|
700
|
-
const adjustedMode = this.setPositionMode === '1' ? 0x01 : 0xff;
|
|
701
|
-
this.debugLog(`${this.accessory.displayName} Mode: ${this.Mode}`);
|
|
616
|
+
await this.convertBLEAddress();
|
|
617
|
+
const { setPositionMode, Mode }: { setPositionMode: number; Mode: string; } = await this.setPerformance();
|
|
618
|
+
const adjustedMode = setPositionMode === 1 ? 0x01 : 0xff;
|
|
619
|
+
this.debugLog(`${this.accessory.displayName} Mode: ${Mode}`);
|
|
702
620
|
if (switchbot !== false) {
|
|
703
621
|
try {
|
|
704
|
-
const device_list = await switchbot.discover({ model:
|
|
705
|
-
this.infoLog(`${this.accessory.displayName} Target Position: ${this.TargetPosition}`);
|
|
622
|
+
const device_list = await switchbot.discover({ model: this.device.bleModel, quick: true, id: this.device.bleMac });
|
|
623
|
+
this.infoLog(`${this.accessory.displayName} Target Position: ${this.WindowCovering.TargetPosition}`);
|
|
706
624
|
|
|
707
|
-
await this.
|
|
708
|
-
max: this.
|
|
625
|
+
await this.retryBLE({
|
|
626
|
+
max: await this.maxRetryBLE(),
|
|
709
627
|
fn: async () => {
|
|
710
|
-
await device_list[0].runToPos(100 - Number(this.TargetPosition), adjustedMode);
|
|
628
|
+
await device_list[0].runToPos(100 - Number(this.WindowCovering.TargetPosition), adjustedMode);
|
|
711
629
|
},
|
|
712
630
|
});
|
|
713
631
|
|
|
714
632
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Done.`);
|
|
633
|
+
this.successLog(`${this.device.deviceType}: ${this.accessory.displayName} `
|
|
634
|
+
+ `TargetPosition: ${this.WindowCovering.TargetPosition} sent over BLE, sent successfully`);
|
|
715
635
|
} catch (e) {
|
|
716
636
|
this.apiError(e);
|
|
717
|
-
this.errorLog(
|
|
718
|
-
|
|
719
|
-
` Connection, Error Message: ${JSON.stringify((e as Error).message)}`,
|
|
720
|
-
);
|
|
637
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed BLEpushChanges with ${this.device.connectionType}`
|
|
638
|
+
+ ` Connection, Error Message: ${JSON.stringify((e as Error).message)}`);
|
|
721
639
|
await this.BLEPushConnection();
|
|
722
640
|
throw new Error('Connection error');
|
|
723
641
|
}
|
|
@@ -726,30 +644,8 @@ export class Curtain {
|
|
|
726
644
|
await this.BLEPushConnection();
|
|
727
645
|
}
|
|
728
646
|
} 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;
|
|
647
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} No BLEpushChanges, CurrentPosition & TargetPosition Are the Same.`
|
|
648
|
+
+ ` CurrentPosition: ${this.WindowCovering.CurrentPosition}, TargetPosition ${this.WindowCovering.TargetPosition}`);
|
|
753
649
|
}
|
|
754
650
|
}
|
|
755
651
|
|
|
@@ -758,24 +654,13 @@ export class Curtain {
|
|
|
758
654
|
let parameter: string;
|
|
759
655
|
let commandType: string;
|
|
760
656
|
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) {
|
|
657
|
+
if (this.WindowCovering.TargetPosition !== this.WindowCovering.CurrentPosition || this.device.disableCaching) {
|
|
658
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Pushing ${this.WindowCovering.TargetPosition}`);
|
|
659
|
+
const adjustedTargetPosition = 100 - Number(this.WindowCovering.TargetPosition);
|
|
660
|
+
const { setPositionMode, Mode }: { setPositionMode: number; Mode: string; } = await this.setPerformance();
|
|
661
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Mode: ${Mode}`);
|
|
662
|
+
const adjustedMode = setPositionMode || 'ff';
|
|
663
|
+
if (this.WindowCovering.HoldPosition) {
|
|
779
664
|
command = 'pause';
|
|
780
665
|
parameter = 'default';
|
|
781
666
|
commandType = 'command';
|
|
@@ -791,35 +676,26 @@ export class Curtain {
|
|
|
791
676
|
});
|
|
792
677
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Sending request to SwitchBot API, body: ${bodyChange},`);
|
|
793
678
|
try {
|
|
794
|
-
const { body, statusCode } = await
|
|
795
|
-
body: bodyChange,
|
|
796
|
-
method: 'POST',
|
|
797
|
-
headers: this.platform.generateHeaders(),
|
|
798
|
-
});
|
|
799
|
-
this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} statusCode: ${statusCode}`);
|
|
679
|
+
const { body, statusCode } = await this.pushChangeRequest(bodyChange);
|
|
800
680
|
const deviceStatus: any = await body.json();
|
|
801
|
-
this.
|
|
802
|
-
this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus body: ${JSON.stringify(deviceStatus.body)}`);
|
|
803
|
-
this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus statusCode: ${deviceStatus.statusCode}`);
|
|
681
|
+
await this.pushStatusCodes(statusCode, deviceStatus);
|
|
804
682
|
if ((statusCode === 200 || statusCode === 100) && (deviceStatus.statusCode === 200 || deviceStatus.statusCode === 100)) {
|
|
805
683
|
this.debugErrorLog(`${this.device.deviceType}: ${this.accessory.displayName} `
|
|
806
684
|
+ `statusCode: ${statusCode} & deviceStatus StatusCode: ${deviceStatus.statusCode}`);
|
|
685
|
+
this.successLog(`${this.device.deviceType}: ${this.accessory.displayName} `
|
|
686
|
+
+ `request to SwitchBot API, body: ${JSON.stringify(JSON.parse(bodyChange))} sent successfully`);
|
|
807
687
|
} else {
|
|
808
688
|
this.statusCode(statusCode);
|
|
809
689
|
this.statusCode(deviceStatus.statusCode);
|
|
810
690
|
}
|
|
811
691
|
} catch (e: any) {
|
|
812
692
|
this.apiError(e);
|
|
813
|
-
this.errorLog(
|
|
814
|
-
|
|
815
|
-
` Connection, Error Message: ${JSON.stringify(e.message)}`,
|
|
816
|
-
);
|
|
693
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed openAPIpushChanges with ${this.device.connectionType}`
|
|
694
|
+
+ ` Connection, Error Message: ${JSON.stringify(e.message)}`);
|
|
817
695
|
}
|
|
818
696
|
} else {
|
|
819
|
-
this.debugLog(
|
|
820
|
-
|
|
821
|
-
` CurrentPosition: ${this.CurrentPosition}, TargetPosition ${this.TargetPosition}`,
|
|
822
|
-
);
|
|
697
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} No OpenAPI Changes, CurrentPosition & TargetPosition Are the Same.`
|
|
698
|
+
+ ` CurrentPosition: ${this.WindowCovering.CurrentPosition}, TargetPosition ${this.WindowCovering.TargetPosition}`);
|
|
823
699
|
}
|
|
824
700
|
}
|
|
825
701
|
|
|
@@ -827,50 +703,53 @@ export class Curtain {
|
|
|
827
703
|
* Handle requests to set the value of the "Target Position" characteristic
|
|
828
704
|
*/
|
|
829
705
|
async TargetPositionSet(value: CharacteristicValue): Promise<void> {
|
|
830
|
-
if (this.TargetPosition === this.accessory.context.TargetPosition) {
|
|
706
|
+
if (this.WindowCovering.TargetPosition === this.accessory.context.TargetPosition) {
|
|
831
707
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} No Changes, Set TargetPosition: ${value}`);
|
|
832
708
|
} else {
|
|
833
709
|
this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Set TargetPosition: ${value}`);
|
|
834
710
|
}
|
|
835
711
|
|
|
836
712
|
// Set HoldPosition to false when TargetPosition is changed
|
|
837
|
-
this.HoldPosition = false;
|
|
838
|
-
this.
|
|
713
|
+
this.WindowCovering.HoldPosition = false;
|
|
714
|
+
this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.HoldPosition, this.WindowCovering.HoldPosition);
|
|
839
715
|
|
|
840
|
-
this.TargetPosition = value;
|
|
716
|
+
this.WindowCovering.TargetPosition = value;
|
|
841
717
|
if (this.device.mqttURL) {
|
|
842
|
-
this.mqttPublish('TargetPosition', this.TargetPosition);
|
|
843
|
-
this.mqttPublish('HoldPosition', this.HoldPosition);
|
|
718
|
+
this.mqttPublish('TargetPosition', this.WindowCovering.TargetPosition.toString());
|
|
719
|
+
this.mqttPublish('HoldPosition', this.WindowCovering.HoldPosition.toString()); // Convert boolean to string
|
|
844
720
|
}
|
|
845
721
|
|
|
846
722
|
await this.setMinMax();
|
|
847
|
-
if (value > this.CurrentPosition) {
|
|
848
|
-
this.PositionState = this.hap.Characteristic.PositionState.INCREASING;
|
|
723
|
+
if (value > this.WindowCovering.CurrentPosition) {
|
|
724
|
+
this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.INCREASING;
|
|
849
725
|
this.setNewTarget = true;
|
|
850
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} value: ${value}
|
|
851
|
-
|
|
852
|
-
|
|
726
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} value: ${value},`
|
|
727
|
+
+ ` CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
|
|
728
|
+
} else if (value < this.WindowCovering.CurrentPosition) {
|
|
729
|
+
this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.DECREASING;
|
|
853
730
|
this.setNewTarget = true;
|
|
854
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} value: ${value}
|
|
731
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} value: ${value},`
|
|
732
|
+
+ ` CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
|
|
855
733
|
} else {
|
|
856
|
-
this.PositionState = this.hap.Characteristic.PositionState.STOPPED;
|
|
734
|
+
this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.STOPPED;
|
|
857
735
|
this.setNewTarget = false;
|
|
858
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} value: ${value}
|
|
736
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} value: ${value},`
|
|
737
|
+
+ ` CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
|
|
859
738
|
}
|
|
860
|
-
this.
|
|
861
|
-
this.
|
|
739
|
+
this.WindowCovering.Service.setCharacteristic(this.hap.Characteristic.PositionState, this.WindowCovering.PositionState);
|
|
740
|
+
this.WindowCovering.Service.getCharacteristic(this.hap.Characteristic.PositionState).updateValue(this.WindowCovering.PositionState);
|
|
862
741
|
|
|
863
742
|
/**
|
|
864
743
|
* If Curtain movement time is short, the moving flag from backend is always false.
|
|
865
744
|
* The minimum time depends on the network control latency.
|
|
866
745
|
*/
|
|
867
746
|
clearTimeout(this.setNewTargetTimer);
|
|
868
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateRate: ${this.
|
|
747
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateRate: ${this.deviceUpdateRate}`);
|
|
869
748
|
if (this.setNewTarget) {
|
|
870
749
|
this.setNewTargetTimer = setTimeout(() => {
|
|
871
750
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} setNewTarget ${this.setNewTarget} timeout`);
|
|
872
751
|
this.setNewTarget = false;
|
|
873
|
-
}, this.
|
|
752
|
+
}, this.deviceUpdateRate * 1000);
|
|
874
753
|
}
|
|
875
754
|
this.doCurtainUpdate.next();
|
|
876
755
|
}
|
|
@@ -880,153 +759,107 @@ export class Curtain {
|
|
|
880
759
|
*/
|
|
881
760
|
async HoldPositionSet(value: CharacteristicValue): Promise<void> {
|
|
882
761
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} HoldPosition: ${value}`);
|
|
883
|
-
this.HoldPosition = value;
|
|
762
|
+
this.WindowCovering.HoldPosition = value;
|
|
884
763
|
this.doCurtainUpdate.next();
|
|
885
764
|
}
|
|
886
765
|
|
|
887
766
|
async updateHomeKitCharacteristics(): Promise<void> {
|
|
888
767
|
await this.setMinMax();
|
|
889
|
-
if (this.CurrentPosition === undefined || Number.isNaN(this.CurrentPosition)) {
|
|
890
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} CurrentPosition: ${this.CurrentPosition}`);
|
|
768
|
+
if (this.WindowCovering.CurrentPosition === undefined || Number.isNaN(this.WindowCovering.CurrentPosition)) {
|
|
769
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
|
|
891
770
|
} else {
|
|
771
|
+
this.accessory.context.CurrentPosition = this.WindowCovering.CurrentPosition;
|
|
772
|
+
this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.CurrentPosition, Number(this.WindowCovering.CurrentPosition));
|
|
773
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic`
|
|
774
|
+
+ ` CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
|
|
892
775
|
if (this.device.mqttURL) {
|
|
893
|
-
this.mqttPublish('CurrentPosition', this.CurrentPosition);
|
|
776
|
+
this.mqttPublish('CurrentPosition', this.WindowCovering.CurrentPosition.toString()); // Convert to string
|
|
894
777
|
}
|
|
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
778
|
}
|
|
899
|
-
if (this.PositionState === undefined) {
|
|
900
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} PositionState: ${this.PositionState}`);
|
|
779
|
+
if (this.WindowCovering.PositionState === undefined) {
|
|
780
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} PositionState: ${this.WindowCovering.PositionState}`);
|
|
901
781
|
} else {
|
|
902
782
|
if (this.device.mqttURL) {
|
|
903
|
-
this.mqttPublish('PositionState', this.PositionState);
|
|
783
|
+
this.mqttPublish('PositionState', this.WindowCovering.PositionState.toString());
|
|
904
784
|
}
|
|
905
|
-
this.accessory.context.PositionState = this.PositionState;
|
|
906
|
-
this.
|
|
907
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic
|
|
785
|
+
this.accessory.context.PositionState = this.WindowCovering.PositionState;
|
|
786
|
+
this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.PositionState, Number(this.WindowCovering.PositionState));
|
|
787
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic`
|
|
788
|
+
+ ` PositionState: ${this.WindowCovering.PositionState}`);
|
|
908
789
|
}
|
|
909
|
-
if (this.TargetPosition === undefined || Number.isNaN(this.TargetPosition)) {
|
|
910
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} TargetPosition: ${this.TargetPosition}`);
|
|
790
|
+
if (this.WindowCovering.TargetPosition === undefined || Number.isNaN(this.WindowCovering.TargetPosition)) {
|
|
791
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} TargetPosition: ${this.WindowCovering.TargetPosition}`);
|
|
911
792
|
} else {
|
|
912
793
|
if (this.device.mqttURL) {
|
|
913
|
-
this.mqttPublish('TargetPosition', this.TargetPosition);
|
|
794
|
+
this.mqttPublish('TargetPosition', this.WindowCovering.TargetPosition.toString());
|
|
914
795
|
}
|
|
915
|
-
this.accessory.context.TargetPosition = this.TargetPosition;
|
|
916
|
-
this.
|
|
917
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic
|
|
796
|
+
this.accessory.context.TargetPosition = this.WindowCovering.TargetPosition;
|
|
797
|
+
this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.TargetPosition, Number(this.WindowCovering.TargetPosition));
|
|
798
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic`
|
|
799
|
+
+ ` TargetPosition: ${this.WindowCovering.TargetPosition}`);
|
|
918
800
|
}
|
|
919
|
-
if (this.HoldPosition === undefined) {
|
|
920
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} HoldPosition: ${this.HoldPosition}`);
|
|
801
|
+
if (this.WindowCovering.HoldPosition === undefined) {
|
|
802
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} HoldPosition: ${this.WindowCovering.HoldPosition}`);
|
|
921
803
|
} else {
|
|
922
804
|
if (this.device.mqttURL) {
|
|
923
|
-
this.mqttPublish('HoldPosition', this.HoldPosition);
|
|
805
|
+
this.mqttPublish('HoldPosition', this.WindowCovering.HoldPosition.toString());
|
|
924
806
|
}
|
|
925
|
-
this.accessory.context.HoldPosition = this.HoldPosition;
|
|
926
|
-
this.
|
|
927
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic
|
|
807
|
+
this.accessory.context.HoldPosition = this.WindowCovering.HoldPosition;
|
|
808
|
+
this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.HoldPosition, this.WindowCovering.HoldPosition);
|
|
809
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic`
|
|
810
|
+
+ ` HoldPosition: ${this.WindowCovering.HoldPosition}`);
|
|
928
811
|
}
|
|
929
812
|
if (!this.device.curtain?.hide_lightsensor) {
|
|
930
|
-
if (this.CurrentAmbientLightLevel === undefined || Number.isNaN(this.CurrentAmbientLightLevel)) {
|
|
931
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}
|
|
813
|
+
if (this.LightSensor!.CurrentAmbientLightLevel === undefined || Number.isNaN(this.LightSensor!.CurrentAmbientLightLevel)) {
|
|
814
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}`
|
|
815
|
+
+ ` CurrentAmbientLightLevel: ${this.LightSensor!.CurrentAmbientLightLevel}`);
|
|
932
816
|
} else {
|
|
933
817
|
if (this.device.mqttURL) {
|
|
934
|
-
this.mqttPublish('CurrentAmbientLightLevel', this.CurrentAmbientLightLevel);
|
|
818
|
+
this.mqttPublish('CurrentAmbientLightLevel', this.LightSensor!.CurrentAmbientLightLevel.toString());
|
|
935
819
|
}
|
|
936
|
-
this.accessory.context.CurrentAmbientLightLevel = this.CurrentAmbientLightLevel;
|
|
937
|
-
this.
|
|
938
|
-
this.debugLog(
|
|
939
|
-
|
|
940
|
-
` updateCharacteristic CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`,
|
|
941
|
-
);
|
|
820
|
+
this.accessory.context.CurrentAmbientLightLevel = this.LightSensor!.CurrentAmbientLightLevel;
|
|
821
|
+
this.LightSensor!.Service.updateCharacteristic(this.hap.Characteristic.CurrentAmbientLightLevel, this.LightSensor!.CurrentAmbientLightLevel);
|
|
822
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}`
|
|
823
|
+
+ ` updateCharacteristic CurrentAmbientLightLevel: ${this.LightSensor!.CurrentAmbientLightLevel}`);
|
|
942
824
|
if (this.device.history) {
|
|
943
825
|
this.historyService?.addEntry({
|
|
944
826
|
time: Math.round(new Date().valueOf() / 1000),
|
|
945
|
-
lux: this.CurrentAmbientLightLevel,
|
|
827
|
+
lux: this.LightSensor!.CurrentAmbientLightLevel,
|
|
946
828
|
});
|
|
947
829
|
}
|
|
948
830
|
}
|
|
949
831
|
}
|
|
950
|
-
if (this.BatteryLevel === undefined) {
|
|
951
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.BatteryLevel}`);
|
|
832
|
+
if (this.Battery.BatteryLevel === undefined) {
|
|
833
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.Battery.BatteryLevel}`);
|
|
952
834
|
} else {
|
|
953
835
|
if (this.device.mqttURL) {
|
|
954
|
-
this.mqttPublish('BatteryLevel', this.BatteryLevel);
|
|
836
|
+
this.mqttPublish('BatteryLevel', this.Battery.BatteryLevel.toString());
|
|
955
837
|
}
|
|
956
|
-
this.accessory.context.BatteryLevel = this.BatteryLevel;
|
|
957
|
-
this.
|
|
958
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic BatteryLevel: ${this.BatteryLevel}`);
|
|
838
|
+
this.accessory.context.BatteryLevel = this.Battery.BatteryLevel;
|
|
839
|
+
this.Battery.Service.updateCharacteristic(this.hap.Characteristic.BatteryLevel, this.Battery.BatteryLevel);
|
|
840
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic BatteryLevel: ${this.Battery.BatteryLevel}`);
|
|
959
841
|
}
|
|
960
|
-
if (this.StatusLowBattery === undefined) {
|
|
961
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} StatusLowBattery: ${this.StatusLowBattery}`);
|
|
842
|
+
if (this.Battery.StatusLowBattery === undefined) {
|
|
843
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} StatusLowBattery: ${this.Battery.StatusLowBattery}`);
|
|
962
844
|
} else {
|
|
963
845
|
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}`);
|
|
846
|
+
this.mqttPublish('StatusLowBattery', this.Battery.StatusLowBattery.toString());
|
|
1001
847
|
}
|
|
848
|
+
this.accessory.context.StatusLowBattery = this.Battery.StatusLowBattery;
|
|
849
|
+
this.Battery.Service.updateCharacteristic(this.hap.Characteristic.StatusLowBattery, this.Battery.StatusLowBattery);
|
|
850
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic`
|
|
851
|
+
+ ` StatusLowBattery: ${this.Battery.StatusLowBattery}`);
|
|
1002
852
|
}
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
async stopScanning(switchbot: any) {
|
|
1006
|
-
switchbot.stopScan();
|
|
1007
|
-
if (this.BLE_IsConnected) {
|
|
1008
|
-
await this.BLEparseStatus();
|
|
1009
|
-
await this.updateHomeKitCharacteristics();
|
|
853
|
+
if (this.Battery.ChargingState === undefined) {
|
|
854
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} ChargingState: ${this.Battery.ChargingState}`);
|
|
1010
855
|
} 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
|
-
})();
|
|
856
|
+
if (this.device.mqttURL) {
|
|
857
|
+
this.mqttPublish('ChargingState', this.Battery.ChargingState.toString());
|
|
858
|
+
}
|
|
859
|
+
this.accessory.context.ChargingState = this.Battery.ChargingState;
|
|
860
|
+
this.Battery.Service.updateCharacteristic(this.hap.Characteristic.ChargingState, this.Battery.ChargingState);
|
|
861
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic`
|
|
862
|
+
+ ` ChargingState: ${this.Battery.ChargingState}`);
|
|
1030
863
|
}
|
|
1031
864
|
}
|
|
1032
865
|
|
|
@@ -1038,372 +871,81 @@ export class Curtain {
|
|
|
1038
871
|
}
|
|
1039
872
|
|
|
1040
873
|
async BLERefreshConnection(switchbot: any): Promise<void> {
|
|
1041
|
-
|
|
874
|
+
if (switchbot !== undefined) {
|
|
875
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} wasn't able to establish BLE Connection, node-switchbot:`
|
|
1042
876
|
+ ` ${JSON.stringify(switchbot)}`);
|
|
877
|
+
}
|
|
1043
878
|
if (this.platform.config.credentials?.token && this.device.connectionType === 'BLE/OpenAPI') {
|
|
1044
879
|
this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} Using OpenAPI Connection to Refresh Status`);
|
|
1045
880
|
await this.openAPIRefreshStatus();
|
|
1046
881
|
}
|
|
1047
882
|
}
|
|
1048
883
|
|
|
1049
|
-
async
|
|
1050
|
-
|
|
884
|
+
async setPerformance() {
|
|
885
|
+
let setPositionMode: number;
|
|
886
|
+
let Mode: string;
|
|
887
|
+
if (Number(this.WindowCovering.TargetPosition) > 50) {
|
|
1051
888
|
if (this.device.curtain?.setOpenMode === '1') {
|
|
1052
|
-
|
|
1053
|
-
|
|
889
|
+
setPositionMode = 1;
|
|
890
|
+
Mode = 'Silent Mode';
|
|
891
|
+
} else if (this.device.curtain?.setOpenMode === '0') {
|
|
892
|
+
setPositionMode = 0;
|
|
893
|
+
Mode = 'Performance Mode';
|
|
1054
894
|
} else {
|
|
1055
|
-
|
|
1056
|
-
|
|
895
|
+
setPositionMode = 0;
|
|
896
|
+
Mode = 'Default Mode';
|
|
1057
897
|
}
|
|
1058
898
|
} else {
|
|
1059
899
|
if (this.device.curtain?.setCloseMode === '1') {
|
|
1060
|
-
|
|
1061
|
-
|
|
900
|
+
setPositionMode = 1;
|
|
901
|
+
Mode = 'Silent Mode';
|
|
902
|
+
} else if (this.device.curtain?.setOpenMode === '0') {
|
|
903
|
+
setPositionMode = 0;
|
|
904
|
+
Mode = 'Performance Mode';
|
|
1062
905
|
} else {
|
|
1063
|
-
|
|
1064
|
-
|
|
906
|
+
setPositionMode = 0;
|
|
907
|
+
Mode = 'Default Mode';
|
|
1065
908
|
}
|
|
1066
909
|
}
|
|
910
|
+
return { setPositionMode, Mode };
|
|
1067
911
|
}
|
|
1068
912
|
|
|
1069
913
|
async setMinMax(): Promise<void> {
|
|
1070
914
|
if (this.device.curtain?.set_min) {
|
|
1071
|
-
if (Number(this.CurrentPosition) <= this.device.curtain?.set_min) {
|
|
1072
|
-
this.CurrentPosition = 0;
|
|
915
|
+
if (Number(this.WindowCovering.CurrentPosition) <= this.device.curtain?.set_min) {
|
|
916
|
+
this.WindowCovering.CurrentPosition = 0;
|
|
1073
917
|
}
|
|
1074
918
|
}
|
|
1075
919
|
if (this.device.curtain?.set_max) {
|
|
1076
|
-
if (Number(this.CurrentPosition) >= this.device.curtain?.set_max) {
|
|
1077
|
-
this.CurrentPosition = 100;
|
|
920
|
+
if (Number(this.WindowCovering.CurrentPosition) >= this.device.curtain?.set_max) {
|
|
921
|
+
this.WindowCovering.CurrentPosition = 100;
|
|
1078
922
|
}
|
|
1079
923
|
}
|
|
1080
924
|
if (this.device.history) {
|
|
1081
925
|
const motion = this.accessory.getService(this.hap.Service.MotionSensor);
|
|
1082
|
-
const state = Number(this.CurrentPosition) > 0 ? 1 : 0;
|
|
926
|
+
const state = Number(this.WindowCovering.CurrentPosition) > 0 ? 1 : 0;
|
|
1083
927
|
motion?.updateCharacteristic(this.hap.Characteristic.MotionDetected, state);
|
|
1084
928
|
}
|
|
1085
929
|
}
|
|
1086
930
|
|
|
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
931
|
async offlineOff(): Promise<void> {
|
|
1221
932
|
if (this.device.offline) {
|
|
1222
|
-
|
|
1223
|
-
|
|
933
|
+
this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.CurrentPosition, 100);
|
|
934
|
+
this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.TargetPosition, 100);
|
|
935
|
+
this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.PositionState, this.hap.Characteristic.PositionState.STOPPED);
|
|
1224
936
|
}
|
|
1225
937
|
}
|
|
1226
938
|
|
|
1227
939
|
async apiError(e: any): Promise<void> {
|
|
1228
|
-
this.
|
|
1229
|
-
this.
|
|
1230
|
-
this.
|
|
940
|
+
this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.CurrentPosition, e);
|
|
941
|
+
this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.PositionState, e);
|
|
942
|
+
this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.TargetPosition, e);
|
|
943
|
+
this.Battery.Service.updateCharacteristic(this.hap.Characteristic.BatteryLevel, e);
|
|
944
|
+
this.Battery.Service.updateCharacteristic(this.hap.Characteristic.StatusLowBattery, e);
|
|
945
|
+
this.Battery.Service.updateCharacteristic(this.hap.Characteristic.ChargingState, e);
|
|
1231
946
|
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;
|
|
947
|
+
this.LightSensor!.Service.updateCharacteristic(this.hap.Characteristic.CurrentAmbientLightLevel, e);
|
|
948
|
+
this.LightSensor!.Service.updateCharacteristic(this.hap.Characteristic.StatusActive, e);
|
|
1244
949
|
}
|
|
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}`);
|
|
1298
|
-
}
|
|
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
950
|
}
|
|
1409
951
|
}
|