@switchbot/homebridge-switchbot 3.5.0-beta.4 → 3.5.0-beta.41
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/CHANGELOG.md +4 -1
- package/config.schema.json +120 -17
- package/dist/device/blindtilt.d.ts +21 -94
- package/dist/device/blindtilt.d.ts.map +1 -1
- package/dist/device/blindtilt.js +351 -757
- package/dist/device/blindtilt.js.map +1 -1
- package/dist/device/bot.d.ts +25 -71
- package/dist/device/bot.d.ts.map +1 -1
- package/dist/device/bot.js +587 -761
- package/dist/device/bot.js.map +1 -1
- package/dist/device/ceilinglight.d.ts +13 -67
- package/dist/device/ceilinglight.d.ts.map +1 -1
- package/dist/device/ceilinglight.js +213 -588
- package/dist/device/ceilinglight.js.map +1 -1
- package/dist/device/colorbulb.d.ts +13 -74
- package/dist/device/colorbulb.d.ts.map +1 -1
- package/dist/device/colorbulb.js +255 -634
- package/dist/device/colorbulb.js.map +1 -1
- package/dist/device/contact.d.ts +14 -65
- package/dist/device/contact.d.ts.map +1 -1
- package/dist/device/contact.js +208 -532
- package/dist/device/contact.js.map +1 -1
- package/dist/device/curtain.d.ts +17 -86
- package/dist/device/curtain.d.ts.map +1 -1
- package/dist/device/curtain.js +339 -787
- package/dist/device/curtain.js.map +1 -1
- package/dist/device/device.d.ts +59 -0
- package/dist/device/device.d.ts.map +1 -0
- package/dist/device/device.js +671 -0
- package/dist/device/device.js.map +1 -0
- package/dist/device/fan.d.ts +51 -0
- package/dist/device/fan.d.ts.map +1 -0
- package/dist/device/fan.js +504 -0
- package/dist/device/fan.js.map +1 -0
- package/dist/device/hub.d.ts +15 -59
- package/dist/device/hub.d.ts.map +1 -1
- package/dist/device/hub.js +246 -597
- package/dist/device/hub.js.map +1 -1
- package/dist/device/humidifier.d.ts +10 -65
- package/dist/device/humidifier.d.ts.map +1 -1
- package/dist/device/humidifier.js +211 -572
- package/dist/device/humidifier.js.map +1 -1
- package/dist/device/iosensor.d.ts +11 -64
- package/dist/device/iosensor.d.ts.map +1 -1
- package/dist/device/iosensor.js +178 -585
- package/dist/device/iosensor.js.map +1 -1
- package/dist/device/lightstrip.d.ts +10 -68
- package/dist/device/lightstrip.d.ts.map +1 -1
- package/dist/device/lightstrip.js +256 -569
- package/dist/device/lightstrip.js.map +1 -1
- package/dist/device/lock.d.ts +15 -62
- package/dist/device/lock.d.ts.map +1 -1
- package/dist/device/lock.js +214 -543
- package/dist/device/lock.js.map +1 -1
- package/dist/device/meter.d.ts +13 -63
- package/dist/device/meter.d.ts.map +1 -1
- package/dist/device/meter.js +174 -578
- package/dist/device/meter.js.map +1 -1
- package/dist/device/meterplus.d.ts +13 -64
- package/dist/device/meterplus.d.ts.map +1 -1
- package/dist/device/meterplus.js +163 -578
- package/dist/device/meterplus.js.map +1 -1
- package/dist/device/motion.d.ts +13 -69
- package/dist/device/motion.d.ts.map +1 -1
- package/dist/device/motion.js +141 -520
- package/dist/device/motion.js.map +1 -1
- package/dist/device/plug.d.ts +9 -57
- package/dist/device/plug.d.ts.map +1 -1
- package/dist/device/plug.js +86 -453
- package/dist/device/plug.js.map +1 -1
- package/dist/device/robotvacuumcleaner.d.ts +11 -62
- package/dist/device/robotvacuumcleaner.d.ts.map +1 -1
- package/dist/device/robotvacuumcleaner.js +144 -452
- package/dist/device/robotvacuumcleaner.js.map +1 -1
- package/dist/device/waterdetector.d.ts +9 -70
- package/dist/device/waterdetector.d.ts.map +1 -1
- package/dist/device/waterdetector.js +125 -665
- package/dist/device/waterdetector.js.map +1 -1
- package/dist/homebridge-ui/public/index.html +2 -2
- package/dist/index.js +1 -1
- package/dist/irdevice/airconditioner.d.ts +8 -48
- package/dist/irdevice/airconditioner.d.ts.map +1 -1
- package/dist/irdevice/airconditioner.js +309 -419
- package/dist/irdevice/airconditioner.js.map +1 -1
- package/dist/irdevice/airpurifier.d.ts +7 -38
- package/dist/irdevice/airpurifier.d.ts.map +1 -1
- package/dist/irdevice/airpurifier.js +72 -304
- package/dist/irdevice/airpurifier.js.map +1 -1
- package/dist/irdevice/camera.d.ts +6 -35
- package/dist/irdevice/camera.d.ts.map +1 -1
- package/dist/irdevice/camera.js +34 -278
- package/dist/irdevice/camera.js.map +1 -1
- package/dist/irdevice/fan.d.ts +6 -39
- package/dist/irdevice/fan.d.ts.map +1 -1
- package/dist/irdevice/fan.js +67 -311
- package/dist/irdevice/fan.js.map +1 -1
- package/dist/irdevice/irdevice.d.ts +40 -0
- package/dist/irdevice/irdevice.d.ts.map +1 -0
- package/dist/irdevice/irdevice.js +512 -0
- package/dist/irdevice/irdevice.js.map +1 -0
- package/dist/irdevice/light.d.ts +6 -34
- package/dist/irdevice/light.d.ts.map +1 -1
- package/dist/irdevice/light.js +23 -272
- package/dist/irdevice/light.js.map +1 -1
- package/dist/irdevice/other.d.ts +18 -47
- package/dist/irdevice/other.d.ts.map +1 -1
- package/dist/irdevice/other.js +352 -546
- package/dist/irdevice/other.js.map +1 -1
- package/dist/irdevice/tv.d.ts +7 -39
- package/dist/irdevice/tv.d.ts.map +1 -1
- package/dist/irdevice/tv.js +82 -321
- package/dist/irdevice/tv.js.map +1 -1
- package/dist/irdevice/vacuumcleaner.d.ts +6 -35
- package/dist/irdevice/vacuumcleaner.d.ts.map +1 -1
- package/dist/irdevice/vacuumcleaner.js +41 -284
- package/dist/irdevice/vacuumcleaner.js.map +1 -1
- package/dist/irdevice/waterheater.d.ts +6 -35
- package/dist/irdevice/waterheater.d.ts.map +1 -1
- package/dist/irdevice/waterheater.js +42 -287
- package/dist/irdevice/waterheater.js.map +1 -1
- package/dist/platform.d.ts +14 -1
- package/dist/platform.d.ts.map +1 -1
- package/dist/platform.js +343 -198
- package/dist/platform.js.map +1 -1
- package/dist/settings.d.ts +41 -11
- package/dist/settings.d.ts.map +1 -1
- package/dist/settings.js +0 -552
- package/dist/settings.js.map +1 -1
- package/dist/utils.d.ts +77 -0
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +638 -1
- package/dist/utils.js.map +1 -1
- package/package.json +16 -15
- package/src/custom.d.ts +2 -1
- package/src/device/blindtilt.ts +377 -783
- package/src/device/bot.ts +620 -845
- package/src/device/ceilinglight.ts +226 -608
- package/src/device/colorbulb.ts +268 -657
- package/src/device/contact.ts +233 -554
- package/src/device/curtain.ts +359 -811
- package/src/device/device.ts +699 -0
- package/src/device/fan.ts +553 -0
- package/src/device/hub.ts +273 -625
- package/src/device/humidifier.ts +241 -619
- package/src/device/iosensor.ts +204 -611
- package/src/device/lightstrip.ts +277 -597
- package/src/device/lock.ts +251 -583
- package/src/device/meter.ts +199 -601
- package/src/device/meterplus.ts +188 -603
- package/src/device/motion.ts +160 -542
- package/src/device/plug.ts +96 -481
- package/src/device/robotvacuumcleaner.ts +165 -478
- package/src/device/waterdetector.ts +142 -689
- package/src/homebridge-ui/public/index.html +2 -2
- package/src/index.ts +1 -1
- package/src/irdevice/airconditioner.ts +330 -446
- package/src/irdevice/airpurifier.ts +89 -321
- package/src/irdevice/camera.ts +42 -293
- package/src/irdevice/fan.ts +78 -327
- package/src/irdevice/irdevice.ts +528 -0
- package/src/irdevice/light.ts +32 -287
- package/src/irdevice/other.ts +396 -615
- package/src/irdevice/tv.ts +100 -339
- package/src/irdevice/vacuumcleaner.ts +49 -305
- package/src/irdevice/waterheater.ts +50 -310
- package/src/platform.ts +353 -206
- package/src/settings.ts +57 -566
- package/src/utils.ts +642 -1
package/src/device/blindtilt.ts
CHANGED
|
@@ -1,113 +1,57 @@
|
|
|
1
|
+
/* Copyright(C) 2021-2024, donavanbecker (https://github.com/donavanbecker). All rights reserved.
|
|
2
|
+
*
|
|
3
|
+
* blindtilt.ts: @switchbot/homebridge-switchbot.
|
|
4
|
+
*/
|
|
1
5
|
import { request } from 'undici';
|
|
2
|
-
import {
|
|
3
|
-
import { MqttClient } from 'mqtt';
|
|
6
|
+
import { BlindTiltMappingMode } from '../utils.js';
|
|
4
7
|
import { interval, Subject } from 'rxjs';
|
|
5
|
-
import
|
|
8
|
+
import { deviceBase } from './device.js';
|
|
6
9
|
import { SwitchBotPlatform } from '../platform.js';
|
|
7
10
|
import { debounceTime, skipWhile, take, tap } from 'rxjs/operators';
|
|
8
|
-
import { Service, PlatformAccessory, CharacteristicValue
|
|
9
|
-
import { device, devicesConfig, serviceData, deviceStatus, Devices
|
|
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
|
-
}
|
|
11
|
+
import { Service, PlatformAccessory, CharacteristicValue } from 'homebridge';
|
|
12
|
+
import { device, devicesConfig, serviceData, deviceStatus, Devices } from '../settings.js';
|
|
13
|
+
|
|
18
14
|
|
|
19
|
-
export class BlindTilt {
|
|
20
|
-
public readonly api: API;
|
|
21
|
-
public readonly log: Logging;
|
|
22
|
-
public readonly config!: SwitchBotPlatformConfig;
|
|
23
|
-
protected readonly hap: HAP;
|
|
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
|
-
OpenAPI_Calibration: serviceData['calibration'];
|
|
45
|
-
OpenAPI_CurrentPosition: serviceData['position'];
|
|
46
|
-
OpenAPI_FirmwareRevision: deviceStatus['version'];
|
|
47
|
-
OpenAPI_CurrentAmbientLightLevel: deviceStatus['brightness'];
|
|
17
|
+
private WindowCovering: {
|
|
18
|
+
Service: Service;
|
|
19
|
+
PositionState: CharacteristicValue;
|
|
20
|
+
TargetPosition: CharacteristicValue;
|
|
21
|
+
CurrentPosition: CharacteristicValue;
|
|
22
|
+
TargetHorizontalTiltAngle: CharacteristicValue;
|
|
23
|
+
CurrentHorizontalTiltAngle: CharacteristicValue;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
private Battery: {
|
|
27
|
+
Service: Service;
|
|
28
|
+
BatteryLevel: CharacteristicValue;
|
|
29
|
+
StatusLowBattery: CharacteristicValue;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
private LightSensor?: {
|
|
33
|
+
Service: Service;
|
|
34
|
+
CurrentAmbientLightLevel?: CharacteristicValue;
|
|
35
|
+
};
|
|
48
36
|
|
|
49
37
|
// OpenAPI Others
|
|
50
|
-
Mode!: string;
|
|
51
|
-
setPositionMode?: string | number;
|
|
52
38
|
mappingMode: BlindTiltMappingMode = BlindTiltMappingMode.OnlyUp;
|
|
53
39
|
|
|
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
40
|
// Target
|
|
66
41
|
setNewTarget!: boolean;
|
|
67
42
|
setNewTargetTimer!: NodeJS.Timeout;
|
|
68
43
|
|
|
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
44
|
// Updates
|
|
84
45
|
blindTiltUpdateInProgress!: boolean;
|
|
85
46
|
doBlindTiltUpdate!: Subject<void>;
|
|
86
47
|
|
|
87
|
-
// Connection
|
|
88
|
-
private readonly OpenAPI: boolean;
|
|
89
|
-
private readonly BLE: boolean;
|
|
90
|
-
|
|
91
48
|
constructor(
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
49
|
+
readonly platform: SwitchBotPlatform,
|
|
50
|
+
accessory: PlatformAccessory,
|
|
51
|
+
device: device & devicesConfig,
|
|
95
52
|
) {
|
|
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';
|
|
53
|
+
super(platform, accessory, device);
|
|
103
54
|
// 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
55
|
this.mappingMode = (device.blindTilt?.mode as BlindTiltMappingMode) ?? BlindTiltMappingMode.OnlyUp;
|
|
112
56
|
this.debugLog(`Mapping mode: ${this.mappingMode}`);
|
|
113
57
|
|
|
@@ -116,33 +60,46 @@ export class BlindTilt {
|
|
|
116
60
|
this.blindTiltUpdateInProgress = false;
|
|
117
61
|
this.setNewTarget = false;
|
|
118
62
|
|
|
63
|
+
// Initialize LightBulb property
|
|
64
|
+
this.WindowCovering = {
|
|
65
|
+
Service: accessory.getService(this.hap.Service.WindowCovering)!,
|
|
66
|
+
PositionState: accessory.context.PositionState || this.hap.Characteristic.PositionState.STOPPED,
|
|
67
|
+
TargetPosition: accessory.context.TargetPosition || 100,
|
|
68
|
+
CurrentPosition: accessory.context.CurrentPosition || 100,
|
|
69
|
+
TargetHorizontalTiltAngle: accessory.context.TargetHorizontalTiltAngle || 0,
|
|
70
|
+
CurrentHorizontalTiltAngle: accessory.context.CurrentHorizontalTiltAngle || 0,
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
// Initialize Battery property
|
|
74
|
+
this.Battery = {
|
|
75
|
+
Service: accessory.getService(this.hap.Service.Battery)!,
|
|
76
|
+
BatteryLevel: accessory.context.BatteryLevel || 100,
|
|
77
|
+
StatusLowBattery: this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL,
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
// Initialize LightSensor property
|
|
81
|
+
if (!this.device.blindTilt?.hide_lightsensor) {
|
|
82
|
+
this.LightSensor = {
|
|
83
|
+
Service: accessory.getService(this.hap.Service.LightSensor)!,
|
|
84
|
+
CurrentAmbientLightLevel: accessory.context.CurrentAmbientLightLevel || 0.0001,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
|
|
119
88
|
// Retrieve initial values and updateHomekit
|
|
120
89
|
this.refreshStatus();
|
|
121
90
|
|
|
122
|
-
// set accessory information
|
|
123
|
-
accessory
|
|
124
|
-
.getService(this.hap.Service.AccessoryInformation)!
|
|
125
|
-
.setCharacteristic(this.hap.Characteristic.Manufacturer, 'SwitchBot')
|
|
126
|
-
.setCharacteristic(this.hap.Characteristic.Model, 'W2701600')
|
|
127
|
-
.setCharacteristic(this.hap.Characteristic.SerialNumber, device.deviceId)
|
|
128
|
-
.setCharacteristic(this.hap.Characteristic.FirmwareRevision, accessory.context.FirmwareRevision);
|
|
129
|
-
|
|
130
91
|
// get the WindowCovering service if it exists, otherwise create a new WindowCovering service
|
|
131
92
|
// you can create multiple services for each accessory
|
|
132
|
-
|
|
133
|
-
(this.windowCoveringService =
|
|
93
|
+
(this.WindowCovering!.Service =
|
|
134
94
|
accessory.getService(this.hap.Service.WindowCovering)
|
|
135
|
-
|| accessory.addService(this.hap.Service.WindowCovering)),
|
|
95
|
+
|| accessory.addService(this.hap.Service.WindowCovering)), accessory.displayName;
|
|
136
96
|
|
|
137
|
-
this.
|
|
138
|
-
if (!this.windowCoveringService.testCharacteristic(this.hap.Characteristic.ConfiguredName)) {
|
|
139
|
-
this.windowCoveringService.addCharacteristic(this.hap.Characteristic.ConfiguredName, accessory.displayName);
|
|
140
|
-
}
|
|
97
|
+
this.WindowCovering!.Service.setCharacteristic(this.hap.Characteristic.Name, accessory.displayName);
|
|
141
98
|
|
|
142
99
|
// create handlers for required characteristics
|
|
143
|
-
this.
|
|
100
|
+
this.WindowCovering!.Service.setCharacteristic(this.hap.Characteristic.PositionState, this.WindowCovering.PositionState);
|
|
144
101
|
|
|
145
|
-
this.
|
|
102
|
+
this.WindowCovering!.Service
|
|
146
103
|
.getCharacteristic(this.hap.Characteristic.CurrentPosition)
|
|
147
104
|
.setProps({
|
|
148
105
|
minStep: this.minStep(device),
|
|
@@ -151,10 +108,10 @@ export class BlindTilt {
|
|
|
151
108
|
validValueRanges: [0, 100],
|
|
152
109
|
})
|
|
153
110
|
.onGet(() => {
|
|
154
|
-
return this.CurrentPosition;
|
|
111
|
+
return this.WindowCovering?.CurrentPosition ?? 0;
|
|
155
112
|
});
|
|
156
113
|
|
|
157
|
-
this.
|
|
114
|
+
this.WindowCovering!.Service
|
|
158
115
|
.getCharacteristic(this.hap.Characteristic.TargetPosition)
|
|
159
116
|
.setProps({
|
|
160
117
|
minStep: this.minStep(device),
|
|
@@ -164,8 +121,8 @@ export class BlindTilt {
|
|
|
164
121
|
})
|
|
165
122
|
.onSet(this.TargetPositionSet.bind(this));
|
|
166
123
|
|
|
167
|
-
this.CurrentHorizontalTiltAngle = 90;
|
|
168
|
-
this.
|
|
124
|
+
this.WindowCovering!.CurrentHorizontalTiltAngle = 90;
|
|
125
|
+
this.WindowCovering!.Service
|
|
169
126
|
.getCharacteristic(this.hap.Characteristic.CurrentHorizontalTiltAngle)
|
|
170
127
|
.setProps({
|
|
171
128
|
minStep: 180,
|
|
@@ -174,12 +131,12 @@ export class BlindTilt {
|
|
|
174
131
|
validValues: [-90, 90],
|
|
175
132
|
})
|
|
176
133
|
.onGet(() => {
|
|
177
|
-
// this.debugLog(`requested CurrentHorizontalTiltAngle: ${this.CurrentHorizontalTiltAngle}`);
|
|
178
|
-
return this.CurrentHorizontalTiltAngle;
|
|
134
|
+
// this.debugLog(`requested CurrentHorizontalTiltAngle: ${this.WindowCovering.CurrentHorizontalTiltAngle}`);
|
|
135
|
+
return this.WindowCovering.CurrentHorizontalTiltAngle ?? 0;
|
|
179
136
|
});
|
|
180
137
|
|
|
181
|
-
this.TargetHorizontalTiltAngle = 90;
|
|
182
|
-
this.
|
|
138
|
+
this.WindowCovering!.TargetHorizontalTiltAngle = 90;
|
|
139
|
+
this.WindowCovering!.Service
|
|
183
140
|
.getCharacteristic(this.hap.Characteristic.TargetHorizontalTiltAngle)
|
|
184
141
|
.setProps({
|
|
185
142
|
minStep: 180,
|
|
@@ -191,13 +148,10 @@ export class BlindTilt {
|
|
|
191
148
|
|
|
192
149
|
// Battery Service
|
|
193
150
|
const batteryService = `${accessory.displayName} Battery`;
|
|
194
|
-
(this.
|
|
151
|
+
(this.Battery.Service = this.accessory.getService(this.hap.Service.Battery)
|
|
195
152
|
|| accessory.addService(this.hap.Service.Battery)), batteryService;
|
|
196
153
|
|
|
197
|
-
this.
|
|
198
|
-
if (!this.batteryService.testCharacteristic(this.hap.Characteristic.ConfiguredName)) {
|
|
199
|
-
this.batteryService.addCharacteristic(this.hap.Characteristic.ConfiguredName, `${accessory.displayName} Battery`);
|
|
200
|
-
}
|
|
154
|
+
this.Battery!.Service.setCharacteristic(this.hap.Characteristic.Name, batteryService);
|
|
201
155
|
|
|
202
156
|
// Update Homekit
|
|
203
157
|
this.updateHomeKitCharacteristics();
|
|
@@ -210,21 +164,21 @@ export class BlindTilt {
|
|
|
210
164
|
});
|
|
211
165
|
|
|
212
166
|
//regisiter webhook event handler
|
|
213
|
-
if (
|
|
214
|
-
this.
|
|
167
|
+
if (device.webhook) {
|
|
168
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} is listening webhook.`);
|
|
215
169
|
this.platform.webhookEventHandler[this.device.deviceId] = async (context) => {
|
|
216
170
|
try {
|
|
217
|
-
this.
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
171
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} received Webhook: ${JSON.stringify(context)}`);
|
|
172
|
+
const { slidePosition, battery } = context;
|
|
173
|
+
const { CurrentPosition } = this.WindowCovering;
|
|
174
|
+
const { BatteryLevel } = this.Battery;
|
|
175
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} ` +
|
|
176
|
+
'(slidePosition, battery) = ' +
|
|
177
|
+
`Webhook:(${slidePosition}, ${battery}), ` +
|
|
178
|
+
`current:(${CurrentPosition}, ${BatteryLevel})`);
|
|
179
|
+
this.WindowCovering!.CurrentPosition = slidePosition;
|
|
180
|
+
this.Battery.BatteryLevel = battery;
|
|
181
|
+
this.updateHomeKitCharacteristics();
|
|
228
182
|
} catch (e: any) {
|
|
229
183
|
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} `
|
|
230
184
|
+ `failed to handle webhook. Received: ${JSON.stringify(context)} Error: ${e}`);
|
|
@@ -233,13 +187,14 @@ export class BlindTilt {
|
|
|
233
187
|
}
|
|
234
188
|
|
|
235
189
|
// update slide progress
|
|
236
|
-
interval(this.
|
|
190
|
+
interval(this.deviceUpdateRate * 1000)
|
|
237
191
|
//.pipe(skipWhile(() => this.blindTiltUpdateInProgress))
|
|
238
192
|
.subscribe(async () => {
|
|
239
|
-
if (this.PositionState === this.hap.Characteristic.PositionState.STOPPED) {
|
|
193
|
+
if (this.WindowCovering!.PositionState === this.hap.Characteristic.PositionState.STOPPED) {
|
|
240
194
|
return;
|
|
241
195
|
}
|
|
242
|
-
this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Refresh Status When Moving
|
|
196
|
+
this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Refresh Status When Moving,`
|
|
197
|
+
+ ` PositionState: ${this.WindowCovering!.PositionState}`);
|
|
243
198
|
await this.refreshStatus();
|
|
244
199
|
});
|
|
245
200
|
|
|
@@ -267,218 +222,229 @@ export class BlindTilt {
|
|
|
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 = await this.minLux();
|
|
270
|
+
const set_maxLux = await this.maxLux();
|
|
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 = (
|
|
284
|
+
this.LightSensor!.CurrentAmbientLightLevel = (set_maxLux - set_minLux) / spaceBetweenLevels;
|
|
339
285
|
this.debugLog(
|
|
340
|
-
`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${
|
|
341
|
-
` Calculation: ${(
|
|
286
|
+
`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${serviceData.lightLevel},` +
|
|
287
|
+
` Calculation: ${(set_maxLux - set_minLux) / spaceBetweenLevels}`,
|
|
342
288
|
);
|
|
343
289
|
break;
|
|
344
290
|
case 3:
|
|
345
|
-
this.CurrentAmbientLightLevel = ((
|
|
346
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${
|
|
291
|
+
this.LightSensor!.CurrentAmbientLightLevel = ((set_maxLux - set_minLux) / spaceBetweenLevels) * 2;
|
|
292
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${serviceData.lightLevel}`);
|
|
347
293
|
break;
|
|
348
294
|
case 4:
|
|
349
|
-
this.CurrentAmbientLightLevel = ((
|
|
350
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${
|
|
295
|
+
this.LightSensor!.CurrentAmbientLightLevel = ((set_maxLux - set_minLux) / spaceBetweenLevels) * 3;
|
|
296
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${serviceData.lightLevel}`);
|
|
351
297
|
break;
|
|
352
298
|
case 5:
|
|
353
|
-
this.CurrentAmbientLightLevel = ((
|
|
354
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${
|
|
299
|
+
this.LightSensor!.CurrentAmbientLightLevel = ((set_maxLux - set_minLux) / spaceBetweenLevels) * 4;
|
|
300
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${serviceData.lightLevel}`);
|
|
355
301
|
break;
|
|
356
302
|
case 6:
|
|
357
|
-
this.CurrentAmbientLightLevel = ((
|
|
358
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${
|
|
303
|
+
this.LightSensor!.CurrentAmbientLightLevel = ((set_maxLux - set_minLux) / spaceBetweenLevels) * 5;
|
|
304
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${serviceData.lightLevel}`);
|
|
359
305
|
break;
|
|
360
306
|
case 7:
|
|
361
|
-
this.CurrentAmbientLightLevel = ((
|
|
362
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${
|
|
307
|
+
this.LightSensor!.CurrentAmbientLightLevel = ((set_maxLux - set_minLux) / spaceBetweenLevels) * 6;
|
|
308
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${serviceData.lightLevel}`);
|
|
363
309
|
break;
|
|
364
310
|
case 8:
|
|
365
|
-
this.CurrentAmbientLightLevel = ((
|
|
366
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${
|
|
311
|
+
this.LightSensor!.CurrentAmbientLightLevel = ((set_maxLux - set_minLux) / spaceBetweenLevels) * 7;
|
|
312
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${serviceData.lightLevel}`);
|
|
367
313
|
break;
|
|
368
314
|
case 9:
|
|
369
|
-
this.CurrentAmbientLightLevel = ((
|
|
370
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${
|
|
315
|
+
this.LightSensor!.CurrentAmbientLightLevel = ((set_maxLux - set_minLux) / spaceBetweenLevels) * 8;
|
|
316
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${serviceData.lightLevel}`);
|
|
371
317
|
break;
|
|
372
318
|
case 10:
|
|
373
319
|
default:
|
|
374
|
-
this.CurrentAmbientLightLevel =
|
|
320
|
+
this.LightSensor!.CurrentAmbientLightLevel = set_maxLux;
|
|
375
321
|
this.debugLog();
|
|
376
322
|
}
|
|
377
323
|
this.debugLog(
|
|
378
|
-
`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${
|
|
379
|
-
` CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`,
|
|
324
|
+
`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${serviceData.lightLevel},` +
|
|
325
|
+
` CurrentAmbientLightLevel: ${this.LightSensor!.CurrentAmbientLightLevel}`,
|
|
380
326
|
);
|
|
381
327
|
}
|
|
382
328
|
// Battery
|
|
383
|
-
this.BatteryLevel = Number(
|
|
384
|
-
if (this.BatteryLevel < 10) {
|
|
385
|
-
this.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW;
|
|
329
|
+
this.Battery.BatteryLevel = Number(serviceData.battery);
|
|
330
|
+
if (this.Battery.BatteryLevel < 10) {
|
|
331
|
+
this.Battery.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW;
|
|
386
332
|
} else {
|
|
387
|
-
this.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
|
|
333
|
+
this.Battery.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
|
|
388
334
|
}
|
|
389
335
|
this.debugLog(
|
|
390
|
-
`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.BatteryLevel},`
|
|
336
|
+
`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.Battery.BatteryLevel},`
|
|
337
|
+
+ ` StatusLowBattery: ${this.Battery.StatusLowBattery}`,
|
|
391
338
|
);
|
|
392
339
|
}
|
|
393
340
|
|
|
394
|
-
|
|
341
|
+
|
|
342
|
+
/**
|
|
343
|
+
* Parse the device status from the SwitchBot OpenAPI
|
|
344
|
+
*/
|
|
345
|
+
async openAPIparseStatus(deviceStatus: deviceStatus): Promise<void> {
|
|
395
346
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIparseStatus`);
|
|
396
347
|
|
|
397
|
-
const [homekitPosition, homekitTiltAngle] = this.mapDeviceValuesToHomekitValues(Number(
|
|
398
|
-
String(
|
|
399
|
-
this.debugLog(` device: ${
|
|
348
|
+
const [homekitPosition, homekitTiltAngle] = this.mapDeviceValuesToHomekitValues(Number(deviceStatus.body.slidePosition),
|
|
349
|
+
String(deviceStatus.body.direction));
|
|
350
|
+
this.debugLog(` device: ${deviceStatus.body.slidePosition} => HK: ${homekitPosition}`);
|
|
400
351
|
|
|
401
|
-
this.CurrentPosition = homekitPosition;
|
|
352
|
+
this.WindowCovering!.CurrentPosition = homekitPosition;
|
|
402
353
|
// CurrentPosition
|
|
403
354
|
await this.setMinMax();
|
|
404
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} CurrentPosition: ${this.CurrentPosition}`);
|
|
355
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
|
|
405
356
|
|
|
406
357
|
if (homekitTiltAngle) {
|
|
407
|
-
this.CurrentHorizontalTiltAngle = homekitTiltAngle!;
|
|
408
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}
|
|
358
|
+
this.WindowCovering.CurrentHorizontalTiltAngle = homekitTiltAngle!;
|
|
359
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}`
|
|
360
|
+
+ ` CurrentHorizontalTiltAngle: ${this.WindowCovering.CurrentHorizontalTiltAngle}`);
|
|
409
361
|
}
|
|
410
362
|
|
|
411
363
|
if (this.setNewTarget) {
|
|
412
364
|
this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Checking Status ...`);
|
|
413
365
|
}
|
|
414
366
|
|
|
415
|
-
if (this.setNewTarget &&
|
|
367
|
+
if (this.setNewTarget && deviceStatus.body.moving) {
|
|
416
368
|
await this.setMinMax();
|
|
417
|
-
if (this.TargetPosition > this.CurrentPosition
|
|
418
|
-
|
|
419
|
-
this.
|
|
420
|
-
this.
|
|
421
|
-
this.
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
this.
|
|
426
|
-
this.
|
|
369
|
+
if (this.WindowCovering.TargetPosition > this.WindowCovering.CurrentPosition
|
|
370
|
+
|| (homekitTiltAngle && this.WindowCovering.TargetHorizontalTiltAngle !== this.WindowCovering.CurrentHorizontalTiltAngle)) {
|
|
371
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Closing, CurrentPosition: ${this.WindowCovering.CurrentPosition} `);
|
|
372
|
+
this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.INCREASING;
|
|
373
|
+
this.WindowCovering.Service.getCharacteristic(this.hap.Characteristic.PositionState).updateValue(this.WindowCovering.PositionState);
|
|
374
|
+
this.debugLog(`${this.device.deviceType}: ${this.WindowCovering.CurrentPosition} INCREASING`
|
|
375
|
+
+ ` PositionState: ${this.WindowCovering.PositionState}`);
|
|
376
|
+
} else if (this.WindowCovering.TargetPosition < this.WindowCovering.CurrentPosition) {
|
|
377
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Opening, CurrentPosition: ${this.WindowCovering.CurrentPosition} `);
|
|
378
|
+
this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.DECREASING;
|
|
379
|
+
this.WindowCovering.Service.getCharacteristic(this.hap.Characteristic.PositionState).updateValue(this.WindowCovering.PositionState);
|
|
380
|
+
this.debugLog(`${this.device.deviceType}: ${this.WindowCovering.CurrentPosition} DECREASING`
|
|
381
|
+
+ ` PositionState: ${this.WindowCovering.PositionState}`);
|
|
427
382
|
} else {
|
|
428
383
|
this.debugLog(
|
|
429
|
-
`${this.device.deviceType}: ${this.CurrentPosition} Standby because reached position,`
|
|
384
|
+
`${this.device.deviceType}: ${this.WindowCovering.CurrentPosition} Standby because reached position,`
|
|
385
|
+
+ ` CurrentPosition: ${this.WindowCovering.CurrentPosition}`,
|
|
430
386
|
);
|
|
431
|
-
this.PositionState = this.hap.Characteristic.PositionState.STOPPED;
|
|
432
|
-
this.
|
|
433
|
-
this.debugLog(`${this.device.deviceType}: ${this.CurrentPosition} STOPPED
|
|
387
|
+
this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.STOPPED;
|
|
388
|
+
this.WindowCovering.Service.getCharacteristic(this.hap.Characteristic.PositionState).updateValue(this.WindowCovering.PositionState);
|
|
389
|
+
this.debugLog(`${this.device.deviceType}: ${this.WindowCovering.CurrentPosition} STOPPED`
|
|
390
|
+
+ ` PositionState: ${this.WindowCovering.PositionState}`);
|
|
434
391
|
}
|
|
435
392
|
} else {
|
|
436
393
|
this.debugLog(
|
|
437
|
-
`${this.device.deviceType}: ${this.accessory.displayName} Standby because device not moving,`
|
|
394
|
+
`${this.device.deviceType}: ${this.accessory.displayName} Standby because device not moving,`
|
|
395
|
+
+ ` CurrentPosition: ${this.WindowCovering.CurrentPosition}`,
|
|
438
396
|
);
|
|
439
|
-
this.TargetPosition = this.CurrentPosition;
|
|
397
|
+
this.WindowCovering.TargetPosition = this.WindowCovering.CurrentPosition;
|
|
440
398
|
if (homekitTiltAngle) {
|
|
441
|
-
this.TargetHorizontalTiltAngle = this.CurrentHorizontalTiltAngle;
|
|
399
|
+
this.WindowCovering.TargetHorizontalTiltAngle = this.WindowCovering.CurrentHorizontalTiltAngle;
|
|
442
400
|
}
|
|
443
|
-
this.PositionState = this.hap.Characteristic.PositionState.STOPPED;
|
|
401
|
+
this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.STOPPED;
|
|
444
402
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Stopped`);
|
|
445
403
|
}
|
|
446
404
|
this.debugLog(
|
|
447
|
-
`${this.device.deviceType}: ${this.accessory.displayName} CurrentPosition: ${this.CurrentPosition},` +
|
|
448
|
-
` TargetPosition: ${this.TargetPosition}, PositionState: ${this.PositionState},`,
|
|
405
|
+
`${this.device.deviceType}: ${this.accessory.displayName} CurrentPosition: ${this.WindowCovering.CurrentPosition},` +
|
|
406
|
+
` TargetPosition: ${this.WindowCovering.TargetPosition}, PositionState: ${this.WindowCovering.PositionState},`,
|
|
449
407
|
);
|
|
450
408
|
|
|
451
409
|
if (!this.device.blindTilt?.hide_lightsensor) {
|
|
452
|
-
|
|
453
|
-
|
|
410
|
+
const set_minLux = await this.minLux();
|
|
411
|
+
const set_maxLux = await this.maxLux();
|
|
454
412
|
// Brightness
|
|
455
|
-
switch (
|
|
413
|
+
switch (deviceStatus.body.brightness) {
|
|
456
414
|
case 'dim':
|
|
457
|
-
this.CurrentAmbientLightLevel =
|
|
415
|
+
this.LightSensor!.CurrentAmbientLightLevel = set_minLux;
|
|
458
416
|
break;
|
|
459
417
|
case 'bright':
|
|
460
418
|
default:
|
|
461
|
-
this.CurrentAmbientLightLevel =
|
|
419
|
+
this.LightSensor!.CurrentAmbientLightLevel = set_maxLux;
|
|
462
420
|
}
|
|
463
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}
|
|
421
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}`
|
|
422
|
+
+ ` CurrentAmbientLightLevel: ${this.LightSensor!.CurrentAmbientLightLevel}`);
|
|
464
423
|
}
|
|
465
424
|
|
|
466
425
|
// BatteryLevel
|
|
467
|
-
this.BatteryLevel = Number(
|
|
468
|
-
if (this.BatteryLevel < 10) {
|
|
469
|
-
this.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW;
|
|
426
|
+
this.Battery.BatteryLevel = Number(deviceStatus.body.battery);
|
|
427
|
+
if (this.Battery.BatteryLevel < 10) {
|
|
428
|
+
this.Battery.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW;
|
|
470
429
|
} else {
|
|
471
|
-
this.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
|
|
430
|
+
this.Battery.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
|
|
472
431
|
}
|
|
473
|
-
if (Number.isNaN(this.BatteryLevel)) {
|
|
474
|
-
this.BatteryLevel = 100;
|
|
432
|
+
if (Number.isNaN(this.Battery.BatteryLevel)) {
|
|
433
|
+
this.Battery.BatteryLevel = 100;
|
|
475
434
|
}
|
|
476
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.BatteryLevel},`
|
|
477
|
-
+ ` StatusLowBattery: ${this.StatusLowBattery}`);
|
|
435
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.Battery.BatteryLevel},`
|
|
436
|
+
+ ` StatusLowBattery: ${this.Battery.StatusLowBattery}`);
|
|
478
437
|
|
|
479
|
-
//
|
|
480
|
-
this.
|
|
481
|
-
|
|
438
|
+
// Firmware Version
|
|
439
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Firmware Version: ${deviceStatus.body.version}`);
|
|
440
|
+
if (deviceStatus.body.version) {
|
|
441
|
+
this.accessory.context.version = deviceStatus.body.version;
|
|
442
|
+
this.accessory
|
|
443
|
+
.getService(this.hap.Service.AccessoryInformation)!
|
|
444
|
+
.setCharacteristic(this.hap.Characteristic.FirmwareRevision, this.accessory.context.version)
|
|
445
|
+
.getCharacteristic(this.hap.Characteristic.FirmwareRevision)
|
|
446
|
+
.updateValue(this.accessory.context.version);
|
|
447
|
+
}
|
|
482
448
|
}
|
|
483
449
|
|
|
484
450
|
async refreshStatus(): Promise<void> {
|
|
@@ -510,21 +476,13 @@ export class BlindTilt {
|
|
|
510
476
|
// Start to monitor advertisement packets
|
|
511
477
|
(async () => {
|
|
512
478
|
// Start to monitor advertisement packets
|
|
513
|
-
await switchbot.startScan({
|
|
514
|
-
model: 'x',
|
|
515
|
-
id: this.device.bleMac,
|
|
516
|
-
});
|
|
479
|
+
await switchbot.startScan({ model: this.device.bleModel, id: this.device.bleMac });
|
|
517
480
|
// Set an event handler
|
|
518
481
|
switchbot.onadvertisement = (ad: any) => {
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
482
|
+
if (this.device.bleMac === ad.address && ad.model === this.device.bleModel) {
|
|
483
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} ${JSON.stringify(ad, null, ' ')}`);
|
|
484
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} address: ${ad.address}, model: ${ad.model}`);
|
|
522
485
|
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;
|
|
528
486
|
} else {
|
|
529
487
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${JSON.stringify(ad.serviceData)}`);
|
|
530
488
|
}
|
|
@@ -534,83 +492,27 @@ export class BlindTilt {
|
|
|
534
492
|
// Stop to monitor
|
|
535
493
|
await switchbot.stopScan();
|
|
536
494
|
// Update HomeKit
|
|
537
|
-
await this.BLEparseStatus();
|
|
495
|
+
await this.BLEparseStatus(switchbot.onadvertisement.serviceData);
|
|
538
496
|
await this.updateHomeKitCharacteristics();
|
|
539
497
|
})();
|
|
540
|
-
|
|
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
|
-
);
|
|
587
|
-
await this.BLERefreshConnection(switchbot);
|
|
588
|
-
});
|
|
589
|
-
} else {
|
|
498
|
+
if (switchbot === undefined) {
|
|
590
499
|
await this.BLERefreshConnection(switchbot);
|
|
591
|
-
}
|
|
500
|
+
}
|
|
592
501
|
}
|
|
593
502
|
|
|
594
503
|
async openAPIRefreshStatus(): Promise<void> {
|
|
595
504
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus`);
|
|
596
505
|
try {
|
|
597
|
-
const { body, statusCode } = await
|
|
598
|
-
headers: this.platform.generateHeaders()
|
|
599
|
-
});
|
|
506
|
+
const { body, statusCode } = await this.platform.retryRequest(this.deviceMaxRetries, this.deviceDelayBetweenRetries,
|
|
507
|
+
`${Devices}/${this.device.deviceId}/status`, { headers: this.platform.generateHeaders() });
|
|
600
508
|
this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} statusCode: ${statusCode}`);
|
|
601
509
|
const deviceStatus: any = await body.json();
|
|
602
510
|
this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus: ${JSON.stringify(deviceStatus)}`);
|
|
603
511
|
this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus statusCode: ${deviceStatus.statusCode}`);
|
|
604
512
|
if ((statusCode === 200 || statusCode === 100) && (deviceStatus.statusCode === 200 || deviceStatus.statusCode === 100)) {
|
|
605
|
-
this.
|
|
513
|
+
this.debugSuccessLog(`${this.device.deviceType}: ${this.accessory.displayName} `
|
|
606
514
|
+ `statusCode: ${statusCode} & deviceStatus StatusCode: ${deviceStatus.statusCode}`);
|
|
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();
|
|
515
|
+
this.openAPIparseStatus(deviceStatus);
|
|
614
516
|
this.updateHomeKitCharacteristics();
|
|
615
517
|
} else {
|
|
616
518
|
this.statusCode(statusCode);
|
|
@@ -649,7 +551,7 @@ 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
557
|
this.device.bleMac = this.device
|
|
@@ -657,26 +559,24 @@ export class BlindTilt {
|
|
|
657
559
|
.join(':')
|
|
658
560
|
.toLowerCase();
|
|
659
561
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
|
|
660
|
-
this.
|
|
661
|
-
|
|
662
|
-
if (adjustedMode === null) {
|
|
663
|
-
this.Mode = 'Default Mode';
|
|
664
|
-
}
|
|
665
|
-
this.debugLog(`${this.accessory.displayName} Mode: ${this.Mode}`);
|
|
562
|
+
const { setPositionMode, Mode }: { setPositionMode: number; Mode: string; } = await this.setPerformance();
|
|
563
|
+
this.debugLog(`${this.accessory.displayName} Mode: ${Mode}`);
|
|
666
564
|
if (switchbot !== false) {
|
|
667
565
|
switchbot
|
|
668
566
|
.discover({ model: 'c', quick: true, id: this.device.bleMac })
|
|
669
567
|
.then(async (device_list: any) => {
|
|
670
|
-
this.infoLog(`${this.accessory.displayName} Target Position: ${this.TargetPosition}`);
|
|
671
|
-
return await this.
|
|
672
|
-
max: this.
|
|
568
|
+
this.infoLog(`${this.accessory.displayName} Target Position: ${this.WindowCovering.TargetPosition}`);
|
|
569
|
+
return await this.retryBLE({
|
|
570
|
+
max: await this.maxRetryBLE(),
|
|
673
571
|
fn: async () => {
|
|
674
|
-
return await device_list[0].runToPos(100 - Number(this.TargetPosition),
|
|
572
|
+
return await device_list[0].runToPos(100 - Number(this.WindowCovering.TargetPosition), setPositionMode);
|
|
675
573
|
},
|
|
676
574
|
});
|
|
677
575
|
})
|
|
678
576
|
.then(() => {
|
|
679
577
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Done.`);
|
|
578
|
+
this.successLog(`${this.device.deviceType}: ${this.accessory.displayName} `
|
|
579
|
+
+ `Target Position: ${this.WindowCovering.TargetPosition} sent over BLE, sent successfully`);
|
|
680
580
|
})
|
|
681
581
|
.catch(async (e: any) => {
|
|
682
582
|
this.apiError(e);
|
|
@@ -693,39 +593,24 @@ export class BlindTilt {
|
|
|
693
593
|
} else {
|
|
694
594
|
this.debugLog(
|
|
695
595
|
`${this.device.deviceType}: ${this.accessory.displayName} No BLEpushChanges, CurrentPosition & TargetPosition Are the Same.` +
|
|
696
|
-
` CurrentPosition: ${this.CurrentPosition}, TargetPosition ${this.TargetPosition}`,
|
|
596
|
+
` CurrentPosition: ${this.WindowCovering.CurrentPosition}, TargetPosition ${this.WindowCovering.TargetPosition}`,
|
|
697
597
|
);
|
|
698
598
|
}
|
|
699
599
|
}
|
|
700
600
|
|
|
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;
|
|
718
|
-
}
|
|
719
|
-
}
|
|
720
|
-
|
|
721
601
|
async openAPIpushChanges(): Promise<void> {
|
|
722
602
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIpushChanges`);
|
|
723
603
|
const hasDifferentAndRelevantHorizontalTiltAngle =
|
|
724
|
-
this.mappingMode === BlindTiltMappingMode.UseTiltForDirection
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
this.
|
|
604
|
+
this.mappingMode === BlindTiltMappingMode.UseTiltForDirection
|
|
605
|
+
&& this.WindowCovering.TargetHorizontalTiltAngle !== this.WindowCovering.CurrentHorizontalTiltAngle;
|
|
606
|
+
if (this.WindowCovering.TargetPosition !== this.WindowCovering.CurrentPosition
|
|
607
|
+
|| hasDifferentAndRelevantHorizontalTiltAngle || this.device.disableCaching) {
|
|
608
|
+
const [direction, position] = this.mapHomekitValuesToDeviceValues(Number(this.WindowCovering.TargetPosition),
|
|
609
|
+
Number(this.WindowCovering.TargetHorizontalTiltAngle));
|
|
610
|
+
const { Mode }: { setPositionMode: number; Mode: string; } = await this.setPerformance();
|
|
611
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}`
|
|
612
|
+
+ ` Pushing ${this.WindowCovering.TargetPosition} (device = ${direction};${position})`);
|
|
613
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Mode: ${Mode}`);
|
|
729
614
|
let bodyChange = '';
|
|
730
615
|
if (position === 100) {
|
|
731
616
|
bodyChange = JSON.stringify({
|
|
@@ -757,8 +642,10 @@ export class BlindTilt {
|
|
|
757
642
|
this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus body: ${JSON.stringify(deviceStatus.body)}`);
|
|
758
643
|
this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus statusCode: ${deviceStatus.statusCode}`);
|
|
759
644
|
if ((statusCode === 200 || statusCode === 100) && (deviceStatus.statusCode === 200 || deviceStatus.statusCode === 100)) {
|
|
760
|
-
this.
|
|
645
|
+
this.debugSuccessLog(`${this.device.deviceType}: ${this.accessory.displayName} `
|
|
761
646
|
+ `statusCode: ${statusCode} & deviceStatus StatusCode: ${deviceStatus.statusCode}`);
|
|
647
|
+
this.successLog(`${this.device.deviceType}: ${this.accessory.displayName} `
|
|
648
|
+
+ `request to SwitchBot API, body: ${JSON.stringify(bodyChange)} sent successfully`);
|
|
762
649
|
} else {
|
|
763
650
|
this.statusCode(statusCode);
|
|
764
651
|
this.statusCode(deviceStatus.statusCode);
|
|
@@ -766,15 +653,16 @@ export class BlindTilt {
|
|
|
766
653
|
} catch (e: any) {
|
|
767
654
|
this.apiError(e);
|
|
768
655
|
this.errorLog(
|
|
769
|
-
`${this.device.deviceType}: ${this.accessory.displayName} failed openAPIpushChanges with ${this.device.connectionType}`
|
|
770
|
-
` Connection, Error Message: ${JSON.stringify(e.message)}`,
|
|
656
|
+
`${this.device.deviceType}: ${this.accessory.displayName} failed openAPIpushChanges with ${this.device.connectionType}`
|
|
657
|
+
+ ` Connection, Error Message: ${JSON.stringify(e.message)}`,
|
|
771
658
|
);
|
|
772
659
|
}
|
|
773
660
|
} else {
|
|
774
661
|
this.debugLog(
|
|
775
|
-
`${this.device.deviceType}: ${this.accessory.displayName} No OpenAPI Changes, CurrentPosition & TargetPosition Are the Same.`
|
|
776
|
-
` CurrentPosition: ${this.CurrentPosition}, TargetPosition ${this.TargetPosition}`
|
|
777
|
-
` CurrentHorizontalTiltAngle: ${this.CurrentHorizontalTiltAngle}
|
|
662
|
+
`${this.device.deviceType}: ${this.accessory.displayName} No OpenAPI Changes, CurrentPosition & TargetPosition Are the Same.`
|
|
663
|
+
+ ` CurrentPosition: ${this.WindowCovering.CurrentPosition}, TargetPosition ${this.WindowCovering.TargetPosition}`
|
|
664
|
+
+ ` CurrentHorizontalTiltAngle: ${this.WindowCovering.CurrentHorizontalTiltAngle},`
|
|
665
|
+
+ ` TargetPosition ${this.WindowCovering.TargetHorizontalTiltAngle}`,
|
|
778
666
|
);
|
|
779
667
|
}
|
|
780
668
|
}
|
|
@@ -783,16 +671,16 @@ export class BlindTilt {
|
|
|
783
671
|
* Handle requests to set the value of the "Target Horizontal Tilt" characteristic
|
|
784
672
|
*/
|
|
785
673
|
async TargetHorizontalTiltAngleSet(value: CharacteristicValue): Promise<void> {
|
|
786
|
-
if (this.TargetHorizontalTiltAngle === this.accessory.context.TargetHorizontalTiltAngle) {
|
|
674
|
+
if (this.WindowCovering.TargetHorizontalTiltAngle === this.accessory.context.TargetHorizontalTiltAngle) {
|
|
787
675
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} No Changes, Set TargetHorizontalTiltAngle: ${value}`);
|
|
788
676
|
} else {
|
|
789
677
|
this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Set TargetHorizontalTiltAngle: ${value}`);
|
|
790
678
|
}
|
|
791
679
|
|
|
792
680
|
//value = value < 0 ? -90 : 90;
|
|
793
|
-
this.TargetHorizontalTiltAngle = value;
|
|
681
|
+
this.WindowCovering.TargetHorizontalTiltAngle = value;
|
|
794
682
|
if (this.device.mqttURL) {
|
|
795
|
-
this.mqttPublish('TargetHorizontalTiltAngle', this.TargetHorizontalTiltAngle);
|
|
683
|
+
this.mqttPublish('TargetHorizontalTiltAngle', this.WindowCovering.TargetHorizontalTiltAngle.toString());
|
|
796
684
|
}
|
|
797
685
|
|
|
798
686
|
this.startUpdatingBlindTiltIfNeeded();
|
|
@@ -802,15 +690,15 @@ export class BlindTilt {
|
|
|
802
690
|
* Handle requests to set the value of the "Target Position" characteristic
|
|
803
691
|
*/
|
|
804
692
|
async TargetPositionSet(value: CharacteristicValue): Promise<void> {
|
|
805
|
-
if (this.TargetPosition === this.accessory.context.TargetPosition) {
|
|
693
|
+
if (this.WindowCovering.TargetPosition === this.accessory.context.TargetPosition) {
|
|
806
694
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} No Changes, Set TargetPosition: ${value}`);
|
|
807
695
|
} else {
|
|
808
696
|
this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Set TargetPosition: ${value}`);
|
|
809
697
|
}
|
|
810
698
|
|
|
811
|
-
this.TargetPosition = value;
|
|
699
|
+
this.WindowCovering.TargetPosition = value;
|
|
812
700
|
if (this.device.mqttURL) {
|
|
813
|
-
this.mqttPublish('TargetPosition', this.TargetPosition);
|
|
701
|
+
this.mqttPublish('TargetPosition', this.WindowCovering.TargetPosition.toString());
|
|
814
702
|
}
|
|
815
703
|
this.startUpdatingBlindTiltIfNeeded();
|
|
816
704
|
}
|
|
@@ -818,39 +706,43 @@ export class BlindTilt {
|
|
|
818
706
|
async startUpdatingBlindTiltIfNeeded(): Promise<void> {
|
|
819
707
|
await this.setMinMax();
|
|
820
708
|
this.debugLog('setMinMax');
|
|
821
|
-
if (this.TargetPosition > this.CurrentPosition
|
|
822
|
-
this.
|
|
709
|
+
if (this.WindowCovering.TargetPosition > this.WindowCovering.CurrentPosition
|
|
710
|
+
|| this.WindowCovering.TargetHorizontalTiltAngle !== this.WindowCovering.CurrentHorizontalTiltAngle) {
|
|
711
|
+
this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.INCREASING;
|
|
823
712
|
this.setNewTarget = true;
|
|
824
713
|
this.debugLog(
|
|
825
|
-
`${this.device.deviceType}: ${this.accessory.displayName} value: ${this.CurrentPosition},`
|
|
714
|
+
`${this.device.deviceType}: ${this.accessory.displayName} value: ${this.WindowCovering.CurrentPosition},`
|
|
715
|
+
+ ` CurrentPosition: ${this.WindowCovering.CurrentPosition}`,
|
|
826
716
|
);
|
|
827
|
-
} else if (this.TargetPosition < this.CurrentPosition) {
|
|
828
|
-
this.PositionState = this.hap.Characteristic.PositionState.DECREASING;
|
|
717
|
+
} else if (this.WindowCovering.TargetPosition < this.WindowCovering.CurrentPosition) {
|
|
718
|
+
this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.DECREASING;
|
|
829
719
|
this.setNewTarget = true;
|
|
830
720
|
this.debugLog(
|
|
831
|
-
`${this.device.deviceType}: ${this.accessory.displayName} value: ${this.CurrentPosition},`
|
|
721
|
+
`${this.device.deviceType}: ${this.accessory.displayName} value: ${this.WindowCovering.CurrentPosition},`
|
|
722
|
+
+ ` CurrentPosition: ${this.WindowCovering.CurrentPosition}`,
|
|
832
723
|
);
|
|
833
724
|
} else {
|
|
834
|
-
this.PositionState = this.hap.Characteristic.PositionState.STOPPED;
|
|
725
|
+
this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.STOPPED;
|
|
835
726
|
this.setNewTarget = false;
|
|
836
727
|
this.debugLog(
|
|
837
|
-
`${this.device.deviceType}: ${this.accessory.displayName} value: ${this.CurrentPosition},`
|
|
728
|
+
`${this.device.deviceType}: ${this.accessory.displayName} value: ${this.WindowCovering.CurrentPosition},`
|
|
729
|
+
+ ` CurrentPosition: ${this.WindowCovering.CurrentPosition}`,
|
|
838
730
|
);
|
|
839
731
|
}
|
|
840
|
-
this.
|
|
841
|
-
this.
|
|
732
|
+
this.WindowCovering.Service.setCharacteristic(this.hap.Characteristic.PositionState, this.WindowCovering.PositionState);
|
|
733
|
+
this.WindowCovering.Service.getCharacteristic(this.hap.Characteristic.PositionState).updateValue(this.WindowCovering.PositionState);
|
|
842
734
|
|
|
843
735
|
/**
|
|
844
736
|
* If Blind Tilt movement time is short, the moving flag from backend is always false.
|
|
845
737
|
* The minimum time depends on the network control latency.
|
|
846
738
|
*/
|
|
847
739
|
clearTimeout(this.setNewTargetTimer);
|
|
848
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateRate: ${this.
|
|
740
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateRate: ${this.deviceUpdateRate}`);
|
|
849
741
|
if (this.setNewTarget) {
|
|
850
742
|
this.setNewTargetTimer = setTimeout(() => {
|
|
851
743
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} setNewTarget ${this.setNewTarget} timeout`);
|
|
852
744
|
this.setNewTarget = false;
|
|
853
|
-
}, this.
|
|
745
|
+
}, this.deviceUpdateRate * 1000);
|
|
854
746
|
}
|
|
855
747
|
this.doBlindTiltUpdate.next();
|
|
856
748
|
}
|
|
@@ -859,152 +751,97 @@ export class BlindTilt {
|
|
|
859
751
|
await this.setMinMax();
|
|
860
752
|
// CurrentHorizontalTiltAngle
|
|
861
753
|
if (this.mappingMode === BlindTiltMappingMode.UseTiltForDirection) {
|
|
862
|
-
if (this.CurrentHorizontalTiltAngle === undefined || Number.isNaN(this.CurrentHorizontalTiltAngle)) {
|
|
863
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}
|
|
754
|
+
if (this.WindowCovering.CurrentHorizontalTiltAngle === undefined || Number.isNaN(this.WindowCovering.CurrentHorizontalTiltAngle)) {
|
|
755
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}`
|
|
756
|
+
+ ` CurrentHorizontalTiltAngle: ${this.WindowCovering.CurrentHorizontalTiltAngle}`);
|
|
864
757
|
} else {
|
|
865
758
|
if (this.device.mqttURL) {
|
|
866
|
-
this.mqttPublish('CurrentHorizontalTiltAngle', this.CurrentHorizontalTiltAngle);
|
|
759
|
+
this.mqttPublish('CurrentHorizontalTiltAngle', this.WindowCovering.CurrentHorizontalTiltAngle.toString());
|
|
867
760
|
}
|
|
868
|
-
this.accessory.context.CurrentHorizontalTiltAngle = this.CurrentHorizontalTiltAngle;
|
|
869
|
-
this.
|
|
761
|
+
this.accessory.context.CurrentHorizontalTiltAngle = this.WindowCovering.CurrentHorizontalTiltAngle;
|
|
762
|
+
this.WindowCovering.Service.updateCharacteristic(
|
|
870
763
|
this.hap.Characteristic.CurrentHorizontalTiltAngle,
|
|
871
|
-
Number(this.CurrentHorizontalTiltAngle),
|
|
764
|
+
Number(this.WindowCovering.CurrentHorizontalTiltAngle),
|
|
872
765
|
);
|
|
873
766
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}
|
|
874
|
-
updateCharacteristic CurrentHorizontalTiltAngle: ${this.CurrentHorizontalTiltAngle}`);
|
|
767
|
+
updateCharacteristic CurrentHorizontalTiltAngle: ${this.WindowCovering.CurrentHorizontalTiltAngle}`);
|
|
875
768
|
}
|
|
876
769
|
}
|
|
877
770
|
// CurrentPosition
|
|
878
|
-
if (this.CurrentPosition === undefined || Number.isNaN(this.CurrentPosition)) {
|
|
879
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} CurrentPosition: ${this.CurrentPosition}`);
|
|
771
|
+
if (this.WindowCovering.CurrentPosition === undefined || Number.isNaN(this.WindowCovering.CurrentPosition)) {
|
|
772
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
|
|
880
773
|
} else {
|
|
881
774
|
if (this.device.mqttURL) {
|
|
882
|
-
this.mqttPublish('CurrentPosition', this.CurrentPosition);
|
|
775
|
+
this.mqttPublish('CurrentPosition', this.WindowCovering.CurrentPosition.toString());
|
|
883
776
|
}
|
|
884
|
-
this.accessory.context.CurrentPosition = this.CurrentPosition;
|
|
885
|
-
this.
|
|
886
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}
|
|
777
|
+
this.accessory.context.CurrentPosition = this.WindowCovering.CurrentPosition;
|
|
778
|
+
this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.CurrentPosition, Number(this.WindowCovering.CurrentPosition));
|
|
779
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}`
|
|
780
|
+
+ ` updateCharacteristic CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
|
|
887
781
|
}
|
|
888
782
|
// PositionState
|
|
889
|
-
if (this.PositionState === undefined) {
|
|
890
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} PositionState: ${this.PositionState}`);
|
|
783
|
+
if (this.WindowCovering.PositionState === undefined) {
|
|
784
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} PositionState: ${this.WindowCovering.PositionState}`);
|
|
891
785
|
} else {
|
|
892
786
|
if (this.device.mqttURL) {
|
|
893
|
-
this.mqttPublish('PositionState', this.PositionState);
|
|
787
|
+
this.mqttPublish('PositionState', this.WindowCovering.PositionState.toString());
|
|
894
788
|
}
|
|
895
|
-
this.accessory.context.PositionState = this.PositionState;
|
|
896
|
-
this.
|
|
897
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic
|
|
789
|
+
this.accessory.context.PositionState = this.WindowCovering.PositionState;
|
|
790
|
+
this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.PositionState, Number(this.WindowCovering.PositionState));
|
|
791
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic`
|
|
792
|
+
+ ` PositionState: ${this.WindowCovering.PositionState}`);
|
|
898
793
|
}
|
|
899
794
|
// TargetPosition
|
|
900
|
-
if (this.TargetPosition === undefined || Number.isNaN(this.TargetPosition)) {
|
|
901
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} TargetPosition: ${this.TargetPosition}`);
|
|
795
|
+
if (this.WindowCovering.TargetPosition === undefined || Number.isNaN(this.WindowCovering.TargetPosition)) {
|
|
796
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} TargetPosition: ${this.WindowCovering.TargetPosition}`);
|
|
902
797
|
} else {
|
|
903
798
|
if (this.device.mqttURL) {
|
|
904
|
-
this.mqttPublish('TargetPosition', this.TargetPosition);
|
|
799
|
+
this.mqttPublish('TargetPosition', this.WindowCovering.TargetPosition.toString());
|
|
905
800
|
}
|
|
906
|
-
this.accessory.context.TargetPosition = this.TargetPosition;
|
|
907
|
-
this.
|
|
908
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic
|
|
801
|
+
this.accessory.context.TargetPosition = this.WindowCovering.TargetPosition;
|
|
802
|
+
this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.TargetPosition, Number(this.WindowCovering.TargetPosition));
|
|
803
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic`
|
|
804
|
+
+ ` TargetPosition: ${this.WindowCovering.TargetPosition}`);
|
|
909
805
|
}
|
|
910
806
|
// CurrentAmbientLightLevel
|
|
911
807
|
if (!this.device.blindTilt?.hide_lightsensor) {
|
|
912
|
-
if (this.CurrentAmbientLightLevel === undefined || Number.isNaN(this.CurrentAmbientLightLevel)) {
|
|
913
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}
|
|
808
|
+
if (this.LightSensor!.CurrentAmbientLightLevel === undefined || Number.isNaN(this.LightSensor!.CurrentAmbientLightLevel)) {
|
|
809
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}`
|
|
810
|
+
+ ` CurrentAmbientLightLevel: ${this.LightSensor!.CurrentAmbientLightLevel}`);
|
|
914
811
|
} else {
|
|
915
812
|
if (this.device.mqttURL) {
|
|
916
|
-
this.mqttPublish('CurrentAmbientLightLevel', this.CurrentAmbientLightLevel);
|
|
813
|
+
this.mqttPublish('CurrentAmbientLightLevel', this.LightSensor!.CurrentAmbientLightLevel.toString());
|
|
917
814
|
}
|
|
918
|
-
this.accessory.context.CurrentAmbientLightLevel = this.CurrentAmbientLightLevel;
|
|
919
|
-
this.
|
|
815
|
+
this.accessory.context.CurrentAmbientLightLevel = this.LightSensor!.CurrentAmbientLightLevel;
|
|
816
|
+
this.LightSensor!.Service.updateCharacteristic(this.hap.Characteristic.CurrentAmbientLightLevel, this.LightSensor!.CurrentAmbientLightLevel);
|
|
920
817
|
this.debugLog(
|
|
921
818
|
`${this.device.deviceType}: ${this.accessory.displayName}` +
|
|
922
|
-
` updateCharacteristic CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`,
|
|
819
|
+
` updateCharacteristic CurrentAmbientLightLevel: ${this.LightSensor!.CurrentAmbientLightLevel}`,
|
|
923
820
|
);
|
|
924
821
|
}
|
|
925
822
|
}
|
|
926
823
|
// BatteryLevel
|
|
927
|
-
if (this.BatteryLevel === undefined) {
|
|
928
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.BatteryLevel}`);
|
|
824
|
+
if (this.Battery.BatteryLevel === undefined) {
|
|
825
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.Battery.BatteryLevel}`);
|
|
929
826
|
} else {
|
|
930
827
|
if (this.device.mqttURL) {
|
|
931
|
-
this.mqttPublish('BatteryLevel', this.BatteryLevel);
|
|
828
|
+
this.mqttPublish('BatteryLevel', this.Battery.BatteryLevel.toString());
|
|
932
829
|
}
|
|
933
|
-
this.accessory.context.BatteryLevel = this.BatteryLevel;
|
|
934
|
-
this.
|
|
935
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic BatteryLevel: ${this.BatteryLevel}`);
|
|
830
|
+
this.accessory.context.BatteryLevel = this.Battery.BatteryLevel;
|
|
831
|
+
this.Battery?.Service.updateCharacteristic(this.hap.Characteristic.BatteryLevel, this.Battery.BatteryLevel);
|
|
832
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic BatteryLevel: ${this.Battery.BatteryLevel}`);
|
|
936
833
|
}
|
|
937
834
|
// StatusLowBattery
|
|
938
|
-
if (this.StatusLowBattery === undefined) {
|
|
939
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} StatusLowBattery: ${this.StatusLowBattery}`);
|
|
835
|
+
if (this.Battery.StatusLowBattery === undefined) {
|
|
836
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} StatusLowBattery: ${this.Battery.StatusLowBattery}`);
|
|
940
837
|
} else {
|
|
941
838
|
if (this.device.mqttURL) {
|
|
942
|
-
this.mqttPublish('StatusLowBattery', this.StatusLowBattery);
|
|
943
|
-
}
|
|
944
|
-
this.accessory.context.StatusLowBattery = this.StatusLowBattery;
|
|
945
|
-
this.batteryService?.updateCharacteristic(this.hap.Characteristic.StatusLowBattery, this.StatusLowBattery);
|
|
946
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic StatusLowBattery: ${this.StatusLowBattery}`);
|
|
947
|
-
}
|
|
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}`);
|
|
839
|
+
this.mqttPublish('StatusLowBattery', this.Battery.StatusLowBattery.toString());
|
|
979
840
|
}
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
switchbot.stopScan();
|
|
985
|
-
if (this.BLE_IsConnected) {
|
|
986
|
-
await this.BLEparseStatus();
|
|
987
|
-
await this.updateHomeKitCharacteristics();
|
|
988
|
-
} else {
|
|
989
|
-
await this.BLERefreshConnection(switchbot);
|
|
990
|
-
}
|
|
991
|
-
}
|
|
992
|
-
|
|
993
|
-
async getCustomBLEAddress(switchbot: any) {
|
|
994
|
-
if (this.device.customBLEaddress && this.deviceLogging.includes('debug')) {
|
|
995
|
-
(async () => {
|
|
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
|
-
})();
|
|
841
|
+
this.accessory.context.StatusLowBattery = this.Battery.StatusLowBattery;
|
|
842
|
+
this.Battery?.Service.updateCharacteristic(this.hap.Characteristic.StatusLowBattery, this.Battery.StatusLowBattery);
|
|
843
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic`
|
|
844
|
+
+ ` StatusLowBattery: ${this.Battery.StatusLowBattery}`);
|
|
1008
845
|
}
|
|
1009
846
|
}
|
|
1010
847
|
|
|
@@ -1024,221 +861,104 @@ export class BlindTilt {
|
|
|
1024
861
|
}
|
|
1025
862
|
}
|
|
1026
863
|
|
|
1027
|
-
async
|
|
1028
|
-
|
|
864
|
+
async setPerformance() {
|
|
865
|
+
let setPositionMode: number;
|
|
866
|
+
let Mode: string;
|
|
867
|
+
if (Number(this.WindowCovering.TargetPosition) > 50) {
|
|
1029
868
|
if (this.device.blindTilt?.setOpenMode === '1') {
|
|
1030
|
-
|
|
1031
|
-
|
|
869
|
+
setPositionMode = 1;
|
|
870
|
+
Mode = 'Silent Mode';
|
|
871
|
+
} else if (this.device.blindTilt?.setOpenMode === '0') {
|
|
872
|
+
setPositionMode = 0;
|
|
873
|
+
Mode = 'Performance Mode';
|
|
1032
874
|
} else {
|
|
1033
|
-
|
|
1034
|
-
|
|
875
|
+
setPositionMode = 0;
|
|
876
|
+
Mode = 'Default Mode';
|
|
1035
877
|
}
|
|
1036
878
|
} else {
|
|
1037
879
|
if (this.device.blindTilt?.setCloseMode === '1') {
|
|
1038
|
-
|
|
1039
|
-
|
|
880
|
+
setPositionMode = 1;
|
|
881
|
+
Mode = 'Silent Mode';
|
|
882
|
+
} else if (this.device.blindTilt?.setOpenMode === '0') {
|
|
883
|
+
setPositionMode = 0;
|
|
884
|
+
Mode = 'Performance Mode';
|
|
1040
885
|
} else {
|
|
1041
|
-
|
|
1042
|
-
|
|
886
|
+
setPositionMode = 0;
|
|
887
|
+
Mode = 'Default Mode';
|
|
1043
888
|
}
|
|
1044
889
|
}
|
|
890
|
+
return { setPositionMode, Mode };
|
|
1045
891
|
}
|
|
1046
892
|
|
|
1047
893
|
async setMinMax(): Promise<void> {
|
|
1048
894
|
if (this.device.blindTilt?.set_min) {
|
|
1049
|
-
if (Number(this.CurrentPosition) <= this.device.blindTilt?.set_min) {
|
|
1050
|
-
this.CurrentPosition = 0;
|
|
895
|
+
if (Number(this.WindowCovering.CurrentPosition) <= this.device.blindTilt?.set_min) {
|
|
896
|
+
this.WindowCovering.CurrentPosition = 0;
|
|
1051
897
|
}
|
|
1052
898
|
}
|
|
1053
899
|
if (this.device.blindTilt?.set_max) {
|
|
1054
|
-
if (Number(this.CurrentPosition) >= this.device.blindTilt?.set_max) {
|
|
1055
|
-
this.CurrentPosition = 100;
|
|
900
|
+
if (Number(this.WindowCovering.CurrentPosition) >= this.device.blindTilt?.set_max) {
|
|
901
|
+
this.WindowCovering.CurrentPosition = 100;
|
|
1056
902
|
}
|
|
1057
903
|
}
|
|
1058
904
|
|
|
1059
905
|
if (this.mappingMode === BlindTiltMappingMode.UseTiltForDirection) {
|
|
1060
|
-
this.CurrentHorizontalTiltAngle = Number(this.CurrentHorizontalTiltAngle) < 0 ? -90 : 90;
|
|
906
|
+
this.WindowCovering.CurrentHorizontalTiltAngle = Number(this.WindowCovering.CurrentHorizontalTiltAngle) < 0 ? -90 : 90;
|
|
1061
907
|
}
|
|
1062
908
|
}
|
|
1063
909
|
|
|
1064
910
|
minStep(device: device & devicesConfig): number {
|
|
911
|
+
let set_minStep: number;
|
|
1065
912
|
if (device.blindTilt?.set_minStep) {
|
|
1066
|
-
|
|
913
|
+
set_minStep = device.blindTilt?.set_minStep;
|
|
1067
914
|
} else {
|
|
1068
|
-
|
|
915
|
+
set_minStep = 1;
|
|
1069
916
|
}
|
|
1070
|
-
return
|
|
917
|
+
return set_minStep;
|
|
1071
918
|
}
|
|
1072
919
|
|
|
1073
|
-
minLux(): number {
|
|
920
|
+
async minLux(): Promise<number> {
|
|
921
|
+
let set_minLux: number;
|
|
1074
922
|
if (this.device.blindTilt?.set_minLux) {
|
|
1075
|
-
|
|
923
|
+
set_minLux = this.device.blindTilt?.set_minLux;
|
|
1076
924
|
} else {
|
|
1077
|
-
|
|
925
|
+
set_minLux = 1;
|
|
1078
926
|
}
|
|
1079
|
-
return
|
|
927
|
+
return set_minLux;
|
|
1080
928
|
}
|
|
1081
929
|
|
|
1082
|
-
maxLux(): number {
|
|
930
|
+
async maxLux(): Promise<number> {
|
|
931
|
+
let set_maxLux: number;
|
|
1083
932
|
if (this.device.blindTilt?.set_maxLux) {
|
|
1084
|
-
|
|
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
|
-
}
|
|
933
|
+
set_maxLux = this.device.blindTilt?.set_maxLux;
|
|
1107
934
|
} else {
|
|
1108
|
-
|
|
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
|
-
);
|
|
935
|
+
set_maxLux = 6001;
|
|
1194
936
|
}
|
|
937
|
+
return set_maxLux;
|
|
1195
938
|
}
|
|
1196
939
|
|
|
1197
940
|
async offlineOff(): Promise<void> {
|
|
1198
941
|
if (this.device.offline) {
|
|
1199
|
-
|
|
1200
|
-
|
|
942
|
+
this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.CurrentPosition, 100);
|
|
943
|
+
this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.PositionState, this.hap.Characteristic.PositionState.STOPPED);
|
|
944
|
+
this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.TargetPosition, 100);
|
|
1201
945
|
}
|
|
1202
946
|
}
|
|
1203
947
|
|
|
1204
948
|
async apiError(e: any): Promise<void> {
|
|
1205
|
-
this.
|
|
1206
|
-
this.
|
|
1207
|
-
this.
|
|
949
|
+
this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.CurrentPosition, e);
|
|
950
|
+
this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.PositionState, e);
|
|
951
|
+
this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.TargetPosition, e);
|
|
1208
952
|
if (!this.device.curtain?.hide_lightsensor) {
|
|
1209
|
-
this.
|
|
953
|
+
this.LightSensor!.Service.updateCharacteristic(this.hap.Characteristic.CurrentAmbientLightLevel, e);
|
|
1210
954
|
}
|
|
1211
955
|
if (this.BLE) {
|
|
1212
|
-
this.
|
|
1213
|
-
this.
|
|
956
|
+
this.Battery?.Service.updateCharacteristic(this.hap.Characteristic.BatteryLevel, e);
|
|
957
|
+
this.Battery?.Service.updateCharacteristic(this.hap.Characteristic.StatusLowBattery, e);
|
|
1214
958
|
}
|
|
1215
959
|
//throw new this.platform.api.hap.HapStatusError(HAPStatus.SERVICE_COMMUNICATION_FAILURE);
|
|
1216
960
|
}
|
|
1217
961
|
|
|
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;
|
|
1239
|
-
}
|
|
1240
|
-
}
|
|
1241
|
-
|
|
1242
962
|
/**
|
|
1243
963
|
* Maps device values to homekit values
|
|
1244
964
|
*
|
|
@@ -1358,130 +1078,4 @@ export class BlindTilt {
|
|
|
1358
1078
|
}
|
|
1359
1079
|
}
|
|
1360
1080
|
}
|
|
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
1081
|
}
|