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