@switchbot/homebridge-switchbot 3.5.0-beta.3 → 3.5.0-beta.30
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 +147 -9
- package/dist/device/blindtilt.d.ts +21 -94
- package/dist/device/blindtilt.d.ts.map +1 -1
- package/dist/device/blindtilt.js +347 -756
- 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 +582 -759
- 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 +209 -587
- 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 +250 -632
- 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 +204 -531
- 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 +335 -786
- 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 +646 -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 +499 -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 +242 -596
- 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 +207 -571
- 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 +174 -584
- 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 +252 -568
- 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 +210 -542
- 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 +170 -577
- 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 +159 -577
- 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 +136 -518
- 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 +82 -452
- 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 +140 -451
- 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 +121 -664
- package/dist/device/waterdetector.js.map +1 -1
- 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 +509 -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 +237 -94
- package/dist/platform.js.map +1 -1
- package/dist/settings.d.ts +40 -10
- 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 +373 -782
- package/src/device/bot.ts +616 -844
- package/src/device/ceilinglight.ts +222 -607
- package/src/device/colorbulb.ts +264 -656
- package/src/device/contact.ts +229 -553
- package/src/device/curtain.ts +355 -810
- package/src/device/device.ts +673 -0
- package/src/device/fan.ts +548 -0
- package/src/device/hub.ts +268 -623
- package/src/device/humidifier.ts +237 -618
- package/src/device/iosensor.ts +200 -610
- package/src/device/lightstrip.ts +273 -596
- package/src/device/lock.ts +247 -582
- package/src/device/meter.ts +196 -601
- package/src/device/meterplus.ts +184 -602
- package/src/device/motion.ts +156 -541
- package/src/device/plug.ts +92 -480
- package/src/device/robotvacuumcleaner.ts +161 -477
- package/src/device/waterdetector.ts +139 -689
- 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 +526 -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 +247 -102
- package/src/settings.ts +56 -565
- 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,226 @@ 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
438
|
// FirmwareRevision
|
|
480
|
-
this.FirmwareRevision =
|
|
481
|
-
|
|
439
|
+
this.accessory.context.FirmwareRevision = deviceStatus.body.version;
|
|
440
|
+
this.accessory
|
|
441
|
+
.getService(this.hap.Service.AccessoryInformation)!
|
|
442
|
+
.setCharacteristic(this.hap.Characteristic.FirmwareRevision, this.accessory.context.FirmwareRevision)
|
|
443
|
+
.getCharacteristic(this.hap.Characteristic.FirmwareRevision)
|
|
444
|
+
.updateValue(this.accessory.context.FirmwareRevision);
|
|
482
445
|
}
|
|
483
446
|
|
|
484
447
|
async refreshStatus(): Promise<void> {
|
|
@@ -510,21 +473,13 @@ export class BlindTilt {
|
|
|
510
473
|
// Start to monitor advertisement packets
|
|
511
474
|
(async () => {
|
|
512
475
|
// Start to monitor advertisement packets
|
|
513
|
-
await switchbot.startScan({
|
|
514
|
-
model: 'x',
|
|
515
|
-
id: this.device.bleMac,
|
|
516
|
-
});
|
|
476
|
+
await switchbot.startScan({ model: this.device.bleModel, id: this.device.bleMac });
|
|
517
477
|
// Set an event handler
|
|
518
478
|
switchbot.onadvertisement = (ad: any) => {
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
479
|
+
if (this.device.bleMac === ad.address && ad.model === this.device.bleModel) {
|
|
480
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} ${JSON.stringify(ad, null, ' ')}`);
|
|
481
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} address: ${ad.address}, model: ${ad.model}`);
|
|
522
482
|
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
483
|
} else {
|
|
529
484
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${JSON.stringify(ad.serviceData)}`);
|
|
530
485
|
}
|
|
@@ -534,83 +489,27 @@ export class BlindTilt {
|
|
|
534
489
|
// Stop to monitor
|
|
535
490
|
await switchbot.stopScan();
|
|
536
491
|
// Update HomeKit
|
|
537
|
-
await this.BLEparseStatus();
|
|
492
|
+
await this.BLEparseStatus(switchbot.onadvertisement.serviceData);
|
|
538
493
|
await this.updateHomeKitCharacteristics();
|
|
539
494
|
})();
|
|
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 {
|
|
495
|
+
if (switchbot === undefined) {
|
|
590
496
|
await this.BLERefreshConnection(switchbot);
|
|
591
|
-
}
|
|
497
|
+
}
|
|
592
498
|
}
|
|
593
499
|
|
|
594
500
|
async openAPIRefreshStatus(): Promise<void> {
|
|
595
501
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus`);
|
|
596
502
|
try {
|
|
597
|
-
const { body, statusCode } = await
|
|
598
|
-
headers: this.platform.generateHeaders()
|
|
599
|
-
});
|
|
503
|
+
const { body, statusCode } = await this.platform.retryRequest(this.deviceMaxRetries, this.deviceDelayBetweenRetries,
|
|
504
|
+
`${Devices}/${this.device.deviceId}/status`, { headers: this.platform.generateHeaders() });
|
|
600
505
|
this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} statusCode: ${statusCode}`);
|
|
601
506
|
const deviceStatus: any = await body.json();
|
|
602
507
|
this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus: ${JSON.stringify(deviceStatus)}`);
|
|
603
508
|
this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus statusCode: ${deviceStatus.statusCode}`);
|
|
604
509
|
if ((statusCode === 200 || statusCode === 100) && (deviceStatus.statusCode === 200 || deviceStatus.statusCode === 100)) {
|
|
605
|
-
this.
|
|
510
|
+
this.debugSuccessLog(`${this.device.deviceType}: ${this.accessory.displayName} `
|
|
606
511
|
+ `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();
|
|
512
|
+
this.openAPIparseStatus(deviceStatus);
|
|
614
513
|
this.updateHomeKitCharacteristics();
|
|
615
514
|
} else {
|
|
616
515
|
this.statusCode(statusCode);
|
|
@@ -649,7 +548,7 @@ export class BlindTilt {
|
|
|
649
548
|
|
|
650
549
|
async BLEpushChanges(): Promise<void> {
|
|
651
550
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLEpushChanges`);
|
|
652
|
-
if (this.TargetPosition !== this.CurrentPosition) {
|
|
551
|
+
if (this.WindowCovering.TargetPosition !== this.WindowCovering.CurrentPosition) {
|
|
653
552
|
const switchbot = await this.platform.connectBLE();
|
|
654
553
|
// Convert to BLE Address
|
|
655
554
|
this.device.bleMac = this.device
|
|
@@ -657,26 +556,24 @@ export class BlindTilt {
|
|
|
657
556
|
.join(':')
|
|
658
557
|
.toLowerCase();
|
|
659
558
|
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}`);
|
|
559
|
+
const { setPositionMode, Mode }: { setPositionMode: number; Mode: string; } = await this.setPerformance();
|
|
560
|
+
this.debugLog(`${this.accessory.displayName} Mode: ${Mode}`);
|
|
666
561
|
if (switchbot !== false) {
|
|
667
562
|
switchbot
|
|
668
563
|
.discover({ model: 'c', quick: true, id: this.device.bleMac })
|
|
669
564
|
.then(async (device_list: any) => {
|
|
670
|
-
this.infoLog(`${this.accessory.displayName} Target Position: ${this.TargetPosition}`);
|
|
671
|
-
return await this.
|
|
672
|
-
max: this.
|
|
565
|
+
this.infoLog(`${this.accessory.displayName} Target Position: ${this.WindowCovering.TargetPosition}`);
|
|
566
|
+
return await this.retryBLE({
|
|
567
|
+
max: await this.maxRetryBLE(),
|
|
673
568
|
fn: async () => {
|
|
674
|
-
return await device_list[0].runToPos(100 - Number(this.TargetPosition),
|
|
569
|
+
return await device_list[0].runToPos(100 - Number(this.WindowCovering.TargetPosition), setPositionMode);
|
|
675
570
|
},
|
|
676
571
|
});
|
|
677
572
|
})
|
|
678
573
|
.then(() => {
|
|
679
574
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Done.`);
|
|
575
|
+
this.successLog(`${this.device.deviceType}: ${this.accessory.displayName} `
|
|
576
|
+
+ `Target Position: ${this.WindowCovering.TargetPosition} sent over BLE, sent successfully`);
|
|
680
577
|
})
|
|
681
578
|
.catch(async (e: any) => {
|
|
682
579
|
this.apiError(e);
|
|
@@ -693,39 +590,24 @@ export class BlindTilt {
|
|
|
693
590
|
} else {
|
|
694
591
|
this.debugLog(
|
|
695
592
|
`${this.device.deviceType}: ${this.accessory.displayName} No BLEpushChanges, CurrentPosition & TargetPosition Are the Same.` +
|
|
696
|
-
` CurrentPosition: ${this.CurrentPosition}, TargetPosition ${this.TargetPosition}`,
|
|
593
|
+
` CurrentPosition: ${this.WindowCovering.CurrentPosition}, TargetPosition ${this.WindowCovering.TargetPosition}`,
|
|
697
594
|
);
|
|
698
595
|
}
|
|
699
596
|
}
|
|
700
597
|
|
|
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
598
|
async openAPIpushChanges(): Promise<void> {
|
|
722
599
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIpushChanges`);
|
|
723
600
|
const hasDifferentAndRelevantHorizontalTiltAngle =
|
|
724
|
-
this.mappingMode === BlindTiltMappingMode.UseTiltForDirection
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
this.
|
|
601
|
+
this.mappingMode === BlindTiltMappingMode.UseTiltForDirection
|
|
602
|
+
&& this.WindowCovering.TargetHorizontalTiltAngle !== this.WindowCovering.CurrentHorizontalTiltAngle;
|
|
603
|
+
if (this.WindowCovering.TargetPosition !== this.WindowCovering.CurrentPosition
|
|
604
|
+
|| hasDifferentAndRelevantHorizontalTiltAngle || this.device.disableCaching) {
|
|
605
|
+
const [direction, position] = this.mapHomekitValuesToDeviceValues(Number(this.WindowCovering.TargetPosition),
|
|
606
|
+
Number(this.WindowCovering.TargetHorizontalTiltAngle));
|
|
607
|
+
const { Mode }: { setPositionMode: number; Mode: string; } = await this.setPerformance();
|
|
608
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}`
|
|
609
|
+
+ ` Pushing ${this.WindowCovering.TargetPosition} (device = ${direction};${position})`);
|
|
610
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Mode: ${Mode}`);
|
|
729
611
|
let bodyChange = '';
|
|
730
612
|
if (position === 100) {
|
|
731
613
|
bodyChange = JSON.stringify({
|
|
@@ -757,8 +639,10 @@ export class BlindTilt {
|
|
|
757
639
|
this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus body: ${JSON.stringify(deviceStatus.body)}`);
|
|
758
640
|
this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus statusCode: ${deviceStatus.statusCode}`);
|
|
759
641
|
if ((statusCode === 200 || statusCode === 100) && (deviceStatus.statusCode === 200 || deviceStatus.statusCode === 100)) {
|
|
760
|
-
this.
|
|
642
|
+
this.debugSuccessLog(`${this.device.deviceType}: ${this.accessory.displayName} `
|
|
761
643
|
+ `statusCode: ${statusCode} & deviceStatus StatusCode: ${deviceStatus.statusCode}`);
|
|
644
|
+
this.successLog(`${this.device.deviceType}: ${this.accessory.displayName} `
|
|
645
|
+
+ `request to SwitchBot API, body: ${JSON.stringify(bodyChange)} sent successfully`);
|
|
762
646
|
} else {
|
|
763
647
|
this.statusCode(statusCode);
|
|
764
648
|
this.statusCode(deviceStatus.statusCode);
|
|
@@ -766,15 +650,16 @@ export class BlindTilt {
|
|
|
766
650
|
} catch (e: any) {
|
|
767
651
|
this.apiError(e);
|
|
768
652
|
this.errorLog(
|
|
769
|
-
`${this.device.deviceType}: ${this.accessory.displayName} failed openAPIpushChanges with ${this.device.connectionType}`
|
|
770
|
-
` Connection, Error Message: ${JSON.stringify(e.message)}`,
|
|
653
|
+
`${this.device.deviceType}: ${this.accessory.displayName} failed openAPIpushChanges with ${this.device.connectionType}`
|
|
654
|
+
+ ` Connection, Error Message: ${JSON.stringify(e.message)}`,
|
|
771
655
|
);
|
|
772
656
|
}
|
|
773
657
|
} else {
|
|
774
658
|
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}
|
|
659
|
+
`${this.device.deviceType}: ${this.accessory.displayName} No OpenAPI Changes, CurrentPosition & TargetPosition Are the Same.`
|
|
660
|
+
+ ` CurrentPosition: ${this.WindowCovering.CurrentPosition}, TargetPosition ${this.WindowCovering.TargetPosition}`
|
|
661
|
+
+ ` CurrentHorizontalTiltAngle: ${this.WindowCovering.CurrentHorizontalTiltAngle},`
|
|
662
|
+
+ ` TargetPosition ${this.WindowCovering.TargetHorizontalTiltAngle}`,
|
|
778
663
|
);
|
|
779
664
|
}
|
|
780
665
|
}
|
|
@@ -783,16 +668,16 @@ export class BlindTilt {
|
|
|
783
668
|
* Handle requests to set the value of the "Target Horizontal Tilt" characteristic
|
|
784
669
|
*/
|
|
785
670
|
async TargetHorizontalTiltAngleSet(value: CharacteristicValue): Promise<void> {
|
|
786
|
-
if (this.TargetHorizontalTiltAngle === this.accessory.context.TargetHorizontalTiltAngle) {
|
|
671
|
+
if (this.WindowCovering.TargetHorizontalTiltAngle === this.accessory.context.TargetHorizontalTiltAngle) {
|
|
787
672
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} No Changes, Set TargetHorizontalTiltAngle: ${value}`);
|
|
788
673
|
} else {
|
|
789
674
|
this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Set TargetHorizontalTiltAngle: ${value}`);
|
|
790
675
|
}
|
|
791
676
|
|
|
792
677
|
//value = value < 0 ? -90 : 90;
|
|
793
|
-
this.TargetHorizontalTiltAngle = value;
|
|
678
|
+
this.WindowCovering.TargetHorizontalTiltAngle = value;
|
|
794
679
|
if (this.device.mqttURL) {
|
|
795
|
-
this.mqttPublish('TargetHorizontalTiltAngle', this.TargetHorizontalTiltAngle);
|
|
680
|
+
this.mqttPublish('TargetHorizontalTiltAngle', this.WindowCovering.TargetHorizontalTiltAngle.toString());
|
|
796
681
|
}
|
|
797
682
|
|
|
798
683
|
this.startUpdatingBlindTiltIfNeeded();
|
|
@@ -802,15 +687,15 @@ export class BlindTilt {
|
|
|
802
687
|
* Handle requests to set the value of the "Target Position" characteristic
|
|
803
688
|
*/
|
|
804
689
|
async TargetPositionSet(value: CharacteristicValue): Promise<void> {
|
|
805
|
-
if (this.TargetPosition === this.accessory.context.TargetPosition) {
|
|
690
|
+
if (this.WindowCovering.TargetPosition === this.accessory.context.TargetPosition) {
|
|
806
691
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} No Changes, Set TargetPosition: ${value}`);
|
|
807
692
|
} else {
|
|
808
693
|
this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Set TargetPosition: ${value}`);
|
|
809
694
|
}
|
|
810
695
|
|
|
811
|
-
this.TargetPosition = value;
|
|
696
|
+
this.WindowCovering.TargetPosition = value;
|
|
812
697
|
if (this.device.mqttURL) {
|
|
813
|
-
this.mqttPublish('TargetPosition', this.TargetPosition);
|
|
698
|
+
this.mqttPublish('TargetPosition', this.WindowCovering.TargetPosition.toString());
|
|
814
699
|
}
|
|
815
700
|
this.startUpdatingBlindTiltIfNeeded();
|
|
816
701
|
}
|
|
@@ -818,39 +703,43 @@ export class BlindTilt {
|
|
|
818
703
|
async startUpdatingBlindTiltIfNeeded(): Promise<void> {
|
|
819
704
|
await this.setMinMax();
|
|
820
705
|
this.debugLog('setMinMax');
|
|
821
|
-
if (this.TargetPosition > this.CurrentPosition
|
|
822
|
-
this.
|
|
706
|
+
if (this.WindowCovering.TargetPosition > this.WindowCovering.CurrentPosition
|
|
707
|
+
|| this.WindowCovering.TargetHorizontalTiltAngle !== this.WindowCovering.CurrentHorizontalTiltAngle) {
|
|
708
|
+
this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.INCREASING;
|
|
823
709
|
this.setNewTarget = true;
|
|
824
710
|
this.debugLog(
|
|
825
|
-
`${this.device.deviceType}: ${this.accessory.displayName} value: ${this.CurrentPosition},`
|
|
711
|
+
`${this.device.deviceType}: ${this.accessory.displayName} value: ${this.WindowCovering.CurrentPosition},`
|
|
712
|
+
+ ` CurrentPosition: ${this.WindowCovering.CurrentPosition}`,
|
|
826
713
|
);
|
|
827
|
-
} else if (this.TargetPosition < this.CurrentPosition) {
|
|
828
|
-
this.PositionState = this.hap.Characteristic.PositionState.DECREASING;
|
|
714
|
+
} else if (this.WindowCovering.TargetPosition < this.WindowCovering.CurrentPosition) {
|
|
715
|
+
this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.DECREASING;
|
|
829
716
|
this.setNewTarget = true;
|
|
830
717
|
this.debugLog(
|
|
831
|
-
`${this.device.deviceType}: ${this.accessory.displayName} value: ${this.CurrentPosition},`
|
|
718
|
+
`${this.device.deviceType}: ${this.accessory.displayName} value: ${this.WindowCovering.CurrentPosition},`
|
|
719
|
+
+ ` CurrentPosition: ${this.WindowCovering.CurrentPosition}`,
|
|
832
720
|
);
|
|
833
721
|
} else {
|
|
834
|
-
this.PositionState = this.hap.Characteristic.PositionState.STOPPED;
|
|
722
|
+
this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.STOPPED;
|
|
835
723
|
this.setNewTarget = false;
|
|
836
724
|
this.debugLog(
|
|
837
|
-
`${this.device.deviceType}: ${this.accessory.displayName} value: ${this.CurrentPosition},`
|
|
725
|
+
`${this.device.deviceType}: ${this.accessory.displayName} value: ${this.WindowCovering.CurrentPosition},`
|
|
726
|
+
+ ` CurrentPosition: ${this.WindowCovering.CurrentPosition}`,
|
|
838
727
|
);
|
|
839
728
|
}
|
|
840
|
-
this.
|
|
841
|
-
this.
|
|
729
|
+
this.WindowCovering.Service.setCharacteristic(this.hap.Characteristic.PositionState, this.WindowCovering.PositionState);
|
|
730
|
+
this.WindowCovering.Service.getCharacteristic(this.hap.Characteristic.PositionState).updateValue(this.WindowCovering.PositionState);
|
|
842
731
|
|
|
843
732
|
/**
|
|
844
733
|
* If Blind Tilt movement time is short, the moving flag from backend is always false.
|
|
845
734
|
* The minimum time depends on the network control latency.
|
|
846
735
|
*/
|
|
847
736
|
clearTimeout(this.setNewTargetTimer);
|
|
848
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateRate: ${this.
|
|
737
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateRate: ${this.deviceUpdateRate}`);
|
|
849
738
|
if (this.setNewTarget) {
|
|
850
739
|
this.setNewTargetTimer = setTimeout(() => {
|
|
851
740
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} setNewTarget ${this.setNewTarget} timeout`);
|
|
852
741
|
this.setNewTarget = false;
|
|
853
|
-
}, this.
|
|
742
|
+
}, this.deviceUpdateRate * 1000);
|
|
854
743
|
}
|
|
855
744
|
this.doBlindTiltUpdate.next();
|
|
856
745
|
}
|
|
@@ -859,152 +748,97 @@ export class BlindTilt {
|
|
|
859
748
|
await this.setMinMax();
|
|
860
749
|
// CurrentHorizontalTiltAngle
|
|
861
750
|
if (this.mappingMode === BlindTiltMappingMode.UseTiltForDirection) {
|
|
862
|
-
if (this.CurrentHorizontalTiltAngle === undefined || Number.isNaN(this.CurrentHorizontalTiltAngle)) {
|
|
863
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}
|
|
751
|
+
if (this.WindowCovering.CurrentHorizontalTiltAngle === undefined || Number.isNaN(this.WindowCovering.CurrentHorizontalTiltAngle)) {
|
|
752
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}`
|
|
753
|
+
+ ` CurrentHorizontalTiltAngle: ${this.WindowCovering.CurrentHorizontalTiltAngle}`);
|
|
864
754
|
} else {
|
|
865
755
|
if (this.device.mqttURL) {
|
|
866
|
-
this.mqttPublish('CurrentHorizontalTiltAngle', this.CurrentHorizontalTiltAngle);
|
|
756
|
+
this.mqttPublish('CurrentHorizontalTiltAngle', this.WindowCovering.CurrentHorizontalTiltAngle.toString());
|
|
867
757
|
}
|
|
868
|
-
this.accessory.context.CurrentHorizontalTiltAngle = this.CurrentHorizontalTiltAngle;
|
|
869
|
-
this.
|
|
758
|
+
this.accessory.context.CurrentHorizontalTiltAngle = this.WindowCovering.CurrentHorizontalTiltAngle;
|
|
759
|
+
this.WindowCovering.Service.updateCharacteristic(
|
|
870
760
|
this.hap.Characteristic.CurrentHorizontalTiltAngle,
|
|
871
|
-
Number(this.CurrentHorizontalTiltAngle),
|
|
761
|
+
Number(this.WindowCovering.CurrentHorizontalTiltAngle),
|
|
872
762
|
);
|
|
873
763
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}
|
|
874
|
-
updateCharacteristic CurrentHorizontalTiltAngle: ${this.CurrentHorizontalTiltAngle}`);
|
|
764
|
+
updateCharacteristic CurrentHorizontalTiltAngle: ${this.WindowCovering.CurrentHorizontalTiltAngle}`);
|
|
875
765
|
}
|
|
876
766
|
}
|
|
877
767
|
// CurrentPosition
|
|
878
|
-
if (this.CurrentPosition === undefined || Number.isNaN(this.CurrentPosition)) {
|
|
879
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} CurrentPosition: ${this.CurrentPosition}`);
|
|
768
|
+
if (this.WindowCovering.CurrentPosition === undefined || Number.isNaN(this.WindowCovering.CurrentPosition)) {
|
|
769
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
|
|
880
770
|
} else {
|
|
881
771
|
if (this.device.mqttURL) {
|
|
882
|
-
this.mqttPublish('CurrentPosition', this.CurrentPosition);
|
|
772
|
+
this.mqttPublish('CurrentPosition', this.WindowCovering.CurrentPosition.toString());
|
|
883
773
|
}
|
|
884
|
-
this.accessory.context.CurrentPosition = this.CurrentPosition;
|
|
885
|
-
this.
|
|
886
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}
|
|
774
|
+
this.accessory.context.CurrentPosition = this.WindowCovering.CurrentPosition;
|
|
775
|
+
this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.CurrentPosition, Number(this.WindowCovering.CurrentPosition));
|
|
776
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}`
|
|
777
|
+
+ ` updateCharacteristic CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
|
|
887
778
|
}
|
|
888
779
|
// PositionState
|
|
889
|
-
if (this.PositionState === undefined) {
|
|
890
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} PositionState: ${this.PositionState}`);
|
|
780
|
+
if (this.WindowCovering.PositionState === undefined) {
|
|
781
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} PositionState: ${this.WindowCovering.PositionState}`);
|
|
891
782
|
} else {
|
|
892
783
|
if (this.device.mqttURL) {
|
|
893
|
-
this.mqttPublish('PositionState', this.PositionState);
|
|
784
|
+
this.mqttPublish('PositionState', this.WindowCovering.PositionState.toString());
|
|
894
785
|
}
|
|
895
|
-
this.accessory.context.PositionState = this.PositionState;
|
|
896
|
-
this.
|
|
897
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic
|
|
786
|
+
this.accessory.context.PositionState = this.WindowCovering.PositionState;
|
|
787
|
+
this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.PositionState, Number(this.WindowCovering.PositionState));
|
|
788
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic`
|
|
789
|
+
+ ` PositionState: ${this.WindowCovering.PositionState}`);
|
|
898
790
|
}
|
|
899
791
|
// TargetPosition
|
|
900
|
-
if (this.TargetPosition === undefined || Number.isNaN(this.TargetPosition)) {
|
|
901
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} TargetPosition: ${this.TargetPosition}`);
|
|
792
|
+
if (this.WindowCovering.TargetPosition === undefined || Number.isNaN(this.WindowCovering.TargetPosition)) {
|
|
793
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} TargetPosition: ${this.WindowCovering.TargetPosition}`);
|
|
902
794
|
} else {
|
|
903
795
|
if (this.device.mqttURL) {
|
|
904
|
-
this.mqttPublish('TargetPosition', this.TargetPosition);
|
|
796
|
+
this.mqttPublish('TargetPosition', this.WindowCovering.TargetPosition.toString());
|
|
905
797
|
}
|
|
906
|
-
this.accessory.context.TargetPosition = this.TargetPosition;
|
|
907
|
-
this.
|
|
908
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic
|
|
798
|
+
this.accessory.context.TargetPosition = this.WindowCovering.TargetPosition;
|
|
799
|
+
this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.TargetPosition, Number(this.WindowCovering.TargetPosition));
|
|
800
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic`
|
|
801
|
+
+ ` TargetPosition: ${this.WindowCovering.TargetPosition}`);
|
|
909
802
|
}
|
|
910
803
|
// CurrentAmbientLightLevel
|
|
911
804
|
if (!this.device.blindTilt?.hide_lightsensor) {
|
|
912
|
-
if (this.CurrentAmbientLightLevel === undefined || Number.isNaN(this.CurrentAmbientLightLevel)) {
|
|
913
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}
|
|
805
|
+
if (this.LightSensor!.CurrentAmbientLightLevel === undefined || Number.isNaN(this.LightSensor!.CurrentAmbientLightLevel)) {
|
|
806
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}`
|
|
807
|
+
+ ` CurrentAmbientLightLevel: ${this.LightSensor!.CurrentAmbientLightLevel}`);
|
|
914
808
|
} else {
|
|
915
809
|
if (this.device.mqttURL) {
|
|
916
|
-
this.mqttPublish('CurrentAmbientLightLevel', this.CurrentAmbientLightLevel);
|
|
810
|
+
this.mqttPublish('CurrentAmbientLightLevel', this.LightSensor!.CurrentAmbientLightLevel.toString());
|
|
917
811
|
}
|
|
918
|
-
this.accessory.context.CurrentAmbientLightLevel = this.CurrentAmbientLightLevel;
|
|
919
|
-
this.
|
|
812
|
+
this.accessory.context.CurrentAmbientLightLevel = this.LightSensor!.CurrentAmbientLightLevel;
|
|
813
|
+
this.LightSensor!.Service.updateCharacteristic(this.hap.Characteristic.CurrentAmbientLightLevel, this.LightSensor!.CurrentAmbientLightLevel);
|
|
920
814
|
this.debugLog(
|
|
921
815
|
`${this.device.deviceType}: ${this.accessory.displayName}` +
|
|
922
|
-
` updateCharacteristic CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`,
|
|
816
|
+
` updateCharacteristic CurrentAmbientLightLevel: ${this.LightSensor!.CurrentAmbientLightLevel}`,
|
|
923
817
|
);
|
|
924
818
|
}
|
|
925
819
|
}
|
|
926
820
|
// BatteryLevel
|
|
927
|
-
if (this.BatteryLevel === undefined) {
|
|
928
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.BatteryLevel}`);
|
|
821
|
+
if (this.Battery.BatteryLevel === undefined) {
|
|
822
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.Battery.BatteryLevel}`);
|
|
929
823
|
} else {
|
|
930
824
|
if (this.device.mqttURL) {
|
|
931
|
-
this.mqttPublish('BatteryLevel', this.BatteryLevel);
|
|
825
|
+
this.mqttPublish('BatteryLevel', this.Battery.BatteryLevel.toString());
|
|
932
826
|
}
|
|
933
|
-
this.accessory.context.BatteryLevel = this.BatteryLevel;
|
|
934
|
-
this.
|
|
935
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic BatteryLevel: ${this.BatteryLevel}`);
|
|
827
|
+
this.accessory.context.BatteryLevel = this.Battery.BatteryLevel;
|
|
828
|
+
this.Battery?.Service.updateCharacteristic(this.hap.Characteristic.BatteryLevel, this.Battery.BatteryLevel);
|
|
829
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic BatteryLevel: ${this.Battery.BatteryLevel}`);
|
|
936
830
|
}
|
|
937
831
|
// StatusLowBattery
|
|
938
|
-
if (this.StatusLowBattery === undefined) {
|
|
939
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} StatusLowBattery: ${this.StatusLowBattery}`);
|
|
832
|
+
if (this.Battery.StatusLowBattery === undefined) {
|
|
833
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} StatusLowBattery: ${this.Battery.StatusLowBattery}`);
|
|
940
834
|
} else {
|
|
941
835
|
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}`);
|
|
836
|
+
this.mqttPublish('StatusLowBattery', this.Battery.StatusLowBattery.toString());
|
|
979
837
|
}
|
|
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
|
-
})();
|
|
838
|
+
this.accessory.context.StatusLowBattery = this.Battery.StatusLowBattery;
|
|
839
|
+
this.Battery?.Service.updateCharacteristic(this.hap.Characteristic.StatusLowBattery, this.Battery.StatusLowBattery);
|
|
840
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic`
|
|
841
|
+
+ ` StatusLowBattery: ${this.Battery.StatusLowBattery}`);
|
|
1008
842
|
}
|
|
1009
843
|
}
|
|
1010
844
|
|
|
@@ -1024,221 +858,104 @@ export class BlindTilt {
|
|
|
1024
858
|
}
|
|
1025
859
|
}
|
|
1026
860
|
|
|
1027
|
-
async
|
|
1028
|
-
|
|
861
|
+
async setPerformance() {
|
|
862
|
+
let setPositionMode: number;
|
|
863
|
+
let Mode: string;
|
|
864
|
+
if (Number(this.WindowCovering.TargetPosition) > 50) {
|
|
1029
865
|
if (this.device.blindTilt?.setOpenMode === '1') {
|
|
1030
|
-
|
|
1031
|
-
|
|
866
|
+
setPositionMode = 1;
|
|
867
|
+
Mode = 'Silent Mode';
|
|
868
|
+
} else if (this.device.blindTilt?.setOpenMode === '0') {
|
|
869
|
+
setPositionMode = 0;
|
|
870
|
+
Mode = 'Performance Mode';
|
|
1032
871
|
} else {
|
|
1033
|
-
|
|
1034
|
-
|
|
872
|
+
setPositionMode = 0;
|
|
873
|
+
Mode = 'Default Mode';
|
|
1035
874
|
}
|
|
1036
875
|
} else {
|
|
1037
876
|
if (this.device.blindTilt?.setCloseMode === '1') {
|
|
1038
|
-
|
|
1039
|
-
|
|
877
|
+
setPositionMode = 1;
|
|
878
|
+
Mode = 'Silent Mode';
|
|
879
|
+
} else if (this.device.blindTilt?.setOpenMode === '0') {
|
|
880
|
+
setPositionMode = 0;
|
|
881
|
+
Mode = 'Performance Mode';
|
|
1040
882
|
} else {
|
|
1041
|
-
|
|
1042
|
-
|
|
883
|
+
setPositionMode = 0;
|
|
884
|
+
Mode = 'Default Mode';
|
|
1043
885
|
}
|
|
1044
886
|
}
|
|
887
|
+
return { setPositionMode, Mode };
|
|
1045
888
|
}
|
|
1046
889
|
|
|
1047
890
|
async setMinMax(): Promise<void> {
|
|
1048
891
|
if (this.device.blindTilt?.set_min) {
|
|
1049
|
-
if (Number(this.CurrentPosition) <= this.device.blindTilt?.set_min) {
|
|
1050
|
-
this.CurrentPosition = 0;
|
|
892
|
+
if (Number(this.WindowCovering.CurrentPosition) <= this.device.blindTilt?.set_min) {
|
|
893
|
+
this.WindowCovering.CurrentPosition = 0;
|
|
1051
894
|
}
|
|
1052
895
|
}
|
|
1053
896
|
if (this.device.blindTilt?.set_max) {
|
|
1054
|
-
if (Number(this.CurrentPosition) >= this.device.blindTilt?.set_max) {
|
|
1055
|
-
this.CurrentPosition = 100;
|
|
897
|
+
if (Number(this.WindowCovering.CurrentPosition) >= this.device.blindTilt?.set_max) {
|
|
898
|
+
this.WindowCovering.CurrentPosition = 100;
|
|
1056
899
|
}
|
|
1057
900
|
}
|
|
1058
901
|
|
|
1059
902
|
if (this.mappingMode === BlindTiltMappingMode.UseTiltForDirection) {
|
|
1060
|
-
this.CurrentHorizontalTiltAngle = Number(this.CurrentHorizontalTiltAngle) < 0 ? -90 : 90;
|
|
903
|
+
this.WindowCovering.CurrentHorizontalTiltAngle = Number(this.WindowCovering.CurrentHorizontalTiltAngle) < 0 ? -90 : 90;
|
|
1061
904
|
}
|
|
1062
905
|
}
|
|
1063
906
|
|
|
1064
907
|
minStep(device: device & devicesConfig): number {
|
|
908
|
+
let set_minStep: number;
|
|
1065
909
|
if (device.blindTilt?.set_minStep) {
|
|
1066
|
-
|
|
910
|
+
set_minStep = device.blindTilt?.set_minStep;
|
|
1067
911
|
} else {
|
|
1068
|
-
|
|
912
|
+
set_minStep = 1;
|
|
1069
913
|
}
|
|
1070
|
-
return
|
|
914
|
+
return set_minStep;
|
|
1071
915
|
}
|
|
1072
916
|
|
|
1073
|
-
minLux(): number {
|
|
917
|
+
async minLux(): Promise<number> {
|
|
918
|
+
let set_minLux: number;
|
|
1074
919
|
if (this.device.blindTilt?.set_minLux) {
|
|
1075
|
-
|
|
920
|
+
set_minLux = this.device.blindTilt?.set_minLux;
|
|
1076
921
|
} else {
|
|
1077
|
-
|
|
922
|
+
set_minLux = 1;
|
|
1078
923
|
}
|
|
1079
|
-
return
|
|
924
|
+
return set_minLux;
|
|
1080
925
|
}
|
|
1081
926
|
|
|
1082
|
-
maxLux(): number {
|
|
927
|
+
async maxLux(): Promise<number> {
|
|
928
|
+
let set_maxLux: number;
|
|
1083
929
|
if (this.device.blindTilt?.set_maxLux) {
|
|
1084
|
-
|
|
930
|
+
set_maxLux = this.device.blindTilt?.set_maxLux;
|
|
1085
931
|
} else {
|
|
1086
|
-
|
|
1087
|
-
}
|
|
1088
|
-
return this.set_maxLux;
|
|
1089
|
-
}
|
|
1090
|
-
|
|
1091
|
-
async scan(device: device & devicesConfig): Promise<void> {
|
|
1092
|
-
if (device.scanDuration) {
|
|
1093
|
-
if (this.updateRate > device.scanDuration) {
|
|
1094
|
-
this.scanDuration = this.updateRate;
|
|
1095
|
-
if (this.BLE) {
|
|
1096
|
-
this.warnLog(
|
|
1097
|
-
`${this.device.deviceType}: ` +
|
|
1098
|
-
`${this.accessory.displayName} scanDuration is less than updateRate, overriding scanDuration with updateRate`,
|
|
1099
|
-
);
|
|
1100
|
-
}
|
|
1101
|
-
} else {
|
|
1102
|
-
this.scanDuration = this.accessory.context.scanDuration = device.scanDuration;
|
|
1103
|
-
}
|
|
1104
|
-
if (this.BLE) {
|
|
1105
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Config scanDuration: ${this.scanDuration}`);
|
|
1106
|
-
}
|
|
1107
|
-
} else {
|
|
1108
|
-
if (this.updateRate > 1) {
|
|
1109
|
-
this.scanDuration = this.updateRate;
|
|
1110
|
-
} else {
|
|
1111
|
-
this.scanDuration = this.accessory.context.scanDuration = 1;
|
|
1112
|
-
}
|
|
1113
|
-
if (this.BLE) {
|
|
1114
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Default scanDuration: ${this.scanDuration}`);
|
|
1115
|
-
}
|
|
1116
|
-
}
|
|
1117
|
-
}
|
|
1118
|
-
|
|
1119
|
-
async statusCode(statusCode: number): Promise<void> {
|
|
1120
|
-
switch (statusCode) {
|
|
1121
|
-
case 151:
|
|
1122
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command not supported by this deviceType, statusCode: ${statusCode}`);
|
|
1123
|
-
break;
|
|
1124
|
-
case 152:
|
|
1125
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device not found, statusCode: ${statusCode}`);
|
|
1126
|
-
break;
|
|
1127
|
-
case 160:
|
|
1128
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command is not supported, statusCode: ${statusCode}`);
|
|
1129
|
-
break;
|
|
1130
|
-
case 161:
|
|
1131
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device is offline, statusCode: ${statusCode}`);
|
|
1132
|
-
this.offlineOff();
|
|
1133
|
-
break;
|
|
1134
|
-
case 171:
|
|
1135
|
-
this.errorLog(
|
|
1136
|
-
`${this.device.deviceType}: ${this.accessory.displayName} Hub Device is offline, statusCode: ${statusCode}. ` +
|
|
1137
|
-
`Hub: ${this.device.hubDeviceId}`,
|
|
1138
|
-
);
|
|
1139
|
-
this.offlineOff();
|
|
1140
|
-
break;
|
|
1141
|
-
case 190:
|
|
1142
|
-
this.errorLog(
|
|
1143
|
-
`${this.device.deviceType}: ${this.accessory.displayName} Device internal error due to device states not synchronized with server,` +
|
|
1144
|
-
` Or command format is invalid, statusCode: ${statusCode}`,
|
|
1145
|
-
);
|
|
1146
|
-
break;
|
|
1147
|
-
case 100:
|
|
1148
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Command successfully sent, statusCode: ${statusCode}`);
|
|
1149
|
-
break;
|
|
1150
|
-
case 200:
|
|
1151
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Request successful, statusCode: ${statusCode}`);
|
|
1152
|
-
break;
|
|
1153
|
-
case 400:
|
|
1154
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Bad Request, The client has issued an invalid request. `
|
|
1155
|
-
+ `This is commonly used to specify validation errors in a request payload, statusCode: ${statusCode}`);
|
|
1156
|
-
break;
|
|
1157
|
-
case 401:
|
|
1158
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Unauthorized, Authorization for the API is required, `
|
|
1159
|
-
+ `but the request has not been authenticated, statusCode: ${statusCode}`);
|
|
1160
|
-
break;
|
|
1161
|
-
case 403:
|
|
1162
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Forbidden, The request has been authenticated but does not `
|
|
1163
|
-
+ `have appropriate permissions, or a requested resource is not found, statusCode: ${statusCode}`);
|
|
1164
|
-
break;
|
|
1165
|
-
case 404:
|
|
1166
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Not Found, Specifies the requested path does not exist, `
|
|
1167
|
-
+ `statusCode: ${statusCode}`);
|
|
1168
|
-
break;
|
|
1169
|
-
case 406:
|
|
1170
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Not Acceptable, The client has requested a MIME type via `
|
|
1171
|
-
+ `the Accept header for a value not supported by the server, statusCode: ${statusCode}`);
|
|
1172
|
-
break;
|
|
1173
|
-
case 415:
|
|
1174
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Unsupported Media Type, The client has defined a contentType `
|
|
1175
|
-
+ `header that is not supported by the server, statusCode: ${statusCode}`);
|
|
1176
|
-
break;
|
|
1177
|
-
case 422:
|
|
1178
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Unprocessable Entity, The client has made a valid request, `
|
|
1179
|
-
+ `but the server cannot process it. This is often used for APIs for which certain limits have been exceeded, statusCode: ${statusCode}`);
|
|
1180
|
-
break;
|
|
1181
|
-
case 429:
|
|
1182
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Too Many Requests, The client has exceeded the number of `
|
|
1183
|
-
+ `requests allowed for a given time window, statusCode: ${statusCode}`);
|
|
1184
|
-
break;
|
|
1185
|
-
case 500:
|
|
1186
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Internal Server Error, An unexpected error on the SmartThings `
|
|
1187
|
-
+ `servers has occurred. These errors should be rare, statusCode: ${statusCode}`);
|
|
1188
|
-
break;
|
|
1189
|
-
default:
|
|
1190
|
-
this.infoLog(
|
|
1191
|
-
`${this.device.deviceType}: ${this.accessory.displayName} Unknown statusCode: ` +
|
|
1192
|
-
`${statusCode}, Submit Bugs Here: ' + 'https://tinyurl.com/SwitchBotBug`,
|
|
1193
|
-
);
|
|
932
|
+
set_maxLux = 6001;
|
|
1194
933
|
}
|
|
934
|
+
return set_maxLux;
|
|
1195
935
|
}
|
|
1196
936
|
|
|
1197
937
|
async offlineOff(): Promise<void> {
|
|
1198
938
|
if (this.device.offline) {
|
|
1199
|
-
|
|
1200
|
-
|
|
939
|
+
this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.CurrentPosition, 100);
|
|
940
|
+
this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.PositionState, this.hap.Characteristic.PositionState.STOPPED);
|
|
941
|
+
this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.TargetPosition, 100);
|
|
1201
942
|
}
|
|
1202
943
|
}
|
|
1203
944
|
|
|
1204
945
|
async apiError(e: any): Promise<void> {
|
|
1205
|
-
this.
|
|
1206
|
-
this.
|
|
1207
|
-
this.
|
|
946
|
+
this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.CurrentPosition, e);
|
|
947
|
+
this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.PositionState, e);
|
|
948
|
+
this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.TargetPosition, e);
|
|
1208
949
|
if (!this.device.curtain?.hide_lightsensor) {
|
|
1209
|
-
this.
|
|
950
|
+
this.LightSensor!.Service.updateCharacteristic(this.hap.Characteristic.CurrentAmbientLightLevel, e);
|
|
1210
951
|
}
|
|
1211
952
|
if (this.BLE) {
|
|
1212
|
-
this.
|
|
1213
|
-
this.
|
|
953
|
+
this.Battery?.Service.updateCharacteristic(this.hap.Characteristic.BatteryLevel, e);
|
|
954
|
+
this.Battery?.Service.updateCharacteristic(this.hap.Characteristic.StatusLowBattery, e);
|
|
1214
955
|
}
|
|
1215
956
|
//throw new this.platform.api.hap.HapStatusError(HAPStatus.SERVICE_COMMUNICATION_FAILURE);
|
|
1216
957
|
}
|
|
1217
958
|
|
|
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
959
|
/**
|
|
1243
960
|
* Maps device values to homekit values
|
|
1244
961
|
*
|
|
@@ -1358,130 +1075,4 @@ export class BlindTilt {
|
|
|
1358
1075
|
}
|
|
1359
1076
|
}
|
|
1360
1077
|
}
|
|
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
1078
|
}
|