@switchbot/homebridge-switchbot 3.5.0-beta.4 → 3.5.0-beta.41
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +4 -1
- package/config.schema.json +120 -17
- package/dist/device/blindtilt.d.ts +21 -94
- package/dist/device/blindtilt.d.ts.map +1 -1
- package/dist/device/blindtilt.js +351 -757
- package/dist/device/blindtilt.js.map +1 -1
- package/dist/device/bot.d.ts +25 -71
- package/dist/device/bot.d.ts.map +1 -1
- package/dist/device/bot.js +587 -761
- package/dist/device/bot.js.map +1 -1
- package/dist/device/ceilinglight.d.ts +13 -67
- package/dist/device/ceilinglight.d.ts.map +1 -1
- package/dist/device/ceilinglight.js +213 -588
- package/dist/device/ceilinglight.js.map +1 -1
- package/dist/device/colorbulb.d.ts +13 -74
- package/dist/device/colorbulb.d.ts.map +1 -1
- package/dist/device/colorbulb.js +255 -634
- package/dist/device/colorbulb.js.map +1 -1
- package/dist/device/contact.d.ts +14 -65
- package/dist/device/contact.d.ts.map +1 -1
- package/dist/device/contact.js +208 -532
- package/dist/device/contact.js.map +1 -1
- package/dist/device/curtain.d.ts +17 -86
- package/dist/device/curtain.d.ts.map +1 -1
- package/dist/device/curtain.js +339 -787
- package/dist/device/curtain.js.map +1 -1
- package/dist/device/device.d.ts +59 -0
- package/dist/device/device.d.ts.map +1 -0
- package/dist/device/device.js +671 -0
- package/dist/device/device.js.map +1 -0
- package/dist/device/fan.d.ts +51 -0
- package/dist/device/fan.d.ts.map +1 -0
- package/dist/device/fan.js +504 -0
- package/dist/device/fan.js.map +1 -0
- package/dist/device/hub.d.ts +15 -59
- package/dist/device/hub.d.ts.map +1 -1
- package/dist/device/hub.js +246 -597
- package/dist/device/hub.js.map +1 -1
- package/dist/device/humidifier.d.ts +10 -65
- package/dist/device/humidifier.d.ts.map +1 -1
- package/dist/device/humidifier.js +211 -572
- package/dist/device/humidifier.js.map +1 -1
- package/dist/device/iosensor.d.ts +11 -64
- package/dist/device/iosensor.d.ts.map +1 -1
- package/dist/device/iosensor.js +178 -585
- package/dist/device/iosensor.js.map +1 -1
- package/dist/device/lightstrip.d.ts +10 -68
- package/dist/device/lightstrip.d.ts.map +1 -1
- package/dist/device/lightstrip.js +256 -569
- package/dist/device/lightstrip.js.map +1 -1
- package/dist/device/lock.d.ts +15 -62
- package/dist/device/lock.d.ts.map +1 -1
- package/dist/device/lock.js +214 -543
- package/dist/device/lock.js.map +1 -1
- package/dist/device/meter.d.ts +13 -63
- package/dist/device/meter.d.ts.map +1 -1
- package/dist/device/meter.js +174 -578
- package/dist/device/meter.js.map +1 -1
- package/dist/device/meterplus.d.ts +13 -64
- package/dist/device/meterplus.d.ts.map +1 -1
- package/dist/device/meterplus.js +163 -578
- package/dist/device/meterplus.js.map +1 -1
- package/dist/device/motion.d.ts +13 -69
- package/dist/device/motion.d.ts.map +1 -1
- package/dist/device/motion.js +141 -520
- package/dist/device/motion.js.map +1 -1
- package/dist/device/plug.d.ts +9 -57
- package/dist/device/plug.d.ts.map +1 -1
- package/dist/device/plug.js +86 -453
- package/dist/device/plug.js.map +1 -1
- package/dist/device/robotvacuumcleaner.d.ts +11 -62
- package/dist/device/robotvacuumcleaner.d.ts.map +1 -1
- package/dist/device/robotvacuumcleaner.js +144 -452
- package/dist/device/robotvacuumcleaner.js.map +1 -1
- package/dist/device/waterdetector.d.ts +9 -70
- package/dist/device/waterdetector.d.ts.map +1 -1
- package/dist/device/waterdetector.js +125 -665
- package/dist/device/waterdetector.js.map +1 -1
- package/dist/homebridge-ui/public/index.html +2 -2
- package/dist/index.js +1 -1
- package/dist/irdevice/airconditioner.d.ts +8 -48
- package/dist/irdevice/airconditioner.d.ts.map +1 -1
- package/dist/irdevice/airconditioner.js +309 -419
- package/dist/irdevice/airconditioner.js.map +1 -1
- package/dist/irdevice/airpurifier.d.ts +7 -38
- package/dist/irdevice/airpurifier.d.ts.map +1 -1
- package/dist/irdevice/airpurifier.js +72 -304
- package/dist/irdevice/airpurifier.js.map +1 -1
- package/dist/irdevice/camera.d.ts +6 -35
- package/dist/irdevice/camera.d.ts.map +1 -1
- package/dist/irdevice/camera.js +34 -278
- package/dist/irdevice/camera.js.map +1 -1
- package/dist/irdevice/fan.d.ts +6 -39
- package/dist/irdevice/fan.d.ts.map +1 -1
- package/dist/irdevice/fan.js +67 -311
- package/dist/irdevice/fan.js.map +1 -1
- package/dist/irdevice/irdevice.d.ts +40 -0
- package/dist/irdevice/irdevice.d.ts.map +1 -0
- package/dist/irdevice/irdevice.js +512 -0
- package/dist/irdevice/irdevice.js.map +1 -0
- package/dist/irdevice/light.d.ts +6 -34
- package/dist/irdevice/light.d.ts.map +1 -1
- package/dist/irdevice/light.js +23 -272
- package/dist/irdevice/light.js.map +1 -1
- package/dist/irdevice/other.d.ts +18 -47
- package/dist/irdevice/other.d.ts.map +1 -1
- package/dist/irdevice/other.js +352 -546
- package/dist/irdevice/other.js.map +1 -1
- package/dist/irdevice/tv.d.ts +7 -39
- package/dist/irdevice/tv.d.ts.map +1 -1
- package/dist/irdevice/tv.js +82 -321
- package/dist/irdevice/tv.js.map +1 -1
- package/dist/irdevice/vacuumcleaner.d.ts +6 -35
- package/dist/irdevice/vacuumcleaner.d.ts.map +1 -1
- package/dist/irdevice/vacuumcleaner.js +41 -284
- package/dist/irdevice/vacuumcleaner.js.map +1 -1
- package/dist/irdevice/waterheater.d.ts +6 -35
- package/dist/irdevice/waterheater.d.ts.map +1 -1
- package/dist/irdevice/waterheater.js +42 -287
- package/dist/irdevice/waterheater.js.map +1 -1
- package/dist/platform.d.ts +14 -1
- package/dist/platform.d.ts.map +1 -1
- package/dist/platform.js +343 -198
- package/dist/platform.js.map +1 -1
- package/dist/settings.d.ts +41 -11
- package/dist/settings.d.ts.map +1 -1
- package/dist/settings.js +0 -552
- package/dist/settings.js.map +1 -1
- package/dist/utils.d.ts +77 -0
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +638 -1
- package/dist/utils.js.map +1 -1
- package/package.json +16 -15
- package/src/custom.d.ts +2 -1
- package/src/device/blindtilt.ts +377 -783
- package/src/device/bot.ts +620 -845
- package/src/device/ceilinglight.ts +226 -608
- package/src/device/colorbulb.ts +268 -657
- package/src/device/contact.ts +233 -554
- package/src/device/curtain.ts +359 -811
- package/src/device/device.ts +699 -0
- package/src/device/fan.ts +553 -0
- package/src/device/hub.ts +273 -625
- package/src/device/humidifier.ts +241 -619
- package/src/device/iosensor.ts +204 -611
- package/src/device/lightstrip.ts +277 -597
- package/src/device/lock.ts +251 -583
- package/src/device/meter.ts +199 -601
- package/src/device/meterplus.ts +188 -603
- package/src/device/motion.ts +160 -542
- package/src/device/plug.ts +96 -481
- package/src/device/robotvacuumcleaner.ts +165 -478
- package/src/device/waterdetector.ts +142 -689
- package/src/homebridge-ui/public/index.html +2 -2
- package/src/index.ts +1 -1
- package/src/irdevice/airconditioner.ts +330 -446
- package/src/irdevice/airpurifier.ts +89 -321
- package/src/irdevice/camera.ts +42 -293
- package/src/irdevice/fan.ts +78 -327
- package/src/irdevice/irdevice.ts +528 -0
- package/src/irdevice/light.ts +32 -287
- package/src/irdevice/other.ts +396 -615
- package/src/irdevice/tv.ts +100 -339
- package/src/irdevice/vacuumcleaner.ts +49 -305
- package/src/irdevice/waterheater.ts +50 -310
- package/src/platform.ts +353 -206
- package/src/settings.ts +57 -566
- package/src/utils.ts +642 -1
package/src/device/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,197 @@ 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
|
-
//
|
|
510
|
-
this.
|
|
511
|
-
|
|
466
|
+
// Firmware Version
|
|
467
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Firmware Version: ${deviceStatus.body.version}`);
|
|
468
|
+
if (deviceStatus.body.version) {
|
|
469
|
+
this.accessory.context.version = deviceStatus.body.version;
|
|
470
|
+
this.accessory
|
|
471
|
+
.getService(this.hap.Service.AccessoryInformation)!
|
|
472
|
+
.setCharacteristic(this.hap.Characteristic.FirmwareRevision, this.accessory.context.version)
|
|
473
|
+
.getCharacteristic(this.hap.Characteristic.FirmwareRevision)
|
|
474
|
+
.updateValue(this.accessory.context.version);
|
|
475
|
+
}
|
|
512
476
|
}
|
|
513
477
|
|
|
514
478
|
async refreshStatus(): Promise<void> {
|
|
@@ -538,118 +502,45 @@ export class Curtain {
|
|
|
538
502
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
|
|
539
503
|
this.getCustomBLEAddress(switchbot);
|
|
540
504
|
// 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
505
|
(async () => {
|
|
550
506
|
// Start to monitor advertisement packets
|
|
551
|
-
await switchbot.startScan({
|
|
552
|
-
model: model,
|
|
553
|
-
id: this.device.bleMac,
|
|
554
|
-
});
|
|
507
|
+
await switchbot.startScan({ model: this.device.bleModel, id: this.device.bleMac });
|
|
555
508
|
// Set an event handler
|
|
556
509
|
switchbot.onadvertisement = (ad: any) => {
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
510
|
+
if (this.device.bleMac === ad.address && ad.model === this.device.bleModel) {
|
|
511
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} ${JSON.stringify(ad, null, ' ')}`);
|
|
512
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} address: ${ad.address}, model: ${ad.model}`);
|
|
560
513
|
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
514
|
} else {
|
|
567
515
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${JSON.stringify(ad.serviceData)}`);
|
|
568
516
|
}
|
|
569
517
|
};
|
|
570
|
-
// Wait
|
|
518
|
+
// Wait 10 seconds
|
|
571
519
|
await switchbot.wait(this.scanDuration * 1000);
|
|
572
520
|
// Stop to monitor
|
|
573
521
|
await switchbot.stopScan();
|
|
574
522
|
// Update HomeKit
|
|
575
|
-
await this.BLEparseStatus();
|
|
523
|
+
await this.BLEparseStatus(switchbot.onadvertisement.serviceData);
|
|
576
524
|
await this.updateHomeKitCharacteristics();
|
|
577
525
|
})();
|
|
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 {
|
|
526
|
+
if (switchbot === undefined) {
|
|
630
527
|
await this.BLERefreshConnection(switchbot);
|
|
631
|
-
}
|
|
528
|
+
}
|
|
632
529
|
}
|
|
633
530
|
|
|
634
531
|
async openAPIRefreshStatus(): Promise<void> {
|
|
635
532
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus`);
|
|
636
533
|
try {
|
|
637
|
-
const { body, statusCode } = await
|
|
638
|
-
headers: this.platform.generateHeaders()
|
|
639
|
-
});
|
|
534
|
+
const { body, statusCode } = await this.platform.retryRequest(this.deviceMaxRetries, this.deviceDelayBetweenRetries,
|
|
535
|
+
`${Devices}/${this.device.deviceId}/status`, { headers: this.platform.generateHeaders() });
|
|
640
536
|
this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} statusCode: ${statusCode}`);
|
|
641
537
|
const deviceStatus: any = await body.json();
|
|
642
538
|
this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus: ${JSON.stringify(deviceStatus)}`);
|
|
643
539
|
this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus statusCode: ${deviceStatus.statusCode}`);
|
|
644
540
|
if ((statusCode === 200 || statusCode === 100) && (deviceStatus.statusCode === 200 || deviceStatus.statusCode === 100)) {
|
|
645
|
-
this.
|
|
541
|
+
this.debugSuccessLog(`${this.device.deviceType}: ${this.accessory.displayName} `
|
|
646
542
|
+ `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();
|
|
543
|
+
this.openAPIparseStatus(deviceStatus);
|
|
653
544
|
this.updateHomeKitCharacteristics();
|
|
654
545
|
} else {
|
|
655
546
|
this.statusCode(statusCode);
|
|
@@ -688,7 +579,7 @@ export class Curtain {
|
|
|
688
579
|
|
|
689
580
|
async BLEpushChanges(): Promise<void> {
|
|
690
581
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLEpushChanges`);
|
|
691
|
-
if (this.TargetPosition !== this.CurrentPosition) {
|
|
582
|
+
if (this.WindowCovering.TargetPosition !== this.WindowCovering.CurrentPosition) {
|
|
692
583
|
const switchbot = await this.platform.connectBLE();
|
|
693
584
|
// Convert to BLE Address
|
|
694
585
|
this.device.bleMac = this.device
|
|
@@ -696,27 +587,29 @@ export class Curtain {
|
|
|
696
587
|
.join(':')
|
|
697
588
|
.toLowerCase();
|
|
698
589
|
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: ${
|
|
590
|
+
const { setPositionMode, Mode }: { setPositionMode: number; Mode: string; } = await this.setPerformance();
|
|
591
|
+
const adjustedMode = setPositionMode === 1 ? 0x01 : 0xff;
|
|
592
|
+
this.debugLog(`${this.accessory.displayName} Mode: ${Mode}`);
|
|
702
593
|
if (switchbot !== false) {
|
|
703
594
|
try {
|
|
704
595
|
const device_list = await switchbot.discover({ model: 'c', quick: true, id: this.device.bleMac });
|
|
705
|
-
this.infoLog(`${this.accessory.displayName} Target Position: ${this.TargetPosition}`);
|
|
596
|
+
this.infoLog(`${this.accessory.displayName} Target Position: ${this.WindowCovering.TargetPosition}`);
|
|
706
597
|
|
|
707
|
-
await this.
|
|
708
|
-
max: this.
|
|
598
|
+
await this.retryBLE({
|
|
599
|
+
max: await this.maxRetryBLE(),
|
|
709
600
|
fn: async () => {
|
|
710
|
-
await device_list[0].runToPos(100 - Number(this.TargetPosition), adjustedMode);
|
|
601
|
+
await device_list[0].runToPos(100 - Number(this.WindowCovering.TargetPosition), adjustedMode);
|
|
711
602
|
},
|
|
712
603
|
});
|
|
713
604
|
|
|
714
605
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Done.`);
|
|
606
|
+
this.successLog(`${this.device.deviceType}: ${this.accessory.displayName} `
|
|
607
|
+
+ `TargetPosition: ${this.WindowCovering.TargetPosition} sent over BLE, sent successfully`);
|
|
715
608
|
} catch (e) {
|
|
716
609
|
this.apiError(e);
|
|
717
610
|
this.errorLog(
|
|
718
611
|
`${this.device.deviceType}: ${this.accessory.displayName} failed BLEpushChanges with ${this.device.connectionType}` +
|
|
719
|
-
|
|
612
|
+
` Connection, Error Message: ${JSON.stringify((e as Error).message)}`,
|
|
720
613
|
);
|
|
721
614
|
await this.BLEPushConnection();
|
|
722
615
|
throw new Error('Connection error');
|
|
@@ -728,54 +621,23 @@ export class Curtain {
|
|
|
728
621
|
} else {
|
|
729
622
|
this.debugLog(
|
|
730
623
|
`${this.device.deviceType}: ${this.accessory.displayName} No BLEpushChanges, CurrentPosition & TargetPosition Are the Same.` +
|
|
731
|
-
` CurrentPosition: ${this.CurrentPosition}, TargetPosition ${this.TargetPosition}`,
|
|
624
|
+
` CurrentPosition: ${this.WindowCovering.CurrentPosition}, TargetPosition ${this.WindowCovering.TargetPosition}`,
|
|
732
625
|
);
|
|
733
626
|
}
|
|
734
627
|
}
|
|
735
628
|
|
|
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
629
|
async openAPIpushChanges(): Promise<void> {
|
|
757
630
|
let command: string;
|
|
758
631
|
let parameter: string;
|
|
759
632
|
let commandType: string;
|
|
760
633
|
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) {
|
|
634
|
+
if (this.WindowCovering.TargetPosition !== this.WindowCovering.CurrentPosition || this.device.disableCaching) {
|
|
635
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Pushing ${this.WindowCovering.TargetPosition}`);
|
|
636
|
+
const adjustedTargetPosition = 100 - Number(this.WindowCovering.TargetPosition);
|
|
637
|
+
const { setPositionMode, Mode }: { setPositionMode: number; Mode: string; } = await this.setPerformance();
|
|
638
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Mode: ${Mode}`);
|
|
639
|
+
const adjustedMode = setPositionMode || 'ff';
|
|
640
|
+
if (this.WindowCovering.HoldPosition) {
|
|
779
641
|
command = 'pause';
|
|
780
642
|
parameter = 'default';
|
|
781
643
|
commandType = 'command';
|
|
@@ -804,6 +666,8 @@ export class Curtain {
|
|
|
804
666
|
if ((statusCode === 200 || statusCode === 100) && (deviceStatus.statusCode === 200 || deviceStatus.statusCode === 100)) {
|
|
805
667
|
this.debugErrorLog(`${this.device.deviceType}: ${this.accessory.displayName} `
|
|
806
668
|
+ `statusCode: ${statusCode} & deviceStatus StatusCode: ${deviceStatus.statusCode}`);
|
|
669
|
+
this.successLog(`${this.device.deviceType}: ${this.accessory.displayName} `
|
|
670
|
+
+ `request to SwitchBot API, body: ${deviceStatus} sent successfully`);
|
|
807
671
|
} else {
|
|
808
672
|
this.statusCode(statusCode);
|
|
809
673
|
this.statusCode(deviceStatus.statusCode);
|
|
@@ -818,7 +682,7 @@ export class Curtain {
|
|
|
818
682
|
} else {
|
|
819
683
|
this.debugLog(
|
|
820
684
|
`${this.device.deviceType}: ${this.accessory.displayName} No OpenAPI Changes, CurrentPosition & TargetPosition Are the Same.` +
|
|
821
|
-
` CurrentPosition: ${this.CurrentPosition}, TargetPosition ${this.TargetPosition}`,
|
|
685
|
+
` CurrentPosition: ${this.WindowCovering.CurrentPosition}, TargetPosition ${this.WindowCovering.TargetPosition}`,
|
|
822
686
|
);
|
|
823
687
|
}
|
|
824
688
|
}
|
|
@@ -827,50 +691,53 @@ export class Curtain {
|
|
|
827
691
|
* Handle requests to set the value of the "Target Position" characteristic
|
|
828
692
|
*/
|
|
829
693
|
async TargetPositionSet(value: CharacteristicValue): Promise<void> {
|
|
830
|
-
if (this.TargetPosition === this.accessory.context.TargetPosition) {
|
|
694
|
+
if (this.WindowCovering.TargetPosition === this.accessory.context.TargetPosition) {
|
|
831
695
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} No Changes, Set TargetPosition: ${value}`);
|
|
832
696
|
} else {
|
|
833
697
|
this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Set TargetPosition: ${value}`);
|
|
834
698
|
}
|
|
835
699
|
|
|
836
700
|
// Set HoldPosition to false when TargetPosition is changed
|
|
837
|
-
this.HoldPosition = false;
|
|
838
|
-
this.
|
|
701
|
+
this.WindowCovering.HoldPosition = false;
|
|
702
|
+
this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.HoldPosition, this.WindowCovering.HoldPosition);
|
|
839
703
|
|
|
840
|
-
this.TargetPosition = value;
|
|
704
|
+
this.WindowCovering.TargetPosition = value;
|
|
841
705
|
if (this.device.mqttURL) {
|
|
842
|
-
this.mqttPublish('TargetPosition', this.TargetPosition);
|
|
843
|
-
this.mqttPublish('HoldPosition', this.HoldPosition);
|
|
706
|
+
this.mqttPublish('TargetPosition', this.WindowCovering.TargetPosition.toString());
|
|
707
|
+
this.mqttPublish('HoldPosition', this.WindowCovering.HoldPosition.toString()); // Convert boolean to string
|
|
844
708
|
}
|
|
845
709
|
|
|
846
710
|
await this.setMinMax();
|
|
847
|
-
if (value > this.CurrentPosition) {
|
|
848
|
-
this.PositionState = this.hap.Characteristic.PositionState.INCREASING;
|
|
711
|
+
if (value > this.WindowCovering.CurrentPosition) {
|
|
712
|
+
this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.INCREASING;
|
|
849
713
|
this.setNewTarget = true;
|
|
850
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} value: ${value}
|
|
851
|
-
|
|
852
|
-
|
|
714
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} value: ${value},`
|
|
715
|
+
+ ` CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
|
|
716
|
+
} else if (value < this.WindowCovering.CurrentPosition) {
|
|
717
|
+
this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.DECREASING;
|
|
853
718
|
this.setNewTarget = true;
|
|
854
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} value: ${value}
|
|
719
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} value: ${value},`
|
|
720
|
+
+ ` CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
|
|
855
721
|
} else {
|
|
856
|
-
this.PositionState = this.hap.Characteristic.PositionState.STOPPED;
|
|
722
|
+
this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.STOPPED;
|
|
857
723
|
this.setNewTarget = false;
|
|
858
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} value: ${value}
|
|
724
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} value: ${value},`
|
|
725
|
+
+ ` CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
|
|
859
726
|
}
|
|
860
|
-
this.
|
|
861
|
-
this.
|
|
727
|
+
this.WindowCovering.Service.setCharacteristic(this.hap.Characteristic.PositionState, this.WindowCovering.PositionState);
|
|
728
|
+
this.WindowCovering.Service.getCharacteristic(this.hap.Characteristic.PositionState).updateValue(this.WindowCovering.PositionState);
|
|
862
729
|
|
|
863
730
|
/**
|
|
864
731
|
* If Curtain movement time is short, the moving flag from backend is always false.
|
|
865
732
|
* The minimum time depends on the network control latency.
|
|
866
733
|
*/
|
|
867
734
|
clearTimeout(this.setNewTargetTimer);
|
|
868
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateRate: ${this.
|
|
735
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateRate: ${this.deviceUpdateRate}`);
|
|
869
736
|
if (this.setNewTarget) {
|
|
870
737
|
this.setNewTargetTimer = setTimeout(() => {
|
|
871
738
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} setNewTarget ${this.setNewTarget} timeout`);
|
|
872
739
|
this.setNewTarget = false;
|
|
873
|
-
}, this.
|
|
740
|
+
}, this.deviceUpdateRate * 1000);
|
|
874
741
|
}
|
|
875
742
|
this.doCurtainUpdate.next();
|
|
876
743
|
}
|
|
@@ -880,153 +747,98 @@ export class Curtain {
|
|
|
880
747
|
*/
|
|
881
748
|
async HoldPositionSet(value: CharacteristicValue): Promise<void> {
|
|
882
749
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} HoldPosition: ${value}`);
|
|
883
|
-
this.HoldPosition = value;
|
|
750
|
+
this.WindowCovering.HoldPosition = value;
|
|
884
751
|
this.doCurtainUpdate.next();
|
|
885
752
|
}
|
|
886
753
|
|
|
887
754
|
async updateHomeKitCharacteristics(): Promise<void> {
|
|
888
755
|
await this.setMinMax();
|
|
889
|
-
if (this.CurrentPosition === undefined || Number.isNaN(this.CurrentPosition)) {
|
|
890
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} CurrentPosition: ${this.CurrentPosition}`);
|
|
756
|
+
if (this.WindowCovering.CurrentPosition === undefined || Number.isNaN(this.WindowCovering.CurrentPosition)) {
|
|
757
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
|
|
891
758
|
} else {
|
|
759
|
+
this.accessory.context.CurrentPosition = this.WindowCovering.CurrentPosition;
|
|
760
|
+
this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.CurrentPosition, Number(this.WindowCovering.CurrentPosition));
|
|
761
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic`
|
|
762
|
+
+ ` CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
|
|
892
763
|
if (this.device.mqttURL) {
|
|
893
|
-
this.mqttPublish('CurrentPosition', this.CurrentPosition);
|
|
764
|
+
this.mqttPublish('CurrentPosition', this.WindowCovering.CurrentPosition.toString()); // Convert to string
|
|
894
765
|
}
|
|
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
766
|
}
|
|
899
|
-
if (this.PositionState === undefined) {
|
|
900
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} PositionState: ${this.PositionState}`);
|
|
767
|
+
if (this.WindowCovering.PositionState === undefined) {
|
|
768
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} PositionState: ${this.WindowCovering.PositionState}`);
|
|
901
769
|
} else {
|
|
902
770
|
if (this.device.mqttURL) {
|
|
903
|
-
this.mqttPublish('PositionState', this.PositionState);
|
|
771
|
+
this.mqttPublish('PositionState', this.WindowCovering.PositionState.toString());
|
|
904
772
|
}
|
|
905
|
-
this.accessory.context.PositionState = this.PositionState;
|
|
906
|
-
this.
|
|
907
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic
|
|
773
|
+
this.accessory.context.PositionState = this.WindowCovering.PositionState;
|
|
774
|
+
this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.PositionState, Number(this.WindowCovering.PositionState));
|
|
775
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic`
|
|
776
|
+
+ ` PositionState: ${this.WindowCovering.PositionState}`);
|
|
908
777
|
}
|
|
909
|
-
if (this.TargetPosition === undefined || Number.isNaN(this.TargetPosition)) {
|
|
910
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} TargetPosition: ${this.TargetPosition}`);
|
|
778
|
+
if (this.WindowCovering.TargetPosition === undefined || Number.isNaN(this.WindowCovering.TargetPosition)) {
|
|
779
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} TargetPosition: ${this.WindowCovering.TargetPosition}`);
|
|
911
780
|
} else {
|
|
912
781
|
if (this.device.mqttURL) {
|
|
913
|
-
this.mqttPublish('TargetPosition', this.TargetPosition);
|
|
782
|
+
this.mqttPublish('TargetPosition', this.WindowCovering.TargetPosition.toString());
|
|
914
783
|
}
|
|
915
|
-
this.accessory.context.TargetPosition = this.TargetPosition;
|
|
916
|
-
this.
|
|
917
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic
|
|
784
|
+
this.accessory.context.TargetPosition = this.WindowCovering.TargetPosition;
|
|
785
|
+
this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.TargetPosition, Number(this.WindowCovering.TargetPosition));
|
|
786
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic`
|
|
787
|
+
+ ` TargetPosition: ${this.WindowCovering.TargetPosition}`);
|
|
918
788
|
}
|
|
919
|
-
if (this.HoldPosition === undefined) {
|
|
920
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} HoldPosition: ${this.HoldPosition}`);
|
|
789
|
+
if (this.WindowCovering.HoldPosition === undefined) {
|
|
790
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} HoldPosition: ${this.WindowCovering.HoldPosition}`);
|
|
921
791
|
} else {
|
|
922
792
|
if (this.device.mqttURL) {
|
|
923
|
-
this.mqttPublish('HoldPosition', this.HoldPosition);
|
|
793
|
+
this.mqttPublish('HoldPosition', this.WindowCovering.HoldPosition.toString());
|
|
924
794
|
}
|
|
925
|
-
this.accessory.context.HoldPosition = this.HoldPosition;
|
|
926
|
-
this.
|
|
927
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic
|
|
795
|
+
this.accessory.context.HoldPosition = this.WindowCovering.HoldPosition;
|
|
796
|
+
this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.HoldPosition, this.WindowCovering.HoldPosition);
|
|
797
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic`
|
|
798
|
+
+ ` HoldPosition: ${this.WindowCovering.HoldPosition}`);
|
|
928
799
|
}
|
|
929
800
|
if (!this.device.curtain?.hide_lightsensor) {
|
|
930
|
-
if (this.CurrentAmbientLightLevel === undefined || Number.isNaN(this.CurrentAmbientLightLevel)) {
|
|
931
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}
|
|
801
|
+
if (this.LightSensor!.CurrentAmbientLightLevel === undefined || Number.isNaN(this.LightSensor!.CurrentAmbientLightLevel)) {
|
|
802
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}`
|
|
803
|
+
+ ` CurrentAmbientLightLevel: ${this.LightSensor!.CurrentAmbientLightLevel}`);
|
|
932
804
|
} else {
|
|
933
805
|
if (this.device.mqttURL) {
|
|
934
|
-
this.mqttPublish('CurrentAmbientLightLevel', this.CurrentAmbientLightLevel);
|
|
806
|
+
this.mqttPublish('CurrentAmbientLightLevel', this.LightSensor!.CurrentAmbientLightLevel.toString());
|
|
935
807
|
}
|
|
936
|
-
this.accessory.context.CurrentAmbientLightLevel = this.CurrentAmbientLightLevel;
|
|
937
|
-
this.
|
|
808
|
+
this.accessory.context.CurrentAmbientLightLevel = this.LightSensor!.CurrentAmbientLightLevel;
|
|
809
|
+
this.LightSensor!.Service.updateCharacteristic(this.hap.Characteristic.CurrentAmbientLightLevel, this.LightSensor!.CurrentAmbientLightLevel);
|
|
938
810
|
this.debugLog(
|
|
939
811
|
`${this.device.deviceType}: ${this.accessory.displayName}` +
|
|
940
|
-
` updateCharacteristic CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`,
|
|
812
|
+
` updateCharacteristic CurrentAmbientLightLevel: ${this.LightSensor!.CurrentAmbientLightLevel}`,
|
|
941
813
|
);
|
|
942
814
|
if (this.device.history) {
|
|
943
815
|
this.historyService?.addEntry({
|
|
944
816
|
time: Math.round(new Date().valueOf() / 1000),
|
|
945
|
-
lux: this.CurrentAmbientLightLevel,
|
|
817
|
+
lux: this.LightSensor!.CurrentAmbientLightLevel,
|
|
946
818
|
});
|
|
947
819
|
}
|
|
948
820
|
}
|
|
949
821
|
}
|
|
950
|
-
if (this.BatteryLevel === undefined) {
|
|
951
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.BatteryLevel}`);
|
|
822
|
+
if (this.Battery.BatteryLevel === undefined) {
|
|
823
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.Battery.BatteryLevel}`);
|
|
952
824
|
} else {
|
|
953
825
|
if (this.device.mqttURL) {
|
|
954
|
-
this.mqttPublish('BatteryLevel', this.BatteryLevel);
|
|
826
|
+
this.mqttPublish('BatteryLevel', this.Battery.BatteryLevel.toString());
|
|
955
827
|
}
|
|
956
|
-
this.accessory.context.BatteryLevel = this.BatteryLevel;
|
|
957
|
-
this.
|
|
958
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic BatteryLevel: ${this.BatteryLevel}`);
|
|
828
|
+
this.accessory.context.BatteryLevel = this.Battery.BatteryLevel;
|
|
829
|
+
this.Battery.Service.updateCharacteristic(this.hap.Characteristic.BatteryLevel, this.Battery.BatteryLevel);
|
|
830
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic BatteryLevel: ${this.Battery.BatteryLevel}`);
|
|
959
831
|
}
|
|
960
|
-
if (this.StatusLowBattery === undefined) {
|
|
961
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} StatusLowBattery: ${this.StatusLowBattery}`);
|
|
832
|
+
if (this.Battery.StatusLowBattery === undefined) {
|
|
833
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} StatusLowBattery: ${this.Battery.StatusLowBattery}`);
|
|
962
834
|
} else {
|
|
963
835
|
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}`);
|
|
836
|
+
this.mqttPublish('StatusLowBattery', this.Battery.StatusLowBattery.toString());
|
|
1001
837
|
}
|
|
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
|
-
})();
|
|
838
|
+
this.accessory.context.StatusLowBattery = this.Battery.StatusLowBattery;
|
|
839
|
+
this.Battery.Service.updateCharacteristic(this.hap.Characteristic.StatusLowBattery, this.Battery.StatusLowBattery);
|
|
840
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic`
|
|
841
|
+
+ ` StatusLowBattery: ${this.Battery.StatusLowBattery}`);
|
|
1030
842
|
}
|
|
1031
843
|
}
|
|
1032
844
|
|
|
@@ -1046,364 +858,100 @@ export class Curtain {
|
|
|
1046
858
|
}
|
|
1047
859
|
}
|
|
1048
860
|
|
|
1049
|
-
async
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
861
|
+
async setPerformance() {
|
|
862
|
+
let setPositionMode: number;
|
|
863
|
+
let Mode: string;
|
|
864
|
+
if (Number(this.WindowCovering.TargetPosition) > 50) {
|
|
865
|
+
if (this.device.blindTilt?.setOpenMode === '1') {
|
|
866
|
+
setPositionMode = 1;
|
|
867
|
+
Mode = 'Silent Mode';
|
|
868
|
+
} else if (this.device.blindTilt?.setOpenMode === '0') {
|
|
869
|
+
setPositionMode = 0;
|
|
870
|
+
Mode = 'Performance Mode';
|
|
1054
871
|
} else {
|
|
1055
|
-
|
|
1056
|
-
|
|
872
|
+
setPositionMode = 0;
|
|
873
|
+
Mode = 'Default Mode';
|
|
1057
874
|
}
|
|
1058
875
|
} else {
|
|
1059
|
-
if (this.device.
|
|
1060
|
-
|
|
1061
|
-
|
|
876
|
+
if (this.device.blindTilt?.setCloseMode === '1') {
|
|
877
|
+
setPositionMode = 1;
|
|
878
|
+
Mode = 'Silent Mode';
|
|
879
|
+
} else if (this.device.blindTilt?.setOpenMode === '0') {
|
|
880
|
+
setPositionMode = 0;
|
|
881
|
+
Mode = 'Performance Mode';
|
|
1062
882
|
} else {
|
|
1063
|
-
|
|
1064
|
-
|
|
883
|
+
setPositionMode = 0;
|
|
884
|
+
Mode = 'Default Mode';
|
|
1065
885
|
}
|
|
1066
886
|
}
|
|
887
|
+
return { setPositionMode, Mode };
|
|
1067
888
|
}
|
|
1068
889
|
|
|
1069
890
|
async setMinMax(): Promise<void> {
|
|
1070
891
|
if (this.device.curtain?.set_min) {
|
|
1071
|
-
if (Number(this.CurrentPosition) <= this.device.curtain?.set_min) {
|
|
1072
|
-
this.CurrentPosition = 0;
|
|
892
|
+
if (Number(this.WindowCovering.CurrentPosition) <= this.device.curtain?.set_min) {
|
|
893
|
+
this.WindowCovering.CurrentPosition = 0;
|
|
1073
894
|
}
|
|
1074
895
|
}
|
|
1075
896
|
if (this.device.curtain?.set_max) {
|
|
1076
|
-
if (Number(this.CurrentPosition) >= this.device.curtain?.set_max) {
|
|
1077
|
-
this.CurrentPosition = 100;
|
|
897
|
+
if (Number(this.WindowCovering.CurrentPosition) >= this.device.curtain?.set_max) {
|
|
898
|
+
this.WindowCovering.CurrentPosition = 100;
|
|
1078
899
|
}
|
|
1079
900
|
}
|
|
1080
901
|
if (this.device.history) {
|
|
1081
902
|
const motion = this.accessory.getService(this.hap.Service.MotionSensor);
|
|
1082
|
-
const state = Number(this.CurrentPosition) > 0 ? 1 : 0;
|
|
903
|
+
const state = Number(this.WindowCovering.CurrentPosition) > 0 ? 1 : 0;
|
|
1083
904
|
motion?.updateCharacteristic(this.hap.Characteristic.MotionDetected, state);
|
|
1084
905
|
}
|
|
1085
906
|
}
|
|
1086
907
|
|
|
1087
908
|
minStep(device: device & devicesConfig): number {
|
|
909
|
+
let set_minStep: number;
|
|
1088
910
|
if (device.curtain?.set_minStep) {
|
|
1089
|
-
|
|
911
|
+
set_minStep = device.curtain?.set_minStep;
|
|
1090
912
|
} else {
|
|
1091
|
-
|
|
913
|
+
set_minStep = 1;
|
|
1092
914
|
}
|
|
1093
|
-
return
|
|
915
|
+
return set_minStep;
|
|
1094
916
|
}
|
|
1095
917
|
|
|
1096
|
-
minLux(): number {
|
|
918
|
+
async minLux(): Promise<number> {
|
|
919
|
+
let set_minLux: number;
|
|
1097
920
|
if (this.device.curtain?.set_minLux) {
|
|
1098
|
-
|
|
921
|
+
set_minLux = this.device.curtain?.set_minLux;
|
|
1099
922
|
} else {
|
|
1100
|
-
|
|
923
|
+
set_minLux = 1;
|
|
1101
924
|
}
|
|
1102
|
-
return
|
|
925
|
+
return set_minLux;
|
|
1103
926
|
}
|
|
1104
927
|
|
|
1105
|
-
maxLux(): number {
|
|
928
|
+
async maxLux(): Promise<number> {
|
|
929
|
+
let set_maxLux: number;
|
|
1106
930
|
if (this.device.curtain?.set_maxLux) {
|
|
1107
|
-
|
|
1108
|
-
} else {
|
|
1109
|
-
this.set_maxLux = 6001;
|
|
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
|
-
}
|
|
931
|
+
set_maxLux = this.device.curtain?.set_maxLux;
|
|
1130
932
|
} else {
|
|
1131
|
-
|
|
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
|
-
);
|
|
933
|
+
set_maxLux = 6001;
|
|
1217
934
|
}
|
|
935
|
+
return set_maxLux;
|
|
1218
936
|
}
|
|
1219
937
|
|
|
1220
938
|
async offlineOff(): Promise<void> {
|
|
1221
939
|
if (this.device.offline) {
|
|
1222
|
-
|
|
1223
|
-
|
|
940
|
+
this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.CurrentPosition, 100);
|
|
941
|
+
this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.TargetPosition, 100);
|
|
942
|
+
this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.PositionState, this.hap.Characteristic.PositionState.STOPPED);
|
|
1224
943
|
}
|
|
1225
944
|
}
|
|
1226
945
|
|
|
1227
946
|
async apiError(e: any): Promise<void> {
|
|
1228
|
-
this.
|
|
1229
|
-
this.
|
|
1230
|
-
this.
|
|
947
|
+
this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.CurrentPosition, e);
|
|
948
|
+
this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.PositionState, e);
|
|
949
|
+
this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.TargetPosition, e);
|
|
1231
950
|
if (!this.device.curtain?.hide_lightsensor) {
|
|
1232
|
-
this.
|
|
951
|
+
this.LightSensor!.Service.updateCharacteristic(this.hap.Characteristic.CurrentAmbientLightLevel, e);
|
|
1233
952
|
}
|
|
1234
|
-
this.
|
|
1235
|
-
this.
|
|
953
|
+
this.Battery.Service.updateCharacteristic(this.hap.Characteristic.BatteryLevel, e);
|
|
954
|
+
this.Battery.Service.updateCharacteristic(this.hap.Characteristic.StatusLowBattery, e);
|
|
1236
955
|
//throw new this.platform.api.hap.HapStatusError(HAPStatus.SERVICE_COMMUNICATION_FAILURE);
|
|
1237
956
|
}
|
|
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
957
|
}
|