@switchbot/homebridge-switchbot 3.5.0-beta.3 → 3.5.0-beta.30
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +4 -1
- package/config.schema.json +147 -9
- package/dist/device/blindtilt.d.ts +21 -94
- package/dist/device/blindtilt.d.ts.map +1 -1
- package/dist/device/blindtilt.js +347 -756
- package/dist/device/blindtilt.js.map +1 -1
- package/dist/device/bot.d.ts +25 -71
- package/dist/device/bot.d.ts.map +1 -1
- package/dist/device/bot.js +582 -759
- package/dist/device/bot.js.map +1 -1
- package/dist/device/ceilinglight.d.ts +13 -67
- package/dist/device/ceilinglight.d.ts.map +1 -1
- package/dist/device/ceilinglight.js +209 -587
- package/dist/device/ceilinglight.js.map +1 -1
- package/dist/device/colorbulb.d.ts +13 -74
- package/dist/device/colorbulb.d.ts.map +1 -1
- package/dist/device/colorbulb.js +250 -632
- package/dist/device/colorbulb.js.map +1 -1
- package/dist/device/contact.d.ts +14 -65
- package/dist/device/contact.d.ts.map +1 -1
- package/dist/device/contact.js +204 -531
- package/dist/device/contact.js.map +1 -1
- package/dist/device/curtain.d.ts +17 -86
- package/dist/device/curtain.d.ts.map +1 -1
- package/dist/device/curtain.js +335 -786
- package/dist/device/curtain.js.map +1 -1
- package/dist/device/device.d.ts +59 -0
- package/dist/device/device.d.ts.map +1 -0
- package/dist/device/device.js +646 -0
- package/dist/device/device.js.map +1 -0
- package/dist/device/fan.d.ts +51 -0
- package/dist/device/fan.d.ts.map +1 -0
- package/dist/device/fan.js +499 -0
- package/dist/device/fan.js.map +1 -0
- package/dist/device/hub.d.ts +15 -59
- package/dist/device/hub.d.ts.map +1 -1
- package/dist/device/hub.js +242 -596
- package/dist/device/hub.js.map +1 -1
- package/dist/device/humidifier.d.ts +10 -65
- package/dist/device/humidifier.d.ts.map +1 -1
- package/dist/device/humidifier.js +207 -571
- package/dist/device/humidifier.js.map +1 -1
- package/dist/device/iosensor.d.ts +11 -64
- package/dist/device/iosensor.d.ts.map +1 -1
- package/dist/device/iosensor.js +174 -584
- package/dist/device/iosensor.js.map +1 -1
- package/dist/device/lightstrip.d.ts +10 -68
- package/dist/device/lightstrip.d.ts.map +1 -1
- package/dist/device/lightstrip.js +252 -568
- package/dist/device/lightstrip.js.map +1 -1
- package/dist/device/lock.d.ts +15 -62
- package/dist/device/lock.d.ts.map +1 -1
- package/dist/device/lock.js +210 -542
- package/dist/device/lock.js.map +1 -1
- package/dist/device/meter.d.ts +13 -63
- package/dist/device/meter.d.ts.map +1 -1
- package/dist/device/meter.js +170 -577
- package/dist/device/meter.js.map +1 -1
- package/dist/device/meterplus.d.ts +13 -64
- package/dist/device/meterplus.d.ts.map +1 -1
- package/dist/device/meterplus.js +159 -577
- package/dist/device/meterplus.js.map +1 -1
- package/dist/device/motion.d.ts +13 -69
- package/dist/device/motion.d.ts.map +1 -1
- package/dist/device/motion.js +136 -518
- package/dist/device/motion.js.map +1 -1
- package/dist/device/plug.d.ts +9 -57
- package/dist/device/plug.d.ts.map +1 -1
- package/dist/device/plug.js +82 -452
- package/dist/device/plug.js.map +1 -1
- package/dist/device/robotvacuumcleaner.d.ts +11 -62
- package/dist/device/robotvacuumcleaner.d.ts.map +1 -1
- package/dist/device/robotvacuumcleaner.js +140 -451
- package/dist/device/robotvacuumcleaner.js.map +1 -1
- package/dist/device/waterdetector.d.ts +9 -70
- package/dist/device/waterdetector.d.ts.map +1 -1
- package/dist/device/waterdetector.js +121 -664
- package/dist/device/waterdetector.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/irdevice/airconditioner.d.ts +8 -48
- package/dist/irdevice/airconditioner.d.ts.map +1 -1
- package/dist/irdevice/airconditioner.js +309 -419
- package/dist/irdevice/airconditioner.js.map +1 -1
- package/dist/irdevice/airpurifier.d.ts +7 -38
- package/dist/irdevice/airpurifier.d.ts.map +1 -1
- package/dist/irdevice/airpurifier.js +72 -304
- package/dist/irdevice/airpurifier.js.map +1 -1
- package/dist/irdevice/camera.d.ts +6 -35
- package/dist/irdevice/camera.d.ts.map +1 -1
- package/dist/irdevice/camera.js +34 -278
- package/dist/irdevice/camera.js.map +1 -1
- package/dist/irdevice/fan.d.ts +6 -39
- package/dist/irdevice/fan.d.ts.map +1 -1
- package/dist/irdevice/fan.js +67 -311
- package/dist/irdevice/fan.js.map +1 -1
- package/dist/irdevice/irdevice.d.ts +40 -0
- package/dist/irdevice/irdevice.d.ts.map +1 -0
- package/dist/irdevice/irdevice.js +509 -0
- package/dist/irdevice/irdevice.js.map +1 -0
- package/dist/irdevice/light.d.ts +6 -34
- package/dist/irdevice/light.d.ts.map +1 -1
- package/dist/irdevice/light.js +23 -272
- package/dist/irdevice/light.js.map +1 -1
- package/dist/irdevice/other.d.ts +18 -47
- package/dist/irdevice/other.d.ts.map +1 -1
- package/dist/irdevice/other.js +352 -546
- package/dist/irdevice/other.js.map +1 -1
- package/dist/irdevice/tv.d.ts +7 -39
- package/dist/irdevice/tv.d.ts.map +1 -1
- package/dist/irdevice/tv.js +82 -321
- package/dist/irdevice/tv.js.map +1 -1
- package/dist/irdevice/vacuumcleaner.d.ts +6 -35
- package/dist/irdevice/vacuumcleaner.d.ts.map +1 -1
- package/dist/irdevice/vacuumcleaner.js +41 -284
- package/dist/irdevice/vacuumcleaner.js.map +1 -1
- package/dist/irdevice/waterheater.d.ts +6 -35
- package/dist/irdevice/waterheater.d.ts.map +1 -1
- package/dist/irdevice/waterheater.js +42 -287
- package/dist/irdevice/waterheater.js.map +1 -1
- package/dist/platform.d.ts +14 -1
- package/dist/platform.d.ts.map +1 -1
- package/dist/platform.js +237 -94
- package/dist/platform.js.map +1 -1
- package/dist/settings.d.ts +40 -10
- package/dist/settings.d.ts.map +1 -1
- package/dist/settings.js +0 -552
- package/dist/settings.js.map +1 -1
- package/dist/utils.d.ts +77 -0
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +638 -1
- package/dist/utils.js.map +1 -1
- package/package.json +16 -15
- package/src/custom.d.ts +2 -1
- package/src/device/blindtilt.ts +373 -782
- package/src/device/bot.ts +616 -844
- package/src/device/ceilinglight.ts +222 -607
- package/src/device/colorbulb.ts +264 -656
- package/src/device/contact.ts +229 -553
- package/src/device/curtain.ts +355 -810
- package/src/device/device.ts +673 -0
- package/src/device/fan.ts +548 -0
- package/src/device/hub.ts +268 -623
- package/src/device/humidifier.ts +237 -618
- package/src/device/iosensor.ts +200 -610
- package/src/device/lightstrip.ts +273 -596
- package/src/device/lock.ts +247 -582
- package/src/device/meter.ts +196 -601
- package/src/device/meterplus.ts +184 -602
- package/src/device/motion.ts +156 -541
- package/src/device/plug.ts +92 -480
- package/src/device/robotvacuumcleaner.ts +161 -477
- package/src/device/waterdetector.ts +139 -689
- package/src/index.ts +1 -1
- package/src/irdevice/airconditioner.ts +330 -446
- package/src/irdevice/airpurifier.ts +89 -321
- package/src/irdevice/camera.ts +42 -293
- package/src/irdevice/fan.ts +78 -327
- package/src/irdevice/irdevice.ts +526 -0
- package/src/irdevice/light.ts +32 -287
- package/src/irdevice/other.ts +396 -615
- package/src/irdevice/tv.ts +100 -339
- package/src/irdevice/vacuumcleaner.ts +49 -305
- package/src/irdevice/waterheater.ts +50 -310
- package/src/platform.ts +247 -102
- package/src/settings.ts +56 -565
- package/src/utils.ts +642 -1
package/src/device/curtain.ts
CHANGED
|
@@ -1,139 +1,100 @@
|
|
|
1
|
+
/* Copyright(C) 2021-2024, donavanbecker (https://github.com/donavanbecker). All rights reserved.
|
|
2
|
+
*
|
|
3
|
+
* curtain.ts: @switchbot/homebridge-switchbot.
|
|
4
|
+
*/
|
|
5
|
+
import { hostname } from 'os';
|
|
1
6
|
import { request } from 'undici';
|
|
2
|
-
import { sleep } from '../utils.js';
|
|
3
|
-
import { MqttClient } from 'mqtt';
|
|
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, CharacteristicChange
|
|
9
|
-
import { device, devicesConfig, serviceData, deviceStatus, Devices
|
|
10
|
-
import { hostname } from 'os';
|
|
11
|
+
import { Service, PlatformAccessory, CharacteristicValue, CharacteristicChange } from 'homebridge';
|
|
12
|
+
import { device, devicesConfig, serviceData, deviceStatus, Devices } from '../settings.js';
|
|
11
13
|
|
|
12
|
-
export class Curtain {
|
|
13
|
-
public readonly api: API;
|
|
14
|
-
public readonly log: Logging;
|
|
15
|
-
public readonly config!: SwitchBotPlatformConfig;
|
|
16
|
-
protected readonly hap: HAP;
|
|
14
|
+
export class Curtain extends deviceBase {
|
|
17
15
|
// Services
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
OpenAPI_CurrentPosition: deviceStatus['slidePosition'];
|
|
37
|
-
OpenAPI_CurrentAmbientLightLevel: deviceStatus['brightness'];
|
|
38
|
-
|
|
39
|
-
// Others
|
|
40
|
-
Mode!: string;
|
|
41
|
-
setPositionMode?: string;
|
|
42
|
-
|
|
43
|
-
// BLE Status
|
|
44
|
-
BLE_InMotion: serviceData['inMotion'];
|
|
45
|
-
BLE_BatteryLevel: serviceData['battery'];
|
|
46
|
-
BLE_Calibration: serviceData['calibration'];
|
|
47
|
-
BLE_CurrentPosition: serviceData['position'];
|
|
48
|
-
BLE_CurrentAmbientLightLevel: serviceData['lightLevel'];
|
|
49
|
-
|
|
50
|
-
// BLE Others
|
|
51
|
-
BLE_IsConnected?: boolean;
|
|
52
|
-
spaceBetweenLevels!: number;
|
|
16
|
+
private WindowCovering!: {
|
|
17
|
+
Service: Service;
|
|
18
|
+
PositionState: CharacteristicValue;
|
|
19
|
+
TargetPosition: CharacteristicValue;
|
|
20
|
+
CurrentPosition: CharacteristicValue;
|
|
21
|
+
HoldPosition: CharacteristicValue;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
private Battery!: {
|
|
25
|
+
Service: Service;
|
|
26
|
+
BatteryLevel: CharacteristicValue;
|
|
27
|
+
StatusLowBattery: CharacteristicValue;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
private LightSensor?: {
|
|
31
|
+
Service: Service;
|
|
32
|
+
CurrentAmbientLightLevel?: CharacteristicValue;
|
|
33
|
+
};
|
|
53
34
|
|
|
54
35
|
// Target
|
|
55
36
|
setNewTarget!: boolean;
|
|
56
37
|
setNewTargetTimer!: NodeJS.Timeout;
|
|
57
38
|
|
|
58
|
-
//MQTT stuff
|
|
59
|
-
mqttClient: MqttClient | null = null;
|
|
60
|
-
|
|
61
|
-
// Config
|
|
62
|
-
updateRate!: number;
|
|
63
|
-
set_minLux!: number;
|
|
64
|
-
set_maxLux!: number;
|
|
65
|
-
set_minStep!: number;
|
|
66
|
-
setOpenMode!: string;
|
|
67
|
-
setCloseMode!: string;
|
|
68
|
-
scanDuration!: number;
|
|
69
|
-
deviceLogging!: string;
|
|
70
|
-
deviceRefreshRate!: number;
|
|
71
|
-
|
|
72
39
|
// Updates
|
|
73
40
|
curtainUpdateInProgress!: boolean;
|
|
74
41
|
doCurtainUpdate!: Subject<void>;
|
|
75
42
|
|
|
76
|
-
// Connection
|
|
77
|
-
private readonly OpenAPI: boolean;
|
|
78
|
-
private readonly BLE: boolean;
|
|
79
|
-
|
|
80
|
-
// EVE history service handler
|
|
81
|
-
historyService: any = null;
|
|
82
|
-
|
|
83
43
|
constructor(
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
44
|
+
readonly platform: SwitchBotPlatform,
|
|
45
|
+
accessory: PlatformAccessory,
|
|
46
|
+
device: device & devicesConfig,
|
|
87
47
|
) {
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
this.
|
|
91
|
-
this.hap = this.api.hap;
|
|
92
|
-
// Connection
|
|
93
|
-
this.BLE = this.device.connectionType === 'BLE' || this.device.connectionType === 'BLE/OpenAPI';
|
|
94
|
-
this.OpenAPI = this.device.connectionType === 'OpenAPI' || this.device.connectionType === 'BLE/OpenAPI';
|
|
95
|
-
// default placeholders
|
|
96
|
-
this.deviceLogs(device);
|
|
97
|
-
this.refreshRate(device);
|
|
98
|
-
this.scan(device);
|
|
99
|
-
this.setupMqtt(device);
|
|
100
|
-
this.deviceContext();
|
|
101
|
-
this.deviceConfig(device);
|
|
102
|
-
|
|
48
|
+
super(platform, accessory, device);
|
|
49
|
+
// default placeholder
|
|
50
|
+
this.history(device);
|
|
103
51
|
// this is subject we use to track when we need to POST changes to the SwitchBot API
|
|
104
52
|
this.doCurtainUpdate = new Subject();
|
|
105
53
|
this.curtainUpdateInProgress = false;
|
|
106
54
|
this.setNewTarget = false;
|
|
107
55
|
|
|
56
|
+
// Initialize LightBulb property
|
|
57
|
+
this.WindowCovering = {
|
|
58
|
+
Service: accessory.getService(this.hap.Service.WindowCovering)!,
|
|
59
|
+
PositionState: accessory.context.PositionState || this.hap.Characteristic.PositionState.STOPPED,
|
|
60
|
+
TargetPosition: accessory.context.TargetPosition || 100,
|
|
61
|
+
CurrentPosition: accessory.context.CurrentPosition || 100,
|
|
62
|
+
HoldPosition: accessory.context.HoldPosition || false,
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
// Initialize Battery property
|
|
66
|
+
this.Battery = {
|
|
67
|
+
Service: accessory.getService(this.hap.Service.Battery)!,
|
|
68
|
+
BatteryLevel: accessory.context.BatteryLevel || 100,
|
|
69
|
+
StatusLowBattery: accessory.context.StatusLowBattery || this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL,
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
// Initialize LightSensor property
|
|
73
|
+
if (!this.device.curtain?.hide_lightsensor) {
|
|
74
|
+
this.LightSensor = {
|
|
75
|
+
Service: accessory.getService(this.hap.Service.LightSensor)!,
|
|
76
|
+
CurrentAmbientLightLevel: accessory.context.CurrentAmbientLightLevel || 0.0001,
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
|
|
108
80
|
// Retrieve initial values and updateHomekit
|
|
109
81
|
this.refreshStatus();
|
|
110
82
|
|
|
111
|
-
// set accessory information
|
|
112
|
-
accessory
|
|
113
|
-
.getService(this.hap.Service.AccessoryInformation)!
|
|
114
|
-
.setCharacteristic(this.hap.Characteristic.Manufacturer, 'SwitchBot')
|
|
115
|
-
.setCharacteristic(this.hap.Characteristic.Model, 'W0701600')
|
|
116
|
-
.setCharacteristic(this.hap.Characteristic.SerialNumber, device.deviceId)
|
|
117
|
-
.setCharacteristic(this.hap.Characteristic.FirmwareRevision, accessory.context.FirmwareRevision);
|
|
118
|
-
|
|
119
83
|
// get the WindowCovering service if it exists, otherwise create a new WindowCovering service
|
|
120
84
|
// you can create multiple services for each accessory
|
|
121
|
-
const
|
|
122
|
-
(this.
|
|
123
|
-
|| accessory.addService(this.hap.Service.WindowCovering)),
|
|
85
|
+
const WindowCoveringService = `${accessory.displayName} ${device.deviceType}`;
|
|
86
|
+
(this.WindowCovering.Service = accessory.getService(this.hap.Service.WindowCovering)
|
|
87
|
+
|| accessory.addService(this.hap.Service.WindowCovering)), WindowCoveringService;
|
|
124
88
|
|
|
125
|
-
this.
|
|
126
|
-
if (!this.windowCoveringService.testCharacteristic(this.hap.Characteristic.ConfiguredName)) {
|
|
127
|
-
this.windowCoveringService.addCharacteristic(this.hap.Characteristic.ConfiguredName, accessory.displayName);
|
|
128
|
-
}
|
|
89
|
+
this.WindowCovering.Service.setCharacteristic(this.hap.Characteristic.Name, accessory.displayName);
|
|
129
90
|
|
|
130
91
|
// each service must implement at-minimum the "required characteristics" for the given service type
|
|
131
92
|
// see https://developers.homebridge.io/#/service/WindowCovering
|
|
132
93
|
|
|
133
94
|
// create handlers for required characteristics
|
|
134
|
-
this.
|
|
95
|
+
this.WindowCovering.Service.setCharacteristic(this.hap.Characteristic.PositionState, this.WindowCovering.PositionState);
|
|
135
96
|
|
|
136
|
-
this.
|
|
97
|
+
this.WindowCovering.Service
|
|
137
98
|
.getCharacteristic(this.hap.Characteristic.CurrentPosition)
|
|
138
99
|
.setProps({
|
|
139
100
|
minStep: this.minStep(device),
|
|
@@ -142,10 +103,10 @@ export class Curtain {
|
|
|
142
103
|
validValueRanges: [0, 100],
|
|
143
104
|
})
|
|
144
105
|
.onGet(() => {
|
|
145
|
-
return this.CurrentPosition;
|
|
106
|
+
return this.WindowCovering.CurrentPosition;
|
|
146
107
|
});
|
|
147
108
|
|
|
148
|
-
this.
|
|
109
|
+
this.WindowCovering.Service
|
|
149
110
|
.getCharacteristic(this.hap.Characteristic.TargetPosition)
|
|
150
111
|
.setProps({
|
|
151
112
|
minStep: this.minStep(device),
|
|
@@ -155,38 +116,32 @@ export class Curtain {
|
|
|
155
116
|
})
|
|
156
117
|
.onSet(this.TargetPositionSet.bind(this));
|
|
157
118
|
|
|
158
|
-
this.
|
|
119
|
+
this.WindowCovering.Service
|
|
159
120
|
.getCharacteristic(this.hap.Characteristic.HoldPosition)
|
|
160
121
|
.onSet(this.HoldPositionSet.bind(this));
|
|
161
122
|
|
|
162
123
|
// Light Sensor Service
|
|
163
124
|
if (device.curtain?.hide_lightsensor) {
|
|
164
125
|
this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Removing Light Sensor Service`);
|
|
165
|
-
this.
|
|
166
|
-
accessory.removeService(this.
|
|
167
|
-
} else if (!this.
|
|
126
|
+
this.LightSensor!.Service = this.accessory.getService(this.hap.Service.LightSensor) as Service;
|
|
127
|
+
accessory.removeService(this.LightSensor!.Service);
|
|
128
|
+
} else if (!this.LightSensor?.Service) {
|
|
168
129
|
this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Add Light Sensor Service`);
|
|
169
|
-
const
|
|
170
|
-
(this.
|
|
171
|
-
|| this.accessory.addService(this.hap.Service.LightSensor)),
|
|
130
|
+
const LightSensorService = `${accessory.displayName} Light Sensor`;
|
|
131
|
+
(this.LightSensor!.Service = this.accessory.getService(this.hap.Service.LightSensor)
|
|
132
|
+
|| this.accessory.addService(this.hap.Service.LightSensor)), LightSensorService;
|
|
172
133
|
|
|
173
|
-
this.
|
|
174
|
-
if (!this.lightSensorService?.testCharacteristic(this.hap.Characteristic.ConfiguredName)) {
|
|
175
|
-
this.lightSensorService.addCharacteristic(this.hap.Characteristic.ConfiguredName, `${accessory.displayName} Light Sensor`);
|
|
176
|
-
}
|
|
134
|
+
this.LightSensor!.Service.setCharacteristic(this.hap.Characteristic.Name, LightSensorService);
|
|
177
135
|
} else {
|
|
178
136
|
this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Light Sensor Service Not Added`);
|
|
179
137
|
}
|
|
180
138
|
|
|
181
139
|
// Battery Service
|
|
182
140
|
const batteryService = `${accessory.displayName} Battery`;
|
|
183
|
-
(this.
|
|
141
|
+
(this.Battery.Service = this.accessory.getService(this.hap.Service.Battery)
|
|
184
142
|
|| accessory.addService(this.hap.Service.Battery)), batteryService;
|
|
185
143
|
|
|
186
|
-
this.
|
|
187
|
-
if (!this.batteryService.testCharacteristic(this.hap.Characteristic.ConfiguredName)) {
|
|
188
|
-
this.batteryService.addCharacteristic(this.hap.Characteristic.ConfiguredName, `${accessory.displayName} Battery`);
|
|
189
|
-
}
|
|
144
|
+
this.Battery.Service.setCharacteristic(this.hap.Characteristic.Name, `${accessory.displayName} Battery`);
|
|
190
145
|
|
|
191
146
|
// Update Homekit
|
|
192
147
|
this.updateHomeKitCharacteristics();
|
|
@@ -199,19 +154,18 @@ export class Curtain {
|
|
|
199
154
|
});
|
|
200
155
|
|
|
201
156
|
//regisiter webhook event handler
|
|
202
|
-
if (
|
|
203
|
-
this.
|
|
157
|
+
if (device.webhook) {
|
|
158
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} is listening webhook.`);
|
|
204
159
|
this.platform.webhookEventHandler[this.device.deviceId] = async (context) => {
|
|
205
160
|
try {
|
|
206
161
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} received Webhook: ${JSON.stringify(context)}`);
|
|
207
162
|
const { slidePosition, battery } = context;
|
|
208
|
-
const { CurrentPosition, BatteryLevel } = this;
|
|
209
163
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} ` +
|
|
210
164
|
'(slidePosition, battery) = ' +
|
|
211
165
|
`Webhook:(${slidePosition}, ${battery}), ` +
|
|
212
|
-
`current:(${CurrentPosition}, ${BatteryLevel})`);
|
|
213
|
-
this.CurrentPosition = slidePosition;
|
|
214
|
-
this.BatteryLevel = battery;
|
|
166
|
+
`current:(${this.WindowCovering.CurrentPosition}, ${this.Battery.BatteryLevel})`);
|
|
167
|
+
this.WindowCovering.CurrentPosition = slidePosition;
|
|
168
|
+
this.Battery.BatteryLevel = battery;
|
|
215
169
|
this.updateHomeKitCharacteristics();
|
|
216
170
|
} catch (e: any) {
|
|
217
171
|
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} `
|
|
@@ -221,13 +175,14 @@ export class Curtain {
|
|
|
221
175
|
}
|
|
222
176
|
|
|
223
177
|
// update slide progress
|
|
224
|
-
interval(this.
|
|
178
|
+
interval(this.deviceUpdateRate * 1000)
|
|
225
179
|
//.pipe(skipWhile(() => this.curtainUpdateInProgress))
|
|
226
180
|
.subscribe(async () => {
|
|
227
|
-
if (this.PositionState === this.hap.Characteristic.PositionState.STOPPED) {
|
|
181
|
+
if (this.WindowCovering.PositionState === this.hap.Characteristic.PositionState.STOPPED) {
|
|
228
182
|
return;
|
|
229
183
|
}
|
|
230
|
-
this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Refresh Status When Moving
|
|
184
|
+
this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Refresh Status When Moving,`
|
|
185
|
+
+ ` PositionState: ${this.WindowCovering.PositionState}`);
|
|
231
186
|
await this.refreshStatus();
|
|
232
187
|
});
|
|
233
188
|
|
|
@@ -257,6 +212,16 @@ export class Curtain {
|
|
|
257
212
|
this.setupHistoryService(device);
|
|
258
213
|
}
|
|
259
214
|
|
|
215
|
+
private history(device: device & devicesConfig) {
|
|
216
|
+
if (device.history === true) {
|
|
217
|
+
// initialize when this accessory is newly created.
|
|
218
|
+
this.accessory.context.lastActivation = this.accessory.context.lastActivation ?? 0;
|
|
219
|
+
} else {
|
|
220
|
+
// removes cached values if history is turned off
|
|
221
|
+
delete this.accessory.context.lastActivation;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
260
225
|
/*
|
|
261
226
|
* Setup EVE history features for curtain devices.
|
|
262
227
|
*/
|
|
@@ -304,7 +269,7 @@ export class Curtain {
|
|
|
304
269
|
}
|
|
305
270
|
|
|
306
271
|
async updateHistory(): Promise<void> {
|
|
307
|
-
const motion = Number(this.CurrentPosition) > 0 ? 1 : 0;
|
|
272
|
+
const motion = Number(this.WindowCovering.CurrentPosition) > 0 ? 1 : 0;
|
|
308
273
|
this.historyService.addEntry({
|
|
309
274
|
time: Math.round(new Date().valueOf() / 1000),
|
|
310
275
|
motion: motion,
|
|
@@ -317,198 +282,194 @@ export class Curtain {
|
|
|
317
282
|
);
|
|
318
283
|
}
|
|
319
284
|
|
|
320
|
-
|
|
321
|
-
* Parse the device status from the SwitchBot api
|
|
322
|
-
*/
|
|
323
|
-
async parseStatus(): Promise<void> {
|
|
324
|
-
if (!this.device.enableCloudService && this.OpenAPI) {
|
|
325
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} parseStatus enableCloudService: ${this.device.enableCloudService}`);
|
|
326
|
-
} else if (this.BLE) {
|
|
327
|
-
await this.BLEparseStatus();
|
|
328
|
-
} else if (this.OpenAPI && this.platform.config.credentials?.token) {
|
|
329
|
-
await this.openAPIparseStatus();
|
|
330
|
-
} else {
|
|
331
|
-
await this.offlineOff();
|
|
332
|
-
this.debugWarnLog(
|
|
333
|
-
`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:` + ` ${this.device.connectionType}, parseStatus will not happen.`,
|
|
334
|
-
);
|
|
335
|
-
}
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
async BLEparseStatus(): Promise<void> {
|
|
285
|
+
async BLEparseStatus(serviceData: serviceData): Promise<void> {
|
|
339
286
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLEparseStatus`);
|
|
340
287
|
// CurrentPosition
|
|
341
|
-
this.CurrentPosition = 100 - Number(
|
|
288
|
+
this.WindowCovering.CurrentPosition = 100 - Number(serviceData.position);
|
|
342
289
|
await this.setMinMax();
|
|
343
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} CurrentPosition ${this.CurrentPosition}`);
|
|
290
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} CurrentPosition ${this.WindowCovering.CurrentPosition}`);
|
|
344
291
|
if (this.setNewTarget) {
|
|
345
292
|
this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Checking Status ...`);
|
|
346
293
|
await this.setMinMax();
|
|
347
|
-
if (Number(this.TargetPosition) > this.CurrentPosition) {
|
|
348
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Closing, CurrentPosition: ${this.CurrentPosition}`);
|
|
349
|
-
this.PositionState = this.hap.Characteristic.PositionState.INCREASING;
|
|
350
|
-
this.
|
|
351
|
-
this.debugLog(`${this.device.deviceType}: ${this.CurrentPosition} INCREASING
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
this.
|
|
355
|
-
this.
|
|
356
|
-
this.
|
|
294
|
+
if (Number(this.WindowCovering.TargetPosition) > this.WindowCovering.CurrentPosition) {
|
|
295
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Closing, CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
|
|
296
|
+
this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.INCREASING;
|
|
297
|
+
this.WindowCovering.Service.getCharacteristic(this.hap.Characteristic.PositionState).updateValue(this.WindowCovering.PositionState);
|
|
298
|
+
this.debugLog(`${this.device.deviceType}: ${this.WindowCovering.CurrentPosition} INCREASING`
|
|
299
|
+
+ ` PositionState: ${this.WindowCovering.PositionState}`);
|
|
300
|
+
} else if (Number(this.WindowCovering.TargetPosition) < this.WindowCovering.CurrentPosition) {
|
|
301
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Opening, CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
|
|
302
|
+
this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.DECREASING;
|
|
303
|
+
this.WindowCovering.Service.getCharacteristic(this.hap.Characteristic.PositionState).updateValue(this.WindowCovering.PositionState);
|
|
304
|
+
this.debugLog(`${this.device.deviceType}: ${this.WindowCovering.CurrentPosition} DECREASING`
|
|
305
|
+
+ ` PositionState: ${this.WindowCovering.PositionState}`);
|
|
357
306
|
} else {
|
|
358
|
-
this.debugLog(`${this.device.deviceType}: ${this.CurrentPosition} Standby
|
|
359
|
-
|
|
360
|
-
this.
|
|
361
|
-
this.
|
|
307
|
+
this.debugLog(`${this.device.deviceType}: ${this.WindowCovering.CurrentPosition} Standby,`
|
|
308
|
+
+ ` CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
|
|
309
|
+
this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.STOPPED;
|
|
310
|
+
this.WindowCovering.Service.getCharacteristic(this.hap.Characteristic.PositionState).updateValue(this.WindowCovering.PositionState);
|
|
311
|
+
this.debugLog(`${this.device.deviceType}: ${this.WindowCovering.CurrentPosition} STOPPED`
|
|
312
|
+
+ ` PositionState: ${this.WindowCovering.PositionState}`);
|
|
362
313
|
}
|
|
363
314
|
} else {
|
|
364
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Standby, CurrentPosition: ${this.CurrentPosition}`);
|
|
365
|
-
this.TargetPosition = this.CurrentPosition;
|
|
366
|
-
this.PositionState = this.hap.Characteristic.PositionState.STOPPED;
|
|
315
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Standby, CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
|
|
316
|
+
this.WindowCovering.TargetPosition = this.WindowCovering.CurrentPosition;
|
|
317
|
+
this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.STOPPED;
|
|
367
318
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Stopped`);
|
|
368
319
|
}
|
|
369
320
|
this.debugLog(
|
|
370
|
-
`${this.device.deviceType}: ${this.accessory.displayName} CurrentPosition: ${this.CurrentPosition},` +
|
|
371
|
-
` TargetPosition: ${this.TargetPosition}, PositionState: ${this.PositionState},`,
|
|
321
|
+
`${this.device.deviceType}: ${this.accessory.displayName} CurrentPosition: ${this.WindowCovering.CurrentPosition},` +
|
|
322
|
+
` TargetPosition: ${this.WindowCovering.TargetPosition}, PositionState: ${this.WindowCovering.PositionState},`,
|
|
372
323
|
);
|
|
373
324
|
|
|
374
325
|
if (!this.device.curtain?.hide_lightsensor) {
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
326
|
+
const set_minLux = await this.minLux();
|
|
327
|
+
const set_maxLux = await this.maxLux();
|
|
328
|
+
const spaceBetweenLevels = 9;
|
|
378
329
|
|
|
379
330
|
// Brightness
|
|
380
|
-
switch (
|
|
331
|
+
switch (serviceData.lightLevel) {
|
|
381
332
|
case 1:
|
|
382
|
-
this.CurrentAmbientLightLevel =
|
|
383
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${
|
|
333
|
+
this.LightSensor!.CurrentAmbientLightLevel = set_minLux;
|
|
334
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${serviceData.lightLevel}`);
|
|
384
335
|
break;
|
|
385
336
|
case 2:
|
|
386
|
-
this.CurrentAmbientLightLevel = (
|
|
337
|
+
this.LightSensor!.CurrentAmbientLightLevel = (set_maxLux - set_minLux) / spaceBetweenLevels;
|
|
387
338
|
this.debugLog(
|
|
388
|
-
`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${
|
|
389
|
-
` Calculation: ${(
|
|
339
|
+
`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${serviceData.lightLevel},` +
|
|
340
|
+
` Calculation: ${(set_maxLux - set_minLux) / spaceBetweenLevels}`,
|
|
390
341
|
);
|
|
391
342
|
break;
|
|
392
343
|
case 3:
|
|
393
|
-
this.CurrentAmbientLightLevel = ((
|
|
394
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${
|
|
344
|
+
this.LightSensor!.CurrentAmbientLightLevel = ((set_maxLux - set_minLux) / spaceBetweenLevels) * 2;
|
|
345
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${serviceData.lightLevel}`);
|
|
395
346
|
break;
|
|
396
347
|
case 4:
|
|
397
|
-
this.CurrentAmbientLightLevel = ((
|
|
398
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${
|
|
348
|
+
this.LightSensor!.CurrentAmbientLightLevel = ((set_maxLux - set_minLux) / spaceBetweenLevels) * 3;
|
|
349
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${serviceData.lightLevel}`);
|
|
399
350
|
break;
|
|
400
351
|
case 5:
|
|
401
|
-
this.CurrentAmbientLightLevel = ((
|
|
402
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${
|
|
352
|
+
this.LightSensor!.CurrentAmbientLightLevel = ((set_maxLux - set_minLux) / spaceBetweenLevels) * 4;
|
|
353
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${serviceData.lightLevel}`);
|
|
403
354
|
break;
|
|
404
355
|
case 6:
|
|
405
|
-
this.CurrentAmbientLightLevel = ((
|
|
406
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${
|
|
356
|
+
this.LightSensor!.CurrentAmbientLightLevel = ((set_maxLux - set_minLux) / spaceBetweenLevels) * 5;
|
|
357
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${serviceData.lightLevel}`);
|
|
407
358
|
break;
|
|
408
359
|
case 7:
|
|
409
|
-
this.CurrentAmbientLightLevel = ((
|
|
410
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${
|
|
360
|
+
this.LightSensor!.CurrentAmbientLightLevel = ((set_maxLux - set_minLux) / spaceBetweenLevels) * 6;
|
|
361
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${serviceData.lightLevel}`);
|
|
411
362
|
break;
|
|
412
363
|
case 8:
|
|
413
|
-
this.CurrentAmbientLightLevel = ((
|
|
414
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${
|
|
364
|
+
this.LightSensor!.CurrentAmbientLightLevel = ((set_maxLux - set_minLux) / spaceBetweenLevels) * 7;
|
|
365
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${serviceData.lightLevel}`);
|
|
415
366
|
break;
|
|
416
367
|
case 9:
|
|
417
|
-
this.CurrentAmbientLightLevel = ((
|
|
418
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${
|
|
368
|
+
this.LightSensor!.CurrentAmbientLightLevel = ((set_maxLux - set_minLux) / spaceBetweenLevels) * 8;
|
|
369
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${serviceData.lightLevel}`);
|
|
419
370
|
break;
|
|
420
371
|
case 10:
|
|
421
372
|
default:
|
|
422
|
-
this.CurrentAmbientLightLevel =
|
|
373
|
+
this.LightSensor!.CurrentAmbientLightLevel = set_maxLux;
|
|
423
374
|
this.debugLog();
|
|
424
375
|
}
|
|
425
376
|
this.debugLog(
|
|
426
|
-
`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${
|
|
427
|
-
` CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`,
|
|
377
|
+
`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${serviceData.lightLevel},` +
|
|
378
|
+
` CurrentAmbientLightLevel: ${this.LightSensor!.CurrentAmbientLightLevel}`,
|
|
428
379
|
);
|
|
429
380
|
}
|
|
430
381
|
// Battery
|
|
431
|
-
this.BatteryLevel = Number(
|
|
432
|
-
if (this.BatteryLevel < 10) {
|
|
433
|
-
this.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW;
|
|
382
|
+
this.Battery.BatteryLevel = Number(serviceData.battery);
|
|
383
|
+
if (this.Battery.BatteryLevel < 10) {
|
|
384
|
+
this.Battery.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW;
|
|
434
385
|
} else {
|
|
435
|
-
this.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
|
|
386
|
+
this.Battery.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
|
|
436
387
|
}
|
|
437
388
|
this.debugLog(
|
|
438
|
-
`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.BatteryLevel},`
|
|
389
|
+
`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.Battery.BatteryLevel},`
|
|
390
|
+
+ ` StatusLowBattery: ${this.Battery.StatusLowBattery}`,
|
|
439
391
|
);
|
|
440
392
|
}
|
|
441
393
|
|
|
442
|
-
async openAPIparseStatus(): Promise<void> {
|
|
394
|
+
async openAPIparseStatus(deviceStatus: deviceStatus): Promise<void> {
|
|
443
395
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIparseStatus`);
|
|
444
396
|
// CurrentPosition
|
|
445
|
-
this.CurrentPosition = 100 - Number(
|
|
397
|
+
this.WindowCovering!.CurrentPosition = 100 - Number(deviceStatus.body.slidePosition);
|
|
446
398
|
await this.setMinMax();
|
|
447
|
-
this.debugLog(`Curtain ${this.accessory.displayName} CurrentPosition: ${this.CurrentPosition}`);
|
|
399
|
+
this.debugLog(`Curtain ${this.accessory.displayName} CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
|
|
448
400
|
if (this.setNewTarget) {
|
|
449
401
|
this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Checking Status ...`);
|
|
450
402
|
}
|
|
451
403
|
|
|
452
|
-
if (this.setNewTarget &&
|
|
404
|
+
if (this.setNewTarget && deviceStatus.body.moving) {
|
|
453
405
|
await this.setMinMax();
|
|
454
|
-
if (Number(this.TargetPosition) > this.CurrentPosition) {
|
|
455
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Closing, CurrentPosition: ${this.CurrentPosition} `);
|
|
456
|
-
this.PositionState = this.hap.Characteristic.PositionState.INCREASING;
|
|
457
|
-
this.
|
|
458
|
-
this.debugLog(`${this.device.deviceType}: ${this.CurrentPosition} INCREASING
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
this.
|
|
462
|
-
this.
|
|
463
|
-
this.
|
|
406
|
+
if (Number(this.WindowCovering.TargetPosition) > this.WindowCovering.CurrentPosition) {
|
|
407
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Closing, CurrentPosition: ${this.WindowCovering.CurrentPosition} `);
|
|
408
|
+
this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.INCREASING;
|
|
409
|
+
this.WindowCovering.Service.getCharacteristic(this.hap.Characteristic.PositionState).updateValue(this.WindowCovering.PositionState);
|
|
410
|
+
this.debugLog(`${this.device.deviceType}: ${this.WindowCovering.CurrentPosition} INCREASING`
|
|
411
|
+
+ ` PositionState: ${this.WindowCovering.PositionState}`);
|
|
412
|
+
} else if (Number(this.WindowCovering.TargetPosition) < this.WindowCovering.CurrentPosition) {
|
|
413
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Opening, CurrentPosition: ${this.WindowCovering.CurrentPosition} `);
|
|
414
|
+
this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.DECREASING;
|
|
415
|
+
this.WindowCovering.Service.getCharacteristic(this.hap.Characteristic.PositionState).updateValue(this.WindowCovering.PositionState);
|
|
416
|
+
this.debugLog(`${this.device.deviceType}: ${this.WindowCovering.CurrentPosition} DECREASING`
|
|
417
|
+
+ ` PositionState: ${this.WindowCovering.PositionState}`);
|
|
464
418
|
} else {
|
|
465
|
-
this.debugLog(`${this.device.deviceType}: ${this.CurrentPosition} Standby
|
|
466
|
-
|
|
467
|
-
this.
|
|
468
|
-
this.
|
|
419
|
+
this.debugLog(`${this.device.deviceType}: ${this.WindowCovering.CurrentPosition} Standby,`
|
|
420
|
+
+ ` CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
|
|
421
|
+
this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.STOPPED;
|
|
422
|
+
this.WindowCovering.Service.getCharacteristic(this.hap.Characteristic.PositionState).updateValue(this.WindowCovering.PositionState);
|
|
423
|
+
this.debugLog(`${this.device.deviceType}: ${this.WindowCovering.CurrentPosition} STOPPED`
|
|
424
|
+
+ ` PositionState: ${this.WindowCovering.PositionState}`);
|
|
469
425
|
}
|
|
470
426
|
} else {
|
|
471
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Standby, CurrentPosition: ${this.CurrentPosition}`);
|
|
472
|
-
this.TargetPosition = this.CurrentPosition;
|
|
473
|
-
this.PositionState = this.hap.Characteristic.PositionState.STOPPED;
|
|
427
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Standby, CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
|
|
428
|
+
this.WindowCovering.TargetPosition = this.WindowCovering.CurrentPosition;
|
|
429
|
+
this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.STOPPED;
|
|
474
430
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Stopped`);
|
|
475
431
|
}
|
|
476
432
|
this.debugLog(
|
|
477
|
-
`${this.device.deviceType}: ${this.accessory.displayName} CurrentPosition: ${this.CurrentPosition},` +
|
|
478
|
-
` TargetPosition: ${this.TargetPosition}, PositionState: ${this.PositionState},`,
|
|
433
|
+
`${this.device.deviceType}: ${this.accessory.displayName} CurrentPosition: ${this.WindowCovering.CurrentPosition},` +
|
|
434
|
+
` TargetPosition: ${this.WindowCovering.TargetPosition}, PositionState: ${this.WindowCovering.PositionState},`,
|
|
479
435
|
);
|
|
480
436
|
|
|
481
437
|
// Brightness
|
|
482
438
|
if (!this.device.curtain?.hide_lightsensor) {
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
switch (
|
|
439
|
+
const set_minLux = await this.minLux();
|
|
440
|
+
const set_maxLux = await this.maxLux();
|
|
441
|
+
switch (deviceStatus.body.brightness) {
|
|
486
442
|
case 'dim':
|
|
487
|
-
this.CurrentAmbientLightLevel =
|
|
443
|
+
this.LightSensor!.CurrentAmbientLightLevel = set_minLux;
|
|
488
444
|
break;
|
|
489
445
|
case 'bright':
|
|
490
446
|
default:
|
|
491
|
-
this.CurrentAmbientLightLevel =
|
|
447
|
+
this.LightSensor!.CurrentAmbientLightLevel = set_maxLux;
|
|
492
448
|
}
|
|
493
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}
|
|
449
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}`
|
|
450
|
+
+ ` CurrentAmbientLightLevel: ${this.LightSensor!.CurrentAmbientLightLevel}`);
|
|
494
451
|
}
|
|
495
452
|
|
|
496
453
|
// BatteryLevel
|
|
497
|
-
this.BatteryLevel = Number(
|
|
498
|
-
if (this.BatteryLevel < 10) {
|
|
499
|
-
this.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW;
|
|
454
|
+
this.Battery.BatteryLevel = Number(deviceStatus.body.battery);
|
|
455
|
+
if (this.Battery.BatteryLevel < 10) {
|
|
456
|
+
this.Battery.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW;
|
|
500
457
|
} else {
|
|
501
|
-
this.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
|
|
458
|
+
this.Battery.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
|
|
502
459
|
}
|
|
503
|
-
if (Number.isNaN(this.BatteryLevel)) {
|
|
504
|
-
this.BatteryLevel = 100;
|
|
460
|
+
if (Number.isNaN(this.Battery.BatteryLevel)) {
|
|
461
|
+
this.Battery.BatteryLevel = 100;
|
|
505
462
|
}
|
|
506
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.BatteryLevel},`
|
|
507
|
-
+ ` StatusLowBattery: ${this.StatusLowBattery}`);
|
|
463
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.Battery.BatteryLevel},`
|
|
464
|
+
+ ` StatusLowBattery: ${this.Battery.StatusLowBattery}`);
|
|
508
465
|
|
|
509
466
|
// FirmwareRevision
|
|
510
|
-
this.FirmwareRevision =
|
|
511
|
-
this.accessory
|
|
467
|
+
this.accessory.context.FirmwareRevision = deviceStatus.body.version;
|
|
468
|
+
this.accessory
|
|
469
|
+
.getService(this.hap.Service.AccessoryInformation)!
|
|
470
|
+
.setCharacteristic(this.hap.Characteristic.FirmwareRevision, this.accessory.context.FirmwareRevision)
|
|
471
|
+
.getCharacteristic(this.hap.Characteristic.FirmwareRevision)
|
|
472
|
+
.updateValue(this.accessory.context.FirmwareRevision);
|
|
512
473
|
}
|
|
513
474
|
|
|
514
475
|
async refreshStatus(): Promise<void> {
|
|
@@ -538,118 +499,45 @@ export class Curtain {
|
|
|
538
499
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
|
|
539
500
|
this.getCustomBLEAddress(switchbot);
|
|
540
501
|
// Start to monitor advertisement packets
|
|
541
|
-
let model: string;
|
|
542
|
-
switch (this.device.configDeviceType) {
|
|
543
|
-
case 'Curtain3':
|
|
544
|
-
model = '{';
|
|
545
|
-
break;
|
|
546
|
-
default:
|
|
547
|
-
model = 'c';
|
|
548
|
-
}
|
|
549
502
|
(async () => {
|
|
550
503
|
// Start to monitor advertisement packets
|
|
551
|
-
await switchbot.startScan({
|
|
552
|
-
model: model,
|
|
553
|
-
id: this.device.bleMac,
|
|
554
|
-
});
|
|
504
|
+
await switchbot.startScan({ model: this.device.bleModel, id: this.device.bleMac });
|
|
555
505
|
// Set an event handler
|
|
556
506
|
switchbot.onadvertisement = (ad: any) => {
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
507
|
+
if (this.device.bleMac === ad.address && ad.model === this.device.bleModel) {
|
|
508
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} ${JSON.stringify(ad, null, ' ')}`);
|
|
509
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} address: ${ad.address}, model: ${ad.model}`);
|
|
560
510
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${JSON.stringify(ad.serviceData)}`);
|
|
561
|
-
this.BLE_Calibration = ad.serviceData.calibration;
|
|
562
|
-
this.BLE_BatteryLevel = ad.serviceData.battery;
|
|
563
|
-
this.BLE_InMotion = ad.serviceData.inMotion;
|
|
564
|
-
this.BLE_CurrentPosition = ad.serviceData.position;
|
|
565
|
-
this.BLE_CurrentAmbientLightLevel = ad.serviceData.lightLevel;
|
|
566
511
|
} else {
|
|
567
512
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${JSON.stringify(ad.serviceData)}`);
|
|
568
513
|
}
|
|
569
514
|
};
|
|
570
|
-
// Wait
|
|
515
|
+
// Wait 10 seconds
|
|
571
516
|
await switchbot.wait(this.scanDuration * 1000);
|
|
572
517
|
// Stop to monitor
|
|
573
518
|
await switchbot.stopScan();
|
|
574
519
|
// Update HomeKit
|
|
575
|
-
await this.BLEparseStatus();
|
|
520
|
+
await this.BLEparseStatus(switchbot.onadvertisement.serviceData);
|
|
576
521
|
await this.updateHomeKitCharacteristics();
|
|
577
522
|
})();
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
/*if (switchbot !== false) {
|
|
581
|
-
switchbot
|
|
582
|
-
.startScan({
|
|
583
|
-
model: model,
|
|
584
|
-
id: this.device.bleMac,
|
|
585
|
-
})
|
|
586
|
-
.then(async () => {
|
|
587
|
-
// Set an event handler
|
|
588
|
-
switchbot.onadvertisement = async (ad: ad) => {
|
|
589
|
-
this.debugLog(
|
|
590
|
-
`${this.device.deviceType}: ${this.accessory.displayName} Config BLE Address: ${this.device.bleMac},` +
|
|
591
|
-
` BLE Address Found: ${ad.address}`,
|
|
592
|
-
);
|
|
593
|
-
this.BLE_Calibration = ad.serviceData.calibration;
|
|
594
|
-
this.BLE_BatteryLevel = ad.serviceData.battery;
|
|
595
|
-
this.BLE_InMotion = ad.serviceData.inMotion;
|
|
596
|
-
this.BLE_CurrentPosition = ad.serviceData.position;
|
|
597
|
-
this.BLE_CurrentAmbientLightLevel = ad.serviceData.lightLevel;
|
|
598
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${JSON.stringify(ad.serviceData)}`);
|
|
599
|
-
this.debugLog(
|
|
600
|
-
`${this.device.deviceType}: ${this.accessory.displayName} calibration: ${ad.serviceData.calibration}, ` +
|
|
601
|
-
`position: ${ad.serviceData.position}, lightLevel: ${ad.serviceData.lightLevel}, battery: ${ad.serviceData.battery}, ` +
|
|
602
|
-
`inMotion: ${ad.serviceData.inMotion}`,
|
|
603
|
-
);
|
|
604
|
-
|
|
605
|
-
if (ad.serviceData) {
|
|
606
|
-
this.BLE_IsConnected = true;
|
|
607
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} connected: ${this.BLE_IsConnected}`);
|
|
608
|
-
await this.stopScanning(switchbot);
|
|
609
|
-
} else {
|
|
610
|
-
this.BLE_IsConnected = false;
|
|
611
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} connected: ${this.BLE_IsConnected}`);
|
|
612
|
-
}
|
|
613
|
-
};
|
|
614
|
-
// Wait
|
|
615
|
-
return await sleep(this.scanDuration * 1000);
|
|
616
|
-
})
|
|
617
|
-
.then(async () => {
|
|
618
|
-
// Stop to monitor
|
|
619
|
-
await this.stopScanning(switchbot);
|
|
620
|
-
})
|
|
621
|
-
.catch(async (e: any) => {
|
|
622
|
-
this.apiError(e);
|
|
623
|
-
this.errorLog(
|
|
624
|
-
`${this.device.deviceType}: ${this.accessory.displayName} failed BLERefreshStatus with ${this.device.connectionType}` +
|
|
625
|
-
` Connection, Error Message: ${JSON.stringify(e.message)}`,
|
|
626
|
-
);
|
|
627
|
-
await this.BLERefreshConnection(switchbot);
|
|
628
|
-
});
|
|
629
|
-
} else {
|
|
523
|
+
if (switchbot === undefined) {
|
|
630
524
|
await this.BLERefreshConnection(switchbot);
|
|
631
|
-
}
|
|
525
|
+
}
|
|
632
526
|
}
|
|
633
527
|
|
|
634
528
|
async openAPIRefreshStatus(): Promise<void> {
|
|
635
529
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus`);
|
|
636
530
|
try {
|
|
637
|
-
const { body, statusCode } = await
|
|
638
|
-
headers: this.platform.generateHeaders()
|
|
639
|
-
});
|
|
531
|
+
const { body, statusCode } = await this.platform.retryRequest(this.deviceMaxRetries, this.deviceDelayBetweenRetries,
|
|
532
|
+
`${Devices}/${this.device.deviceId}/status`, { headers: this.platform.generateHeaders() });
|
|
640
533
|
this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} statusCode: ${statusCode}`);
|
|
641
534
|
const deviceStatus: any = await body.json();
|
|
642
535
|
this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus: ${JSON.stringify(deviceStatus)}`);
|
|
643
536
|
this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus statusCode: ${deviceStatus.statusCode}`);
|
|
644
537
|
if ((statusCode === 200 || statusCode === 100) && (deviceStatus.statusCode === 200 || deviceStatus.statusCode === 100)) {
|
|
645
|
-
this.
|
|
538
|
+
this.debugSuccessLog(`${this.device.deviceType}: ${this.accessory.displayName} `
|
|
646
539
|
+ `statusCode: ${statusCode} & deviceStatus StatusCode: ${deviceStatus.statusCode}`);
|
|
647
|
-
this.
|
|
648
|
-
this.OpenAPI_InMotion = deviceStatus.body.moving;
|
|
649
|
-
this.OpenAPI_CurrentAmbientLightLevel = deviceStatus.body.brightness;
|
|
650
|
-
this.OpenAPI_BatteryLevel = deviceStatus.body.battery;
|
|
651
|
-
this.OpenAPI_FirmwareRevision = deviceStatus.body.version;
|
|
652
|
-
this.openAPIparseStatus();
|
|
540
|
+
this.openAPIparseStatus(deviceStatus);
|
|
653
541
|
this.updateHomeKitCharacteristics();
|
|
654
542
|
} else {
|
|
655
543
|
this.statusCode(statusCode);
|
|
@@ -688,7 +576,7 @@ export class Curtain {
|
|
|
688
576
|
|
|
689
577
|
async BLEpushChanges(): Promise<void> {
|
|
690
578
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLEpushChanges`);
|
|
691
|
-
if (this.TargetPosition !== this.CurrentPosition) {
|
|
579
|
+
if (this.WindowCovering.TargetPosition !== this.WindowCovering.CurrentPosition) {
|
|
692
580
|
const switchbot = await this.platform.connectBLE();
|
|
693
581
|
// Convert to BLE Address
|
|
694
582
|
this.device.bleMac = this.device
|
|
@@ -696,27 +584,29 @@ export class Curtain {
|
|
|
696
584
|
.join(':')
|
|
697
585
|
.toLowerCase();
|
|
698
586
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
|
|
699
|
-
this.
|
|
700
|
-
const adjustedMode =
|
|
701
|
-
this.debugLog(`${this.accessory.displayName} Mode: ${
|
|
587
|
+
const { setPositionMode, Mode }: { setPositionMode: number; Mode: string; } = await this.setPerformance();
|
|
588
|
+
const adjustedMode = setPositionMode === 1 ? 0x01 : 0xff;
|
|
589
|
+
this.debugLog(`${this.accessory.displayName} Mode: ${Mode}`);
|
|
702
590
|
if (switchbot !== false) {
|
|
703
591
|
try {
|
|
704
592
|
const device_list = await switchbot.discover({ model: 'c', quick: true, id: this.device.bleMac });
|
|
705
|
-
this.infoLog(`${this.accessory.displayName} Target Position: ${this.TargetPosition}`);
|
|
593
|
+
this.infoLog(`${this.accessory.displayName} Target Position: ${this.WindowCovering.TargetPosition}`);
|
|
706
594
|
|
|
707
|
-
await this.
|
|
708
|
-
max: this.
|
|
595
|
+
await this.retryBLE({
|
|
596
|
+
max: await this.maxRetryBLE(),
|
|
709
597
|
fn: async () => {
|
|
710
|
-
await device_list[0].runToPos(100 - Number(this.TargetPosition), adjustedMode);
|
|
598
|
+
await device_list[0].runToPos(100 - Number(this.WindowCovering.TargetPosition), adjustedMode);
|
|
711
599
|
},
|
|
712
600
|
});
|
|
713
601
|
|
|
714
602
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Done.`);
|
|
603
|
+
this.successLog(`${this.device.deviceType}: ${this.accessory.displayName} `
|
|
604
|
+
+ `TargetPosition: ${this.WindowCovering.TargetPosition} sent over BLE, sent successfully`);
|
|
715
605
|
} catch (e) {
|
|
716
606
|
this.apiError(e);
|
|
717
607
|
this.errorLog(
|
|
718
608
|
`${this.device.deviceType}: ${this.accessory.displayName} failed BLEpushChanges with ${this.device.connectionType}` +
|
|
719
|
-
|
|
609
|
+
` Connection, Error Message: ${JSON.stringify((e as Error).message)}`,
|
|
720
610
|
);
|
|
721
611
|
await this.BLEPushConnection();
|
|
722
612
|
throw new Error('Connection error');
|
|
@@ -728,54 +618,23 @@ export class Curtain {
|
|
|
728
618
|
} else {
|
|
729
619
|
this.debugLog(
|
|
730
620
|
`${this.device.deviceType}: ${this.accessory.displayName} No BLEpushChanges, CurrentPosition & TargetPosition Are the Same.` +
|
|
731
|
-
` CurrentPosition: ${this.CurrentPosition}, TargetPosition ${this.TargetPosition}`,
|
|
621
|
+
` CurrentPosition: ${this.WindowCovering.CurrentPosition}, TargetPosition ${this.WindowCovering.TargetPosition}`,
|
|
732
622
|
);
|
|
733
623
|
}
|
|
734
624
|
}
|
|
735
625
|
|
|
736
|
-
async retry({ max, fn }: { max: number; fn: { (): any; (): Promise<any> } }): Promise<null> {
|
|
737
|
-
return fn().catch(async (e: any) => {
|
|
738
|
-
if (max === 0) {
|
|
739
|
-
throw e;
|
|
740
|
-
}
|
|
741
|
-
this.infoLog(e);
|
|
742
|
-
this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Retrying`);
|
|
743
|
-
await sleep(1000);
|
|
744
|
-
return this.retry({ max: max - 1, fn });
|
|
745
|
-
});
|
|
746
|
-
}
|
|
747
|
-
|
|
748
|
-
maxRetry(): number {
|
|
749
|
-
if (this.device.maxRetry) {
|
|
750
|
-
return this.device.maxRetry;
|
|
751
|
-
} else {
|
|
752
|
-
return 5;
|
|
753
|
-
}
|
|
754
|
-
}
|
|
755
|
-
|
|
756
626
|
async openAPIpushChanges(): Promise<void> {
|
|
757
627
|
let command: string;
|
|
758
628
|
let parameter: string;
|
|
759
629
|
let commandType: string;
|
|
760
630
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIpushChanges`);
|
|
761
|
-
if (this.TargetPosition !== this.CurrentPosition || this.device.disableCaching) {
|
|
762
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Pushing ${this.TargetPosition}`);
|
|
763
|
-
const adjustedTargetPosition = 100 - Number(this.TargetPosition);
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
}
|
|
769
|
-
if (this.setPositionMode === '1') {
|
|
770
|
-
this.Mode = 'Silent Mode';
|
|
771
|
-
} else if (this.setPositionMode === '0') {
|
|
772
|
-
this.Mode = 'Performance Mode';
|
|
773
|
-
} else {
|
|
774
|
-
this.Mode = 'Default Mode';
|
|
775
|
-
}
|
|
776
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Mode: ${this.Mode}`);
|
|
777
|
-
const adjustedMode = this.setPositionMode || 'ff';
|
|
778
|
-
if (this.HoldPosition) {
|
|
631
|
+
if (this.WindowCovering.TargetPosition !== this.WindowCovering.CurrentPosition || this.device.disableCaching) {
|
|
632
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Pushing ${this.WindowCovering.TargetPosition}`);
|
|
633
|
+
const adjustedTargetPosition = 100 - Number(this.WindowCovering.TargetPosition);
|
|
634
|
+
const { setPositionMode, Mode }: { setPositionMode: number; Mode: string; } = await this.setPerformance();
|
|
635
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Mode: ${Mode}`);
|
|
636
|
+
const adjustedMode = setPositionMode || 'ff';
|
|
637
|
+
if (this.WindowCovering.HoldPosition) {
|
|
779
638
|
command = 'pause';
|
|
780
639
|
parameter = 'default';
|
|
781
640
|
commandType = 'command';
|
|
@@ -804,6 +663,8 @@ export class Curtain {
|
|
|
804
663
|
if ((statusCode === 200 || statusCode === 100) && (deviceStatus.statusCode === 200 || deviceStatus.statusCode === 100)) {
|
|
805
664
|
this.debugErrorLog(`${this.device.deviceType}: ${this.accessory.displayName} `
|
|
806
665
|
+ `statusCode: ${statusCode} & deviceStatus StatusCode: ${deviceStatus.statusCode}`);
|
|
666
|
+
this.successLog(`${this.device.deviceType}: ${this.accessory.displayName} `
|
|
667
|
+
+ `request to SwitchBot API, body: ${deviceStatus} sent successfully`);
|
|
807
668
|
} else {
|
|
808
669
|
this.statusCode(statusCode);
|
|
809
670
|
this.statusCode(deviceStatus.statusCode);
|
|
@@ -818,7 +679,7 @@ export class Curtain {
|
|
|
818
679
|
} else {
|
|
819
680
|
this.debugLog(
|
|
820
681
|
`${this.device.deviceType}: ${this.accessory.displayName} No OpenAPI Changes, CurrentPosition & TargetPosition Are the Same.` +
|
|
821
|
-
` CurrentPosition: ${this.CurrentPosition}, TargetPosition ${this.TargetPosition}`,
|
|
682
|
+
` CurrentPosition: ${this.WindowCovering.CurrentPosition}, TargetPosition ${this.WindowCovering.TargetPosition}`,
|
|
822
683
|
);
|
|
823
684
|
}
|
|
824
685
|
}
|
|
@@ -827,50 +688,53 @@ export class Curtain {
|
|
|
827
688
|
* Handle requests to set the value of the "Target Position" characteristic
|
|
828
689
|
*/
|
|
829
690
|
async TargetPositionSet(value: CharacteristicValue): Promise<void> {
|
|
830
|
-
if (this.TargetPosition === this.accessory.context.TargetPosition) {
|
|
691
|
+
if (this.WindowCovering.TargetPosition === this.accessory.context.TargetPosition) {
|
|
831
692
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} No Changes, Set TargetPosition: ${value}`);
|
|
832
693
|
} else {
|
|
833
694
|
this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Set TargetPosition: ${value}`);
|
|
834
695
|
}
|
|
835
696
|
|
|
836
697
|
// Set HoldPosition to false when TargetPosition is changed
|
|
837
|
-
this.HoldPosition = false;
|
|
838
|
-
this.
|
|
698
|
+
this.WindowCovering.HoldPosition = false;
|
|
699
|
+
this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.HoldPosition, this.WindowCovering.HoldPosition);
|
|
839
700
|
|
|
840
|
-
this.TargetPosition = value;
|
|
701
|
+
this.WindowCovering.TargetPosition = value;
|
|
841
702
|
if (this.device.mqttURL) {
|
|
842
|
-
this.mqttPublish('TargetPosition', this.TargetPosition);
|
|
843
|
-
this.mqttPublish('HoldPosition', this.HoldPosition);
|
|
703
|
+
this.mqttPublish('TargetPosition', this.WindowCovering.TargetPosition.toString());
|
|
704
|
+
this.mqttPublish('HoldPosition', this.WindowCovering.HoldPosition.toString()); // Convert boolean to string
|
|
844
705
|
}
|
|
845
706
|
|
|
846
707
|
await this.setMinMax();
|
|
847
|
-
if (value > this.CurrentPosition) {
|
|
848
|
-
this.PositionState = this.hap.Characteristic.PositionState.INCREASING;
|
|
708
|
+
if (value > this.WindowCovering.CurrentPosition) {
|
|
709
|
+
this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.INCREASING;
|
|
849
710
|
this.setNewTarget = true;
|
|
850
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} value: ${value}
|
|
851
|
-
|
|
852
|
-
|
|
711
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} value: ${value},`
|
|
712
|
+
+ ` CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
|
|
713
|
+
} else if (value < this.WindowCovering.CurrentPosition) {
|
|
714
|
+
this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.DECREASING;
|
|
853
715
|
this.setNewTarget = true;
|
|
854
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} value: ${value}
|
|
716
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} value: ${value},`
|
|
717
|
+
+ ` CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
|
|
855
718
|
} else {
|
|
856
|
-
this.PositionState = this.hap.Characteristic.PositionState.STOPPED;
|
|
719
|
+
this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.STOPPED;
|
|
857
720
|
this.setNewTarget = false;
|
|
858
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} value: ${value}
|
|
721
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} value: ${value},`
|
|
722
|
+
+ ` CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
|
|
859
723
|
}
|
|
860
|
-
this.
|
|
861
|
-
this.
|
|
724
|
+
this.WindowCovering.Service.setCharacteristic(this.hap.Characteristic.PositionState, this.WindowCovering.PositionState);
|
|
725
|
+
this.WindowCovering.Service.getCharacteristic(this.hap.Characteristic.PositionState).updateValue(this.WindowCovering.PositionState);
|
|
862
726
|
|
|
863
727
|
/**
|
|
864
728
|
* If Curtain movement time is short, the moving flag from backend is always false.
|
|
865
729
|
* The minimum time depends on the network control latency.
|
|
866
730
|
*/
|
|
867
731
|
clearTimeout(this.setNewTargetTimer);
|
|
868
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateRate: ${this.
|
|
732
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateRate: ${this.deviceUpdateRate}`);
|
|
869
733
|
if (this.setNewTarget) {
|
|
870
734
|
this.setNewTargetTimer = setTimeout(() => {
|
|
871
735
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} setNewTarget ${this.setNewTarget} timeout`);
|
|
872
736
|
this.setNewTarget = false;
|
|
873
|
-
}, this.
|
|
737
|
+
}, this.deviceUpdateRate * 1000);
|
|
874
738
|
}
|
|
875
739
|
this.doCurtainUpdate.next();
|
|
876
740
|
}
|
|
@@ -880,153 +744,98 @@ export class Curtain {
|
|
|
880
744
|
*/
|
|
881
745
|
async HoldPositionSet(value: CharacteristicValue): Promise<void> {
|
|
882
746
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} HoldPosition: ${value}`);
|
|
883
|
-
this.HoldPosition = value;
|
|
747
|
+
this.WindowCovering.HoldPosition = value;
|
|
884
748
|
this.doCurtainUpdate.next();
|
|
885
749
|
}
|
|
886
750
|
|
|
887
751
|
async updateHomeKitCharacteristics(): Promise<void> {
|
|
888
752
|
await this.setMinMax();
|
|
889
|
-
if (this.CurrentPosition === undefined || Number.isNaN(this.CurrentPosition)) {
|
|
890
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} CurrentPosition: ${this.CurrentPosition}`);
|
|
753
|
+
if (this.WindowCovering.CurrentPosition === undefined || Number.isNaN(this.WindowCovering.CurrentPosition)) {
|
|
754
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
|
|
891
755
|
} else {
|
|
756
|
+
this.accessory.context.CurrentPosition = this.WindowCovering.CurrentPosition;
|
|
757
|
+
this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.CurrentPosition, Number(this.WindowCovering.CurrentPosition));
|
|
758
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic`
|
|
759
|
+
+ ` CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
|
|
892
760
|
if (this.device.mqttURL) {
|
|
893
|
-
this.mqttPublish('CurrentPosition', this.CurrentPosition);
|
|
761
|
+
this.mqttPublish('CurrentPosition', this.WindowCovering.CurrentPosition.toString()); // Convert to string
|
|
894
762
|
}
|
|
895
|
-
this.accessory.context.CurrentPosition = this.CurrentPosition;
|
|
896
|
-
this.windowCoveringService.updateCharacteristic(this.hap.Characteristic.CurrentPosition, Number(this.CurrentPosition));
|
|
897
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic CurrentPosition: ${this.CurrentPosition}`);
|
|
898
763
|
}
|
|
899
|
-
if (this.PositionState === undefined) {
|
|
900
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} PositionState: ${this.PositionState}`);
|
|
764
|
+
if (this.WindowCovering.PositionState === undefined) {
|
|
765
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} PositionState: ${this.WindowCovering.PositionState}`);
|
|
901
766
|
} else {
|
|
902
767
|
if (this.device.mqttURL) {
|
|
903
|
-
this.mqttPublish('PositionState', this.PositionState);
|
|
768
|
+
this.mqttPublish('PositionState', this.WindowCovering.PositionState.toString());
|
|
904
769
|
}
|
|
905
|
-
this.accessory.context.PositionState = this.PositionState;
|
|
906
|
-
this.
|
|
907
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic
|
|
770
|
+
this.accessory.context.PositionState = this.WindowCovering.PositionState;
|
|
771
|
+
this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.PositionState, Number(this.WindowCovering.PositionState));
|
|
772
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic`
|
|
773
|
+
+ ` PositionState: ${this.WindowCovering.PositionState}`);
|
|
908
774
|
}
|
|
909
|
-
if (this.TargetPosition === undefined || Number.isNaN(this.TargetPosition)) {
|
|
910
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} TargetPosition: ${this.TargetPosition}`);
|
|
775
|
+
if (this.WindowCovering.TargetPosition === undefined || Number.isNaN(this.WindowCovering.TargetPosition)) {
|
|
776
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} TargetPosition: ${this.WindowCovering.TargetPosition}`);
|
|
911
777
|
} else {
|
|
912
778
|
if (this.device.mqttURL) {
|
|
913
|
-
this.mqttPublish('TargetPosition', this.TargetPosition);
|
|
779
|
+
this.mqttPublish('TargetPosition', this.WindowCovering.TargetPosition.toString());
|
|
914
780
|
}
|
|
915
|
-
this.accessory.context.TargetPosition = this.TargetPosition;
|
|
916
|
-
this.
|
|
917
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic
|
|
781
|
+
this.accessory.context.TargetPosition = this.WindowCovering.TargetPosition;
|
|
782
|
+
this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.TargetPosition, Number(this.WindowCovering.TargetPosition));
|
|
783
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic`
|
|
784
|
+
+ ` TargetPosition: ${this.WindowCovering.TargetPosition}`);
|
|
918
785
|
}
|
|
919
|
-
if (this.HoldPosition === undefined) {
|
|
920
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} HoldPosition: ${this.HoldPosition}`);
|
|
786
|
+
if (this.WindowCovering.HoldPosition === undefined) {
|
|
787
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} HoldPosition: ${this.WindowCovering.HoldPosition}`);
|
|
921
788
|
} else {
|
|
922
789
|
if (this.device.mqttURL) {
|
|
923
|
-
this.mqttPublish('HoldPosition', this.HoldPosition);
|
|
790
|
+
this.mqttPublish('HoldPosition', this.WindowCovering.HoldPosition.toString());
|
|
924
791
|
}
|
|
925
|
-
this.accessory.context.HoldPosition = this.HoldPosition;
|
|
926
|
-
this.
|
|
927
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic
|
|
792
|
+
this.accessory.context.HoldPosition = this.WindowCovering.HoldPosition;
|
|
793
|
+
this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.HoldPosition, this.WindowCovering.HoldPosition);
|
|
794
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic`
|
|
795
|
+
+ ` HoldPosition: ${this.WindowCovering.HoldPosition}`);
|
|
928
796
|
}
|
|
929
797
|
if (!this.device.curtain?.hide_lightsensor) {
|
|
930
|
-
if (this.CurrentAmbientLightLevel === undefined || Number.isNaN(this.CurrentAmbientLightLevel)) {
|
|
931
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}
|
|
798
|
+
if (this.LightSensor!.CurrentAmbientLightLevel === undefined || Number.isNaN(this.LightSensor!.CurrentAmbientLightLevel)) {
|
|
799
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}`
|
|
800
|
+
+ ` CurrentAmbientLightLevel: ${this.LightSensor!.CurrentAmbientLightLevel}`);
|
|
932
801
|
} else {
|
|
933
802
|
if (this.device.mqttURL) {
|
|
934
|
-
this.mqttPublish('CurrentAmbientLightLevel', this.CurrentAmbientLightLevel);
|
|
803
|
+
this.mqttPublish('CurrentAmbientLightLevel', this.LightSensor!.CurrentAmbientLightLevel.toString());
|
|
935
804
|
}
|
|
936
|
-
this.accessory.context.CurrentAmbientLightLevel = this.CurrentAmbientLightLevel;
|
|
937
|
-
this.
|
|
805
|
+
this.accessory.context.CurrentAmbientLightLevel = this.LightSensor!.CurrentAmbientLightLevel;
|
|
806
|
+
this.LightSensor!.Service.updateCharacteristic(this.hap.Characteristic.CurrentAmbientLightLevel, this.LightSensor!.CurrentAmbientLightLevel);
|
|
938
807
|
this.debugLog(
|
|
939
808
|
`${this.device.deviceType}: ${this.accessory.displayName}` +
|
|
940
|
-
` updateCharacteristic CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`,
|
|
809
|
+
` updateCharacteristic CurrentAmbientLightLevel: ${this.LightSensor!.CurrentAmbientLightLevel}`,
|
|
941
810
|
);
|
|
942
811
|
if (this.device.history) {
|
|
943
812
|
this.historyService?.addEntry({
|
|
944
813
|
time: Math.round(new Date().valueOf() / 1000),
|
|
945
|
-
lux: this.CurrentAmbientLightLevel,
|
|
814
|
+
lux: this.LightSensor!.CurrentAmbientLightLevel,
|
|
946
815
|
});
|
|
947
816
|
}
|
|
948
817
|
}
|
|
949
818
|
}
|
|
950
|
-
if (this.BatteryLevel === undefined) {
|
|
951
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.BatteryLevel}`);
|
|
819
|
+
if (this.Battery.BatteryLevel === undefined) {
|
|
820
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.Battery.BatteryLevel}`);
|
|
952
821
|
} else {
|
|
953
822
|
if (this.device.mqttURL) {
|
|
954
|
-
this.mqttPublish('BatteryLevel', this.BatteryLevel);
|
|
823
|
+
this.mqttPublish('BatteryLevel', this.Battery.BatteryLevel.toString());
|
|
955
824
|
}
|
|
956
|
-
this.accessory.context.BatteryLevel = this.BatteryLevel;
|
|
957
|
-
this.
|
|
958
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic BatteryLevel: ${this.BatteryLevel}`);
|
|
825
|
+
this.accessory.context.BatteryLevel = this.Battery.BatteryLevel;
|
|
826
|
+
this.Battery.Service.updateCharacteristic(this.hap.Characteristic.BatteryLevel, this.Battery.BatteryLevel);
|
|
827
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic BatteryLevel: ${this.Battery.BatteryLevel}`);
|
|
959
828
|
}
|
|
960
|
-
if (this.StatusLowBattery === undefined) {
|
|
961
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} StatusLowBattery: ${this.StatusLowBattery}`);
|
|
829
|
+
if (this.Battery.StatusLowBattery === undefined) {
|
|
830
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} StatusLowBattery: ${this.Battery.StatusLowBattery}`);
|
|
962
831
|
} else {
|
|
963
832
|
if (this.device.mqttURL) {
|
|
964
|
-
this.mqttPublish('StatusLowBattery', this.StatusLowBattery);
|
|
965
|
-
}
|
|
966
|
-
this.accessory.context.StatusLowBattery = this.StatusLowBattery;
|
|
967
|
-
this.batteryService?.updateCharacteristic(this.hap.Characteristic.StatusLowBattery, this.StatusLowBattery);
|
|
968
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic StatusLowBattery: ${this.StatusLowBattery}`);
|
|
969
|
-
}
|
|
970
|
-
}
|
|
971
|
-
|
|
972
|
-
/*
|
|
973
|
-
* Publish MQTT message for topics of
|
|
974
|
-
* 'homebridge-switchbot/curtain/xx:xx:xx:xx:xx:xx'
|
|
975
|
-
*/
|
|
976
|
-
mqttPublish(topic: string, message: any) {
|
|
977
|
-
const mac = this.device.deviceId
|
|
978
|
-
?.toLowerCase()
|
|
979
|
-
.match(/[\s\S]{1,2}/g)
|
|
980
|
-
?.join(':');
|
|
981
|
-
const options = this.device.mqttPubOptions || {};
|
|
982
|
-
this.mqttClient?.publish(`homebridge-switchbot/curtain/${mac}/${topic}`, `${message}`, options);
|
|
983
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} MQTT message: ${topic}/${message} options:${JSON.stringify(options)}`);
|
|
984
|
-
}
|
|
985
|
-
|
|
986
|
-
/*
|
|
987
|
-
* Setup MQTT hadler if URL is specified.
|
|
988
|
-
*/
|
|
989
|
-
async setupMqtt(device: device & devicesConfig): Promise<void> {
|
|
990
|
-
if (device.mqttURL) {
|
|
991
|
-
try {
|
|
992
|
-
const { connectAsync } = asyncmqtt;
|
|
993
|
-
this.mqttClient = await connectAsync(device.mqttURL, device.mqttOptions || {});
|
|
994
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} MQTT connection has been established successfully.`);
|
|
995
|
-
this.mqttClient.on('error', (e: Error) => {
|
|
996
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Failed to publish MQTT messages. ${e}`);
|
|
997
|
-
});
|
|
998
|
-
} catch (e) {
|
|
999
|
-
this.mqttClient = null;
|
|
1000
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Failed to establish MQTT connection. ${e}`);
|
|
833
|
+
this.mqttPublish('StatusLowBattery', this.Battery.StatusLowBattery.toString());
|
|
1001
834
|
}
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
switchbot.stopScan();
|
|
1007
|
-
if (this.BLE_IsConnected) {
|
|
1008
|
-
await this.BLEparseStatus();
|
|
1009
|
-
await this.updateHomeKitCharacteristics();
|
|
1010
|
-
} else {
|
|
1011
|
-
await this.BLERefreshConnection(switchbot);
|
|
1012
|
-
}
|
|
1013
|
-
}
|
|
1014
|
-
|
|
1015
|
-
async getCustomBLEAddress(switchbot: any) {
|
|
1016
|
-
if (this.device.customBLEaddress && this.deviceLogging.includes('debug')) {
|
|
1017
|
-
(async () => {
|
|
1018
|
-
// Start to monitor advertisement packets
|
|
1019
|
-
await switchbot.startScan({
|
|
1020
|
-
model: 'c',
|
|
1021
|
-
});
|
|
1022
|
-
// Set an event handler
|
|
1023
|
-
switchbot.onadvertisement = (ad: any) => {
|
|
1024
|
-
this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} ad: ${JSON.stringify(ad, null, ' ')}`);
|
|
1025
|
-
};
|
|
1026
|
-
await sleep(10000);
|
|
1027
|
-
// Stop to monitor
|
|
1028
|
-
switchbot.stopScan();
|
|
1029
|
-
})();
|
|
835
|
+
this.accessory.context.StatusLowBattery = this.Battery.StatusLowBattery;
|
|
836
|
+
this.Battery.Service.updateCharacteristic(this.hap.Characteristic.StatusLowBattery, this.Battery.StatusLowBattery);
|
|
837
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic`
|
|
838
|
+
+ ` StatusLowBattery: ${this.Battery.StatusLowBattery}`);
|
|
1030
839
|
}
|
|
1031
840
|
}
|
|
1032
841
|
|
|
@@ -1046,364 +855,100 @@ export class Curtain {
|
|
|
1046
855
|
}
|
|
1047
856
|
}
|
|
1048
857
|
|
|
1049
|
-
async
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
858
|
+
async setPerformance() {
|
|
859
|
+
let setPositionMode: number;
|
|
860
|
+
let Mode: string;
|
|
861
|
+
if (Number(this.WindowCovering.TargetPosition) > 50) {
|
|
862
|
+
if (this.device.blindTilt?.setOpenMode === '1') {
|
|
863
|
+
setPositionMode = 1;
|
|
864
|
+
Mode = 'Silent Mode';
|
|
865
|
+
} else if (this.device.blindTilt?.setOpenMode === '0') {
|
|
866
|
+
setPositionMode = 0;
|
|
867
|
+
Mode = 'Performance Mode';
|
|
1054
868
|
} else {
|
|
1055
|
-
|
|
1056
|
-
|
|
869
|
+
setPositionMode = 0;
|
|
870
|
+
Mode = 'Default Mode';
|
|
1057
871
|
}
|
|
1058
872
|
} else {
|
|
1059
|
-
if (this.device.
|
|
1060
|
-
|
|
1061
|
-
|
|
873
|
+
if (this.device.blindTilt?.setCloseMode === '1') {
|
|
874
|
+
setPositionMode = 1;
|
|
875
|
+
Mode = 'Silent Mode';
|
|
876
|
+
} else if (this.device.blindTilt?.setOpenMode === '0') {
|
|
877
|
+
setPositionMode = 0;
|
|
878
|
+
Mode = 'Performance Mode';
|
|
1062
879
|
} else {
|
|
1063
|
-
|
|
1064
|
-
|
|
880
|
+
setPositionMode = 0;
|
|
881
|
+
Mode = 'Default Mode';
|
|
1065
882
|
}
|
|
1066
883
|
}
|
|
884
|
+
return { setPositionMode, Mode };
|
|
1067
885
|
}
|
|
1068
886
|
|
|
1069
887
|
async setMinMax(): Promise<void> {
|
|
1070
888
|
if (this.device.curtain?.set_min) {
|
|
1071
|
-
if (Number(this.CurrentPosition) <= this.device.curtain?.set_min) {
|
|
1072
|
-
this.CurrentPosition = 0;
|
|
889
|
+
if (Number(this.WindowCovering.CurrentPosition) <= this.device.curtain?.set_min) {
|
|
890
|
+
this.WindowCovering.CurrentPosition = 0;
|
|
1073
891
|
}
|
|
1074
892
|
}
|
|
1075
893
|
if (this.device.curtain?.set_max) {
|
|
1076
|
-
if (Number(this.CurrentPosition) >= this.device.curtain?.set_max) {
|
|
1077
|
-
this.CurrentPosition = 100;
|
|
894
|
+
if (Number(this.WindowCovering.CurrentPosition) >= this.device.curtain?.set_max) {
|
|
895
|
+
this.WindowCovering.CurrentPosition = 100;
|
|
1078
896
|
}
|
|
1079
897
|
}
|
|
1080
898
|
if (this.device.history) {
|
|
1081
899
|
const motion = this.accessory.getService(this.hap.Service.MotionSensor);
|
|
1082
|
-
const state = Number(this.CurrentPosition) > 0 ? 1 : 0;
|
|
900
|
+
const state = Number(this.WindowCovering.CurrentPosition) > 0 ? 1 : 0;
|
|
1083
901
|
motion?.updateCharacteristic(this.hap.Characteristic.MotionDetected, state);
|
|
1084
902
|
}
|
|
1085
903
|
}
|
|
1086
904
|
|
|
1087
905
|
minStep(device: device & devicesConfig): number {
|
|
906
|
+
let set_minStep: number;
|
|
1088
907
|
if (device.curtain?.set_minStep) {
|
|
1089
|
-
|
|
908
|
+
set_minStep = device.curtain?.set_minStep;
|
|
1090
909
|
} else {
|
|
1091
|
-
|
|
910
|
+
set_minStep = 1;
|
|
1092
911
|
}
|
|
1093
|
-
return
|
|
912
|
+
return set_minStep;
|
|
1094
913
|
}
|
|
1095
914
|
|
|
1096
|
-
minLux(): number {
|
|
915
|
+
async minLux(): Promise<number> {
|
|
916
|
+
let set_minLux: number;
|
|
1097
917
|
if (this.device.curtain?.set_minLux) {
|
|
1098
|
-
|
|
918
|
+
set_minLux = this.device.curtain?.set_minLux;
|
|
1099
919
|
} else {
|
|
1100
|
-
|
|
920
|
+
set_minLux = 1;
|
|
1101
921
|
}
|
|
1102
|
-
return
|
|
922
|
+
return set_minLux;
|
|
1103
923
|
}
|
|
1104
924
|
|
|
1105
|
-
maxLux(): number {
|
|
925
|
+
async maxLux(): Promise<number> {
|
|
926
|
+
let set_maxLux: number;
|
|
1106
927
|
if (this.device.curtain?.set_maxLux) {
|
|
1107
|
-
|
|
928
|
+
set_maxLux = this.device.curtain?.set_maxLux;
|
|
1108
929
|
} else {
|
|
1109
|
-
|
|
1110
|
-
}
|
|
1111
|
-
return this.set_maxLux;
|
|
1112
|
-
}
|
|
1113
|
-
|
|
1114
|
-
async scan(device: device & devicesConfig): Promise<void> {
|
|
1115
|
-
if (device.scanDuration) {
|
|
1116
|
-
if (this.updateRate > device.scanDuration) {
|
|
1117
|
-
this.scanDuration = this.updateRate;
|
|
1118
|
-
if (this.BLE) {
|
|
1119
|
-
this.warnLog(
|
|
1120
|
-
`${this.device.deviceType}: ` +
|
|
1121
|
-
`${this.accessory.displayName} scanDuration is less than updateRate, overriding scanDuration with updateRate`,
|
|
1122
|
-
);
|
|
1123
|
-
}
|
|
1124
|
-
} else {
|
|
1125
|
-
this.scanDuration = this.accessory.context.scanDuration = device.scanDuration;
|
|
1126
|
-
}
|
|
1127
|
-
if (this.BLE) {
|
|
1128
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Config scanDuration: ${this.scanDuration}`);
|
|
1129
|
-
}
|
|
1130
|
-
} else {
|
|
1131
|
-
if (this.updateRate > 1) {
|
|
1132
|
-
this.scanDuration = this.updateRate;
|
|
1133
|
-
} else {
|
|
1134
|
-
this.scanDuration = this.accessory.context.scanDuration = 1;
|
|
1135
|
-
}
|
|
1136
|
-
if (this.BLE) {
|
|
1137
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Default scanDuration: ${this.scanDuration}`);
|
|
1138
|
-
}
|
|
1139
|
-
}
|
|
1140
|
-
}
|
|
1141
|
-
|
|
1142
|
-
async statusCode(statusCode: number): Promise<void> {
|
|
1143
|
-
switch (statusCode) {
|
|
1144
|
-
case 151:
|
|
1145
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command not supported by this deviceType, statusCode: ${statusCode}`);
|
|
1146
|
-
break;
|
|
1147
|
-
case 152:
|
|
1148
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device not found, statusCode: ${statusCode}`);
|
|
1149
|
-
break;
|
|
1150
|
-
case 160:
|
|
1151
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command is not supported, statusCode: ${statusCode}`);
|
|
1152
|
-
break;
|
|
1153
|
-
case 161:
|
|
1154
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device is offline, statusCode: ${statusCode}`);
|
|
1155
|
-
this.offlineOff();
|
|
1156
|
-
break;
|
|
1157
|
-
case 171:
|
|
1158
|
-
this.errorLog(
|
|
1159
|
-
`${this.device.deviceType}: ${this.accessory.displayName} Hub Device is offline, statusCode: ${statusCode}. ` +
|
|
1160
|
-
`Hub: ${this.device.hubDeviceId}`,
|
|
1161
|
-
);
|
|
1162
|
-
this.offlineOff();
|
|
1163
|
-
break;
|
|
1164
|
-
case 190:
|
|
1165
|
-
this.errorLog(
|
|
1166
|
-
`${this.device.deviceType}: ${this.accessory.displayName} Device internal error due to device states not synchronized with server,` +
|
|
1167
|
-
` Or command format is invalid, statusCode: ${statusCode}`,
|
|
1168
|
-
);
|
|
1169
|
-
break;
|
|
1170
|
-
case 100:
|
|
1171
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Command successfully sent, statusCode: ${statusCode}`);
|
|
1172
|
-
break;
|
|
1173
|
-
case 200:
|
|
1174
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Request successful, statusCode: ${statusCode}`);
|
|
1175
|
-
break;
|
|
1176
|
-
case 400:
|
|
1177
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Bad Request, The client has issued an invalid request. `
|
|
1178
|
-
+ `This is commonly used to specify validation errors in a request payload, statusCode: ${statusCode}`);
|
|
1179
|
-
break;
|
|
1180
|
-
case 401:
|
|
1181
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Unauthorized, Authorization for the API is required, `
|
|
1182
|
-
+ `but the request has not been authenticated, statusCode: ${statusCode}`);
|
|
1183
|
-
break;
|
|
1184
|
-
case 403:
|
|
1185
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Forbidden, The request has been authenticated but does not `
|
|
1186
|
-
+ `have appropriate permissions, or a requested resource is not found, statusCode: ${statusCode}`);
|
|
1187
|
-
break;
|
|
1188
|
-
case 404:
|
|
1189
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Not Found, Specifies the requested path does not exist, `
|
|
1190
|
-
+ `statusCode: ${statusCode}`);
|
|
1191
|
-
break;
|
|
1192
|
-
case 406:
|
|
1193
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Not Acceptable, The client has requested a MIME type via `
|
|
1194
|
-
+ `the Accept header for a value not supported by the server, statusCode: ${statusCode}`);
|
|
1195
|
-
break;
|
|
1196
|
-
case 415:
|
|
1197
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Unsupported Media Type, The client has defined a contentType `
|
|
1198
|
-
+ `header that is not supported by the server, statusCode: ${statusCode}`);
|
|
1199
|
-
break;
|
|
1200
|
-
case 422:
|
|
1201
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Unprocessable Entity, The client has made a valid request, `
|
|
1202
|
-
+ `but the server cannot process it. This is often used for APIs for which certain limits have been exceeded, statusCode: ${statusCode}`);
|
|
1203
|
-
break;
|
|
1204
|
-
case 429:
|
|
1205
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Too Many Requests, The client has exceeded the number of `
|
|
1206
|
-
+ `requests allowed for a given time window, statusCode: ${statusCode}`);
|
|
1207
|
-
break;
|
|
1208
|
-
case 500:
|
|
1209
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Internal Server Error, An unexpected error on the SmartThings `
|
|
1210
|
-
+ `servers has occurred. These errors should be rare, statusCode: ${statusCode}`);
|
|
1211
|
-
break;
|
|
1212
|
-
default:
|
|
1213
|
-
this.infoLog(
|
|
1214
|
-
`${this.device.deviceType}: ${this.accessory.displayName} Unknown statusCode: ` +
|
|
1215
|
-
`${statusCode}, Submit Bugs Here: ' + 'https://tinyurl.com/SwitchBotBug`,
|
|
1216
|
-
);
|
|
930
|
+
set_maxLux = 6001;
|
|
1217
931
|
}
|
|
932
|
+
return set_maxLux;
|
|
1218
933
|
}
|
|
1219
934
|
|
|
1220
935
|
async offlineOff(): Promise<void> {
|
|
1221
936
|
if (this.device.offline) {
|
|
1222
|
-
|
|
1223
|
-
|
|
937
|
+
this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.CurrentPosition, 100);
|
|
938
|
+
this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.TargetPosition, 100);
|
|
939
|
+
this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.PositionState, this.hap.Characteristic.PositionState.STOPPED);
|
|
1224
940
|
}
|
|
1225
941
|
}
|
|
1226
942
|
|
|
1227
943
|
async apiError(e: any): Promise<void> {
|
|
1228
|
-
this.
|
|
1229
|
-
this.
|
|
1230
|
-
this.
|
|
944
|
+
this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.CurrentPosition, e);
|
|
945
|
+
this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.PositionState, e);
|
|
946
|
+
this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.TargetPosition, e);
|
|
1231
947
|
if (!this.device.curtain?.hide_lightsensor) {
|
|
1232
|
-
this.
|
|
948
|
+
this.LightSensor!.Service.updateCharacteristic(this.hap.Characteristic.CurrentAmbientLightLevel, e);
|
|
1233
949
|
}
|
|
1234
|
-
this.
|
|
1235
|
-
this.
|
|
950
|
+
this.Battery.Service.updateCharacteristic(this.hap.Characteristic.BatteryLevel, e);
|
|
951
|
+
this.Battery.Service.updateCharacteristic(this.hap.Characteristic.StatusLowBattery, e);
|
|
1236
952
|
//throw new this.platform.api.hap.HapStatusError(HAPStatus.SERVICE_COMMUNICATION_FAILURE);
|
|
1237
953
|
}
|
|
1238
|
-
|
|
1239
|
-
async deviceContext() {
|
|
1240
|
-
if (this.accessory.context.CurrentPosition === undefined) {
|
|
1241
|
-
this.CurrentPosition = 0;
|
|
1242
|
-
} else {
|
|
1243
|
-
this.CurrentPosition = this.accessory.context.CurrentPosition;
|
|
1244
|
-
}
|
|
1245
|
-
|
|
1246
|
-
if (this.accessory.context.TargetPosition === undefined) {
|
|
1247
|
-
this.TargetPosition = 0;
|
|
1248
|
-
} else {
|
|
1249
|
-
this.TargetPosition = this.accessory.context.TargetPosition;
|
|
1250
|
-
}
|
|
1251
|
-
|
|
1252
|
-
if (this.accessory.context.PositionState === undefined) {
|
|
1253
|
-
this.PositionState = this.hap.Characteristic.PositionState.STOPPED;
|
|
1254
|
-
} else {
|
|
1255
|
-
this.PositionState = this.accessory.context.PositionState;
|
|
1256
|
-
}
|
|
1257
|
-
|
|
1258
|
-
if (!this.device.curtain?.hide_lightsensor) {
|
|
1259
|
-
if (this.accessory.context.CurrentAmbientLightLevel !== undefined) {
|
|
1260
|
-
this.CurrentAmbientLightLevel = this.accessory.context.CurrentAmbientLightLevel;
|
|
1261
|
-
}
|
|
1262
|
-
}
|
|
1263
|
-
|
|
1264
|
-
if (this.BLE) {
|
|
1265
|
-
if (this.accessory.context.BatteryLevel === undefined) {
|
|
1266
|
-
this.BatteryLevel = 100;
|
|
1267
|
-
} else {
|
|
1268
|
-
this.BatteryLevel = this.accessory.context.BatteryLevel;
|
|
1269
|
-
}
|
|
1270
|
-
if (this.accessory.context.StatusLowBattery === undefined) {
|
|
1271
|
-
this.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
|
|
1272
|
-
} else {
|
|
1273
|
-
this.StatusLowBattery = this.accessory.context.StatusLowBattery;
|
|
1274
|
-
}
|
|
1275
|
-
}
|
|
1276
|
-
|
|
1277
|
-
if (this.device.history === true) {
|
|
1278
|
-
// initialize when this accessory is newly created.
|
|
1279
|
-
this.accessory.context.lastActivation = this.accessory.context.lastActivation ?? 0;
|
|
1280
|
-
} else {
|
|
1281
|
-
// removes cached values if history is turned off
|
|
1282
|
-
delete this.accessory.context.lastActivation;
|
|
1283
|
-
}
|
|
1284
|
-
if (this.FirmwareRevision === undefined) {
|
|
1285
|
-
this.FirmwareRevision = this.platform.version;
|
|
1286
|
-
this.accessory.context.FirmwareRevision = this.FirmwareRevision;
|
|
1287
|
-
}
|
|
1288
|
-
}
|
|
1289
|
-
|
|
1290
|
-
async refreshRate(device: device & devicesConfig): Promise<void> {
|
|
1291
|
-
// refreshRate
|
|
1292
|
-
if (device.refreshRate) {
|
|
1293
|
-
this.deviceRefreshRate = this.accessory.context.refreshRate = device.refreshRate;
|
|
1294
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Config refreshRate: ${this.deviceRefreshRate}`);
|
|
1295
|
-
} else if (this.platform.config.options!.refreshRate) {
|
|
1296
|
-
this.deviceRefreshRate = this.accessory.context.refreshRate = this.platform.config.options!.refreshRate;
|
|
1297
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Platform Config refreshRate: ${this.deviceRefreshRate}`);
|
|
1298
|
-
}
|
|
1299
|
-
// updateRate
|
|
1300
|
-
if (device?.curtain?.updateRate) {
|
|
1301
|
-
this.updateRate = device?.curtain?.updateRate;
|
|
1302
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Config Curtain updateRate: ${this.updateRate}`);
|
|
1303
|
-
} else {
|
|
1304
|
-
this.updateRate = 7;
|
|
1305
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Default Curtain updateRate: ${this.updateRate}`);
|
|
1306
|
-
}
|
|
1307
|
-
}
|
|
1308
|
-
|
|
1309
|
-
async deviceConfig(device: device & devicesConfig): Promise<void> {
|
|
1310
|
-
let config = {};
|
|
1311
|
-
if (device.curtain) {
|
|
1312
|
-
config = device.curtain;
|
|
1313
|
-
}
|
|
1314
|
-
if (device.connectionType !== undefined) {
|
|
1315
|
-
config['connectionType'] = device.connectionType;
|
|
1316
|
-
}
|
|
1317
|
-
if (device.external !== undefined) {
|
|
1318
|
-
config['external'] = device.external;
|
|
1319
|
-
}
|
|
1320
|
-
if (device.mqttURL !== undefined) {
|
|
1321
|
-
config['mqttURL'] = device.mqttURL;
|
|
1322
|
-
}
|
|
1323
|
-
if (device.logging !== undefined) {
|
|
1324
|
-
config['logging'] = device.logging;
|
|
1325
|
-
}
|
|
1326
|
-
if (device.refreshRate !== undefined) {
|
|
1327
|
-
config['refreshRate'] = device.refreshRate;
|
|
1328
|
-
}
|
|
1329
|
-
if (device.scanDuration !== undefined) {
|
|
1330
|
-
config['scanDuration'] = device.scanDuration;
|
|
1331
|
-
}
|
|
1332
|
-
if (device.maxRetry !== undefined) {
|
|
1333
|
-
config['maxRetry'] = device.maxRetry;
|
|
1334
|
-
}
|
|
1335
|
-
if (device.webhook !== undefined) {
|
|
1336
|
-
config['webhook'] = device.webhook;
|
|
1337
|
-
}
|
|
1338
|
-
if (Object.entries(config).length !== 0) {
|
|
1339
|
-
this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} Config: ${JSON.stringify(config)}`);
|
|
1340
|
-
}
|
|
1341
|
-
}
|
|
1342
|
-
|
|
1343
|
-
async deviceLogs(device: device & devicesConfig): Promise<void> {
|
|
1344
|
-
if (this.platform.debugMode) {
|
|
1345
|
-
this.deviceLogging = this.accessory.context.logging = 'debugMode';
|
|
1346
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Debug Mode Logging: ${this.deviceLogging}`);
|
|
1347
|
-
} else if (device.logging) {
|
|
1348
|
-
this.deviceLogging = this.accessory.context.logging = device.logging;
|
|
1349
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Config Logging: ${this.deviceLogging}`);
|
|
1350
|
-
} else if (this.platform.config.options?.logging) {
|
|
1351
|
-
this.deviceLogging = this.accessory.context.logging = this.platform.config.options?.logging;
|
|
1352
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Platform Config Logging: ${this.deviceLogging}`);
|
|
1353
|
-
} else {
|
|
1354
|
-
this.deviceLogging = this.accessory.context.logging = 'standard';
|
|
1355
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Logging Not Set, Using: ${this.deviceLogging}`);
|
|
1356
|
-
}
|
|
1357
|
-
}
|
|
1358
|
-
|
|
1359
|
-
/**
|
|
1360
|
-
* Logging for Device
|
|
1361
|
-
*/
|
|
1362
|
-
infoLog(...log: any[]): void {
|
|
1363
|
-
if (this.enablingDeviceLogging()) {
|
|
1364
|
-
this.platform.log.info(String(...log));
|
|
1365
|
-
}
|
|
1366
|
-
}
|
|
1367
|
-
|
|
1368
|
-
warnLog(...log: any[]): void {
|
|
1369
|
-
if (this.enablingDeviceLogging()) {
|
|
1370
|
-
this.platform.log.warn(String(...log));
|
|
1371
|
-
}
|
|
1372
|
-
}
|
|
1373
|
-
|
|
1374
|
-
debugWarnLog(...log: any[]): void {
|
|
1375
|
-
if (this.enablingDeviceLogging()) {
|
|
1376
|
-
if (this.deviceLogging?.includes('debug')) {
|
|
1377
|
-
this.platform.log.warn('[DEBUG]', String(...log));
|
|
1378
|
-
}
|
|
1379
|
-
}
|
|
1380
|
-
}
|
|
1381
|
-
|
|
1382
|
-
errorLog(...log: any[]): void {
|
|
1383
|
-
if (this.enablingDeviceLogging()) {
|
|
1384
|
-
this.platform.log.error(String(...log));
|
|
1385
|
-
}
|
|
1386
|
-
}
|
|
1387
|
-
|
|
1388
|
-
debugErrorLog(...log: any[]): void {
|
|
1389
|
-
if (this.enablingDeviceLogging()) {
|
|
1390
|
-
if (this.deviceLogging?.includes('debug')) {
|
|
1391
|
-
this.platform.log.error('[DEBUG]', String(...log));
|
|
1392
|
-
}
|
|
1393
|
-
}
|
|
1394
|
-
}
|
|
1395
|
-
|
|
1396
|
-
debugLog(...log: any[]): void {
|
|
1397
|
-
if (this.enablingDeviceLogging()) {
|
|
1398
|
-
if (this.deviceLogging === 'debug') {
|
|
1399
|
-
this.platform.log.info('[DEBUG]', String(...log));
|
|
1400
|
-
} else {
|
|
1401
|
-
this.platform.log.debug(String(...log));
|
|
1402
|
-
}
|
|
1403
|
-
}
|
|
1404
|
-
}
|
|
1405
|
-
|
|
1406
|
-
enablingDeviceLogging(): boolean {
|
|
1407
|
-
return this.deviceLogging.includes('debug') || this.deviceLogging === 'standard';
|
|
1408
|
-
}
|
|
1409
954
|
}
|