@switchbot/homebridge-switchbot 3.7.1-beta.2 → 3.7.1-beta.21
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 +10 -0
- package/README.md +14 -0
- package/assets/security-privacy-bluetooth.png +0 -0
- package/config.schema.json +74 -2
- package/dist/device/blindtilt.d.ts +21 -9
- package/dist/device/blindtilt.d.ts.map +1 -1
- package/dist/device/blindtilt.js +167 -96
- package/dist/device/blindtilt.js.map +1 -1
- package/dist/device/bot-old.d.ts +132 -0
- package/dist/device/bot-old.d.ts.map +1 -0
- package/dist/device/bot-old.js +1482 -0
- package/dist/device/bot-old.js.map +1 -0
- package/dist/device/bot.d.ts +10 -9
- package/dist/device/bot.d.ts.map +1 -1
- package/dist/device/bot.js +186 -187
- package/dist/device/bot.js.map +1 -1
- package/dist/device/ceilinglight.d.ts +14 -13
- package/dist/device/ceilinglight.d.ts.map +1 -1
- package/dist/device/ceilinglight.js +87 -97
- package/dist/device/ceilinglight.js.map +1 -1
- package/dist/device/colorbulb.d.ts +13 -12
- package/dist/device/colorbulb.d.ts.map +1 -1
- package/dist/device/colorbulb.js +92 -105
- package/dist/device/colorbulb.js.map +1 -1
- package/dist/device/contact.d.ts +6 -5
- package/dist/device/contact.d.ts.map +1 -1
- package/dist/device/contact.js +71 -68
- package/dist/device/contact.js.map +1 -1
- package/dist/device/curtain.d.ts +17 -5
- package/dist/device/curtain.d.ts.map +1 -1
- package/dist/device/curtain.js +184 -118
- package/dist/device/curtain.js.map +1 -1
- package/dist/device/device.d.ts +18 -18
- package/dist/device/device.d.ts.map +1 -1
- package/dist/device/device.js +33 -36
- package/dist/device/device.js.map +1 -1
- package/dist/device/fan.d.ts +9 -8
- package/dist/device/fan.d.ts.map +1 -1
- package/dist/device/fan.js +94 -101
- package/dist/device/fan.js.map +1 -1
- package/dist/device/hub.d.ts +6 -5
- package/dist/device/hub.d.ts.map +1 -1
- package/dist/device/hub.js +69 -65
- package/dist/device/hub.js.map +1 -1
- package/dist/device/humidifier.d.ts +6 -5
- package/dist/device/humidifier.d.ts.map +1 -1
- package/dist/device/humidifier.js +89 -104
- package/dist/device/humidifier.js.map +1 -1
- package/dist/device/iosensor.d.ts +6 -5
- package/dist/device/iosensor.d.ts.map +1 -1
- package/dist/device/iosensor.js +72 -66
- package/dist/device/iosensor.js.map +1 -1
- package/dist/device/lightstrip.d.ts +7 -6
- package/dist/device/lightstrip.d.ts.map +1 -1
- package/dist/device/lightstrip.js +85 -99
- package/dist/device/lightstrip.js.map +1 -1
- package/dist/device/lock.d.ts +10 -9
- package/dist/device/lock.d.ts.map +1 -1
- package/dist/device/lock.js +89 -79
- package/dist/device/lock.js.map +1 -1
- package/dist/device/meter.d.ts +6 -5
- package/dist/device/meter.d.ts.map +1 -1
- package/dist/device/meter.js +72 -65
- package/dist/device/meter.js.map +1 -1
- package/dist/device/meterplus.d.ts +6 -5
- package/dist/device/meterplus.d.ts.map +1 -1
- package/dist/device/meterplus.js +72 -64
- package/dist/device/meterplus.js.map +1 -1
- package/dist/device/motion.d.ts +6 -5
- package/dist/device/motion.d.ts.map +1 -1
- package/dist/device/motion.js +65 -58
- package/dist/device/motion.js.map +1 -1
- package/dist/device/plug.d.ts +13 -12
- package/dist/device/plug.d.ts.map +1 -1
- package/dist/device/plug.js +68 -52
- package/dist/device/plug.js.map +1 -1
- package/dist/device/robotvacuumcleaner.d.ts +12 -11
- package/dist/device/robotvacuumcleaner.d.ts.map +1 -1
- package/dist/device/robotvacuumcleaner.js +93 -82
- package/dist/device/robotvacuumcleaner.js.map +1 -1
- package/dist/device/waterdetector.d.ts +6 -5
- package/dist/device/waterdetector.d.ts.map +1 -1
- package/dist/device/waterdetector.js +73 -63
- package/dist/device/waterdetector.js.map +1 -1
- package/dist/homebridge-ui/server.js +2 -2
- package/dist/homebridge-ui/server.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -4
- package/dist/index.js.map +1 -1
- package/dist/irdevice/airconditioner.d.ts +8 -8
- package/dist/irdevice/airconditioner.d.ts.map +1 -1
- package/dist/irdevice/airconditioner.js +61 -105
- package/dist/irdevice/airconditioner.js.map +1 -1
- package/dist/irdevice/airpurifier.d.ts +10 -10
- package/dist/irdevice/airpurifier.d.ts.map +1 -1
- package/dist/irdevice/airpurifier.js +22 -42
- package/dist/irdevice/airpurifier.js.map +1 -1
- package/dist/irdevice/camera.d.ts +9 -9
- package/dist/irdevice/camera.d.ts.map +1 -1
- package/dist/irdevice/camera.js +15 -25
- package/dist/irdevice/camera.js.map +1 -1
- package/dist/irdevice/fan.d.ts +8 -8
- package/dist/irdevice/fan.d.ts.map +1 -1
- package/dist/irdevice/fan.js +21 -40
- package/dist/irdevice/fan.js.map +1 -1
- package/dist/irdevice/irdevice.d.ts +11 -11
- package/dist/irdevice/irdevice.d.ts.map +1 -1
- package/dist/irdevice/irdevice.js +14 -22
- package/dist/irdevice/irdevice.js.map +1 -1
- package/dist/irdevice/light.d.ts +9 -9
- package/dist/irdevice/light.d.ts.map +1 -1
- package/dist/irdevice/light.js +24 -47
- package/dist/irdevice/light.js.map +1 -1
- package/dist/irdevice/other.d.ts +9 -9
- package/dist/irdevice/other.d.ts.map +1 -1
- package/dist/irdevice/other.js +40 -83
- package/dist/irdevice/other.js.map +1 -1
- package/dist/irdevice/tv.d.ts +9 -9
- package/dist/irdevice/tv.d.ts.map +1 -1
- package/dist/irdevice/tv.js +29 -54
- package/dist/irdevice/tv.js.map +1 -1
- package/dist/irdevice/vacuumcleaner.d.ts +5 -5
- package/dist/irdevice/vacuumcleaner.d.ts.map +1 -1
- package/dist/irdevice/vacuumcleaner.js +11 -21
- package/dist/irdevice/vacuumcleaner.js.map +1 -1
- package/dist/irdevice/waterheater.d.ts +5 -5
- package/dist/irdevice/waterheater.d.ts.map +1 -1
- package/dist/irdevice/waterheater.js +11 -22
- package/dist/irdevice/waterheater.js.map +1 -1
- package/dist/platform.d.ts +24 -23
- package/dist/platform.d.ts.map +1 -1
- package/dist/platform.js +509 -723
- package/dist/platform.js.map +1 -1
- package/dist/settings.d.ts +5 -2
- package/dist/settings.d.ts.map +1 -1
- package/dist/settings.js.map +1 -1
- package/dist/types/bledevicestatus.d.ts +9 -9
- package/dist/types/bledevicestatus.d.ts.map +1 -1
- package/dist/types/devicelist.d.ts +6 -6
- package/dist/types/devicelist.d.ts.map +1 -1
- package/dist/types/deviceresponse.d.ts +4 -4
- package/dist/types/deviceresponse.d.ts.map +1 -1
- package/dist/types/devicestatus.d.ts +2 -2
- package/dist/types/devicestatus.d.ts.map +1 -1
- package/dist/types/devicewebhookstatus.d.ts +5 -5
- package/dist/types/devicewebhookstatus.d.ts.map +1 -1
- package/dist/types/irdevicelist.d.ts +4 -4
- package/dist/types/irdevicelist.d.ts.map +1 -1
- package/dist/types/pushbody.d.ts +2 -2
- package/dist/types/pushbody.d.ts.map +1 -1
- package/dist/utils.d.ts +4 -4
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +9 -13
- package/dist/utils.js.map +1 -1
- package/eslint.config.js +48 -93
- package/package.json +64 -57
- package/src/device/blindtilt.ts +537 -456
- package/src/device/bot-old.ts +1540 -0
- package/src/device/bot.ts +732 -725
- package/src/device/ceilinglight.ts +359 -368
- package/src/device/colorbulb.ts +441 -453
- package/src/device/contact.ts +229 -226
- package/src/device/curtain.ts +526 -444
- package/src/device/device.ts +206 -208
- package/src/device/fan.ts +336 -345
- package/src/device/hub.ts +213 -214
- package/src/device/humidifier.ts +326 -347
- package/src/device/iosensor.ts +211 -209
- package/src/device/lightstrip.ts +391 -404
- package/src/device/lock.ts +292 -282
- package/src/device/meter.ts +212 -210
- package/src/device/meterplus.ts +212 -209
- package/src/device/motion.ts +198 -190
- package/src/device/plug.ts +203 -182
- package/src/device/robotvacuumcleaner.ts +280 -269
- package/src/device/waterdetector.ts +198 -189
- package/src/homebridge-ui/server.ts +16 -15
- package/src/index.ts +5 -6
- package/src/irdevice/airconditioner.ts +277 -326
- package/src/irdevice/airpurifier.ts +124 -143
- package/src/irdevice/camera.ts +58 -64
- package/src/irdevice/fan.ts +106 -123
- package/src/irdevice/irdevice.ts +116 -119
- package/src/irdevice/light.ts +119 -143
- package/src/irdevice/other.ts +417 -461
- package/src/irdevice/tv.ts +155 -177
- package/src/irdevice/vacuumcleaner.ts +54 -60
- package/src/irdevice/waterheater.ts +56 -63
- package/src/platform.ts +1491 -1681
- package/src/settings.ts +172 -169
- package/src/types/bledevicestatus.ts +252 -256
- package/src/types/devicelist.ts +79 -79
- package/src/types/deviceresponse.ts +12 -13
- package/src/types/devicestatus.ts +124 -124
- package/src/types/devicewebhookstatus.ts +126 -131
- package/src/types/irdevicelist.ts +10 -10
- package/src/types/pushbody.ts +5 -5
- package/src/utils.ts +64 -65
- package/tsconfig.json +10 -9
package/src/device/blindtilt.ts
CHANGED
|
@@ -2,84 +2,103 @@
|
|
|
2
2
|
*
|
|
3
3
|
* blindtilt.ts: @switchbot/homebridge-switchbot.
|
|
4
4
|
*/
|
|
5
|
-
import {
|
|
6
|
-
import { BlindTiltMappingMode } from '../utils.js';
|
|
7
|
-
import { SwitchBotBLEModel, SwitchBotBLEModelName } from 'node-switchbot';
|
|
8
|
-
import { Subject, debounceTime, interval, skipWhile, take, tap } from 'rxjs';
|
|
5
|
+
import type { CharacteristicValue, PlatformAccessory, Service } from 'homebridge'
|
|
9
6
|
|
|
10
|
-
import type {
|
|
11
|
-
import type {
|
|
12
|
-
import type {
|
|
13
|
-
import type {
|
|
14
|
-
import type { blindTiltStatus } from '../types/devicestatus.js'
|
|
15
|
-
import type { blindTiltWebhookContext } from '../types/devicewebhookstatus.js'
|
|
16
|
-
import type { Service, PlatformAccessory, CharacteristicValue } from 'homebridge';
|
|
7
|
+
import type { SwitchBotPlatform } from '../platform.js'
|
|
8
|
+
import type { devicesConfig } from '../settings.js'
|
|
9
|
+
import type { blindTiltServiceData } from '../types/bledevicestatus.js'
|
|
10
|
+
import type { device } from '../types/devicelist.js'
|
|
11
|
+
import type { blindTiltStatus } from '../types/devicestatus.js'
|
|
12
|
+
import type { blindTiltWebhookContext } from '../types/devicewebhookstatus.js'
|
|
17
13
|
|
|
14
|
+
/*
|
|
15
|
+
* For Testing Locally:
|
|
16
|
+
* import { SwitchBotBLEModel, SwitchBotBLEModelName } from '/Users/Shared/GitHub/OpenWonderLabs/node-switchbot/dist/index.js';
|
|
17
|
+
*/
|
|
18
|
+
import { SwitchBotBLEModel, SwitchBotBLEModelName } from 'node-switchbot'
|
|
19
|
+
import { debounceTime, interval, skipWhile, Subject, take, tap } from 'rxjs'
|
|
20
|
+
|
|
21
|
+
import { BlindTiltMappingMode } from '../utils.js'
|
|
22
|
+
import { deviceBase } from './device.js'
|
|
18
23
|
|
|
19
24
|
export class BlindTilt extends deviceBase {
|
|
20
25
|
// Services
|
|
21
26
|
private WindowCovering: {
|
|
22
|
-
Name: CharacteristicValue
|
|
23
|
-
Service: Service
|
|
24
|
-
PositionState: CharacteristicValue
|
|
25
|
-
TargetPosition: CharacteristicValue
|
|
26
|
-
CurrentPosition: CharacteristicValue
|
|
27
|
-
TargetHorizontalTiltAngle: CharacteristicValue
|
|
28
|
-
CurrentHorizontalTiltAngle: CharacteristicValue
|
|
29
|
-
}
|
|
27
|
+
Name: CharacteristicValue
|
|
28
|
+
Service: Service
|
|
29
|
+
PositionState: CharacteristicValue
|
|
30
|
+
TargetPosition: CharacteristicValue
|
|
31
|
+
CurrentPosition: CharacteristicValue
|
|
32
|
+
TargetHorizontalTiltAngle: CharacteristicValue
|
|
33
|
+
CurrentHorizontalTiltAngle: CharacteristicValue
|
|
34
|
+
}
|
|
30
35
|
|
|
31
36
|
private Battery: {
|
|
32
|
-
Name: CharacteristicValue
|
|
33
|
-
Service: Service
|
|
34
|
-
BatteryLevel: CharacteristicValue
|
|
35
|
-
StatusLowBattery: CharacteristicValue
|
|
36
|
-
ChargingState?: CharacteristicValue
|
|
37
|
-
}
|
|
37
|
+
Name: CharacteristicValue
|
|
38
|
+
Service: Service
|
|
39
|
+
BatteryLevel: CharacteristicValue
|
|
40
|
+
StatusLowBattery: CharacteristicValue
|
|
41
|
+
ChargingState?: CharacteristicValue
|
|
42
|
+
}
|
|
38
43
|
|
|
39
44
|
private LightSensor?: {
|
|
40
|
-
Name: CharacteristicValue
|
|
41
|
-
Service: Service
|
|
42
|
-
CurrentAmbientLightLevel?: CharacteristicValue
|
|
43
|
-
}
|
|
45
|
+
Name: CharacteristicValue
|
|
46
|
+
Service: Service
|
|
47
|
+
CurrentAmbientLightLevel?: CharacteristicValue
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
private OpenModeSwitch?: {
|
|
51
|
+
Name: CharacteristicValue
|
|
52
|
+
Service: Service
|
|
53
|
+
On: CharacteristicValue
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
private CloseModeSwitch?: {
|
|
57
|
+
Name: CharacteristicValue
|
|
58
|
+
Service: Service
|
|
59
|
+
On: CharacteristicValue
|
|
60
|
+
}
|
|
44
61
|
|
|
45
62
|
// OpenAPI
|
|
46
|
-
deviceStatus!: blindTiltStatus
|
|
47
|
-
mappingMode: BlindTiltMappingMode = BlindTiltMappingMode.OnlyUp
|
|
63
|
+
deviceStatus!: blindTiltStatus
|
|
64
|
+
mappingMode: BlindTiltMappingMode = BlindTiltMappingMode.OnlyUp
|
|
48
65
|
|
|
49
|
-
//Webhook
|
|
50
|
-
webhookContext!: blindTiltWebhookContext
|
|
66
|
+
// Webhook
|
|
67
|
+
webhookContext!: blindTiltWebhookContext
|
|
51
68
|
|
|
52
69
|
// BLE
|
|
53
|
-
serviceData!: blindTiltServiceData
|
|
70
|
+
serviceData!: blindTiltServiceData
|
|
54
71
|
|
|
55
72
|
// Target
|
|
56
|
-
setNewTarget!: boolean
|
|
57
|
-
setNewTargetTimer!: NodeJS.Timeout
|
|
73
|
+
setNewTarget!: boolean
|
|
74
|
+
setNewTargetTimer!: NodeJS.Timeout
|
|
58
75
|
|
|
59
76
|
// Updates
|
|
60
|
-
|
|
61
|
-
|
|
77
|
+
blindTiltMoving: boolean
|
|
78
|
+
blindTiltUpdateInProgress: boolean
|
|
79
|
+
doBlindTiltUpdate: Subject<void>
|
|
62
80
|
|
|
63
81
|
constructor(
|
|
64
82
|
readonly platform: SwitchBotPlatform,
|
|
65
83
|
accessory: PlatformAccessory,
|
|
66
84
|
device: device & devicesConfig,
|
|
67
85
|
) {
|
|
68
|
-
super(platform, accessory, device)
|
|
86
|
+
super(platform, accessory, device)
|
|
69
87
|
// Set category
|
|
70
|
-
accessory.category = this.hap.Categories.WINDOW_COVERING
|
|
88
|
+
accessory.category = this.hap.Categories.WINDOW_COVERING
|
|
71
89
|
|
|
72
90
|
// default placeholders
|
|
73
|
-
this.mappingMode = (device.blindTilt?.mode as BlindTiltMappingMode) ?? BlindTiltMappingMode.OnlyUp
|
|
74
|
-
this.debugLog(`Mapping mode: ${this.mappingMode}`)
|
|
91
|
+
this.mappingMode = (device.blindTilt?.mode as BlindTiltMappingMode) ?? BlindTiltMappingMode.OnlyUp
|
|
92
|
+
this.debugLog(`Mapping mode: ${this.mappingMode}`)
|
|
75
93
|
|
|
76
94
|
// this is subject we use to track when we need to POST changes to the SwitchBot API
|
|
77
|
-
this.doBlindTiltUpdate = new Subject()
|
|
78
|
-
this.
|
|
79
|
-
this.
|
|
95
|
+
this.doBlindTiltUpdate = new Subject()
|
|
96
|
+
this.blindTiltMoving = false
|
|
97
|
+
this.blindTiltUpdateInProgress = false
|
|
98
|
+
this.setNewTarget = false
|
|
80
99
|
|
|
81
100
|
// Initialize WindowCovering Service
|
|
82
|
-
accessory.context.WindowCovering = accessory.context.WindowCovering ?? {}
|
|
101
|
+
accessory.context.WindowCovering = accessory.context.WindowCovering ?? {}
|
|
83
102
|
this.WindowCovering = {
|
|
84
103
|
Name: accessory.displayName,
|
|
85
104
|
Service: accessory.getService(this.hap.Service.WindowCovering) ?? accessory.addService(this.hap.Service.WindowCovering) as Service,
|
|
@@ -88,291 +107,336 @@ export class BlindTilt extends deviceBase {
|
|
|
88
107
|
CurrentPosition: accessory.context.CurrentPosition ?? 100,
|
|
89
108
|
TargetHorizontalTiltAngle: accessory.context.TargetHorizontalTiltAngle ?? 90,
|
|
90
109
|
CurrentHorizontalTiltAngle: accessory.context.CurrentHorizontalTiltAngle ?? 90,
|
|
91
|
-
}
|
|
92
|
-
accessory.context.WindowCovering = this.WindowCovering as object
|
|
110
|
+
}
|
|
111
|
+
accessory.context.WindowCovering = this.WindowCovering as object
|
|
93
112
|
|
|
94
113
|
// Initialize WindowCovering Characteristics
|
|
95
|
-
this.WindowCovering.Service
|
|
96
|
-
.
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
})
|
|
104
|
-
.onGet(() => {
|
|
105
|
-
return this.WindowCovering.TargetPosition;
|
|
106
|
-
})
|
|
107
|
-
.onSet(this.TargetPositionSet.bind(this));
|
|
114
|
+
this.WindowCovering.Service.setCharacteristic(this.hap.Characteristic.Name, this.WindowCovering.Name).getCharacteristic(this.hap.Characteristic.TargetPosition).setProps({
|
|
115
|
+
minStep: device.blindTilt?.set_minStep ?? 1,
|
|
116
|
+
minValue: 0,
|
|
117
|
+
maxValue: 100,
|
|
118
|
+
validValueRanges: [0, 100],
|
|
119
|
+
}).onGet(() => {
|
|
120
|
+
return this.WindowCovering.TargetPosition
|
|
121
|
+
}).onSet(this.TargetPositionSet.bind(this))
|
|
108
122
|
|
|
109
123
|
// Initialize WindowCovering CurrentPosition Characteristic
|
|
110
|
-
this.WindowCovering.Service
|
|
111
|
-
.
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
return this.WindowCovering.CurrentPosition ?? 0;
|
|
119
|
-
});
|
|
124
|
+
this.WindowCovering.Service.getCharacteristic(this.hap.Characteristic.CurrentPosition).setProps({
|
|
125
|
+
minStep: device.blindTilt?.set_minStep ?? 1,
|
|
126
|
+
minValue: 0,
|
|
127
|
+
maxValue: 100,
|
|
128
|
+
validValueRanges: [0, 100],
|
|
129
|
+
}).onGet(() => {
|
|
130
|
+
return this.WindowCovering.CurrentPosition ?? 0
|
|
131
|
+
})
|
|
120
132
|
|
|
121
133
|
// Initialize WindowCovering TargetHorizontalTiltAngle Characteristic
|
|
122
|
-
this.WindowCovering.Service
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
.onGet(() => {
|
|
131
|
-
return this.WindowCovering.TargetHorizontalTiltAngle;
|
|
132
|
-
})
|
|
133
|
-
.onSet(this.TargetHorizontalTiltAngleSet.bind(this));
|
|
134
|
+
this.WindowCovering.Service.getCharacteristic(this.hap.Characteristic.TargetHorizontalTiltAngle).setProps({
|
|
135
|
+
minStep: 180,
|
|
136
|
+
minValue: -90,
|
|
137
|
+
maxValue: 90,
|
|
138
|
+
validValues: [-90, 90],
|
|
139
|
+
}).onGet(() => {
|
|
140
|
+
return this.WindowCovering.TargetHorizontalTiltAngle
|
|
141
|
+
}).onSet(this.TargetHorizontalTiltAngleSet.bind(this))
|
|
134
142
|
|
|
135
143
|
// Initialize WindowCovering CurrentHorizontalTiltAngle Characteristic
|
|
136
|
-
this.WindowCovering.Service
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
return this.WindowCovering.CurrentHorizontalTiltAngle ?? 0;
|
|
145
|
-
});
|
|
144
|
+
this.WindowCovering.Service.getCharacteristic(this.hap.Characteristic.CurrentHorizontalTiltAngle).setProps({
|
|
145
|
+
minStep: 180,
|
|
146
|
+
minValue: -90,
|
|
147
|
+
maxValue: 90,
|
|
148
|
+
validValues: [-90, 90],
|
|
149
|
+
}).onGet(() => {
|
|
150
|
+
return this.WindowCovering.CurrentHorizontalTiltAngle ?? 0
|
|
151
|
+
})
|
|
146
152
|
|
|
147
153
|
// Initialize Battery Service
|
|
148
|
-
accessory.context.Battery = accessory.context.Battery ?? {}
|
|
154
|
+
accessory.context.Battery = accessory.context.Battery ?? {}
|
|
149
155
|
this.Battery = {
|
|
150
156
|
Name: `${accessory.displayName} Battery`,
|
|
151
157
|
Service: accessory.getService(this.hap.Service.Battery) ?? accessory.addService(this.hap.Service.Battery) as Service,
|
|
152
158
|
BatteryLevel: accessory.context.BatteryLevel ?? 100,
|
|
153
159
|
StatusLowBattery: this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL,
|
|
154
160
|
ChargingState: accessory.context.ChargingState ?? this.hap.Characteristic.ChargingState.NOT_CHARGING,
|
|
155
|
-
}
|
|
156
|
-
accessory.context.Battery = this.Battery as object
|
|
161
|
+
}
|
|
162
|
+
accessory.context.Battery = this.Battery as object
|
|
157
163
|
|
|
158
164
|
// Initialize Battery Name Characteristic
|
|
159
|
-
this.Battery.Service
|
|
160
|
-
.setCharacteristic(this.hap.Characteristic.Name, this.Battery.Name)
|
|
161
|
-
.setCharacteristic(this.hap.Characteristic.ChargingState, this.hap.Characteristic.ChargingState.NOT_CHARGEABLE);
|
|
165
|
+
this.Battery.Service.setCharacteristic(this.hap.Characteristic.Name, this.Battery.Name).setCharacteristic(this.hap.Characteristic.ChargingState, this.hap.Characteristic.ChargingState.NOT_CHARGEABLE)
|
|
162
166
|
|
|
163
167
|
// Initialize LightSensor Service
|
|
164
168
|
if (device.blindTilt?.hide_lightsensor) {
|
|
165
169
|
if (this.LightSensor?.Service) {
|
|
166
|
-
this.debugLog('Removing Light Sensor Service')
|
|
167
|
-
this.LightSensor.Service = accessory.getService(this.hap.Service.LightSensor) as Service
|
|
168
|
-
accessory.removeService(this.LightSensor.Service)
|
|
169
|
-
accessory.context.LightSensor = {}
|
|
170
|
+
this.debugLog('Removing Light Sensor Service')
|
|
171
|
+
this.LightSensor.Service = accessory.getService(this.hap.Service.LightSensor) as Service
|
|
172
|
+
accessory.removeService(this.LightSensor.Service)
|
|
173
|
+
accessory.context.LightSensor = {}
|
|
170
174
|
} else {
|
|
171
|
-
this.debugLog('Light Sensor Service is already removed')
|
|
175
|
+
this.debugLog('Light Sensor Service is already removed')
|
|
172
176
|
}
|
|
173
177
|
} else {
|
|
174
|
-
accessory.context.LightSensor = accessory.context.LightSensor ?? {}
|
|
178
|
+
accessory.context.LightSensor = accessory.context.LightSensor ?? {}
|
|
175
179
|
this.LightSensor = {
|
|
176
180
|
Name: `${accessory.displayName} Light Sensor`,
|
|
177
181
|
Service: accessory.getService(this.hap.Service.LightSensor) ?? accessory.addService(this.hap.Service.LightSensor) as Service,
|
|
178
182
|
CurrentAmbientLightLevel: accessory.context.CurrentAmbientLightLevel ?? 0.0001,
|
|
179
|
-
}
|
|
180
|
-
accessory.context.LightSensor = this.LightSensor as object
|
|
183
|
+
}
|
|
184
|
+
accessory.context.LightSensor = this.LightSensor as object
|
|
181
185
|
|
|
182
186
|
// Initialize LightSensor Characteristics
|
|
183
|
-
this.LightSensor.Service
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
187
|
+
this.LightSensor.Service.setCharacteristic(this.hap.Characteristic.Name, this.LightSensor.Name).setCharacteristic(this.hap.Characteristic.StatusActive, true).getCharacteristic(this.hap.Characteristic.CurrentAmbientLightLevel).onGet(() => {
|
|
188
|
+
return this.LightSensor?.CurrentAmbientLightLevel ?? 0.0001
|
|
189
|
+
})
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// Initialize Open Mode Switch Service
|
|
193
|
+
if (!device.blindTilt?.silentModeSwitch) {
|
|
194
|
+
if (this.OpenModeSwitch?.Service) {
|
|
195
|
+
this.debugLog('Removing Open Mode Switch Service')
|
|
196
|
+
this.OpenModeSwitch.Service = this.accessory.getService(this.hap.Service.Switch) as Service
|
|
197
|
+
accessory.removeService(this.OpenModeSwitch.Service)
|
|
198
|
+
accessory.context.OpenModeSwitch = {}
|
|
199
|
+
}
|
|
200
|
+
} else {
|
|
201
|
+
accessory.context.OpenModeSwitch = accessory.context.OpenModeSwitch ?? {}
|
|
202
|
+
this.OpenModeSwitch = {
|
|
203
|
+
Name: `${accessory.displayName} Silent Open Mode`,
|
|
204
|
+
Service: accessory.getService(this.hap.Service.Switch) ?? accessory.addService(this.hap.Service.Switch) as Service,
|
|
205
|
+
On: accessory.context.OpenModeSwitch.On ?? false,
|
|
206
|
+
}
|
|
207
|
+
accessory.context.OpenModeSwitch = this.OpenModeSwitch as object
|
|
208
|
+
|
|
209
|
+
// Initialize Open Mode Switch Service
|
|
210
|
+
this.OpenModeSwitch.Service.setCharacteristic(this.hap.Characteristic.Name, this.OpenModeSwitch.Name).getCharacteristic(this.hap.Characteristic.On).onGet(() => {
|
|
211
|
+
return this.OpenModeSwitch?.On ?? false
|
|
212
|
+
})
|
|
213
|
+
|
|
214
|
+
this.OpenModeSwitch.Service.getCharacteristic(this.hap.Characteristic.On).onSet(this.OpenModeSwitchSet.bind(this))
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
// Initialize Close Mode Switch Service
|
|
218
|
+
if (!device.blindTilt?.silentModeSwitch) {
|
|
219
|
+
if (this.CloseModeSwitch?.Service) {
|
|
220
|
+
this.debugLog('Removing Close Mode Switch Service')
|
|
221
|
+
this.CloseModeSwitch.Service = this.accessory.getService(this.hap.Service.Switch) as Service
|
|
222
|
+
accessory.removeService(this.CloseModeSwitch.Service)
|
|
223
|
+
accessory.context.CloseModeSwitch = {}
|
|
224
|
+
}
|
|
225
|
+
} else {
|
|
226
|
+
accessory.context.CloseModeSwitch = accessory.context.CloseModeSwitch ?? {}
|
|
227
|
+
this.CloseModeSwitch = {
|
|
228
|
+
Name: `${accessory.displayName} Silent Close Mode`,
|
|
229
|
+
Service: accessory.getService(this.hap.Service.Switch) ?? accessory.addService(this.hap.Service.Switch) as Service,
|
|
230
|
+
On: accessory.context.CloseModeSwitch.On ?? false,
|
|
231
|
+
}
|
|
232
|
+
accessory.context.CloseModeSwitch = this.CloseModeSwitch as object
|
|
233
|
+
|
|
234
|
+
// Initialize Close Mode Switch Service
|
|
235
|
+
this.CloseModeSwitch.Service.setCharacteristic(this.hap.Characteristic.Name, this.CloseModeSwitch.Name).getCharacteristic(this.hap.Characteristic.On).onGet(() => {
|
|
236
|
+
return this.CloseModeSwitch?.On ?? false
|
|
237
|
+
})
|
|
238
|
+
|
|
239
|
+
this.CloseModeSwitch.Service.getCharacteristic(this.hap.Characteristic.On).onSet(this.CloseModeSwitchSet.bind(this))
|
|
190
240
|
}
|
|
191
241
|
|
|
192
242
|
// Retrieve initial values and updateHomekit
|
|
193
|
-
|
|
194
|
-
|
|
243
|
+
try {
|
|
244
|
+
this.debugLog('Retrieve initial values and update Homekit')
|
|
245
|
+
this.refreshStatus()
|
|
246
|
+
} catch (e: any) {
|
|
247
|
+
this.errorLog(`failed to retrieve initial values and update Homekit, Error: ${e}`)
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
// regisiter webhook event handler if enabled
|
|
251
|
+
try {
|
|
252
|
+
this.debugLog('Registering Webhook Event Handler')
|
|
253
|
+
this.registerWebhook()
|
|
254
|
+
} catch (e: any) {
|
|
255
|
+
this.errorLog(`failed to registerWebhook, Error: ${e}`)
|
|
256
|
+
}
|
|
195
257
|
|
|
196
|
-
//regisiter
|
|
197
|
-
|
|
198
|
-
|
|
258
|
+
// regisiter platform BLE event handler if enabled
|
|
259
|
+
try {
|
|
260
|
+
this.debugLog('Registering Platform BLE Event Handler')
|
|
261
|
+
this.registerPlatformBLE()
|
|
262
|
+
} catch (e: any) {
|
|
263
|
+
this.errorLog(`failed to registerPlatformBLE, Error: ${e}`)
|
|
264
|
+
}
|
|
199
265
|
|
|
200
266
|
// Start an update interval
|
|
201
267
|
interval(this.deviceRefreshRate * 1000)
|
|
202
268
|
.pipe(skipWhile(() => this.blindTiltUpdateInProgress))
|
|
203
269
|
.subscribe(async () => {
|
|
204
|
-
await this.refreshStatus()
|
|
205
|
-
})
|
|
270
|
+
await this.refreshStatus()
|
|
271
|
+
})
|
|
206
272
|
|
|
207
273
|
// update slide progress
|
|
208
274
|
interval(this.deviceUpdateRate * 1000)
|
|
275
|
+
.pipe(skipWhile(() => !this.blindTiltMoving))
|
|
209
276
|
.subscribe(async () => {
|
|
210
277
|
if (this.WindowCovering.PositionState === this.hap.Characteristic.PositionState.STOPPED) {
|
|
211
|
-
return
|
|
278
|
+
return
|
|
212
279
|
}
|
|
213
|
-
this.debugLog(`Refresh Status When Moving, PositionState: ${this.WindowCovering.PositionState}`)
|
|
214
|
-
await this.refreshStatus()
|
|
215
|
-
})
|
|
280
|
+
this.debugLog(`Refresh Status When Moving, PositionState: ${this.WindowCovering.PositionState}`)
|
|
281
|
+
await this.refreshStatus()
|
|
282
|
+
})
|
|
216
283
|
|
|
217
284
|
// Watch for BlindTilt change events
|
|
218
285
|
// We put in a debounce of 100ms so we don't make duplicate calls
|
|
219
286
|
this.doBlindTiltUpdate
|
|
220
287
|
.pipe(
|
|
221
288
|
tap(() => {
|
|
222
|
-
this.blindTiltUpdateInProgress = true
|
|
289
|
+
this.blindTiltUpdateInProgress = true
|
|
223
290
|
}),
|
|
224
291
|
debounceTime(this.devicePushRate * 1000),
|
|
225
292
|
)
|
|
226
293
|
.subscribe(async () => {
|
|
227
294
|
try {
|
|
228
|
-
await this.pushChanges()
|
|
295
|
+
await this.pushChanges()
|
|
229
296
|
} catch (e: any) {
|
|
230
|
-
await this.apiError(e)
|
|
231
|
-
await this.errorLog(`failed pushChanges with ${device.connectionType} Connection, Error Message: ${JSON.stringify(e.message)}`)
|
|
297
|
+
await this.apiError(e)
|
|
298
|
+
await this.errorLog(`failed pushChanges with ${device.connectionType} Connection, Error Message: ${JSON.stringify(e.message)}`)
|
|
232
299
|
}
|
|
233
|
-
this.blindTiltUpdateInProgress = false
|
|
234
|
-
})
|
|
300
|
+
this.blindTiltUpdateInProgress = false
|
|
301
|
+
})
|
|
235
302
|
}
|
|
236
303
|
|
|
237
304
|
/**
|
|
238
305
|
* Parse the device status from the SwitchBotBLE API
|
|
239
306
|
*/
|
|
240
307
|
async BLEparseStatus(): Promise<void> {
|
|
241
|
-
await this.debugLog('BLEparseStatus')
|
|
242
|
-
await this.debugLog(`(direction, slidePosition, battery, version) = BLE:(${this.serviceData.tilt}, ${this.serviceData.tilt}
|
|
243
|
-
+ ` ${this.serviceData.battery}, ${this.accessory.context.version}), current:(${this.WindowCovering.CurrentHorizontalTiltAngle},`
|
|
244
|
-
+ ` ${this.WindowCovering.CurrentPosition}, ${this.Battery.BatteryLevel}, ${this.accessory.context.version})`);
|
|
308
|
+
await this.debugLog('BLEparseStatus')
|
|
309
|
+
await this.debugLog(`(direction, slidePosition, battery, version) = BLE:(${this.serviceData.tilt}, ${this.serviceData.tilt}, ${this.serviceData.battery}, ${this.accessory.context.version}), current:(${this.WindowCovering.CurrentHorizontalTiltAngle}, ${this.WindowCovering.CurrentPosition}, ${this.Battery.BatteryLevel}, ${this.accessory.context.version})`)
|
|
245
310
|
|
|
246
311
|
// CurrentPosition
|
|
247
|
-
this.WindowCovering.CurrentPosition = 100 - Number(this.serviceData.tilt)
|
|
248
|
-
await this.setMinMax()
|
|
249
|
-
await this.debugLog(`CurrentPosition ${this.WindowCovering.CurrentPosition}`)
|
|
312
|
+
this.WindowCovering.CurrentPosition = 100 - Number(this.serviceData.tilt)
|
|
313
|
+
await this.setMinMax()
|
|
314
|
+
await this.debugLog(`CurrentPosition ${this.WindowCovering.CurrentPosition}`)
|
|
250
315
|
if (this.setNewTarget) {
|
|
251
|
-
await this.infoLog('Checking Status ...')
|
|
316
|
+
await this.infoLog('Checking Status ...')
|
|
252
317
|
}
|
|
253
318
|
if (this.setNewTarget && this.serviceData.inMotion) {
|
|
254
|
-
|
|
319
|
+
this.blindTiltMoving = true
|
|
320
|
+
await this.setMinMax()
|
|
255
321
|
if (Number(this.WindowCovering.TargetPosition) > this.WindowCovering.CurrentPosition) {
|
|
256
|
-
await this.debugLog(`Closing, CurrentPosition: ${this.WindowCovering.CurrentPosition}`)
|
|
257
|
-
this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.INCREASING
|
|
258
|
-
this.WindowCovering.Service.getCharacteristic(this.hap.Characteristic.PositionState).updateValue(this.WindowCovering.PositionState)
|
|
259
|
-
await this.debugLog(`Increasing, PositionState: ${this.WindowCovering.PositionState}`)
|
|
322
|
+
await this.debugLog(`Closing, CurrentPosition: ${this.WindowCovering.CurrentPosition}`)
|
|
323
|
+
this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.INCREASING
|
|
324
|
+
this.WindowCovering.Service.getCharacteristic(this.hap.Characteristic.PositionState).updateValue(this.WindowCovering.PositionState)
|
|
325
|
+
await this.debugLog(`Increasing, PositionState: ${this.WindowCovering.PositionState}`)
|
|
260
326
|
} else if (Number(this.WindowCovering.TargetPosition) < this.WindowCovering.CurrentPosition) {
|
|
261
|
-
await this.debugLog(`Opening, CurrentPosition: ${this.WindowCovering.CurrentPosition}`)
|
|
262
|
-
this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.DECREASING
|
|
263
|
-
this.WindowCovering.Service.getCharacteristic(this.hap.Characteristic.PositionState).updateValue(this.WindowCovering.PositionState)
|
|
264
|
-
await this.debugLog(`Decreasing, PositionState: ${this.WindowCovering.PositionState}`)
|
|
327
|
+
await this.debugLog(`Opening, CurrentPosition: ${this.WindowCovering.CurrentPosition}`)
|
|
328
|
+
this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.DECREASING
|
|
329
|
+
this.WindowCovering.Service.getCharacteristic(this.hap.Characteristic.PositionState).updateValue(this.WindowCovering.PositionState)
|
|
330
|
+
await this.debugLog(`Decreasing, PositionState: ${this.WindowCovering.PositionState}`)
|
|
265
331
|
} else {
|
|
266
|
-
await this.debugLog(`Standby, CurrentPosition: ${this.WindowCovering.CurrentPosition}`)
|
|
267
|
-
this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.STOPPED
|
|
268
|
-
this.WindowCovering.Service.getCharacteristic(this.hap.Characteristic.PositionState).updateValue(this.WindowCovering.PositionState)
|
|
269
|
-
await this.debugLog('Stopped, PositionState', this.WindowCovering.PositionState)
|
|
332
|
+
await this.debugLog(`Standby, CurrentPosition: ${this.WindowCovering.CurrentPosition}`)
|
|
333
|
+
this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.STOPPED
|
|
334
|
+
this.WindowCovering.Service.getCharacteristic(this.hap.Characteristic.PositionState).updateValue(this.WindowCovering.PositionState)
|
|
335
|
+
await this.debugLog('Stopped, PositionState', this.WindowCovering.PositionState)
|
|
270
336
|
}
|
|
271
337
|
} else {
|
|
272
|
-
|
|
273
|
-
this.
|
|
274
|
-
this.WindowCovering.
|
|
275
|
-
|
|
338
|
+
this.blindTiltMoving = false
|
|
339
|
+
await this.debugLog(`Standby, CurrentPosition: ${this.WindowCovering.CurrentPosition}`)
|
|
340
|
+
this.WindowCovering.TargetPosition = this.WindowCovering.CurrentPosition
|
|
341
|
+
this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.STOPPED
|
|
342
|
+
await this.debugLog(`Stopped, PositionState: ${this.WindowCovering.PositionState}`)
|
|
276
343
|
}
|
|
277
|
-
await this.debugLog(`CurrentPosition: ${this.WindowCovering.CurrentPosition}, TargetPosition: ${this.WindowCovering.TargetPosition}
|
|
278
|
-
+ ` PositionState: ${this.WindowCovering.PositionState}`);
|
|
344
|
+
await this.debugLog(`CurrentPosition: ${this.WindowCovering.CurrentPosition}, TargetPosition: ${this.WindowCovering.TargetPosition}, PositionState: ${this.WindowCovering.PositionState}`)
|
|
279
345
|
|
|
280
346
|
// CurrentAmbientLightLevel
|
|
281
347
|
if (!this.device.blindTilt?.hide_lightsensor && this.LightSensor?.Service) {
|
|
282
|
-
const set_minLux = this.device.blindTilt?.set_minLux ?? 1
|
|
283
|
-
const set_maxLux = this.device.blindTilt?.set_maxLux ?? 6001
|
|
284
|
-
const spaceBetweenLevels = 9
|
|
285
|
-
|
|
348
|
+
const set_minLux = this.device.blindTilt?.set_minLux ?? 1
|
|
349
|
+
const set_maxLux = this.device.blindTilt?.set_maxLux ?? 6001
|
|
350
|
+
const spaceBetweenLevels = 9
|
|
286
351
|
|
|
287
|
-
await this.getLightLevel(this.serviceData.lightLevel, set_minLux, set_maxLux, spaceBetweenLevels)
|
|
288
|
-
await this.debugLog(`LightLevel: ${this.serviceData.lightLevel}, CurrentAmbientLightLevel: ${this.LightSensor!.CurrentAmbientLightLevel}`)
|
|
352
|
+
await this.getLightLevel(this.serviceData.lightLevel, set_minLux, set_maxLux, spaceBetweenLevels)
|
|
353
|
+
await this.debugLog(`LightLevel: ${this.serviceData.lightLevel}, CurrentAmbientLightLevel: ${this.LightSensor!.CurrentAmbientLightLevel}`)
|
|
289
354
|
}
|
|
290
355
|
|
|
291
356
|
// BatteryLevel
|
|
292
|
-
this.Battery.BatteryLevel = this.serviceData.battery
|
|
293
|
-
await this.debugLog(`BatteryLevel: ${this.Battery.BatteryLevel}`)
|
|
357
|
+
this.Battery.BatteryLevel = this.serviceData.battery
|
|
358
|
+
await this.debugLog(`BatteryLevel: ${this.Battery.BatteryLevel}`)
|
|
294
359
|
|
|
295
360
|
// StatusLowBattery
|
|
296
361
|
this.Battery.StatusLowBattery = this.Battery.BatteryLevel < 10
|
|
297
|
-
? this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW
|
|
298
|
-
|
|
362
|
+
? this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW
|
|
363
|
+
: this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL
|
|
364
|
+
await this.debugLog(`StatusLowBattery: ${this.Battery.StatusLowBattery}`)
|
|
299
365
|
};
|
|
300
366
|
|
|
301
367
|
/**
|
|
302
368
|
* Parse the device status from the SwitchBot OpenAPI
|
|
303
369
|
*/
|
|
304
370
|
async openAPIparseStatus(): Promise<void> {
|
|
305
|
-
await this.debugLog('openAPIparseStatus')
|
|
306
|
-
await this.debugLog(`(direction, slidePosition, battery, version) = OpenAPI:(${this.deviceStatus.direction}, ${this.deviceStatus.slidePosition}
|
|
307
|
-
+ ` ${this.deviceStatus.battery}, ${this.deviceStatus.version}), current:(${this.WindowCovering.CurrentHorizontalTiltAngle},`
|
|
308
|
-
+ ` ${this.WindowCovering.CurrentPosition}, ${this.Battery.BatteryLevel}, ${this.accessory.context.version})`);
|
|
371
|
+
await this.debugLog('openAPIparseStatus')
|
|
372
|
+
await this.debugLog(`(direction, slidePosition, battery, version) = OpenAPI:(${this.deviceStatus.direction}, ${this.deviceStatus.slidePosition}, ${this.deviceStatus.battery}, ${this.deviceStatus.version}), current:(${this.WindowCovering.CurrentHorizontalTiltAngle}, ${this.WindowCovering.CurrentPosition}, ${this.Battery.BatteryLevel}, ${this.accessory.context.version})`)
|
|
309
373
|
|
|
310
374
|
// CurrentPosition
|
|
311
|
-
await this.getCurrentPosttionDirection(this.deviceStatus.direction, this.deviceStatus.slidePosition)
|
|
375
|
+
await this.getCurrentPosttionDirection(this.deviceStatus.direction, this.deviceStatus.slidePosition)
|
|
312
376
|
|
|
313
377
|
if (!this.device.blindTilt?.hide_lightsensor && this.LightSensor?.Service) {
|
|
314
|
-
const set_minLux = this.device.blindTilt?.set_minLux ?? 1
|
|
315
|
-
const set_maxLux = this.device.blindTilt?.set_maxLux ?? 6001
|
|
316
|
-
const lightLevel = this.deviceStatus.lightLevel === 'bright' ? set_maxLux : set_minLux
|
|
317
|
-
this.LightSensor.CurrentAmbientLightLevel = await this.getLightLevel(lightLevel, set_minLux, set_maxLux, 2)
|
|
318
|
-
await this.debugLog(`LightLevel: ${this.deviceStatus.lightLevel}, CurrentAmbientLightLevel: ${this.LightSensor.CurrentAmbientLightLevel}`)
|
|
378
|
+
const set_minLux = this.device.blindTilt?.set_minLux ?? 1
|
|
379
|
+
const set_maxLux = this.device.blindTilt?.set_maxLux ?? 6001
|
|
380
|
+
const lightLevel = this.deviceStatus.lightLevel === 'bright' ? set_maxLux : set_minLux
|
|
381
|
+
this.LightSensor.CurrentAmbientLightLevel = await this.getLightLevel(lightLevel, set_minLux, set_maxLux, 2)
|
|
382
|
+
await this.debugLog(`LightLevel: ${this.deviceStatus.lightLevel}, CurrentAmbientLightLevel: ${this.LightSensor.CurrentAmbientLightLevel}`)
|
|
319
383
|
}
|
|
320
384
|
|
|
321
385
|
// BatteryLevel
|
|
322
|
-
this.Battery.BatteryLevel = this.deviceStatus.battery
|
|
323
|
-
await this.debugLog(`BatteryLevel: ${this.Battery.BatteryLevel}`)
|
|
386
|
+
this.Battery.BatteryLevel = this.deviceStatus.battery
|
|
387
|
+
await this.debugLog(`BatteryLevel: ${this.Battery.BatteryLevel}`)
|
|
324
388
|
|
|
325
389
|
// StatusLowBattery
|
|
326
390
|
this.Battery.StatusLowBattery = this.Battery.BatteryLevel < 10
|
|
327
|
-
? this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW
|
|
328
|
-
|
|
391
|
+
? this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW
|
|
392
|
+
: this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL
|
|
393
|
+
await this.debugLog(`StatusLowBattery: ${this.Battery.StatusLowBattery}`)
|
|
329
394
|
|
|
330
395
|
// Firmware Version
|
|
331
|
-
const version = this.deviceStatus.version.toString()
|
|
332
|
-
await this.debugLog(`Firmware Version: ${version.replace(/^V|-.*$/g, '')}`)
|
|
333
|
-
let deviceVersion: string
|
|
396
|
+
const version = this.deviceStatus.version.toString()
|
|
397
|
+
await this.debugLog(`Firmware Version: ${version.replace(/^V|-.*$/g, '')}`)
|
|
398
|
+
let deviceVersion: string
|
|
334
399
|
if (version?.includes('.') === false) {
|
|
335
|
-
const replace = version?.replace(/^V|-.*$/g, '')
|
|
336
|
-
const match = replace?.match(
|
|
337
|
-
const blindTiltVersion = match?.join('.') ?? '0.0.0'
|
|
338
|
-
deviceVersion = blindTiltVersion
|
|
400
|
+
const replace = version?.replace(/^V|-.*$/g, '')
|
|
401
|
+
const match = replace?.match(/./g)
|
|
402
|
+
const blindTiltVersion = match?.join('.') ?? '0.0.0'
|
|
403
|
+
deviceVersion = blindTiltVersion
|
|
339
404
|
} else {
|
|
340
|
-
deviceVersion = version.replace(/^V|-.*$/g, '') ?? '0.0.0'
|
|
405
|
+
deviceVersion = version.replace(/^V|-.*$/g, '') ?? '0.0.0'
|
|
341
406
|
}
|
|
342
407
|
this.accessory
|
|
343
408
|
.getService(this.hap.Service.AccessoryInformation)!
|
|
344
409
|
.setCharacteristic(this.hap.Characteristic.HardwareRevision, deviceVersion)
|
|
345
410
|
.setCharacteristic(this.hap.Characteristic.FirmwareRevision, deviceVersion)
|
|
346
411
|
.getCharacteristic(this.hap.Characteristic.FirmwareRevision)
|
|
347
|
-
.updateValue(deviceVersion)
|
|
348
|
-
this.accessory.context.version = deviceVersion
|
|
349
|
-
await this.debugLog(`version: ${this.accessory.context.version}`)
|
|
412
|
+
.updateValue(deviceVersion)
|
|
413
|
+
this.accessory.context.version = deviceVersion
|
|
414
|
+
await this.debugLog(`version: ${this.accessory.context.version}`)
|
|
350
415
|
}
|
|
351
416
|
|
|
352
417
|
async parseStatusWebhook(): Promise<void> {
|
|
353
|
-
await this.debugLog('parseStatusWebhook')
|
|
354
|
-
await this.debugLog(`(slidePosition, battery, version) = Webhook:(${this.webhookContext.direction}, ${this.webhookContext.slidePosition}
|
|
355
|
-
+ ` ${this.webhookContext.battery}, ${this.webhookContext.version}, current:(${this.WindowCovering.CurrentHorizontalTiltAngle},`
|
|
356
|
-
+ ` ${this.WindowCovering.CurrentPosition}, ${this.Battery.BatteryLevel}, ${this.accessory.context.version})`);
|
|
418
|
+
await this.debugLog('parseStatusWebhook')
|
|
419
|
+
await this.debugLog(`(slidePosition, battery, version) = Webhook:(${this.webhookContext.direction}, ${this.webhookContext.slidePosition}, ${this.webhookContext.battery}, ${this.webhookContext.version}, current:(${this.WindowCovering.CurrentHorizontalTiltAngle}, ${this.WindowCovering.CurrentPosition}, ${this.Battery.BatteryLevel}, ${this.accessory.context.version})`)
|
|
357
420
|
// CurrentPosition and CurrentHorizontalTiltAngle
|
|
358
|
-
await this.getCurrentPosttionDirection(this.webhookContext.direction, this.webhookContext.slidePosition)
|
|
421
|
+
await this.getCurrentPosttionDirection(this.webhookContext.direction, this.webhookContext.slidePosition)
|
|
359
422
|
// BatteryLevel
|
|
360
|
-
this.Battery.BatteryLevel = this.webhookContext.battery
|
|
361
|
-
await this.debugLog(`BatteryLevel: ${this.Battery.BatteryLevel}`)
|
|
423
|
+
this.Battery.BatteryLevel = this.webhookContext.battery
|
|
424
|
+
await this.debugLog(`BatteryLevel: ${this.Battery.BatteryLevel}`)
|
|
362
425
|
// StatusLowBattery
|
|
363
426
|
this.Battery.StatusLowBattery = this.Battery.BatteryLevel < 10
|
|
364
|
-
? this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW
|
|
365
|
-
|
|
427
|
+
? this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW
|
|
428
|
+
: this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL
|
|
429
|
+
await this.debugLog(`StatusLowBattery: ${this.Battery.StatusLowBattery}`)
|
|
366
430
|
// Firmware Version
|
|
367
|
-
const deviceVersion = this.webhookContext.version.replace(/^V|-.*$/g, '') ?? '0.0.0'
|
|
431
|
+
const deviceVersion = this.webhookContext.version.replace(/^V|-.*$/g, '') ?? '0.0.0'
|
|
368
432
|
this.accessory
|
|
369
433
|
.getService(this.hap.Service.AccessoryInformation)!
|
|
370
434
|
.setCharacteristic(this.hap.Characteristic.HardwareRevision, deviceVersion)
|
|
371
435
|
.setCharacteristic(this.hap.Characteristic.FirmwareRevision, deviceVersion)
|
|
372
436
|
.getCharacteristic(this.hap.Characteristic.FirmwareRevision)
|
|
373
|
-
.updateValue(deviceVersion)
|
|
374
|
-
this.accessory.context.version = deviceVersion
|
|
375
|
-
await this.debugSuccessLog(`version: ${this.accessory.context.version}`)
|
|
437
|
+
.updateValue(deviceVersion)
|
|
438
|
+
this.accessory.context.version = deviceVersion
|
|
439
|
+
await this.debugSuccessLog(`version: ${this.accessory.context.version}`)
|
|
376
440
|
}
|
|
377
441
|
|
|
378
442
|
/**
|
|
@@ -380,123 +444,128 @@ export class BlindTilt extends deviceBase {
|
|
|
380
444
|
*/
|
|
381
445
|
async refreshStatus(): Promise<void> {
|
|
382
446
|
if (!this.device.enableCloudService && this.OpenAPI) {
|
|
383
|
-
await this.errorLog(`refreshStatus enableCloudService: ${this.device.enableCloudService}`)
|
|
384
|
-
} else if (this.BLE
|
|
385
|
-
await this.BLERefreshStatus()
|
|
447
|
+
await this.errorLog(`refreshStatus enableCloudService: ${this.device.enableCloudService}`)
|
|
448
|
+
} else if (this.BLE) {
|
|
449
|
+
await this.BLERefreshStatus()
|
|
386
450
|
} else if (this.OpenAPI && this.platform.config.credentials?.token) {
|
|
387
|
-
await this.openAPIRefreshStatus()
|
|
451
|
+
await this.openAPIRefreshStatus()
|
|
388
452
|
} else {
|
|
389
|
-
await this.offlineOff()
|
|
390
|
-
await this.debugWarnLog(`Connection Type: ${this.device.connectionType}, refreshStatus will not happen.`)
|
|
453
|
+
await this.offlineOff()
|
|
454
|
+
await this.debugWarnLog(`Connection Type: ${this.device.connectionType}, refreshStatus will not happen.`)
|
|
391
455
|
}
|
|
392
456
|
}
|
|
393
457
|
|
|
394
458
|
async BLERefreshStatus(): Promise<void> {
|
|
459
|
+
await this.debugLog('BLERefreshStatus')
|
|
460
|
+
const switchbot = await this.switchbotBLE()
|
|
461
|
+
if (switchbot === undefined) {
|
|
462
|
+
await this.BLERefreshConnection(switchbot)
|
|
463
|
+
} else {
|
|
464
|
+
// Start to monitor advertisement packets
|
|
465
|
+
(async () => {
|
|
466
|
+
// Start to monitor advertisement packets
|
|
467
|
+
const serviceData = await this.monitorAdvertisementPackets(switchbot) as blindTiltServiceData
|
|
468
|
+
// Update HomeKit
|
|
469
|
+
if (serviceData.model === SwitchBotBLEModel.BlindTilt && serviceData.modelName === SwitchBotBLEModelName.BlindTilt) {
|
|
470
|
+
this.serviceData = serviceData
|
|
471
|
+
await this.BLEparseStatus()
|
|
472
|
+
await this.updateHomeKitCharacteristics()
|
|
473
|
+
} else {
|
|
474
|
+
await this.errorLog(`failed to get serviceData, serviceData: ${serviceData}`)
|
|
475
|
+
await this.BLERefreshConnection(switchbot)
|
|
476
|
+
}
|
|
477
|
+
})()
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
async registerPlatformBLE(): Promise<void> {
|
|
482
|
+
await this.debugLog('registerPlatformBLE')
|
|
395
483
|
if (this.config.options?.BLE) {
|
|
396
|
-
await this.debugLog('is listening to Platform BLE.')
|
|
397
|
-
this.device.bleMac = this.device.deviceId!.match(/.{1,2}/g)!.join(':').toLowerCase()
|
|
398
|
-
await this.debugLog(`bleMac: ${this.device.bleMac}`)
|
|
484
|
+
await this.debugLog('is listening to Platform BLE.')
|
|
485
|
+
this.device.bleMac = this.device.deviceId!.match(/.{1,2}/g)!.join(':').toLowerCase()
|
|
486
|
+
await this.debugLog(`bleMac: ${this.device.bleMac}`)
|
|
399
487
|
this.platform.bleEventHandler[this.device.bleMac] = async (context: blindTiltServiceData) => {
|
|
400
488
|
try {
|
|
401
|
-
await this.debugLog(`received BLE: ${JSON.stringify(context)}`)
|
|
402
|
-
this.serviceData = context
|
|
403
|
-
await this.BLEparseStatus()
|
|
404
|
-
await this.updateHomeKitCharacteristics()
|
|
489
|
+
await this.debugLog(`received BLE: ${JSON.stringify(context)}`)
|
|
490
|
+
this.serviceData = context
|
|
491
|
+
await this.BLEparseStatus()
|
|
492
|
+
await this.updateHomeKitCharacteristics()
|
|
405
493
|
} catch (e: any) {
|
|
406
|
-
await this.errorLog(`failed to handle BLE. Received: ${JSON.stringify(context)} Error: ${e}`)
|
|
494
|
+
await this.errorLog(`failed to handle BLE. Received: ${JSON.stringify(context)} Error: ${e}`)
|
|
407
495
|
}
|
|
408
|
-
};
|
|
409
|
-
} else {
|
|
410
|
-
await this.debugLog('is using Device BLE Scanning.');
|
|
411
|
-
const switchbot = await this.switchbotBLE();
|
|
412
|
-
if (switchbot === undefined) {
|
|
413
|
-
await this.BLERefreshConnection(switchbot);
|
|
414
|
-
} else {
|
|
415
|
-
// Start to monitor advertisement packets
|
|
416
|
-
(async () => {
|
|
417
|
-
// Start to monitor advertisement packets
|
|
418
|
-
const serviceData = await this.monitorAdvertisementPackets(switchbot) as blindTiltServiceData;
|
|
419
|
-
// Update HomeKit
|
|
420
|
-
if (serviceData.model === SwitchBotBLEModel.BlindTilt && serviceData.modelName === SwitchBotBLEModelName.BlindTilt) {
|
|
421
|
-
this.serviceData = serviceData;
|
|
422
|
-
await this.BLEparseStatus();
|
|
423
|
-
await this.updateHomeKitCharacteristics();
|
|
424
|
-
} else {
|
|
425
|
-
await this.errorLog(`failed to get serviceData, serviceData: ${serviceData}`);
|
|
426
|
-
await this.BLERefreshConnection(switchbot);
|
|
427
|
-
}
|
|
428
|
-
})();
|
|
429
496
|
}
|
|
497
|
+
} else {
|
|
498
|
+
await this.debugLog('is not listening to Platform BLE')
|
|
430
499
|
}
|
|
431
500
|
}
|
|
432
501
|
|
|
433
502
|
async openAPIRefreshStatus(): Promise<void> {
|
|
434
|
-
await this.debugLog('openAPIRefreshStatus')
|
|
503
|
+
await this.debugLog('openAPIRefreshStatus')
|
|
435
504
|
try {
|
|
436
|
-
const { body, statusCode } = await this.deviceRefreshStatus()
|
|
437
|
-
const deviceStatus: any = await body.json()
|
|
438
|
-
await this.debugLog(`statusCode: ${statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`)
|
|
505
|
+
const { body, statusCode } = await this.deviceRefreshStatus()
|
|
506
|
+
const deviceStatus: any = await body.json()
|
|
507
|
+
await this.debugLog(`statusCode: ${statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`)
|
|
439
508
|
if (await this.successfulStatusCodes(statusCode, deviceStatus)) {
|
|
440
|
-
await this.debugSuccessLog(`statusCode: ${statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`)
|
|
441
|
-
this.deviceStatus = deviceStatus.body
|
|
442
|
-
await this.openAPIparseStatus()
|
|
443
|
-
await this.updateHomeKitCharacteristics()
|
|
509
|
+
await this.debugSuccessLog(`statusCode: ${statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`)
|
|
510
|
+
this.deviceStatus = deviceStatus.body
|
|
511
|
+
await this.openAPIparseStatus()
|
|
512
|
+
await this.updateHomeKitCharacteristics()
|
|
444
513
|
} else {
|
|
445
|
-
await this.debugWarnLog(`statusCode: ${statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`)
|
|
446
|
-
await this.debugWarnLog(statusCode, deviceStatus)
|
|
514
|
+
await this.debugWarnLog(`statusCode: ${statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`)
|
|
515
|
+
await this.debugWarnLog(statusCode, deviceStatus)
|
|
447
516
|
}
|
|
448
517
|
} catch (e: any) {
|
|
449
|
-
await this.apiError(e)
|
|
450
|
-
await this.errorLog(`failed openAPIRefreshStatus with ${this.device.connectionType} Connection, Error Message: ${JSON.stringify(e.message)}`)
|
|
518
|
+
await this.apiError(e)
|
|
519
|
+
await this.errorLog(`failed openAPIRefreshStatus with ${this.device.connectionType} Connection, Error Message: ${JSON.stringify(e.message)}`)
|
|
451
520
|
}
|
|
452
521
|
}
|
|
453
522
|
|
|
454
523
|
async registerWebhook(): Promise<void> {
|
|
455
524
|
if (this.device.webhook) {
|
|
456
|
-
await this.debugLog('is listening webhook.')
|
|
525
|
+
await this.debugLog('is listening webhook.')
|
|
457
526
|
this.platform.webhookEventHandler[this.device.deviceId] = async (context: blindTiltWebhookContext) => {
|
|
458
527
|
try {
|
|
459
|
-
await this.debugLog(`received Webhook: ${JSON.stringify(context)}`)
|
|
460
|
-
this.webhookContext = context
|
|
461
|
-
await this.parseStatusWebhook()
|
|
462
|
-
await this.updateHomeKitCharacteristics()
|
|
528
|
+
await this.debugLog(`received Webhook: ${JSON.stringify(context)}`)
|
|
529
|
+
this.webhookContext = context
|
|
530
|
+
await this.parseStatusWebhook()
|
|
531
|
+
await this.updateHomeKitCharacteristics()
|
|
463
532
|
} catch (e: any) {
|
|
464
|
-
await this.errorLog(`failed to handle webhook. Received: ${JSON.stringify(context)} Error: ${e}`)
|
|
533
|
+
await this.errorLog(`failed to handle webhook. Received: ${JSON.stringify(context)} Error: ${e}`)
|
|
465
534
|
}
|
|
466
|
-
}
|
|
535
|
+
}
|
|
467
536
|
} else {
|
|
468
|
-
await this.debugLog('is not listening webhook.')
|
|
537
|
+
await this.debugLog('is not listening webhook.')
|
|
469
538
|
}
|
|
470
539
|
}
|
|
471
540
|
|
|
472
541
|
async pushChanges(): Promise<void> {
|
|
473
542
|
if (!this.device.enableCloudService && this.OpenAPI) {
|
|
474
|
-
await this.errorLog(`pushChanges enableCloudService: ${this.device.enableCloudService}`)
|
|
543
|
+
await this.errorLog(`pushChanges enableCloudService: ${this.device.enableCloudService}`)
|
|
475
544
|
} else if (this.BLE) {
|
|
476
|
-
await this.BLEpushChanges()
|
|
545
|
+
await this.BLEpushChanges()
|
|
477
546
|
} else if (this.OpenAPI && this.platform.config.credentials?.token) {
|
|
478
|
-
await this.openAPIpushChanges()
|
|
547
|
+
await this.openAPIpushChanges()
|
|
479
548
|
} else {
|
|
480
|
-
await this.offlineOff()
|
|
481
|
-
await this.debugWarnLog(`Connection Type: ${this.device.connectionType}, pushChanges will not happen.`)
|
|
549
|
+
await this.offlineOff()
|
|
550
|
+
await this.debugWarnLog(`Connection Type: ${this.device.connectionType}, pushChanges will not happen.`)
|
|
482
551
|
}
|
|
483
552
|
// Refresh the status from the API
|
|
484
553
|
interval(15000)
|
|
485
554
|
.pipe(skipWhile(() => this.blindTiltUpdateInProgress))
|
|
486
555
|
.pipe(take(1))
|
|
487
556
|
.subscribe(async () => {
|
|
488
|
-
await this.refreshStatus()
|
|
489
|
-
})
|
|
557
|
+
await this.refreshStatus()
|
|
558
|
+
})
|
|
490
559
|
}
|
|
491
560
|
|
|
492
561
|
async BLEpushChanges(): Promise<void> {
|
|
493
|
-
await this.debugLog('BLEpushChanges')
|
|
562
|
+
await this.debugLog('BLEpushChanges')
|
|
494
563
|
if (this.WindowCovering.TargetPosition !== this.WindowCovering.CurrentPosition) {
|
|
495
|
-
await this.debugLog(`BLEpushChanges On: ${this.WindowCovering.TargetPosition} OnCached: ${this.WindowCovering.CurrentPosition}`)
|
|
496
|
-
const switchbot = await this.platform.connectBLE(this.accessory, this.device)
|
|
497
|
-
await this.convertBLEAddress()
|
|
498
|
-
const { setPositionMode, Mode }: { setPositionMode: number
|
|
499
|
-
await this.debugLog(`Mode: ${Mode}, setPositionMode: ${setPositionMode}`)
|
|
564
|
+
await this.debugLog(`BLEpushChanges On: ${this.WindowCovering.TargetPosition} OnCached: ${this.WindowCovering.CurrentPosition}`)
|
|
565
|
+
const switchbot = await this.platform.connectBLE(this.accessory, this.device)
|
|
566
|
+
await this.convertBLEAddress()
|
|
567
|
+
const { setPositionMode, Mode }: { setPositionMode: number, Mode: string } = await this.setPerformance()
|
|
568
|
+
await this.debugLog(`Mode: ${Mode}, setPositionMode: ${setPositionMode}`)
|
|
500
569
|
if (switchbot !== false) {
|
|
501
570
|
switchbot
|
|
502
571
|
.discover({ model: this.device.bleModel, quick: true, id: this.device.bleMac })
|
|
@@ -504,82 +573,78 @@ export class BlindTilt extends deviceBase {
|
|
|
504
573
|
return await this.retryBLE({
|
|
505
574
|
max: await this.maxRetryBLE(),
|
|
506
575
|
fn: async () => {
|
|
507
|
-
return await device_list[0].runToPos(100 - Number(this.WindowCovering.TargetPosition), setPositionMode)
|
|
576
|
+
return await device_list[0].runToPos(100 - Number(this.WindowCovering.TargetPosition), setPositionMode)
|
|
508
577
|
},
|
|
509
|
-
})
|
|
578
|
+
})
|
|
510
579
|
})
|
|
511
580
|
.then(async () => {
|
|
512
|
-
await this.successLog(`TargetPostion: ${this.WindowCovering.TargetPosition} sent over SwitchBot BLE, sent successfully`)
|
|
513
|
-
await this.updateHomeKitCharacteristics()
|
|
581
|
+
await this.successLog(`TargetPostion: ${this.WindowCovering.TargetPosition} sent over SwitchBot BLE, sent successfully`)
|
|
582
|
+
await this.updateHomeKitCharacteristics()
|
|
514
583
|
})
|
|
515
584
|
.catch(async (e: any) => {
|
|
516
|
-
await this.apiError(e)
|
|
517
|
-
await this.errorLog(`failed BLEpushChanges with ${this.device.connectionType} Connection, Error Message: ${JSON.stringify(e.message)}`)
|
|
518
|
-
await this.BLEPushConnection()
|
|
519
|
-
})
|
|
585
|
+
await this.apiError(e)
|
|
586
|
+
await this.errorLog(`failed BLEpushChanges with ${this.device.connectionType} Connection, Error Message: ${JSON.stringify(e.message)}`)
|
|
587
|
+
await this.BLEPushConnection()
|
|
588
|
+
})
|
|
520
589
|
} else {
|
|
521
|
-
await this.errorLog(`wasn't able to establish BLE Connection, node-switchbot: ${switchbot}`)
|
|
522
|
-
await this.BLEPushConnection()
|
|
590
|
+
await this.errorLog(`wasn't able to establish BLE Connection, node-switchbot: ${switchbot}`)
|
|
591
|
+
await this.BLEPushConnection()
|
|
523
592
|
}
|
|
524
593
|
} else {
|
|
525
|
-
await this.debugLog(`No changes (BLEpushChanges), TargetPosition: ${this.WindowCovering.TargetPosition}
|
|
526
|
-
+ ` CurrentPosition: ${this.WindowCovering.CurrentPosition}`);
|
|
594
|
+
await this.debugLog(`No changes (BLEpushChanges), TargetPosition: ${this.WindowCovering.TargetPosition}, CurrentPosition: ${this.WindowCovering.CurrentPosition}`)
|
|
527
595
|
}
|
|
528
596
|
}
|
|
529
597
|
|
|
530
598
|
async openAPIpushChanges(): Promise<void> {
|
|
531
|
-
await this.debugLog('openAPIpushChanges')
|
|
532
|
-
const hasDifferentAndRelevantHorizontalTiltAngle
|
|
533
|
-
this.mappingMode === BlindTiltMappingMode.UseTiltForDirection
|
|
534
|
-
&& this.WindowCovering.TargetHorizontalTiltAngle !== this.WindowCovering.CurrentHorizontalTiltAngle
|
|
599
|
+
await this.debugLog('openAPIpushChanges')
|
|
600
|
+
const hasDifferentAndRelevantHorizontalTiltAngle
|
|
601
|
+
= this.mappingMode === BlindTiltMappingMode.UseTiltForDirection
|
|
602
|
+
&& this.WindowCovering.TargetHorizontalTiltAngle !== this.WindowCovering.CurrentHorizontalTiltAngle
|
|
535
603
|
if (this.WindowCovering.TargetPosition !== this.WindowCovering.CurrentPosition
|
|
536
604
|
|| hasDifferentAndRelevantHorizontalTiltAngle || this.device.disableCaching) {
|
|
537
|
-
const [direction, position] = this.mapHomekitValuesToDeviceValues(Number(this.WindowCovering.TargetPosition),
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
await this.debugLog(`
|
|
541
|
-
|
|
542
|
-
let bodyChange: string;
|
|
605
|
+
const [direction, position] = this.mapHomekitValuesToDeviceValues(Number(this.WindowCovering.TargetPosition), Number(this.WindowCovering.TargetHorizontalTiltAngle))
|
|
606
|
+
const { Mode, setPositionMode }: { setPositionMode: number, Mode: string } = await this.setPerformance()
|
|
607
|
+
await this.debugLog(`Pushing ${this.WindowCovering.TargetPosition} (device = ${direction};${position})`)
|
|
608
|
+
await this.debugLog(`Mode: ${Mode}, setPositionMode: ${setPositionMode}`)
|
|
609
|
+
let bodyChange: string
|
|
543
610
|
if (position === 100) {
|
|
544
611
|
bodyChange = JSON.stringify({
|
|
545
612
|
command: 'fullyOpen',
|
|
546
613
|
parameter: 'default',
|
|
547
614
|
commandType: 'command',
|
|
548
|
-
})
|
|
615
|
+
})
|
|
549
616
|
} else if (position === 0) {
|
|
550
617
|
bodyChange = JSON.stringify({
|
|
551
618
|
command: direction === 'up' ? 'closeUp' : 'closeDown',
|
|
552
619
|
parameter: 'default',
|
|
553
620
|
commandType: 'command',
|
|
554
|
-
})
|
|
621
|
+
})
|
|
555
622
|
} else {
|
|
556
623
|
bodyChange = JSON.stringify({
|
|
557
624
|
command: 'setPosition',
|
|
558
625
|
parameter: `${direction};${position}`,
|
|
559
626
|
commandType: 'command',
|
|
560
|
-
})
|
|
627
|
+
})
|
|
561
628
|
}
|
|
562
|
-
await this.debugLog(`SwitchBot OpenAPI bodyChange: ${JSON.stringify(bodyChange)}`)
|
|
629
|
+
await this.debugLog(`SwitchBot OpenAPI bodyChange: ${JSON.stringify(bodyChange)}`)
|
|
563
630
|
try {
|
|
564
|
-
const { body, statusCode } = await this.pushChangeRequest(bodyChange)
|
|
565
|
-
const deviceStatus: any = await body.json()
|
|
566
|
-
await this.debugLog(`statusCode: ${statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`)
|
|
631
|
+
const { body, statusCode } = await this.pushChangeRequest(bodyChange)
|
|
632
|
+
const deviceStatus: any = await body.json()
|
|
633
|
+
await this.debugLog(`statusCode: ${statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`)
|
|
567
634
|
if (await this.successfulStatusCodes(statusCode, deviceStatus)) {
|
|
568
|
-
await this.debugSuccessLog(`statusCode: ${statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`)
|
|
569
|
-
await this.updateHomeKitCharacteristics()
|
|
635
|
+
await this.debugSuccessLog(`statusCode: ${statusCode}, deviceStatus: ${JSON.stringify(deviceStatus)}`)
|
|
636
|
+
await this.updateHomeKitCharacteristics()
|
|
570
637
|
} else {
|
|
571
|
-
await this.statusCode(statusCode)
|
|
572
|
-
await this.statusCode(deviceStatus.statusCode)
|
|
638
|
+
await this.statusCode(statusCode)
|
|
639
|
+
await this.statusCode(deviceStatus.statusCode)
|
|
573
640
|
}
|
|
574
641
|
} catch (e: any) {
|
|
575
|
-
await this.apiError(e)
|
|
576
|
-
await this.errorLog(`failed openAPIpushChanges with ${this.device.connectionType} Connection, Error Message: ${JSON.stringify(e.message)}`)
|
|
642
|
+
await this.apiError(e)
|
|
643
|
+
await this.errorLog(`failed openAPIpushChanges with ${this.device.connectionType} Connection, Error Message: ${JSON.stringify(e.message)}`)
|
|
577
644
|
}
|
|
578
645
|
} else {
|
|
579
|
-
await this.debugLog(`No changes (openAPIpushChanges), TargetPosition: ${this.WindowCovering.TargetPosition}
|
|
580
|
-
|
|
581
|
-
await this.debugLog(`No changes (openAPIpushChanges), TargetHorizontalTiltAngle: ${this.WindowCovering.TargetHorizontalTiltAngle},`
|
|
582
|
-
+ ` CurrentHorizontalTiltAngle: ${this.WindowCovering.CurrentHorizontalTiltAngle}`);
|
|
646
|
+
await this.debugLog(`No changes (openAPIpushChanges), TargetPosition: ${this.WindowCovering.TargetPosition}, CurrentPosition: ${this.WindowCovering.CurrentPosition}`)
|
|
647
|
+
await this.debugLog(`No changes (openAPIpushChanges), TargetHorizontalTiltAngle: ${this.WindowCovering.TargetHorizontalTiltAngle}, CurrentHorizontalTiltAngle: ${this.WindowCovering.CurrentHorizontalTiltAngle}`)
|
|
583
648
|
}
|
|
584
649
|
}
|
|
585
650
|
|
|
@@ -588,15 +653,15 @@ export class BlindTilt extends deviceBase {
|
|
|
588
653
|
*/
|
|
589
654
|
async TargetHorizontalTiltAngleSet(value: CharacteristicValue): Promise<void> {
|
|
590
655
|
if (this.WindowCovering.TargetHorizontalTiltAngle !== this.accessory.context.TargetHorizontalTiltAngle) {
|
|
591
|
-
await this.debugLog(`Set TargetHorizontalTiltAngle: ${value}`)
|
|
656
|
+
await this.debugLog(`Set TargetHorizontalTiltAngle: ${value}`)
|
|
592
657
|
} else {
|
|
593
|
-
await this.debugLog(`No changes, TargetHorizontalTiltAngle: ${value}`)
|
|
658
|
+
await this.debugLog(`No changes, TargetHorizontalTiltAngle: ${value}`)
|
|
594
659
|
}
|
|
595
660
|
|
|
596
|
-
//value = value < 0 ? -90 : 90;
|
|
597
|
-
this.WindowCovering.TargetHorizontalTiltAngle = value
|
|
598
|
-
await this.mqtt('TargetHorizontalTiltAngle', this.WindowCovering.TargetHorizontalTiltAngle)
|
|
599
|
-
await this.startUpdatingBlindTiltIfNeeded()
|
|
661
|
+
// value = value < 0 ? -90 : 90;
|
|
662
|
+
this.WindowCovering.TargetHorizontalTiltAngle = value
|
|
663
|
+
await this.mqtt('TargetHorizontalTiltAngle', this.WindowCovering.TargetHorizontalTiltAngle)
|
|
664
|
+
await this.startUpdatingBlindTiltIfNeeded()
|
|
600
665
|
}
|
|
601
666
|
|
|
602
667
|
/**
|
|
@@ -604,172 +669,188 @@ export class BlindTilt extends deviceBase {
|
|
|
604
669
|
*/
|
|
605
670
|
async TargetPositionSet(value: CharacteristicValue): Promise<void> {
|
|
606
671
|
if (this.WindowCovering.TargetPosition !== this.accessory.context.TargetPosition) {
|
|
607
|
-
await this.debugLog(`Set TargetPosition: ${value}`)
|
|
672
|
+
await this.debugLog(`Set TargetPosition: ${value}`)
|
|
608
673
|
} else {
|
|
609
|
-
await this.debugLog(`No changes, TargetPosition: ${value}`)
|
|
674
|
+
await this.debugLog(`No changes, TargetPosition: ${value}`)
|
|
610
675
|
}
|
|
611
676
|
|
|
612
|
-
this.WindowCovering.TargetPosition = value
|
|
613
|
-
await this.mqtt('TargetPosition', this.WindowCovering.TargetPosition)
|
|
614
|
-
await this.startUpdatingBlindTiltIfNeeded()
|
|
677
|
+
this.WindowCovering.TargetPosition = value
|
|
678
|
+
await this.mqtt('TargetPosition', this.WindowCovering.TargetPosition)
|
|
679
|
+
await this.startUpdatingBlindTiltIfNeeded()
|
|
615
680
|
}
|
|
616
681
|
|
|
617
682
|
async startUpdatingBlindTiltIfNeeded(): Promise<void> {
|
|
618
|
-
await this.setMinMax()
|
|
619
|
-
await this.debugLog('setMinMax')
|
|
683
|
+
await this.setMinMax()
|
|
684
|
+
await this.debugLog('setMinMax')
|
|
620
685
|
if (this.WindowCovering.TargetPosition > this.WindowCovering.CurrentPosition
|
|
621
686
|
|| this.WindowCovering.TargetHorizontalTiltAngle !== this.WindowCovering.CurrentHorizontalTiltAngle) {
|
|
622
|
-
this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.INCREASING
|
|
623
|
-
this.setNewTarget = true
|
|
624
|
-
await this.debugLog(`value: ${this.WindowCovering.CurrentPosition}, CurrentPosition: ${this.WindowCovering.CurrentPosition}`)
|
|
687
|
+
this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.INCREASING
|
|
688
|
+
this.setNewTarget = true
|
|
689
|
+
await this.debugLog(`value: ${this.WindowCovering.CurrentPosition}, CurrentPosition: ${this.WindowCovering.CurrentPosition}`)
|
|
625
690
|
} else if (this.WindowCovering.TargetPosition < this.WindowCovering.CurrentPosition) {
|
|
626
|
-
this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.DECREASING
|
|
627
|
-
this.setNewTarget = true
|
|
628
|
-
await this.debugLog(`value: ${this.WindowCovering.CurrentPosition}, CurrentPosition: ${this.WindowCovering.CurrentPosition}`)
|
|
691
|
+
this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.DECREASING
|
|
692
|
+
this.setNewTarget = true
|
|
693
|
+
await this.debugLog(`value: ${this.WindowCovering.CurrentPosition}, CurrentPosition: ${this.WindowCovering.CurrentPosition}`)
|
|
629
694
|
} else {
|
|
630
|
-
this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.STOPPED
|
|
631
|
-
this.setNewTarget = false
|
|
632
|
-
await this.debugLog(`value: ${this.WindowCovering.CurrentPosition}, CurrentPosition: ${this.WindowCovering.CurrentPosition}`)
|
|
695
|
+
this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.STOPPED
|
|
696
|
+
this.setNewTarget = false
|
|
697
|
+
await this.debugLog(`value: ${this.WindowCovering.CurrentPosition}, CurrentPosition: ${this.WindowCovering.CurrentPosition}`)
|
|
633
698
|
}
|
|
634
|
-
this.WindowCovering.Service.setCharacteristic(this.hap.Characteristic.PositionState, this.WindowCovering.PositionState)
|
|
635
|
-
this.WindowCovering.Service.getCharacteristic(this.hap.Characteristic.PositionState).updateValue(this.WindowCovering.PositionState)
|
|
699
|
+
this.WindowCovering.Service.setCharacteristic(this.hap.Characteristic.PositionState, this.WindowCovering.PositionState)
|
|
700
|
+
this.WindowCovering.Service.getCharacteristic(this.hap.Characteristic.PositionState).updateValue(this.WindowCovering.PositionState)
|
|
636
701
|
|
|
637
702
|
/**
|
|
638
703
|
* If Blind Tilt movement time is short, the moving flag from backend is always false.
|
|
639
704
|
* The minimum time depends on the network control latency.
|
|
640
705
|
*/
|
|
641
|
-
clearTimeout(this.setNewTargetTimer)
|
|
642
|
-
await this.debugLog(`deviceUpdateRate: ${this.deviceUpdateRate}`)
|
|
706
|
+
clearTimeout(this.setNewTargetTimer)
|
|
707
|
+
await this.debugLog(`deviceUpdateRate: ${this.deviceUpdateRate}`)
|
|
643
708
|
if (this.setNewTarget) {
|
|
644
709
|
this.setNewTargetTimer = setTimeout(async () => {
|
|
645
|
-
await this.debugLog(`setNewTarget ${this.setNewTarget} timeout`)
|
|
646
|
-
this.setNewTarget = false
|
|
647
|
-
}, this.deviceUpdateRate * 1000)
|
|
710
|
+
await this.debugLog(`setNewTarget ${this.setNewTarget} timeout`)
|
|
711
|
+
this.setNewTarget = false
|
|
712
|
+
}, this.deviceUpdateRate * 1000)
|
|
713
|
+
}
|
|
714
|
+
this.doBlindTiltUpdate.next()
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
/**
|
|
718
|
+
* Handle requests to set the value of the "Target Position" characteristic
|
|
719
|
+
*/
|
|
720
|
+
async OpenModeSwitchSet(value: CharacteristicValue): Promise<void> {
|
|
721
|
+
if (this.OpenModeSwitch && this.device.blindTilt?.silentModeSwitch) {
|
|
722
|
+
this.debugLog(`Silent Open Mode: ${value}`)
|
|
723
|
+
this.OpenModeSwitch.On = value
|
|
724
|
+
this.accessory.context.OpenModeSwitch.On = value
|
|
725
|
+
this.doBlindTiltUpdate.next()
|
|
726
|
+
}
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
/**
|
|
730
|
+
* Handle requests to set the value of the "Target Position" characteristic
|
|
731
|
+
*/
|
|
732
|
+
async CloseModeSwitchSet(value: CharacteristicValue): Promise<void> {
|
|
733
|
+
if (this.CloseModeSwitch && this.device.blindTilt?.silentModeSwitch) {
|
|
734
|
+
this.debugLog(`Silent Close Mode: ${value}`)
|
|
735
|
+
this.CloseModeSwitch.On = value
|
|
736
|
+
this.accessory.context.CloseModeSwitch.On = value
|
|
737
|
+
this.doBlindTiltUpdate.next()
|
|
648
738
|
}
|
|
649
|
-
this.doBlindTiltUpdate.next();
|
|
650
739
|
}
|
|
651
740
|
|
|
652
741
|
async updateHomeKitCharacteristics(): Promise<void> {
|
|
653
|
-
await this.setMinMax()
|
|
742
|
+
await this.setMinMax()
|
|
654
743
|
// CurrentHorizontalTiltAngle
|
|
655
744
|
if (this.mappingMode === BlindTiltMappingMode.UseTiltForDirection) {
|
|
656
|
-
await this.updateCharacteristic(this.WindowCovering.Service, this.hap.Characteristic.CurrentHorizontalTiltAngle,
|
|
657
|
-
this.WindowCovering.CurrentHorizontalTiltAngle, 'CurrentHorizontalTiltAngle');
|
|
745
|
+
await this.updateCharacteristic(this.WindowCovering.Service, this.hap.Characteristic.CurrentHorizontalTiltAngle, this.WindowCovering.CurrentHorizontalTiltAngle, 'CurrentHorizontalTiltAngle')
|
|
658
746
|
}
|
|
659
747
|
// CurrentPosition
|
|
660
|
-
await this.updateCharacteristic(this.WindowCovering.Service, this.hap.Characteristic.CurrentPosition,
|
|
661
|
-
this.WindowCovering.CurrentPosition, 'CurrentPosition');
|
|
748
|
+
await this.updateCharacteristic(this.WindowCovering.Service, this.hap.Characteristic.CurrentPosition, this.WindowCovering.CurrentPosition, 'CurrentPosition')
|
|
662
749
|
// PositionState
|
|
663
|
-
await this.updateCharacteristic(this.WindowCovering.Service, this.hap.Characteristic.PositionState,
|
|
664
|
-
this.WindowCovering.PositionState, 'PositionState');
|
|
750
|
+
await this.updateCharacteristic(this.WindowCovering.Service, this.hap.Characteristic.PositionState, this.WindowCovering.PositionState, 'PositionState')
|
|
665
751
|
// TargetPosition
|
|
666
|
-
await this.updateCharacteristic(this.WindowCovering.Service, this.hap.Characteristic.TargetPosition,
|
|
667
|
-
this.WindowCovering.TargetPosition, 'TargetPosition');
|
|
752
|
+
await this.updateCharacteristic(this.WindowCovering.Service, this.hap.Characteristic.TargetPosition, this.WindowCovering.TargetPosition, 'TargetPosition')
|
|
668
753
|
// CurrentAmbientLightLevel
|
|
669
754
|
if (!this.device.blindTilt?.hide_lightsensor && this.LightSensor?.Service) {
|
|
670
|
-
const history = { time: Math.round(new Date().valueOf() / 1000), lux: this.LightSensor.CurrentAmbientLightLevel }
|
|
671
|
-
await this.updateCharacteristic(this.LightSensor?.Service, this.hap.Characteristic.CurrentAmbientLightLevel,
|
|
672
|
-
this.LightSensor?.CurrentAmbientLightLevel, 'CurrentAmbientLightLevel', history);
|
|
755
|
+
const history = { time: Math.round(new Date().valueOf() / 1000), lux: this.LightSensor.CurrentAmbientLightLevel }
|
|
756
|
+
await this.updateCharacteristic(this.LightSensor?.Service, this.hap.Characteristic.CurrentAmbientLightLevel, this.LightSensor?.CurrentAmbientLightLevel, 'CurrentAmbientLightLevel', history)
|
|
673
757
|
}
|
|
674
758
|
// BatteryLevel
|
|
675
|
-
await this.updateCharacteristic(this.Battery.Service, this.hap.Characteristic.BatteryLevel,
|
|
676
|
-
this.Battery.BatteryLevel, 'BatteryLevel');
|
|
759
|
+
await this.updateCharacteristic(this.Battery.Service, this.hap.Characteristic.BatteryLevel, this.Battery.BatteryLevel, 'BatteryLevel')
|
|
677
760
|
// StatusLowBattery
|
|
678
|
-
await this.updateCharacteristic(this.Battery.Service, this.hap.Characteristic.StatusLowBattery,
|
|
679
|
-
this.Battery.StatusLowBattery, 'StatusLowBattery');
|
|
761
|
+
await this.updateCharacteristic(this.Battery.Service, this.hap.Characteristic.StatusLowBattery, this.Battery.StatusLowBattery, 'StatusLowBattery')
|
|
680
762
|
// ChargingState
|
|
681
|
-
await this.updateCharacteristic(this.Battery.Service, this.hap.Characteristic.ChargingState,
|
|
682
|
-
this.Battery.ChargingState, 'ChargingState');
|
|
763
|
+
await this.updateCharacteristic(this.Battery.Service, this.hap.Characteristic.ChargingState, this.Battery.ChargingState, 'ChargingState')
|
|
683
764
|
}
|
|
684
765
|
|
|
685
766
|
async BLEPushConnection() {
|
|
686
767
|
if (this.platform.config.credentials?.token && this.device.connectionType === 'BLE/OpenAPI') {
|
|
687
|
-
await this.warnLog('Using OpenAPI Connection to Push Changes')
|
|
688
|
-
await this.openAPIpushChanges()
|
|
768
|
+
await this.warnLog('Using OpenAPI Connection to Push Changes')
|
|
769
|
+
await this.openAPIpushChanges()
|
|
689
770
|
}
|
|
690
771
|
}
|
|
691
772
|
|
|
692
773
|
async BLERefreshConnection(switchbot: any): Promise<void> {
|
|
693
|
-
await this.errorLog(`wasn't able to establish BLE Connection, node-switchbot: ${switchbot}`)
|
|
774
|
+
await this.errorLog(`wasn't able to establish BLE Connection, node-switchbot: ${switchbot}`)
|
|
694
775
|
if (this.platform.config.credentials?.token && this.device.connectionType === 'BLE/OpenAPI') {
|
|
695
|
-
await this.warnLog('Using OpenAPI Connection to Refresh Status')
|
|
696
|
-
await this.openAPIRefreshStatus()
|
|
776
|
+
await this.warnLog('Using OpenAPI Connection to Refresh Status')
|
|
777
|
+
await this.openAPIRefreshStatus()
|
|
697
778
|
}
|
|
698
779
|
}
|
|
699
780
|
|
|
700
781
|
async setPerformance() {
|
|
701
|
-
let setPositionMode: number
|
|
702
|
-
let Mode: string
|
|
782
|
+
let setPositionMode: number
|
|
783
|
+
let Mode: string
|
|
703
784
|
if (Number(this.WindowCovering.TargetPosition) > 50) {
|
|
704
|
-
if (this.device.blindTilt?.setOpenMode === '1') {
|
|
705
|
-
setPositionMode = 1
|
|
706
|
-
Mode = 'Silent Mode'
|
|
707
|
-
} else if (this.device.blindTilt?.setOpenMode === '0') {
|
|
708
|
-
setPositionMode = 0
|
|
709
|
-
Mode = 'Performance Mode'
|
|
785
|
+
if (this.device.blindTilt?.setOpenMode === '1' || this.OpenModeSwitch?.On) {
|
|
786
|
+
setPositionMode = 1
|
|
787
|
+
Mode = 'Silent Mode'
|
|
788
|
+
} else if (this.device.blindTilt?.setOpenMode === '0' || !this.OpenModeSwitch?.On) {
|
|
789
|
+
setPositionMode = 0
|
|
790
|
+
Mode = 'Performance Mode'
|
|
710
791
|
} else {
|
|
711
|
-
setPositionMode = 0
|
|
712
|
-
Mode = 'Default Mode'
|
|
792
|
+
setPositionMode = 0
|
|
793
|
+
Mode = 'Default Mode'
|
|
713
794
|
}
|
|
714
795
|
} else {
|
|
715
|
-
if (this.device.blindTilt?.setCloseMode === '1') {
|
|
716
|
-
setPositionMode = 1
|
|
717
|
-
Mode = 'Silent Mode'
|
|
718
|
-
} else if (this.device.blindTilt?.setOpenMode === '0') {
|
|
719
|
-
setPositionMode = 0
|
|
720
|
-
Mode = 'Performance Mode'
|
|
796
|
+
if (this.device.blindTilt?.setCloseMode === '1' || this.CloseModeSwitch?.On) {
|
|
797
|
+
setPositionMode = 1
|
|
798
|
+
Mode = 'Silent Mode'
|
|
799
|
+
} else if (this.device.blindTilt?.setOpenMode === '0' || !this.CloseModeSwitch?.On) {
|
|
800
|
+
setPositionMode = 0
|
|
801
|
+
Mode = 'Performance Mode'
|
|
721
802
|
} else {
|
|
722
|
-
setPositionMode = 0
|
|
723
|
-
Mode = 'Default Mode'
|
|
803
|
+
setPositionMode = 0
|
|
804
|
+
Mode = 'Default Mode'
|
|
724
805
|
}
|
|
725
806
|
}
|
|
726
|
-
return { setPositionMode, Mode }
|
|
807
|
+
return { setPositionMode, Mode }
|
|
727
808
|
}
|
|
728
809
|
|
|
729
810
|
async setMinMax(): Promise<void> {
|
|
730
811
|
if (this.device.blindTilt?.set_min) {
|
|
731
812
|
if (Number(this.WindowCovering.CurrentPosition) <= this.device.blindTilt?.set_min) {
|
|
732
|
-
this.WindowCovering.CurrentPosition = 0
|
|
813
|
+
this.WindowCovering.CurrentPosition = 0
|
|
733
814
|
}
|
|
734
815
|
}
|
|
735
816
|
if (this.device.blindTilt?.set_max) {
|
|
736
817
|
if (Number(this.WindowCovering.CurrentPosition) >= this.device.blindTilt?.set_max) {
|
|
737
|
-
this.WindowCovering.CurrentPosition = 100
|
|
818
|
+
this.WindowCovering.CurrentPosition = 100
|
|
738
819
|
}
|
|
739
820
|
}
|
|
740
821
|
if (this.device.history) {
|
|
741
|
-
const motion = this.accessory.getService(this.hap.Service.MotionSensor)
|
|
742
|
-
const state = Number(this.WindowCovering.CurrentPosition) > 0 ? 1 : 0
|
|
743
|
-
motion?.updateCharacteristic(this.hap.Characteristic.MotionDetected, state)
|
|
822
|
+
const motion = this.accessory.getService(this.hap.Service.MotionSensor)
|
|
823
|
+
const state = Number(this.WindowCovering.CurrentPosition) > 0 ? 1 : 0
|
|
824
|
+
motion?.updateCharacteristic(this.hap.Characteristic.MotionDetected, state)
|
|
744
825
|
}
|
|
745
826
|
|
|
746
827
|
if (this.mappingMode === BlindTiltMappingMode.UseTiltForDirection) {
|
|
747
|
-
this.WindowCovering.CurrentHorizontalTiltAngle = Number(this.WindowCovering.CurrentHorizontalTiltAngle) < 0 ? -90 : 90
|
|
828
|
+
this.WindowCovering.CurrentHorizontalTiltAngle = Number(this.WindowCovering.CurrentHorizontalTiltAngle) < 0 ? -90 : 90
|
|
748
829
|
}
|
|
749
830
|
}
|
|
750
831
|
|
|
751
832
|
async offlineOff(): Promise<void> {
|
|
752
833
|
if (this.device.offline) {
|
|
753
|
-
this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.CurrentPosition, 100)
|
|
754
|
-
this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.PositionState, this.hap.Characteristic.PositionState.STOPPED)
|
|
755
|
-
this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.TargetPosition, 100)
|
|
756
|
-
this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.CurrentHorizontalTiltAngle, 90)
|
|
757
|
-
this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.TargetHorizontalTiltAngle, 90)
|
|
834
|
+
this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.CurrentPosition, 100)
|
|
835
|
+
this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.PositionState, this.hap.Characteristic.PositionState.STOPPED)
|
|
836
|
+
this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.TargetPosition, 100)
|
|
837
|
+
this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.CurrentHorizontalTiltAngle, 90)
|
|
838
|
+
this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.TargetHorizontalTiltAngle, 90)
|
|
758
839
|
}
|
|
759
840
|
}
|
|
760
841
|
|
|
761
842
|
async apiError(e: any): Promise<void> {
|
|
762
|
-
this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.CurrentPosition, e)
|
|
763
|
-
this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.PositionState, e)
|
|
764
|
-
this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.TargetPosition, e)
|
|
765
|
-
this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.CurrentHorizontalTiltAngle, e)
|
|
766
|
-
this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.TargetHorizontalTiltAngle, e)
|
|
767
|
-
this.Battery.Service.updateCharacteristic(this.hap.Characteristic.BatteryLevel, e)
|
|
768
|
-
this.Battery.Service.updateCharacteristic(this.hap.Characteristic.StatusLowBattery, e)
|
|
769
|
-
this.Battery.Service.updateCharacteristic(this.hap.Characteristic.ChargingState, e)
|
|
843
|
+
this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.CurrentPosition, e)
|
|
844
|
+
this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.PositionState, e)
|
|
845
|
+
this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.TargetPosition, e)
|
|
846
|
+
this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.CurrentHorizontalTiltAngle, e)
|
|
847
|
+
this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.TargetHorizontalTiltAngle, e)
|
|
848
|
+
this.Battery.Service.updateCharacteristic(this.hap.Characteristic.BatteryLevel, e)
|
|
849
|
+
this.Battery.Service.updateCharacteristic(this.hap.Characteristic.StatusLowBattery, e)
|
|
850
|
+
this.Battery.Service.updateCharacteristic(this.hap.Characteristic.ChargingState, e)
|
|
770
851
|
if (!this.device.blindTilt?.hide_lightsensor && this.LightSensor?.Service) {
|
|
771
|
-
this.LightSensor.Service.updateCharacteristic(this.hap.Characteristic.CurrentAmbientLightLevel, e)
|
|
772
|
-
this.LightSensor.Service.updateCharacteristic(this.hap.Characteristic.StatusActive, e)
|
|
852
|
+
this.LightSensor.Service.updateCharacteristic(this.hap.Characteristic.CurrentAmbientLightLevel, e)
|
|
853
|
+
this.LightSensor.Service.updateCharacteristic(this.hap.Characteristic.StatusActive, e)
|
|
773
854
|
}
|
|
774
855
|
}
|
|
775
856
|
|
|
@@ -777,58 +858,58 @@ export class BlindTilt extends deviceBase {
|
|
|
777
858
|
direction: blindTiltStatus['direction'] | blindTiltWebhookContext['direction'],
|
|
778
859
|
slidePosition: blindTiltStatus['slidePosition'] | blindTiltWebhookContext['slidePosition'],
|
|
779
860
|
) {
|
|
780
|
-
const [homekitPosition, homekitTiltAngle] = this.mapDeviceValuesToHomekitValues(Number(slidePosition),
|
|
781
|
-
|
|
782
|
-
await this.debugLog(`
|
|
783
|
-
await this.debugLog(`Homekit Position: ${homekitPosition}`);
|
|
861
|
+
const [homekitPosition, homekitTiltAngle] = this.mapDeviceValuesToHomekitValues(Number(slidePosition), String(direction))
|
|
862
|
+
await this.debugLog(`Slide Position: ${slidePosition}`)
|
|
863
|
+
await this.debugLog(`Homekit Position: ${homekitPosition}`)
|
|
784
864
|
|
|
785
|
-
this.WindowCovering.CurrentPosition = homekitPosition
|
|
786
|
-
await this.setMinMax()
|
|
787
|
-
await this.debugLog(`CurrentPosition: ${this.WindowCovering.CurrentPosition}`)
|
|
865
|
+
this.WindowCovering.CurrentPosition = homekitPosition
|
|
866
|
+
await this.setMinMax()
|
|
867
|
+
await this.debugLog(`CurrentPosition: ${this.WindowCovering.CurrentPosition}`)
|
|
788
868
|
|
|
789
869
|
if (homekitTiltAngle) {
|
|
790
|
-
this.WindowCovering.CurrentHorizontalTiltAngle = homekitTiltAngle
|
|
791
|
-
await this.debugLog(`CurrentHorizontalTiltAngle: ${this.WindowCovering.CurrentHorizontalTiltAngle}`)
|
|
870
|
+
this.WindowCovering.CurrentHorizontalTiltAngle = homekitTiltAngle!
|
|
871
|
+
await this.debugLog(`CurrentHorizontalTiltAngle: ${this.WindowCovering.CurrentHorizontalTiltAngle}`)
|
|
792
872
|
}
|
|
793
873
|
|
|
794
874
|
if (this.setNewTarget) {
|
|
795
|
-
|
|
796
|
-
await this.
|
|
875
|
+
this.blindTiltMoving = true
|
|
876
|
+
await this.infoLog('Checking Status ...')
|
|
877
|
+
await this.setMinMax()
|
|
797
878
|
if (this.WindowCovering.TargetPosition > this.WindowCovering.CurrentPosition
|
|
798
879
|
|| (homekitTiltAngle && this.WindowCovering.TargetHorizontalTiltAngle !== this.WindowCovering.CurrentHorizontalTiltAngle)) {
|
|
799
|
-
await this.debugLog(`Closing, CurrentPosition: ${this.WindowCovering.CurrentPosition}`)
|
|
800
|
-
this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.INCREASING
|
|
801
|
-
this.WindowCovering.Service.getCharacteristic(this.hap.Characteristic.PositionState).updateValue(this.WindowCovering.PositionState)
|
|
802
|
-
await this.debugLog(`Increasing, PositionState: ${this.WindowCovering.PositionState}`)
|
|
880
|
+
await this.debugLog(`Closing, CurrentPosition: ${this.WindowCovering.CurrentPosition}`)
|
|
881
|
+
this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.INCREASING
|
|
882
|
+
this.WindowCovering.Service.getCharacteristic(this.hap.Characteristic.PositionState).updateValue(this.WindowCovering.PositionState)
|
|
883
|
+
await this.debugLog(`Increasing, PositionState: ${this.WindowCovering.PositionState}`)
|
|
803
884
|
} else if (this.WindowCovering.TargetPosition < this.WindowCovering.CurrentPosition) {
|
|
804
|
-
await this.debugLog(`Opening, CurrentPosition: ${this.WindowCovering.CurrentPosition}`)
|
|
805
|
-
this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.DECREASING
|
|
806
|
-
this.WindowCovering.Service.getCharacteristic(this.hap.Characteristic.PositionState).updateValue(this.WindowCovering.PositionState)
|
|
807
|
-
await this.debugLog(`Decreasing, PositionState: ${this.WindowCovering.PositionState}`)
|
|
885
|
+
await this.debugLog(`Opening, CurrentPosition: ${this.WindowCovering.CurrentPosition}`)
|
|
886
|
+
this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.DECREASING
|
|
887
|
+
this.WindowCovering.Service.getCharacteristic(this.hap.Characteristic.PositionState).updateValue(this.WindowCovering.PositionState)
|
|
888
|
+
await this.debugLog(`Decreasing, PositionState: ${this.WindowCovering.PositionState}`)
|
|
808
889
|
} else {
|
|
809
|
-
await this.debugLog(`Standby because reached position, CurrentPosition: ${this.WindowCovering.CurrentPosition}`)
|
|
810
|
-
this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.STOPPED
|
|
811
|
-
this.WindowCovering.Service.getCharacteristic(this.hap.Characteristic.PositionState).updateValue(this.WindowCovering.PositionState)
|
|
812
|
-
await this.debugLog(`Stopped, PositionState: ${this.WindowCovering.PositionState}`)
|
|
890
|
+
await this.debugLog(`Standby because reached position, CurrentPosition: ${this.WindowCovering.CurrentPosition}`)
|
|
891
|
+
this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.STOPPED
|
|
892
|
+
this.WindowCovering.Service.getCharacteristic(this.hap.Characteristic.PositionState).updateValue(this.WindowCovering.PositionState)
|
|
893
|
+
await this.debugLog(`Stopped, PositionState: ${this.WindowCovering.PositionState}`)
|
|
813
894
|
}
|
|
814
895
|
} else {
|
|
815
|
-
|
|
816
|
-
this.
|
|
896
|
+
this.blindTiltMoving = false
|
|
897
|
+
await this.debugLog(`Standby because device not moving, CurrentPosition: ${this.WindowCovering.CurrentPosition}`)
|
|
898
|
+
this.WindowCovering.TargetPosition = this.WindowCovering.CurrentPosition
|
|
817
899
|
if (homekitTiltAngle) {
|
|
818
|
-
this.WindowCovering.TargetHorizontalTiltAngle = this.WindowCovering.CurrentHorizontalTiltAngle
|
|
900
|
+
this.WindowCovering.TargetHorizontalTiltAngle = this.WindowCovering.CurrentHorizontalTiltAngle
|
|
819
901
|
}
|
|
820
|
-
this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.STOPPED
|
|
821
|
-
await this.debugLog(`Stopped, PositionState: ${this.WindowCovering.PositionState}`)
|
|
902
|
+
this.WindowCovering.PositionState = this.hap.Characteristic.PositionState.STOPPED
|
|
903
|
+
await this.debugLog(`Stopped, PositionState: ${this.WindowCovering.PositionState}`)
|
|
822
904
|
}
|
|
823
|
-
await this.debugLog(`CurrentPosition: ${this.WindowCovering.CurrentPosition}, TargetPosition: ${this.WindowCovering.TargetPosition}
|
|
824
|
-
+ ` PositionState: ${this.WindowCovering.PositionState}`);
|
|
905
|
+
await this.debugLog(`CurrentPosition: ${this.WindowCovering.CurrentPosition}, TargetPosition: ${this.WindowCovering.TargetPosition}, PositionState: ${this.WindowCovering.PositionState}`)
|
|
825
906
|
}
|
|
826
907
|
|
|
827
908
|
/**
|
|
828
909
|
* Maps device values to homekit values
|
|
829
910
|
*
|
|
830
911
|
* @param devicePosition the position as reported by the devide
|
|
831
|
-
* @param
|
|
912
|
+
* @param deviceDirection the direction as reported by the device
|
|
832
913
|
* @returns [homekit position, homekit tiltAngle]
|
|
833
914
|
*/
|
|
834
915
|
mapDeviceValuesToHomekitValues(devicePosition: number, deviceDirection: string): [CharacteristicValue, CharacteristicValue?] {
|
|
@@ -838,44 +919,44 @@ export class BlindTilt extends deviceBase {
|
|
|
838
919
|
|
|
839
920
|
// homekit position 0 => closed
|
|
840
921
|
// homekit position 100 => open
|
|
841
|
-
const direction = deviceDirection === 'up' ? 'up' : 'down'
|
|
842
|
-
this.debugLog(`Mapping device values to homekit values, devicePostion: ${devicePosition}, deviceDirection: ${direction}`)
|
|
922
|
+
const direction = deviceDirection === 'up' ? 'up' : 'down'
|
|
923
|
+
this.debugLog(`Mapping device values to homekit values, devicePostion: ${devicePosition}, deviceDirection: ${direction}`)
|
|
843
924
|
switch (this.mappingMode) {
|
|
844
925
|
case BlindTiltMappingMode.OnlyUp:
|
|
845
926
|
// we only close upwards, so we see anything that is tilted downwards(<50) as open
|
|
846
927
|
if (devicePosition < 50) {
|
|
847
|
-
return [100, undefined]
|
|
928
|
+
return [100, undefined] // fully open in homekit
|
|
848
929
|
} else {
|
|
849
930
|
// we range from 50->100, with 100 being closed, so map to homekit by scaling to 0..100 and then reversing
|
|
850
|
-
return [100 - (devicePosition - 50) * 2, undefined]
|
|
931
|
+
return [100 - (devicePosition - 50) * 2, undefined]
|
|
851
932
|
}
|
|
852
933
|
|
|
853
934
|
case BlindTiltMappingMode.OnlyDown:
|
|
854
935
|
// we only close downwards, so we see anything that is tilted upwards(>50) as upwards
|
|
855
936
|
if (devicePosition > 50) {
|
|
856
|
-
return [100, undefined]
|
|
937
|
+
return [100, undefined] // fully open in homekit
|
|
857
938
|
} else {
|
|
858
939
|
// we range from 0..50 so scale to homekit and then reverse
|
|
859
|
-
return [devicePosition * 2, undefined]
|
|
940
|
+
return [devicePosition * 2, undefined]
|
|
860
941
|
}
|
|
861
942
|
|
|
862
943
|
case BlindTiltMappingMode.DownAndUp:
|
|
863
944
|
// we close both ways with closed downwards being 0 in homekit and closed upwards in homekit being 100. Open is 50 in homekit
|
|
864
|
-
return [devicePosition, undefined]
|
|
945
|
+
return [devicePosition, undefined]
|
|
865
946
|
|
|
866
947
|
case BlindTiltMappingMode.UpAndDown:
|
|
867
948
|
// we close both ways with closed downwards being 1000 in homekit and closed upwards in homekit being 0. Open is 50 in homekit.,
|
|
868
949
|
// so we reverse the value
|
|
869
|
-
return [100 - devicePosition, undefined]
|
|
950
|
+
return [100 - devicePosition, undefined]
|
|
870
951
|
|
|
871
952
|
case BlindTiltMappingMode.UseTiltForDirection:
|
|
872
953
|
// we use tilt for direction, so being closed downwards is 0 in homekit with -90 tilt, while being closed upwards is 0 with 90 tilt.
|
|
873
954
|
if (devicePosition <= 50) {
|
|
874
955
|
// downwards tilted, so we range from 0..50, with 0 being closed and 50 being open, so scale.
|
|
875
|
-
return [devicePosition * 2, -90]
|
|
956
|
+
return [devicePosition * 2, -90]
|
|
876
957
|
} else {
|
|
877
958
|
// upwards tilted, so we range from 50..100, with 50 being open and 100 being closed, so scale and rever
|
|
878
|
-
return [100 - (devicePosition - 50) * 2, 90]
|
|
959
|
+
return [100 - (devicePosition - 50) * 2, 90]
|
|
879
960
|
}
|
|
880
961
|
}
|
|
881
962
|
}
|
|
@@ -884,7 +965,7 @@ export class BlindTilt extends deviceBase {
|
|
|
884
965
|
* Maps homekit values to device values
|
|
885
966
|
*
|
|
886
967
|
* @param homekitPosition the position as reported by homekit
|
|
887
|
-
* @param homekitTiltAngle
|
|
968
|
+
* @param homekitTiltAngle the tilt angle as reported by homekit
|
|
888
969
|
* @returns [device position, device direction]
|
|
889
970
|
*/
|
|
890
971
|
mapHomekitValuesToDeviceValues(homekitPosition: number, homekitTiltAngle: number): [string, number] {
|
|
@@ -899,10 +980,10 @@ export class BlindTilt extends deviceBase {
|
|
|
899
980
|
switch (this.mappingMode) {
|
|
900
981
|
case BlindTiltMappingMode.OnlyUp:
|
|
901
982
|
// invert
|
|
902
|
-
return ['up', homekitPosition]
|
|
983
|
+
return ['up', homekitPosition]
|
|
903
984
|
case BlindTiltMappingMode.OnlyDown:
|
|
904
985
|
// invert
|
|
905
|
-
return ['down', homekitPosition]
|
|
986
|
+
return ['down', homekitPosition]
|
|
906
987
|
|
|
907
988
|
case BlindTiltMappingMode.DownAndUp:
|
|
908
989
|
// homekit 0 = downwards closed,
|
|
@@ -910,10 +991,10 @@ export class BlindTilt extends deviceBase {
|
|
|
910
991
|
// homekit 100 = upwards closed
|
|
911
992
|
if (homekitPosition <= 50) {
|
|
912
993
|
// homekit 0..50 -> device 100..0 so scale and invert
|
|
913
|
-
return ['down', 100 - homekitPosition * 2]
|
|
994
|
+
return ['down', 100 - homekitPosition * 2]
|
|
914
995
|
} else {
|
|
915
996
|
// homekit 50..100 -> device 0..100, so rebase, scale and invert
|
|
916
|
-
return ['up', (homekitPosition - 50) * 2]
|
|
997
|
+
return ['up', (homekitPosition - 50) * 2]
|
|
917
998
|
}
|
|
918
999
|
|
|
919
1000
|
case BlindTiltMappingMode.UpAndDown:
|
|
@@ -922,10 +1003,10 @@ export class BlindTilt extends deviceBase {
|
|
|
922
1003
|
// homekit 100 = upwards closed
|
|
923
1004
|
if (homekitPosition <= 50) {
|
|
924
1005
|
// homekit 0..50 -> device 0..100 so scale and invert
|
|
925
|
-
return ['up', homekitPosition * 2]
|
|
1006
|
+
return ['up', homekitPosition * 2]
|
|
926
1007
|
} else {
|
|
927
1008
|
// homekit 50..100 -> device 100...0 so scale
|
|
928
|
-
return ['down', 100 - homekitPosition * 2]
|
|
1009
|
+
return ['down', 100 - homekitPosition * 2]
|
|
929
1010
|
}
|
|
930
1011
|
|
|
931
1012
|
case BlindTiltMappingMode.UseTiltForDirection:
|
|
@@ -936,11 +1017,11 @@ export class BlindTilt extends deviceBase {
|
|
|
936
1017
|
if (homekitTiltAngle! <= 0) {
|
|
937
1018
|
// downwards
|
|
938
1019
|
// homekit 0..100 -> device 0..100, so invert
|
|
939
|
-
return ['down', homekitPosition]
|
|
1020
|
+
return ['down', homekitPosition]
|
|
940
1021
|
} else {
|
|
941
1022
|
// upwards
|
|
942
1023
|
// homekit 0..100 -> device 0..100, so invert
|
|
943
|
-
return ['up', homekitPosition]
|
|
1024
|
+
return ['up', homekitPosition]
|
|
944
1025
|
}
|
|
945
1026
|
}
|
|
946
1027
|
}
|