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