@switchbot/homebridge-switchbot 3.5.0-beta.8 → 3.5.0
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/.vscode/settings.json +4 -1
- package/CHANGELOG.md +4 -1
- package/config.schema.json +170 -26
- package/dist/device/blindtilt.d.ts +21 -96
- package/dist/device/blindtilt.d.ts.map +1 -1
- package/dist/device/blindtilt.js +439 -817
- package/dist/device/blindtilt.js.map +1 -1
- package/dist/device/bot.d.ts +27 -72
- package/dist/device/bot.d.ts.map +1 -1
- package/dist/device/bot.js +835 -865
- package/dist/device/bot.js.map +1 -1
- package/dist/device/ceilinglight.d.ts +15 -69
- package/dist/device/ceilinglight.d.ts.map +1 -1
- package/dist/device/ceilinglight.js +287 -653
- package/dist/device/ceilinglight.js.map +1 -1
- package/dist/device/colorbulb.d.ts +15 -76
- package/dist/device/colorbulb.d.ts.map +1 -1
- package/dist/device/colorbulb.js +354 -732
- package/dist/device/colorbulb.js.map +1 -1
- package/dist/device/contact.d.ts +14 -66
- package/dist/device/contact.d.ts.map +1 -1
- package/dist/device/contact.js +268 -576
- package/dist/device/contact.js.map +1 -1
- package/dist/device/curtain.d.ts +18 -89
- package/dist/device/curtain.d.ts.map +1 -1
- package/dist/device/curtain.js +431 -851
- package/dist/device/curtain.js.map +1 -1
- package/dist/device/device.d.ts +60 -0
- package/dist/device/device.d.ts.map +1 -0
- package/dist/device/device.js +739 -0
- package/dist/device/device.js.map +1 -0
- package/dist/device/fan.d.ts +63 -0
- package/dist/device/fan.d.ts.map +1 -0
- package/dist/device/fan.js +698 -0
- package/dist/device/fan.js.map +1 -0
- package/dist/device/hub.d.ts +15 -60
- package/dist/device/hub.d.ts.map +1 -1
- package/dist/device/hub.js +257 -631
- package/dist/device/hub.js.map +1 -1
- package/dist/device/humidifier.d.ts +11 -66
- package/dist/device/humidifier.d.ts.map +1 -1
- package/dist/device/humidifier.js +266 -629
- package/dist/device/humidifier.js.map +1 -1
- package/dist/device/iosensor.d.ts +12 -64
- package/dist/device/iosensor.d.ts.map +1 -1
- package/dist/device/iosensor.js +215 -615
- package/dist/device/iosensor.js.map +1 -1
- package/dist/device/lightstrip.d.ts +12 -70
- package/dist/device/lightstrip.d.ts.map +1 -1
- package/dist/device/lightstrip.js +336 -645
- package/dist/device/lightstrip.js.map +1 -1
- package/dist/device/lock.d.ts +17 -63
- package/dist/device/lock.d.ts.map +1 -1
- package/dist/device/lock.js +290 -595
- package/dist/device/lock.js.map +1 -1
- package/dist/device/meter.d.ts +15 -64
- package/dist/device/meter.d.ts.map +1 -1
- package/dist/device/meter.js +211 -608
- package/dist/device/meter.js.map +1 -1
- package/dist/device/meterplus.d.ts +15 -65
- package/dist/device/meterplus.d.ts.map +1 -1
- package/dist/device/meterplus.js +205 -615
- package/dist/device/meterplus.js.map +1 -1
- package/dist/device/motion.d.ts +12 -69
- package/dist/device/motion.d.ts.map +1 -1
- package/dist/device/motion.js +202 -563
- package/dist/device/motion.js.map +1 -1
- package/dist/device/plug.d.ts +10 -57
- package/dist/device/plug.d.ts.map +1 -1
- package/dist/device/plug.js +125 -484
- package/dist/device/plug.js.map +1 -1
- package/dist/device/robotvacuumcleaner.d.ts +13 -63
- package/dist/device/robotvacuumcleaner.d.ts.map +1 -1
- package/dist/device/robotvacuumcleaner.js +233 -549
- package/dist/device/robotvacuumcleaner.js.map +1 -1
- package/dist/device/waterdetector.d.ts +11 -63
- package/dist/device/waterdetector.d.ts.map +1 -1
- package/dist/device/waterdetector.js +170 -493
- package/dist/device/waterdetector.js.map +1 -1
- package/dist/homebridge-ui/public/index.html +22 -16
- package/dist/homebridge-ui/server.js +1 -1
- package/dist/homebridge-ui/server.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/irdevice/airconditioner.d.ts +10 -50
- package/dist/irdevice/airconditioner.d.ts.map +1 -1
- package/dist/irdevice/airconditioner.js +340 -468
- package/dist/irdevice/airconditioner.js.map +1 -1
- package/dist/irdevice/airpurifier.d.ts +8 -39
- package/dist/irdevice/airpurifier.d.ts.map +1 -1
- package/dist/irdevice/airpurifier.js +105 -319
- package/dist/irdevice/airpurifier.js.map +1 -1
- package/dist/irdevice/camera.d.ts +7 -36
- package/dist/irdevice/camera.d.ts.map +1 -1
- package/dist/irdevice/camera.js +44 -285
- package/dist/irdevice/camera.js.map +1 -1
- package/dist/irdevice/fan.d.ts +7 -43
- package/dist/irdevice/fan.d.ts.map +1 -1
- package/dist/irdevice/fan.js +92 -350
- package/dist/irdevice/fan.js.map +1 -1
- package/dist/irdevice/irdevice.d.ts +40 -0
- package/dist/irdevice/irdevice.d.ts.map +1 -0
- package/dist/irdevice/irdevice.js +369 -0
- package/dist/irdevice/irdevice.js.map +1 -0
- package/dist/irdevice/light.d.ts +12 -45
- package/dist/irdevice/light.d.ts.map +1 -1
- package/dist/irdevice/light.js +118 -362
- package/dist/irdevice/light.js.map +1 -1
- package/dist/irdevice/other.d.ts +19 -48
- package/dist/irdevice/other.d.ts.map +1 -1
- package/dist/irdevice/other.js +438 -570
- package/dist/irdevice/other.js.map +1 -1
- package/dist/irdevice/tv.d.ts +8 -40
- package/dist/irdevice/tv.d.ts.map +1 -1
- package/dist/irdevice/tv.js +91 -339
- package/dist/irdevice/tv.js.map +1 -1
- package/dist/irdevice/vacuumcleaner.d.ts +7 -36
- package/dist/irdevice/vacuumcleaner.d.ts.map +1 -1
- package/dist/irdevice/vacuumcleaner.js +45 -285
- package/dist/irdevice/vacuumcleaner.js.map +1 -1
- package/dist/irdevice/waterheater.d.ts +7 -36
- package/dist/irdevice/waterheater.d.ts.map +1 -1
- package/dist/irdevice/waterheater.js +47 -291
- package/dist/irdevice/waterheater.js.map +1 -1
- package/dist/platform.d.ts +22 -8
- package/dist/platform.d.ts.map +1 -1
- package/dist/platform.js +342 -191
- package/dist/platform.js.map +1 -1
- package/dist/settings.d.ts +64 -17
- package/dist/settings.d.ts.map +1 -1
- package/dist/settings.js +16 -552
- package/dist/settings.js.map +1 -1
- package/dist/utils.d.ts +77 -0
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +638 -1
- package/dist/utils.js.map +1 -1
- package/eslint.config.js +96 -0
- package/package.json +20 -16
- package/src/custom.d.ts +2 -1
- package/src/device/blindtilt.ts +472 -888
- package/src/device/bot.ts +893 -968
- package/src/device/ceilinglight.ts +304 -709
- package/src/device/colorbulb.ts +370 -803
- package/src/device/contact.ts +301 -611
- package/src/device/curtain.ts +460 -908
- package/src/device/device.ts +755 -0
- package/src/device/fan.ts +749 -0
- package/src/device/hub.ts +294 -664
- package/src/device/humidifier.ts +299 -696
- package/src/device/iosensor.ts +251 -644
- package/src/device/lightstrip.ts +362 -712
- package/src/device/lock.ts +328 -653
- package/src/device/meter.ts +247 -637
- package/src/device/meterplus.ts +240 -644
- package/src/device/motion.ts +230 -598
- package/src/device/plug.ts +139 -525
- package/src/device/robotvacuumcleaner.ts +258 -593
- package/src/device/waterdetector.ts +191 -522
- package/src/homebridge-ui/public/index.html +22 -16
- package/src/homebridge-ui/server.ts +1 -1
- package/src/index.ts +4 -3
- package/src/irdevice/airconditioner.ts +370 -527
- package/src/irdevice/airpurifier.ts +132 -356
- package/src/irdevice/camera.ts +58 -311
- package/src/irdevice/fan.ts +109 -379
- package/src/irdevice/irdevice.ts +382 -0
- package/src/irdevice/light.ts +157 -412
- package/src/irdevice/other.ts +507 -648
- package/src/irdevice/tv.ts +121 -375
- package/src/irdevice/vacuumcleaner.ts +59 -311
- package/src/irdevice/waterheater.ts +61 -320
- package/src/platform.ts +395 -259
- package/src/settings.ts +118 -609
- package/src/utils.ts +642 -1
- package/.github/npm-version-script.cjs +0 -81
- package/src/device/waterdetector.json +0 -11
package/src/device/bot.ts
CHANGED
|
@@ -1,114 +1,155 @@
|
|
|
1
|
+
/* Copyright(C) 2021-2024, donavanbecker (https://github.com/donavanbecker). All rights reserved.
|
|
2
|
+
*
|
|
3
|
+
* bot.ts: @switchbot/homebridge-switchbot.
|
|
4
|
+
*/
|
|
1
5
|
import { request } from 'undici';
|
|
2
|
-
import {
|
|
6
|
+
import { deviceBase } from './device.js';
|
|
3
7
|
import { interval, Subject } from 'rxjs';
|
|
4
|
-
import {
|
|
8
|
+
import { Devices } from '../settings.js';
|
|
5
9
|
import { debounceTime, skipWhile, take, tap } from 'rxjs/operators';
|
|
6
|
-
|
|
7
|
-
import {
|
|
10
|
+
|
|
11
|
+
import type { SwitchBotPlatform } from '../platform.js';
|
|
12
|
+
import type { Service, PlatformAccessory, CharacteristicValue } from 'homebridge';
|
|
13
|
+
import type { device, devicesConfig, serviceData, deviceStatus } from '../settings.js';
|
|
8
14
|
|
|
9
15
|
/**
|
|
10
16
|
* Platform Accessory
|
|
11
17
|
* An instance of this class is created for each accessory your platform registers
|
|
12
18
|
* Each accessory may expose multiple services of different service types.
|
|
13
19
|
*/
|
|
14
|
-
export class Bot {
|
|
15
|
-
public readonly api: API;
|
|
16
|
-
public readonly log: Logging;
|
|
17
|
-
public readonly config!: SwitchBotPlatformConfig;
|
|
18
|
-
protected readonly hap: HAP;
|
|
20
|
+
export class Bot extends deviceBase {
|
|
19
21
|
// Services
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
22
|
+
private Battery: {
|
|
23
|
+
Name: CharacteristicValue;
|
|
24
|
+
Service: Service;
|
|
25
|
+
BatteryLevel: CharacteristicValue;
|
|
26
|
+
StatusLowBattery: CharacteristicValue;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
private Switch?: {
|
|
30
|
+
Name: CharacteristicValue;
|
|
31
|
+
Service: Service;
|
|
32
|
+
On: CharacteristicValue;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
private GarageDoor?: {
|
|
36
|
+
Name: CharacteristicValue;
|
|
37
|
+
Service: Service;
|
|
38
|
+
On: CharacteristicValue;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
private Door?: {
|
|
42
|
+
Name: CharacteristicValue;
|
|
43
|
+
Service: Service;
|
|
44
|
+
On: CharacteristicValue;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
private Window?: {
|
|
48
|
+
Name: CharacteristicValue;
|
|
49
|
+
Service: Service;
|
|
50
|
+
On: CharacteristicValue;
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
private WindowCovering?: {
|
|
54
|
+
Name: CharacteristicValue;
|
|
55
|
+
Service: Service;
|
|
56
|
+
On: CharacteristicValue;
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
private LockMechanism?: {
|
|
60
|
+
Name: CharacteristicValue;
|
|
61
|
+
Service: Service;
|
|
62
|
+
On: CharacteristicValue;
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
private Faucet?: {
|
|
66
|
+
Name: CharacteristicValue;
|
|
67
|
+
Service: Service;
|
|
68
|
+
On: CharacteristicValue;
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
private Fan?: {
|
|
72
|
+
Name: CharacteristicValue;
|
|
73
|
+
Service: Service;
|
|
74
|
+
On: CharacteristicValue;
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
private StatefulProgrammableSwitch?: {
|
|
78
|
+
Name: CharacteristicValue;
|
|
79
|
+
Service: Service;
|
|
80
|
+
On: CharacteristicValue;
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
private Outlet?: {
|
|
84
|
+
Name: CharacteristicValue;
|
|
85
|
+
Service: Service;
|
|
86
|
+
On: CharacteristicValue;
|
|
87
|
+
};
|
|
50
88
|
|
|
51
89
|
// Config
|
|
52
90
|
botMode!: string;
|
|
53
91
|
allowPush?: boolean;
|
|
54
92
|
doublePress!: number;
|
|
55
|
-
scanDuration!: number;
|
|
56
93
|
botDeviceType!: string;
|
|
57
94
|
pushRatePress!: number;
|
|
58
|
-
deviceLogging!: string;
|
|
59
95
|
multiPressCount!: number;
|
|
60
|
-
deviceRefreshRate!: number;
|
|
61
96
|
|
|
62
97
|
// Updates
|
|
63
98
|
botUpdateInProgress!: boolean;
|
|
64
99
|
doBotUpdate!: Subject<void>;
|
|
65
100
|
|
|
66
|
-
// Connection
|
|
67
|
-
private readonly OpenAPI: boolean;
|
|
68
|
-
private readonly BLE: boolean;
|
|
69
|
-
|
|
70
101
|
constructor(
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
102
|
+
readonly platform: SwitchBotPlatform,
|
|
103
|
+
accessory: PlatformAccessory,
|
|
104
|
+
device: device & devicesConfig,
|
|
74
105
|
) {
|
|
75
|
-
|
|
76
|
-
this.log = this.platform.log;
|
|
77
|
-
this.config = this.platform.config;
|
|
78
|
-
this.hap = this.api.hap;
|
|
79
|
-
// Connection
|
|
80
|
-
this.BLE = this.device.connectionType === 'BLE' || this.device.connectionType === 'BLE/OpenAPI';
|
|
81
|
-
this.OpenAPI = this.device.connectionType === 'OpenAPI' || this.device.connectionType === 'BLE/OpenAPI';
|
|
106
|
+
super(platform, accessory, device);
|
|
82
107
|
// default placeholders
|
|
83
|
-
this.
|
|
84
|
-
this.deviceType(device);
|
|
85
|
-
this.scan(device);
|
|
86
|
-
this.refreshRate(device);
|
|
87
|
-
this.PressOrSwitch(device);
|
|
88
|
-
this.allowPushChanges(device);
|
|
89
|
-
this.deviceContext();
|
|
90
|
-
this.DoublePress(device);
|
|
91
|
-
this.deviceConfig(device);
|
|
92
|
-
|
|
93
|
-
this.multiPressCount = 0;
|
|
108
|
+
this.getBotConfigSettings(device);
|
|
94
109
|
|
|
95
110
|
// this is subject we use to track when we need to POST changes to the SwitchBot API
|
|
96
111
|
this.doBotUpdate = new Subject();
|
|
97
112
|
this.botUpdateInProgress = false;
|
|
98
113
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
.
|
|
105
|
-
.
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
114
|
+
accessory.context.Battery = accessory.context.Battery ?? {};
|
|
115
|
+
// Initialize Battery property
|
|
116
|
+
this.Battery = {
|
|
117
|
+
Name: accessory.context.Battery.Name ?? `${accessory.displayName} Battery`,
|
|
118
|
+
Service: accessory.getService(this.hap.Service.Battery) ?? accessory.addService(this.hap.Service.Battery) as Service,
|
|
119
|
+
BatteryLevel: accessory.context.BatteryLevel ?? 100,
|
|
120
|
+
StatusLowBattery: accessory.context.StatusLowBattery ?? this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL,
|
|
121
|
+
};
|
|
122
|
+
accessory.context.Battery = this.Battery as object;
|
|
123
|
+
|
|
124
|
+
// Initialize Battery Characteristics
|
|
125
|
+
this.Battery.Service
|
|
126
|
+
.setCharacteristic(this.hap.Characteristic.Name, this.Battery.Name)
|
|
127
|
+
.setCharacteristic(this.hap.Characteristic.StatusLowBattery, this.Battery.StatusLowBattery)
|
|
128
|
+
.setCharacteristic(this.hap.Characteristic.ChargingState, this.hap.Characteristic.ChargingState.NOT_CHARGEABLE);
|
|
109
129
|
|
|
110
130
|
// deviceType
|
|
111
131
|
if (this.botDeviceType === 'switch') {
|
|
132
|
+
// Initialize Switch Service
|
|
133
|
+
accessory.context.Switch = accessory.context.Switch ?? {};
|
|
134
|
+
this.Switch = {
|
|
135
|
+
Name: accessory.context.Switch.Name ?? accessory.displayName,
|
|
136
|
+
Service: accessory.getService(this.hap.Service.Switch) ?? accessory.addService(this.hap.Service.Switch) as Service,
|
|
137
|
+
On: accessory.context.On ?? false,
|
|
138
|
+
};
|
|
139
|
+
accessory.context.Switch = this.Switch as object;
|
|
140
|
+
this.debugWarnLog(`${this.device.deviceType}: ${accessory.displayName} Displaying as Switch`);
|
|
141
|
+
|
|
142
|
+
// Initialize Switch Characteristics
|
|
143
|
+
this.Switch.Service
|
|
144
|
+
.setCharacteristic(this.hap.Characteristic.Name, this.Switch.Name)
|
|
145
|
+
.setCharacteristic(this.hap.Characteristic.On, this.Switch.On)
|
|
146
|
+
.getCharacteristic(this.hap.Characteristic.On)
|
|
147
|
+
.onGet(() => {
|
|
148
|
+
return this.Switch!.On;
|
|
149
|
+
})
|
|
150
|
+
.onSet(this.OnSet.bind(this));
|
|
151
|
+
|
|
152
|
+
// Remove other services
|
|
112
153
|
this.removeFanService(accessory);
|
|
113
154
|
this.removeLockService(accessory);
|
|
114
155
|
this.removeDoorService(accessory);
|
|
@@ -118,19 +159,33 @@ export class Bot {
|
|
|
118
159
|
this.removeGarageDoorService(accessory);
|
|
119
160
|
this.removeWindowCoveringService(accessory);
|
|
120
161
|
this.removeStatefulProgrammableSwitchService(accessory);
|
|
162
|
+
} else if (this.botDeviceType === 'garagedoor') {
|
|
163
|
+
// Initialize GarageDoor Service
|
|
164
|
+
accessory.context.GarageDoor = accessory.context.GarageDoor ?? {};
|
|
165
|
+
this.GarageDoor = {
|
|
166
|
+
Name: accessory.context.GarageDoor.Name ?? accessory.displayName,
|
|
167
|
+
Service: accessory.getService(this.hap.Service.GarageDoorOpener) ?? accessory.addService(this.hap.Service.GarageDoorOpener) as Service,
|
|
168
|
+
On: accessory.context.On ?? false,
|
|
169
|
+
};
|
|
170
|
+
accessory.context.GarageDoor = this.GarageDoor as object;
|
|
171
|
+
this.debugWarnLog(`${this.device.deviceType}: ${accessory.displayName} Displaying as Garage Door Opener`);
|
|
121
172
|
|
|
122
|
-
//
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
173
|
+
// Initialize GarageDoor Characteristics
|
|
174
|
+
this.GarageDoor.Service
|
|
175
|
+
.setCharacteristic(this.hap.Characteristic.Name, this.GarageDoor.Name)
|
|
176
|
+
.setCharacteristic(this.hap.Characteristic.ObstructionDetected, false)
|
|
177
|
+
.getCharacteristic(this.hap.Characteristic.TargetDoorState).setProps({
|
|
178
|
+
validValues: [0, 100],
|
|
179
|
+
minValue: 0,
|
|
180
|
+
maxValue: 100,
|
|
181
|
+
minStep: 100,
|
|
182
|
+
})
|
|
183
|
+
.onGet(() => {
|
|
184
|
+
return this.GarageDoor!.On;
|
|
185
|
+
})
|
|
186
|
+
.onSet(this.OnSet.bind(this));
|
|
127
187
|
|
|
128
|
-
|
|
129
|
-
if (!this.switchService.testCharacteristic(this.hap.Characteristic.ConfiguredName)) {
|
|
130
|
-
this.switchService.addCharacteristic(this.hap.Characteristic.ConfiguredName, accessory.displayName);
|
|
131
|
-
}
|
|
132
|
-
this.switchService.getCharacteristic(this.hap.Characteristic.On).onSet(this.OnSet.bind(this));
|
|
133
|
-
} else if (this.botDeviceType === 'garagedoor') {
|
|
188
|
+
// Remove other services
|
|
134
189
|
this.removeFanService(accessory);
|
|
135
190
|
this.removeLockService(accessory);
|
|
136
191
|
this.removeDoorService(accessory);
|
|
@@ -140,20 +195,33 @@ export class Bot {
|
|
|
140
195
|
this.removeWindowService(accessory);
|
|
141
196
|
this.removeWindowCoveringService(accessory);
|
|
142
197
|
this.removeStatefulProgrammableSwitchService(accessory);
|
|
198
|
+
} else if (this.botDeviceType === 'door') {
|
|
199
|
+
// Initialize Door Service
|
|
200
|
+
accessory.context.Door = accessory.context.Door ?? {};
|
|
201
|
+
this.Door = {
|
|
202
|
+
Name: accessory.context.Door.Name ?? accessory.displayName,
|
|
203
|
+
Service: accessory.getService(this.hap.Service.Door) ?? accessory.addService(this.hap.Service.Door) as Service,
|
|
204
|
+
On: accessory.context.On ?? false,
|
|
205
|
+
};
|
|
206
|
+
accessory.context.Door = this.Door as object;
|
|
207
|
+
this.debugWarnLog(`${this.device.deviceType}: ${accessory.displayName} Displaying as Door`);
|
|
143
208
|
|
|
144
|
-
//
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
209
|
+
// Initialize Door Characteristics
|
|
210
|
+
this.Door.Service
|
|
211
|
+
.setCharacteristic(this.hap.Characteristic.Name, this.Door.Name)
|
|
212
|
+
.setCharacteristic(this.hap.Characteristic.PositionState, this.hap.Characteristic.PositionState.STOPPED)
|
|
213
|
+
.getCharacteristic(this.hap.Characteristic.TargetPosition).setProps({
|
|
214
|
+
validValues: [0, 100],
|
|
215
|
+
minValue: 0,
|
|
216
|
+
maxValue: 100,
|
|
217
|
+
minStep: 100,
|
|
218
|
+
})
|
|
219
|
+
.onGet(() => {
|
|
220
|
+
return this.Door!.On;
|
|
221
|
+
})
|
|
222
|
+
.onSet(this.OnSet.bind(this));
|
|
149
223
|
|
|
150
|
-
|
|
151
|
-
if (!this.garageDoorService.testCharacteristic(this.hap.Characteristic.ConfiguredName)) {
|
|
152
|
-
this.garageDoorService.addCharacteristic(this.hap.Characteristic.ConfiguredName, accessory.displayName);
|
|
153
|
-
}
|
|
154
|
-
this.garageDoorService.getCharacteristic(this.hap.Characteristic.TargetDoorState).onSet(this.OnSet.bind(this));
|
|
155
|
-
this.garageDoorService.setCharacteristic(this.hap.Characteristic.ObstructionDetected, false);
|
|
156
|
-
} else if (this.botDeviceType === 'door') {
|
|
224
|
+
// Remove other services
|
|
157
225
|
this.removeFanService(accessory);
|
|
158
226
|
this.removeLockService(accessory);
|
|
159
227
|
this.removeOutletService(accessory);
|
|
@@ -163,28 +231,33 @@ export class Bot {
|
|
|
163
231
|
this.removeGarageDoorService(accessory);
|
|
164
232
|
this.removeWindowCoveringService(accessory);
|
|
165
233
|
this.removeStatefulProgrammableSwitchService(accessory);
|
|
234
|
+
} else if (this.botDeviceType === 'window') {
|
|
235
|
+
// Initialize Window Service
|
|
236
|
+
accessory.context.Window = accessory.context.Window ?? {};
|
|
237
|
+
this.Window = {
|
|
238
|
+
Name: accessory.context.Window.Name ?? accessory.displayName,
|
|
239
|
+
Service: accessory.getService(this.hap.Service.Window) ?? accessory.addService(this.hap.Service.Window) as Service,
|
|
240
|
+
On: accessory.context.On ?? false,
|
|
241
|
+
};
|
|
242
|
+
accessory.context.Window = this.Window as object;
|
|
243
|
+
this.debugWarnLog(`${this.device.deviceType}: ${accessory.displayName} Displaying as Window`);
|
|
166
244
|
|
|
167
|
-
//
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
this.doorService.setCharacteristic(this.hap.Characteristic.Name, accessory.displayName);
|
|
174
|
-
if (!this.doorService.testCharacteristic(this.hap.Characteristic.ConfiguredName)) {
|
|
175
|
-
this.doorService.addCharacteristic(this.hap.Characteristic.ConfiguredName, accessory.displayName);
|
|
176
|
-
}
|
|
177
|
-
this.doorService
|
|
178
|
-
.getCharacteristic(this.hap.Characteristic.TargetPosition)
|
|
179
|
-
.setProps({
|
|
245
|
+
// Initialize Window Characteristics
|
|
246
|
+
this.Window.Service
|
|
247
|
+
.setCharacteristic(this.hap.Characteristic.Name, this.Window.Name)
|
|
248
|
+
.setCharacteristic(this.hap.Characteristic.PositionState, this.hap.Characteristic.PositionState.STOPPED)
|
|
249
|
+
.getCharacteristic(this.hap.Characteristic.TargetPosition).setProps({
|
|
180
250
|
validValues: [0, 100],
|
|
181
251
|
minValue: 0,
|
|
182
252
|
maxValue: 100,
|
|
183
253
|
minStep: 100,
|
|
184
254
|
})
|
|
255
|
+
.onGet(() => {
|
|
256
|
+
return this.Window!.On;
|
|
257
|
+
})
|
|
185
258
|
.onSet(this.OnSet.bind(this));
|
|
186
|
-
|
|
187
|
-
|
|
259
|
+
|
|
260
|
+
// Remove other services
|
|
188
261
|
this.removeFanService(accessory);
|
|
189
262
|
this.removeLockService(accessory);
|
|
190
263
|
this.removeDoorService(accessory);
|
|
@@ -194,28 +267,33 @@ export class Bot {
|
|
|
194
267
|
this.removeGarageDoorService(accessory);
|
|
195
268
|
this.removeWindowCoveringService(accessory);
|
|
196
269
|
this.removeStatefulProgrammableSwitchService(accessory);
|
|
270
|
+
} else if (this.botDeviceType === 'windowcovering') {
|
|
271
|
+
// Initialize WindowCovering Service
|
|
272
|
+
accessory.context.WindowCovering = accessory.context.WindowCovering ?? {};
|
|
273
|
+
this.WindowCovering = {
|
|
274
|
+
Name: accessory.context.WindowCovering.Name ?? accessory.displayName,
|
|
275
|
+
Service: accessory.getService(this.hap.Service.WindowCovering) ?? accessory.addService(this.hap.Service.WindowCovering) as Service,
|
|
276
|
+
On: accessory.context.On ?? false,
|
|
277
|
+
};
|
|
278
|
+
accessory.context.WindowCovering = this.WindowCovering as object;
|
|
279
|
+
this.debugWarnLog(`${this.device.deviceType}: ${accessory.displayName} Displaying as Window Covering`);
|
|
197
280
|
|
|
198
|
-
//
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
this.windowService.setCharacteristic(this.hap.Characteristic.Name, accessory.displayName);
|
|
205
|
-
if (!this.windowService.testCharacteristic(this.hap.Characteristic.ConfiguredName)) {
|
|
206
|
-
this.windowService.addCharacteristic(this.hap.Characteristic.ConfiguredName, accessory.displayName);
|
|
207
|
-
}
|
|
208
|
-
this.windowService
|
|
209
|
-
.getCharacteristic(this.hap.Characteristic.TargetPosition)
|
|
210
|
-
.setProps({
|
|
281
|
+
// Initialize WindowCovering Characteristics
|
|
282
|
+
this.WindowCovering.Service
|
|
283
|
+
.setCharacteristic(this.hap.Characteristic.Name, this.WindowCovering.Name)
|
|
284
|
+
.setCharacteristic(this.hap.Characteristic.PositionState, this.hap.Characteristic.PositionState.STOPPED)
|
|
285
|
+
.getCharacteristic(this.hap.Characteristic.TargetPosition).setProps({
|
|
211
286
|
validValues: [0, 100],
|
|
212
287
|
minValue: 0,
|
|
213
288
|
maxValue: 100,
|
|
214
289
|
minStep: 100,
|
|
215
290
|
})
|
|
291
|
+
.onGet(() => {
|
|
292
|
+
return this.WindowCovering!.On;
|
|
293
|
+
})
|
|
216
294
|
.onSet(this.OnSet.bind(this));
|
|
217
|
-
|
|
218
|
-
|
|
295
|
+
|
|
296
|
+
// Remove other services
|
|
219
297
|
this.removeFanService(accessory);
|
|
220
298
|
this.removeLockService(accessory);
|
|
221
299
|
this.removeDoorService(accessory);
|
|
@@ -225,28 +303,27 @@ export class Bot {
|
|
|
225
303
|
this.removeWindowService(accessory);
|
|
226
304
|
this.removeGarageDoorService(accessory);
|
|
227
305
|
this.removeStatefulProgrammableSwitchService(accessory);
|
|
306
|
+
} else if (this.botDeviceType === 'lock') {
|
|
307
|
+
// Initialize Lock Service
|
|
308
|
+
accessory.context.LockMechanism = accessory.context.LockMechanism ?? {};
|
|
309
|
+
this.LockMechanism = {
|
|
310
|
+
Name: accessory.context.LockMechanism.Name ?? accessory.displayName,
|
|
311
|
+
Service: accessory.getService(this.hap.Service.LockMechanism) ?? accessory.addService(this.hap.Service.LockMechanism) as Service,
|
|
312
|
+
On: accessory.context.On ?? false,
|
|
313
|
+
};
|
|
314
|
+
accessory.context.LockMechanism = this.LockMechanism as object;
|
|
315
|
+
this.debugWarnLog(`${this.device.deviceType}: ${accessory.displayName} Displaying as Lock`);
|
|
228
316
|
|
|
229
|
-
//
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
this.windowCoveringService.setCharacteristic(this.hap.Characteristic.Name, accessory.displayName);
|
|
236
|
-
if (!this.windowCoveringService.testCharacteristic(this.hap.Characteristic.ConfiguredName)) {
|
|
237
|
-
this.windowCoveringService.addCharacteristic(this.hap.Characteristic.ConfiguredName, accessory.displayName);
|
|
238
|
-
}
|
|
239
|
-
this.windowCoveringService
|
|
240
|
-
.getCharacteristic(this.hap.Characteristic.TargetPosition)
|
|
241
|
-
.setProps({
|
|
242
|
-
validValues: [0, 100],
|
|
243
|
-
minValue: 0,
|
|
244
|
-
maxValue: 100,
|
|
245
|
-
minStep: 100,
|
|
317
|
+
// Initialize Lock Characteristics
|
|
318
|
+
this.LockMechanism.Service
|
|
319
|
+
.setCharacteristic(this.hap.Characteristic.Name, this.LockMechanism.Name)
|
|
320
|
+
.getCharacteristic(this.hap.Characteristic.LockTargetState)
|
|
321
|
+
.onGet(() => {
|
|
322
|
+
return this.LockMechanism!.On;
|
|
246
323
|
})
|
|
247
324
|
.onSet(this.OnSet.bind(this));
|
|
248
|
-
|
|
249
|
-
|
|
325
|
+
|
|
326
|
+
// Remove other services
|
|
250
327
|
this.removeFanService(accessory);
|
|
251
328
|
this.removeDoorService(accessory);
|
|
252
329
|
this.removeOutletService(accessory);
|
|
@@ -256,19 +333,27 @@ export class Bot {
|
|
|
256
333
|
this.removeGarageDoorService(accessory);
|
|
257
334
|
this.removeWindowCoveringService(accessory);
|
|
258
335
|
this.removeStatefulProgrammableSwitchService(accessory);
|
|
336
|
+
} else if (this.botDeviceType === 'faucet') {
|
|
337
|
+
// Initialize Faucet Service
|
|
338
|
+
accessory.context.Faucet = accessory.context.Faucet ?? {};
|
|
339
|
+
this.Faucet = {
|
|
340
|
+
Name: accessory.context.Faucet.Name ?? accessory.displayName,
|
|
341
|
+
Service: accessory.getService(this.hap.Service.Faucet) ?? accessory.addService(this.hap.Service.Faucet) as Service,
|
|
342
|
+
On: accessory.context.On ?? false,
|
|
343
|
+
};
|
|
344
|
+
accessory.context.Faucet = this.Faucet as object;
|
|
345
|
+
this.debugWarnLog(`${this.device.deviceType}: ${accessory.displayName} Displaying as Faucet`);
|
|
259
346
|
|
|
260
|
-
//
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
347
|
+
// Initialize Faucet Characteristics
|
|
348
|
+
this.Faucet.Service
|
|
349
|
+
.setCharacteristic(this.hap.Characteristic.Name, this.Faucet.Name)
|
|
350
|
+
.getCharacteristic(this.hap.Characteristic.Active)
|
|
351
|
+
.onGet(() => {
|
|
352
|
+
return this.Faucet!.On;
|
|
353
|
+
})
|
|
354
|
+
.onSet(this.OnSet.bind(this));
|
|
265
355
|
|
|
266
|
-
|
|
267
|
-
if (!this.lockService.testCharacteristic(this.hap.Characteristic.ConfiguredName)) {
|
|
268
|
-
this.lockService.addCharacteristic(this.hap.Characteristic.ConfiguredName, accessory.displayName);
|
|
269
|
-
}
|
|
270
|
-
this.lockService.getCharacteristic(this.hap.Characteristic.LockTargetState).onSet(this.OnSet.bind(this));
|
|
271
|
-
} else if (this.botDeviceType === 'faucet') {
|
|
356
|
+
// Remove other services
|
|
272
357
|
this.removeFanService(accessory);
|
|
273
358
|
this.removeLockService(accessory);
|
|
274
359
|
this.removeDoorService(accessory);
|
|
@@ -278,19 +363,27 @@ export class Bot {
|
|
|
278
363
|
this.removeGarageDoorService(accessory);
|
|
279
364
|
this.removeWindowCoveringService(accessory);
|
|
280
365
|
this.removeStatefulProgrammableSwitchService(accessory);
|
|
366
|
+
} else if (this.botDeviceType === 'fan') {
|
|
367
|
+
// Initialize Fan Service
|
|
368
|
+
accessory.context.Fan = accessory.context.Fan ?? {};
|
|
369
|
+
this.Fan = {
|
|
370
|
+
Name: accessory.context.Fan.Name ?? accessory.displayName,
|
|
371
|
+
Service: accessory.getService(this.hap.Service.Fanv2) ?? accessory.addService(this.hap.Service.Fanv2) as Service,
|
|
372
|
+
On: accessory.context.On ?? false,
|
|
373
|
+
};
|
|
374
|
+
accessory.context.Fan = this.Fan as object;
|
|
375
|
+
this.debugWarnLog(`${this.device.deviceType}: ${accessory.displayName} Displaying as Fan`);
|
|
281
376
|
|
|
282
|
-
//
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
377
|
+
// Initialize Fan Characteristics
|
|
378
|
+
this.Fan.Service
|
|
379
|
+
.setCharacteristic(this.hap.Characteristic.Name, this.Fan.Name)
|
|
380
|
+
.getCharacteristic(this.hap.Characteristic.On)
|
|
381
|
+
.onGet(() => {
|
|
382
|
+
return this.Fan!.On;
|
|
383
|
+
})
|
|
384
|
+
.onSet(this.OnSet.bind(this));
|
|
287
385
|
|
|
288
|
-
|
|
289
|
-
if (!this.faucetService.testCharacteristic(this.hap.Characteristic.ConfiguredName)) {
|
|
290
|
-
this.faucetService.addCharacteristic(this.hap.Characteristic.ConfiguredName, accessory.displayName);
|
|
291
|
-
}
|
|
292
|
-
this.faucetService.getCharacteristic(this.hap.Characteristic.Active).onSet(this.OnSet.bind(this));
|
|
293
|
-
} else if (this.botDeviceType === 'fan') {
|
|
386
|
+
// Remove other services
|
|
294
387
|
this.removeLockService(accessory);
|
|
295
388
|
this.removeDoorService(accessory);
|
|
296
389
|
this.removeFaucetService(accessory);
|
|
@@ -300,19 +393,28 @@ export class Bot {
|
|
|
300
393
|
this.removeGarageDoorService(accessory);
|
|
301
394
|
this.removeWindowCoveringService(accessory);
|
|
302
395
|
this.removeStatefulProgrammableSwitchService(accessory);
|
|
396
|
+
} else if (this.botDeviceType === 'stateful') {
|
|
397
|
+
// Initialize StatefulProgrammableSwitch Service
|
|
398
|
+
accessory.context.StatefulProgrammableSwitch = accessory.context.StatefulProgrammableSwitch ?? {};
|
|
399
|
+
this.StatefulProgrammableSwitch = {
|
|
400
|
+
Name: accessory.context.StatefulProgrammableSwitch.Name ?? accessory.displayName,
|
|
401
|
+
Service: accessory.getService(this.hap.Service.StatefulProgrammableSwitch)
|
|
402
|
+
?? accessory.addService(this.hap.Service.StatefulProgrammableSwitch) as Service,
|
|
403
|
+
On: accessory.context.On ?? false,
|
|
404
|
+
};
|
|
405
|
+
accessory.context.StatefulProgrammableSwitch = this.StatefulProgrammableSwitch as object;
|
|
406
|
+
this.debugWarnLog(`${this.device.deviceType}: ${accessory.displayName} Displaying as Stateful Programmable Switch`);
|
|
303
407
|
|
|
304
|
-
//
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
408
|
+
// Initialize StatefulProgrammableSwitch Characteristics
|
|
409
|
+
this.StatefulProgrammableSwitch.Service
|
|
410
|
+
.setCharacteristic(this.hap.Characteristic.Name, this.StatefulProgrammableSwitch.Name)
|
|
411
|
+
.getCharacteristic(this.hap.Characteristic.ProgrammableSwitchOutputState)
|
|
412
|
+
.onGet(() => {
|
|
413
|
+
return this.StatefulProgrammableSwitch!.On;
|
|
414
|
+
})
|
|
415
|
+
.onSet(this.OnSet.bind(this));
|
|
309
416
|
|
|
310
|
-
|
|
311
|
-
if (!this.fanService.testCharacteristic(this.hap.Characteristic.ConfiguredName)) {
|
|
312
|
-
this.fanService.addCharacteristic(this.hap.Characteristic.ConfiguredName, accessory.displayName);
|
|
313
|
-
}
|
|
314
|
-
this.fanService.getCharacteristic(this.hap.Characteristic.On).onSet(this.OnSet.bind(this));
|
|
315
|
-
} else if (this.botDeviceType === 'stateful') {
|
|
417
|
+
// Remove other services
|
|
316
418
|
this.removeFanService(accessory);
|
|
317
419
|
this.removeLockService(accessory);
|
|
318
420
|
this.removeDoorService(accessory);
|
|
@@ -322,21 +424,27 @@ export class Bot {
|
|
|
322
424
|
this.removeWindowService(accessory);
|
|
323
425
|
this.removeGarageDoorService(accessory);
|
|
324
426
|
this.removeWindowCoveringService(accessory);
|
|
427
|
+
} else {
|
|
428
|
+
// Initialize Switch property
|
|
429
|
+
accessory.context.Outlet = accessory.context.Outlet ?? {};
|
|
430
|
+
this.Outlet = {
|
|
431
|
+
Name: accessory.context.Outlet.Name ?? accessory.displayName,
|
|
432
|
+
Service: accessory.getService(this.hap.Service.Outlet) ?? accessory.addService(this.hap.Service.Outlet) as Service,
|
|
433
|
+
On: accessory.context.On ?? false,
|
|
434
|
+
};
|
|
435
|
+
accessory.context.Outlet = this.Outlet as object;
|
|
436
|
+
this.debugWarnLog(`${this.device.deviceType}: ${accessory.displayName} Displaying as Outlet`);
|
|
325
437
|
|
|
326
|
-
//
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
if (!this.statefulProgrammableSwitchService.testCharacteristic(this.hap.Characteristic.ConfiguredName)) {
|
|
334
|
-
this.statefulProgrammableSwitchService.addCharacteristic(this.hap.Characteristic.ConfiguredName, accessory.displayName);
|
|
335
|
-
}
|
|
336
|
-
this.statefulProgrammableSwitchService
|
|
337
|
-
.getCharacteristic(this.hap.Characteristic.ProgrammableSwitchOutputState)
|
|
438
|
+
// Initialize Outlet Characteristics
|
|
439
|
+
this.Outlet.Service
|
|
440
|
+
.setCharacteristic(this.hap.Characteristic.Name, this.Outlet.Name)
|
|
441
|
+
.getCharacteristic(this.hap.Characteristic.On)
|
|
442
|
+
.onGet(() => {
|
|
443
|
+
return this.Outlet!.On;
|
|
444
|
+
})
|
|
338
445
|
.onSet(this.OnSet.bind(this));
|
|
339
|
-
|
|
446
|
+
|
|
447
|
+
// Remove other services
|
|
340
448
|
this.removeFanService(accessory);
|
|
341
449
|
this.removeLockService(accessory);
|
|
342
450
|
this.removeDoorService(accessory);
|
|
@@ -346,30 +454,10 @@ export class Bot {
|
|
|
346
454
|
this.removeGarageDoorService(accessory);
|
|
347
455
|
this.removeWindowCoveringService(accessory);
|
|
348
456
|
this.removeStatefulProgrammableSwitchService(accessory);
|
|
349
|
-
|
|
350
|
-
// Add outletService
|
|
351
|
-
const outletService = `${accessory.displayName} Outlet`;
|
|
352
|
-
(this.outletService = accessory.getService(this.hap.Service.Outlet)
|
|
353
|
-
|| accessory.addService(this.hap.Service.Outlet)), outletService;
|
|
354
|
-
this.debugWarnLog(`${this.device.deviceType}: ${accessory.displayName} Displaying as Outlet`);
|
|
355
|
-
|
|
356
|
-
this.outletService.setCharacteristic(this.hap.Characteristic.Name, accessory.displayName);
|
|
357
|
-
if (!this.outletService.testCharacteristic(this.hap.Characteristic.ConfiguredName)) {
|
|
358
|
-
this.outletService.addCharacteristic(this.hap.Characteristic.ConfiguredName, accessory.displayName);
|
|
359
|
-
}
|
|
360
|
-
this.outletService.getCharacteristic(this.hap.Characteristic.On).onSet(this.OnSet.bind(this));
|
|
361
457
|
}
|
|
362
458
|
|
|
363
|
-
//
|
|
364
|
-
|
|
365
|
-
(this.batteryService = this.accessory.getService(this.hap.Service.Battery)
|
|
366
|
-
|| accessory.addService(this.hap.Service.Battery)), batteryService;
|
|
367
|
-
|
|
368
|
-
this.batteryService.setCharacteristic(this.hap.Characteristic.Name, `${accessory.displayName} Battery`);
|
|
369
|
-
if (!this.batteryService.testCharacteristic(this.hap.Characteristic.ConfiguredName)) {
|
|
370
|
-
this.batteryService.addCharacteristic(this.hap.Characteristic.ConfiguredName, `${accessory.displayName} Battery`);
|
|
371
|
-
}
|
|
372
|
-
this.batteryService.setCharacteristic(this.hap.Characteristic.ChargingState, this.hap.Characteristic.ChargingState.NOT_CHARGEABLE);
|
|
459
|
+
// Retrieve initial values and updateHomekit
|
|
460
|
+
this.refreshStatus();
|
|
373
461
|
|
|
374
462
|
// Retrieve initial values and updateHomekit
|
|
375
463
|
this.updateHomeKitCharacteristics();
|
|
@@ -381,28 +469,8 @@ export class Bot {
|
|
|
381
469
|
await this.refreshStatus();
|
|
382
470
|
});
|
|
383
471
|
|
|
384
|
-
//regisiter webhook event handler
|
|
385
|
-
|
|
386
|
-
this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} is listening webhook.`);
|
|
387
|
-
this.platform.webhookEventHandler[this.device.deviceId] = async (context) => {
|
|
388
|
-
try {
|
|
389
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} received Webhook: ${JSON.stringify(context)}`);
|
|
390
|
-
const { power, battery, deviceMode } = context;
|
|
391
|
-
const { On, BatteryLevel, botMode } = this;
|
|
392
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} ` +
|
|
393
|
-
'(power, battery, deviceMode) = ' +
|
|
394
|
-
`Webhook:(${power}, ${battery}, ${deviceMode}), ` +
|
|
395
|
-
`current:(${On}, ${BatteryLevel}, ${botMode})`);
|
|
396
|
-
this.On = power;
|
|
397
|
-
this.BatteryLevel = battery;
|
|
398
|
-
this.botMode = deviceMode;
|
|
399
|
-
this.updateHomeKitCharacteristics();
|
|
400
|
-
} catch (e: any) {
|
|
401
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} `
|
|
402
|
-
+ `failed to handle webhook. Received: ${JSON.stringify(context)} Error: ${e}`);
|
|
403
|
-
}
|
|
404
|
-
};
|
|
405
|
-
}
|
|
472
|
+
// regisiter webhook event handler
|
|
473
|
+
this.registerWebhook(accessory, device);
|
|
406
474
|
|
|
407
475
|
// Watch for Bot change events
|
|
408
476
|
// We put in a debounce of 1000ms so we don't make duplicate calls
|
|
@@ -411,7 +479,7 @@ export class Bot {
|
|
|
411
479
|
tap(() => {
|
|
412
480
|
this.botUpdateInProgress = true;
|
|
413
481
|
}),
|
|
414
|
-
debounceTime(this.
|
|
482
|
+
debounceTime(this.devicePushRate * 1000),
|
|
415
483
|
)
|
|
416
484
|
.subscribe(async () => {
|
|
417
485
|
try {
|
|
@@ -426,90 +494,90 @@ export class Bot {
|
|
|
426
494
|
}
|
|
427
495
|
} catch (e: any) {
|
|
428
496
|
this.apiError(e);
|
|
429
|
-
this.errorLog(
|
|
430
|
-
|
|
431
|
-
` Error Message: ${JSON.stringify(e.message)}`,
|
|
432
|
-
);
|
|
497
|
+
this.errorLog(`${device.deviceType}: ${accessory.displayName} failed pushChanges with ${device.connectionType} Connection,`
|
|
498
|
+
+ ` Error Message: ${JSON.stringify(e.message)}`);
|
|
433
499
|
}
|
|
434
500
|
this.botUpdateInProgress = false;
|
|
435
501
|
});
|
|
436
502
|
}
|
|
437
503
|
|
|
438
504
|
/**
|
|
439
|
-
* Parse the device status from the
|
|
505
|
+
* Parse the device status from the SwitchBotBLE API
|
|
440
506
|
*/
|
|
441
|
-
async
|
|
442
|
-
if (!this.device.enableCloudService && this.OpenAPI) {
|
|
443
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} parseStatus enableCloudService: ${this.device.enableCloudService}`);
|
|
444
|
-
} else if (this.BLE) {
|
|
445
|
-
await this.BLEparseStatus();
|
|
446
|
-
} else if (this.OpenAPI && this.platform.config.credentials?.token) {
|
|
447
|
-
await this.openAPIparseStatus();
|
|
448
|
-
} else {
|
|
449
|
-
await this.offlineOff();
|
|
450
|
-
this.debugWarnLog(
|
|
451
|
-
`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:` + ` ${this.device.connectionType}, parseStatus will not happen.`,
|
|
452
|
-
);
|
|
453
|
-
}
|
|
454
|
-
}
|
|
455
|
-
|
|
456
|
-
async BLEparseStatus(): Promise<void> {
|
|
507
|
+
async BLEparseStatus(serviceData: serviceData): Promise<void> {
|
|
457
508
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLEparseStatus`);
|
|
458
509
|
// BLEmode (true if Switch Mode) | (false if Press Mode)
|
|
459
|
-
if (
|
|
460
|
-
this.accessory.context.On = this.
|
|
461
|
-
if (this.
|
|
462
|
-
this.
|
|
510
|
+
if (serviceData.mode) {
|
|
511
|
+
this.accessory.context.On = await this.getOn();
|
|
512
|
+
if (this.getOn() === undefined) {
|
|
513
|
+
this.setOn(Boolean(serviceData.state));
|
|
463
514
|
}
|
|
464
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Switch Mode
|
|
515
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Switch Mode,`
|
|
516
|
+
+ ` mode: ${serviceData.mode}, On: ${this.accessory.context.On}`);
|
|
465
517
|
} else {
|
|
466
|
-
this.
|
|
467
|
-
this.accessory.context.On = this.
|
|
468
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Press Mode
|
|
518
|
+
this.setOn(false);
|
|
519
|
+
this.accessory.context.On = await this.getOn();
|
|
520
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Press Mode,`
|
|
521
|
+
+ ` mode: ${serviceData.mode}, On: ${this.accessory.context.On}`);
|
|
469
522
|
}
|
|
470
523
|
|
|
471
|
-
this.BatteryLevel = Number(
|
|
472
|
-
if (this.BatteryLevel < 10) {
|
|
473
|
-
this.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW;
|
|
524
|
+
this.Battery.BatteryLevel = Number(serviceData.battery);
|
|
525
|
+
if (this.Battery.BatteryLevel < 10) {
|
|
526
|
+
this.Battery.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW;
|
|
474
527
|
} else {
|
|
475
|
-
this.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
|
|
528
|
+
this.Battery.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
|
|
476
529
|
}
|
|
477
|
-
if (Number.isNaN(this.BatteryLevel)) {
|
|
478
|
-
this.BatteryLevel = 100;
|
|
530
|
+
if (Number.isNaN(this.Battery.BatteryLevel)) {
|
|
531
|
+
this.Battery.BatteryLevel = 100;
|
|
479
532
|
}
|
|
480
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.BatteryLevel},`
|
|
481
|
-
+ ` StatusLowBattery: ${this.StatusLowBattery}`);
|
|
533
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.Battery.BatteryLevel},`
|
|
534
|
+
+ ` StatusLowBattery: ${this.Battery.StatusLowBattery}`);
|
|
482
535
|
}
|
|
483
536
|
|
|
484
|
-
|
|
537
|
+
|
|
538
|
+
/**
|
|
539
|
+
* Parse the device status from the SwitchBot OpenAPI
|
|
540
|
+
*/
|
|
541
|
+
async openAPIparseStatus(deviceStatus: deviceStatus): Promise<void> {
|
|
485
542
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIparseStatus`);
|
|
486
543
|
if (this.botMode === 'press') {
|
|
487
|
-
this.
|
|
488
|
-
this.accessory.context.On = this.
|
|
544
|
+
this.setOn(false);
|
|
545
|
+
this.accessory.context.On = await this.getOn();
|
|
489
546
|
} else {
|
|
490
|
-
this.accessory.context.On = this.
|
|
491
|
-
if (this.
|
|
492
|
-
this.
|
|
547
|
+
this.accessory.context.On = await this.getOn();
|
|
548
|
+
if (this.getOn() === undefined) {
|
|
549
|
+
this.setOn(false);
|
|
493
550
|
}
|
|
494
551
|
}
|
|
495
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.On}`);
|
|
552
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.accessory.context.On}`);
|
|
496
553
|
|
|
497
554
|
// Battery
|
|
498
|
-
this.BatteryLevel = Number(
|
|
499
|
-
if (this.BatteryLevel < 10) {
|
|
500
|
-
this.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW;
|
|
555
|
+
this.Battery.BatteryLevel = Number(deviceStatus.body.battery);
|
|
556
|
+
if (this.Battery.BatteryLevel < 10) {
|
|
557
|
+
this.Battery.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW;
|
|
501
558
|
} else {
|
|
502
|
-
this.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
|
|
503
|
-
}
|
|
504
|
-
if (Number.isNaN(this.BatteryLevel)) {
|
|
505
|
-
this.BatteryLevel = 100;
|
|
559
|
+
this.Battery.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
|
|
560
|
+
}
|
|
561
|
+
if (Number.isNaN(this.Battery.BatteryLevel)) {
|
|
562
|
+
this.Battery.BatteryLevel = 100;
|
|
563
|
+
}
|
|
564
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.Battery.BatteryLevel},`
|
|
565
|
+
+ ` StatusLowBattery: ${this.Battery.StatusLowBattery}`);
|
|
566
|
+
|
|
567
|
+
// Firmware Version
|
|
568
|
+
const version = deviceStatus.body.version?.toString();
|
|
569
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Firmware Version: ${version?.replace(/^V|-.*$/g, '')}`);
|
|
570
|
+
if (deviceStatus.body.version) {
|
|
571
|
+
const deviceVersion = version?.replace(/^V|-.*$/g, '') ?? '0.0.0';
|
|
572
|
+
this.accessory
|
|
573
|
+
.getService(this.hap.Service.AccessoryInformation)!
|
|
574
|
+
.setCharacteristic(this.hap.Characteristic.HardwareRevision, deviceVersion)
|
|
575
|
+
.setCharacteristic(this.hap.Characteristic.FirmwareRevision, deviceVersion)
|
|
576
|
+
.getCharacteristic(this.hap.Characteristic.FirmwareRevision)
|
|
577
|
+
.updateValue(deviceVersion);
|
|
578
|
+
this.accessory.context.deviceVersion = deviceVersion;
|
|
579
|
+
this.debugSuccessLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceVersion: ${this.accessory.context.deviceVersion}`);
|
|
506
580
|
}
|
|
507
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.BatteryLevel},`
|
|
508
|
-
+ ` StatusLowBattery: ${this.StatusLowBattery}`);
|
|
509
|
-
|
|
510
|
-
// FirmwareRevision
|
|
511
|
-
this.FirmwareRevision = this.OpenAPI_FirmwareRevision!;
|
|
512
|
-
this.accessory.context.FirmwareRevision = this.FirmwareRevision;
|
|
513
581
|
}
|
|
514
582
|
|
|
515
583
|
/**
|
|
@@ -524,10 +592,8 @@ export class Bot {
|
|
|
524
592
|
await this.openAPIRefreshStatus();
|
|
525
593
|
} else {
|
|
526
594
|
await this.offlineOff();
|
|
527
|
-
this.debugWarnLog(
|
|
528
|
-
|
|
529
|
-
` ${this.device.connectionType}, refreshStatus will not happen.`,
|
|
530
|
-
);
|
|
595
|
+
this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:`
|
|
596
|
+
+ ` ${this.device.connectionType}, refreshStatus will not happen.`);
|
|
531
597
|
}
|
|
532
598
|
}
|
|
533
599
|
|
|
@@ -544,99 +610,43 @@ export class Bot {
|
|
|
544
610
|
// Start to monitor advertisement packets
|
|
545
611
|
(async () => {
|
|
546
612
|
// Start to monitor advertisement packets
|
|
547
|
-
await switchbot.startScan({
|
|
548
|
-
model: 'H',
|
|
549
|
-
id: this.device.bleMac,
|
|
550
|
-
});
|
|
613
|
+
await switchbot.startScan({ model: this.device.bleModel, id: this.device.bleMac });
|
|
551
614
|
// Set an event handler
|
|
552
615
|
switchbot.onadvertisement = (ad: any) => {
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
616
|
+
if (this.device.bleMac === ad.address && ad.model === this.device.bleModel) {
|
|
617
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} ${JSON.stringify(ad, null, ' ')}`);
|
|
618
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} address: ${ad.address}, model: ${ad.model}`);
|
|
556
619
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${JSON.stringify(ad.serviceData)}`);
|
|
557
|
-
this.BLE_Mode = ad.serviceData.mode;
|
|
558
|
-
this.BLE_On = ad.serviceData.state;
|
|
559
|
-
this.BLE_BatteryLevel = ad.serviceData.battery;
|
|
560
620
|
} else {
|
|
561
621
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${JSON.stringify(ad.serviceData)}`);
|
|
562
622
|
}
|
|
563
623
|
};
|
|
564
|
-
// Wait
|
|
624
|
+
// Wait 10 seconds
|
|
565
625
|
await switchbot.wait(this.scanDuration * 1000);
|
|
566
626
|
// Stop to monitor
|
|
567
627
|
await switchbot.stopScan();
|
|
568
628
|
// Update HomeKit
|
|
569
|
-
await this.BLEparseStatus();
|
|
629
|
+
await this.BLEparseStatus(switchbot.onadvertisement.serviceData);
|
|
570
630
|
await this.updateHomeKitCharacteristics();
|
|
571
631
|
})();
|
|
572
|
-
|
|
573
|
-
switchbot
|
|
574
|
-
.startScan({
|
|
575
|
-
model: 'H',
|
|
576
|
-
id: this.device.bleMac,
|
|
577
|
-
})
|
|
578
|
-
.then(async () => {
|
|
579
|
-
// Set an event handler
|
|
580
|
-
switchbot.onadvertisement = async (ad: ad) => {
|
|
581
|
-
this.debugLog(
|
|
582
|
-
`${this.device.deviceType}: ${this.accessory.displayName} Config BLE Address: ${this.device.bleMac},` +
|
|
583
|
-
` BLE Address Found: ${ad.address}`,
|
|
584
|
-
);
|
|
585
|
-
this.BLE_Mode = ad.serviceData.mode;
|
|
586
|
-
this.BLE_On = ad.serviceData.state;
|
|
587
|
-
this.BLE_BatteryLevel = ad.serviceData.battery;
|
|
588
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${JSON.stringify(ad.serviceData)}`);
|
|
589
|
-
this.debugLog(
|
|
590
|
-
`${this.device.deviceType}: ${this.accessory.displayName}, model: ${ad.serviceData.model}, modelName: ` +
|
|
591
|
-
`${ad.serviceData.modelName}, mode: ${ad.serviceData.mode}, state: ${ad.serviceData.state}, battery: ${ad.serviceData.battery}`,
|
|
592
|
-
);
|
|
593
|
-
|
|
594
|
-
if (ad.serviceData) {
|
|
595
|
-
this.BLE_IsConnected = true;
|
|
596
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} connected: ${this.BLE_IsConnected}`);
|
|
597
|
-
await this.stopScanning(switchbot);
|
|
598
|
-
} else {
|
|
599
|
-
this.BLE_IsConnected = false;
|
|
600
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} connected: ${this.BLE_IsConnected}`);
|
|
601
|
-
}
|
|
602
|
-
};
|
|
603
|
-
// Wait
|
|
604
|
-
return await sleep(this.scanDuration * 1000);
|
|
605
|
-
})
|
|
606
|
-
.then(async () => {
|
|
607
|
-
// Stop to monitor
|
|
608
|
-
await this.stopScanning(switchbot);
|
|
609
|
-
})
|
|
610
|
-
.catch(async (e: any) => {
|
|
611
|
-
this.apiError(e);
|
|
612
|
-
this.errorLog(
|
|
613
|
-
`${this.device.deviceType}: ${this.accessory.displayName} failed BLERefreshStatus with ${this.device.connectionType}` +
|
|
614
|
-
` Connection, Error Message: ${JSON.stringify(e.message)}`,
|
|
615
|
-
);
|
|
616
|
-
await this.BLERefreshConnection(switchbot);
|
|
617
|
-
});
|
|
618
|
-
} else {
|
|
632
|
+
if (switchbot === undefined) {
|
|
619
633
|
await this.BLERefreshConnection(switchbot);
|
|
620
|
-
}
|
|
634
|
+
}
|
|
621
635
|
}
|
|
622
636
|
|
|
623
637
|
async openAPIRefreshStatus(): Promise<void> {
|
|
624
638
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus`);
|
|
625
639
|
try {
|
|
626
|
-
const { body, statusCode } = await
|
|
627
|
-
headers: this.platform.generateHeaders()
|
|
628
|
-
});
|
|
640
|
+
const { body, statusCode } = await this.platform.retryRequest(this.deviceMaxRetries, this.deviceDelayBetweenRetries,
|
|
641
|
+
`${Devices}/${this.device.deviceId}/status`, { headers: this.platform.generateHeaders() });
|
|
629
642
|
this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} statusCode: ${statusCode}`);
|
|
630
643
|
const deviceStatus: any = await body.json();
|
|
631
644
|
this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus: ${JSON.stringify(deviceStatus)}`);
|
|
632
645
|
this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus statusCode: ${deviceStatus.statusCode}`);
|
|
633
646
|
if ((statusCode === 200 || statusCode === 100) && (deviceStatus.statusCode === 200 || deviceStatus.statusCode === 100)) {
|
|
634
|
-
this.
|
|
647
|
+
this.debugSuccessLog(`${this.device.deviceType}: ${this.accessory.displayName} `
|
|
635
648
|
+ `statusCode: ${statusCode} & deviceStatus StatusCode: ${deviceStatus.statusCode}`);
|
|
636
|
-
this.
|
|
637
|
-
this.OpenAPI_BatteryLevel = deviceStatus.body.battery;
|
|
638
|
-
this.OpenAPI_FirmwareRevision = deviceStatus.body.version;
|
|
639
|
-
this.openAPIparseStatus();
|
|
649
|
+
this.openAPIparseStatus(deviceStatus);
|
|
640
650
|
this.updateHomeKitCharacteristics();
|
|
641
651
|
} else {
|
|
642
652
|
this.statusCode(statusCode);
|
|
@@ -644,10 +654,33 @@ export class Bot {
|
|
|
644
654
|
}
|
|
645
655
|
} catch (e: any) {
|
|
646
656
|
this.apiError(e);
|
|
647
|
-
this.errorLog(
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
657
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed openAPIRefreshStatus with ${this.device.connectionType}`
|
|
658
|
+
+ ` Connection, Error Message: ${JSON.stringify(e.message)}`);
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
async registerWebhook(accessory: PlatformAccessory, device: device & devicesConfig) {
|
|
663
|
+
if (device.webhook) {
|
|
664
|
+
this.debugLog(`${device.deviceType}: ${accessory.displayName} is listening webhook.`);
|
|
665
|
+
this.platform.webhookEventHandler[device.deviceId] = async (context) => {
|
|
666
|
+
try {
|
|
667
|
+
this.debugLog(`${device.deviceType}: ${accessory.displayName} received Webhook: ${JSON.stringify(context)}`);
|
|
668
|
+
const { power, battery, deviceMode } = context;
|
|
669
|
+
const { botMode } = this;
|
|
670
|
+
const On = await this.getOn();
|
|
671
|
+
const { BatteryLevel } = this.Battery;
|
|
672
|
+
this.debugLog(`${device.deviceType}: ${accessory.displayName} (power, battery, deviceMode) = Webhook:(${power}, ${battery}, ${deviceMode}),`
|
|
673
|
+
+ ` current:(${On}, ${BatteryLevel}, ${botMode})`);
|
|
674
|
+
await this.setOn(power);
|
|
675
|
+
this.Battery.BatteryLevel = battery;
|
|
676
|
+
this.botMode = deviceMode;
|
|
677
|
+
this.updateHomeKitCharacteristics();
|
|
678
|
+
} catch (e: any) {
|
|
679
|
+
this.errorLog(`${device.deviceType}: ${accessory.displayName} failed to handle webhook. Received: ${JSON.stringify(context)} Error: ${e}`);
|
|
680
|
+
}
|
|
681
|
+
};
|
|
682
|
+
} else {
|
|
683
|
+
this.debugLog(`${device.deviceType}: ${accessory.displayName} is not listening webhook.`);
|
|
651
684
|
}
|
|
652
685
|
}
|
|
653
686
|
|
|
@@ -667,9 +700,8 @@ export class Bot {
|
|
|
667
700
|
await this.openAPIpushChanges();
|
|
668
701
|
} else {
|
|
669
702
|
await this.offlineOff();
|
|
670
|
-
this.debugWarnLog(
|
|
671
|
-
|
|
672
|
-
);
|
|
703
|
+
this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:`
|
|
704
|
+
+ ` ${this.device.connectionType}, pushChanges will not happen.`);
|
|
673
705
|
}
|
|
674
706
|
// Refresh the status from the API
|
|
675
707
|
interval(15000)
|
|
@@ -682,8 +714,9 @@ export class Bot {
|
|
|
682
714
|
|
|
683
715
|
async BLEpushChanges(): Promise<void> {
|
|
684
716
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLEpushChanges`);
|
|
685
|
-
|
|
686
|
-
|
|
717
|
+
const On = await this.getOn();
|
|
718
|
+
if (On !== this.accessory.context.On || this.allowPush) {
|
|
719
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLEpushChanges On: ${On} OnCached: ${this.accessory.context.On}`);
|
|
687
720
|
const switchbot = await this.platform.connectBLE();
|
|
688
721
|
// Convert to BLE Address
|
|
689
722
|
this.device.bleMac = this.device
|
|
@@ -697,27 +730,27 @@ export class Bot {
|
|
|
697
730
|
switchbot
|
|
698
731
|
.discover({ model: 'H', quick: true, id: this.device.bleMac })
|
|
699
732
|
.then(async (device_list: { press: (arg0: { id: string | undefined }) => any }[]) => {
|
|
700
|
-
this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${
|
|
733
|
+
this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${On}`);
|
|
701
734
|
return await device_list[0].press({ id: this.device.bleMac });
|
|
702
735
|
})
|
|
703
736
|
.then(() => {
|
|
704
737
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Done.`);
|
|
705
|
-
this.
|
|
738
|
+
this.successLog(`${this.device.deviceType}: ${this.accessory.displayName} `
|
|
739
|
+
+ `On: ${On} sent over BLE, sent successfully`);
|
|
740
|
+
this.accessory.context.On = On;
|
|
706
741
|
setTimeout(() => {
|
|
707
742
|
if (this.botDeviceType === 'switch') {
|
|
708
|
-
this.
|
|
743
|
+
this.Switch?.Service.getCharacteristic(this.hap.Characteristic.On).updateValue(On);
|
|
709
744
|
} else {
|
|
710
|
-
this.
|
|
745
|
+
this.Outlet?.Service.getCharacteristic(this.hap.Characteristic.On).updateValue(On);
|
|
711
746
|
}
|
|
712
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${
|
|
747
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${On}, Switch Timeout`);
|
|
713
748
|
}, 500);
|
|
714
749
|
})
|
|
715
750
|
.catch(async (e: any) => {
|
|
716
751
|
this.apiError(e);
|
|
717
|
-
this.errorLog(
|
|
718
|
-
|
|
719
|
-
` Connection & botMode: ${this.botMode}, Error Message: ${JSON.stringify(e.message)}`,
|
|
720
|
-
);
|
|
752
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed BLEpushChanges with ${this.device.connectionType}`
|
|
753
|
+
+ ` Connection & botMode: ${this.botMode}, Error Message: ${JSON.stringify(e.message)}`);
|
|
721
754
|
await this.BLEPushConnection();
|
|
722
755
|
});
|
|
723
756
|
} else if (this.botMode === 'switch') {
|
|
@@ -725,11 +758,11 @@ export class Bot {
|
|
|
725
758
|
switchbot
|
|
726
759
|
.discover({ model: 'H', quick: true, id: this.device.bleMac })
|
|
727
760
|
.then(async (device_list: any) => {
|
|
728
|
-
this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${
|
|
729
|
-
return await this.
|
|
730
|
-
max: this.
|
|
761
|
+
this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${On}`);
|
|
762
|
+
return await this.retryBLE({
|
|
763
|
+
max: await this.maxRetryBLE(),
|
|
731
764
|
fn: async () => {
|
|
732
|
-
if (
|
|
765
|
+
if (On) {
|
|
733
766
|
return await device_list[0].turnOn({ id: this.device.bleMac });
|
|
734
767
|
} else {
|
|
735
768
|
return await device_list[0].turnOff({ id: this.device.bleMac });
|
|
@@ -739,46 +772,43 @@ export class Bot {
|
|
|
739
772
|
})
|
|
740
773
|
.then(() => {
|
|
741
774
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Done.`);
|
|
742
|
-
this.accessory.context.On =
|
|
775
|
+
this.accessory.context.On = On;
|
|
743
776
|
})
|
|
744
777
|
.catch(async (e: any) => {
|
|
745
778
|
this.apiError(e);
|
|
746
|
-
this.errorLog(
|
|
747
|
-
|
|
748
|
-
` Connection & botMode: ${this.botMode}, Error Message: ${JSON.stringify(e.message)}`,
|
|
749
|
-
);
|
|
779
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed BLEpushChanges with ${this.device.connectionType}`
|
|
780
|
+
+ ` Connection & botMode: ${this.botMode}, Error Message: ${JSON.stringify(e.message)}`);
|
|
750
781
|
await this.BLEPushConnection();
|
|
751
782
|
});
|
|
752
783
|
} else {
|
|
753
784
|
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Bot Mode: ${this.botMode}`);
|
|
754
785
|
}
|
|
755
786
|
} else {
|
|
756
|
-
this.debugLog(
|
|
757
|
-
`${this.device.deviceType}: ${this.accessory.displayName} No BLEpushChanges.` + `On: ${this.On}, ` + `OnCached: ${this.accessory.context.On}`,
|
|
758
|
-
);
|
|
787
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} No BLEpushChanges, On: ${On}, OnCached: ${this.accessory.context.On}`);
|
|
759
788
|
}
|
|
760
789
|
}
|
|
761
790
|
|
|
762
791
|
async openAPIpushChanges(): Promise<void> {
|
|
763
792
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIpushChanges`);
|
|
793
|
+
let On = await this.getOn();
|
|
764
794
|
if (this.multiPressCount > 0) {
|
|
765
795
|
this.debugLog(`${this.device.deviceType}: ${this.multiPressCount} request(s) queued.`);
|
|
766
|
-
|
|
796
|
+
On = true;
|
|
767
797
|
}
|
|
768
|
-
if (
|
|
798
|
+
if (On !== this.accessory.context.On || this.allowPush || this.multiPressCount > 0) {
|
|
769
799
|
let command = '';
|
|
770
|
-
if (this.botMode === 'switch' &&
|
|
800
|
+
if (this.botMode === 'switch' && On) {
|
|
771
801
|
command = 'turnOn';
|
|
772
|
-
|
|
773
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Switch Mode, Turning ${
|
|
774
|
-
} else if (this.botMode === 'switch' && !
|
|
802
|
+
On = true;
|
|
803
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Switch Mode, Turning ${On}`);
|
|
804
|
+
} else if (this.botMode === 'switch' && !On) {
|
|
775
805
|
command = 'turnOff';
|
|
776
|
-
|
|
777
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Switch Mode, Turning ${
|
|
806
|
+
On = false;
|
|
807
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Switch Mode, Turning ${On}`);
|
|
778
808
|
} else if (this.botMode === 'press' || this.botMode === 'multipress') {
|
|
779
809
|
command = 'press';
|
|
780
810
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Press Mode`);
|
|
781
|
-
|
|
811
|
+
On = false;
|
|
782
812
|
} else {
|
|
783
813
|
throw new Error(`${this.device.deviceType}: ${this.accessory.displayName} Device Parameters not set for this Bot.`);
|
|
784
814
|
}
|
|
@@ -800,8 +830,10 @@ export class Bot {
|
|
|
800
830
|
this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus body: ${JSON.stringify(deviceStatus.body)}`);
|
|
801
831
|
this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus statusCode: ${deviceStatus.statusCode}`);
|
|
802
832
|
if ((statusCode === 200 || statusCode === 100) && (deviceStatus.statusCode === 200 || deviceStatus.statusCode === 100)) {
|
|
803
|
-
this.
|
|
833
|
+
this.debugSuccessLog(`${this.device.deviceType}: ${this.accessory.displayName} `
|
|
804
834
|
+ `statusCode: ${statusCode} & deviceStatus StatusCode: ${deviceStatus.statusCode}`);
|
|
835
|
+
this.successLog(`${this.device.deviceType}: ${this.accessory.displayName} `
|
|
836
|
+
+ `request to SwitchBot API, body: ${JSON.stringify(JSON.parse(bodyChange))} sent successfully`);
|
|
805
837
|
} else {
|
|
806
838
|
this.statusCode(statusCode);
|
|
807
839
|
this.statusCode(deviceStatus.statusCode);
|
|
@@ -810,23 +842,18 @@ export class Bot {
|
|
|
810
842
|
this.multiPressCount--;
|
|
811
843
|
if (this.multiPressCount > 0) {
|
|
812
844
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Multi Press Count: ${this.multiPressCount}`);
|
|
813
|
-
|
|
845
|
+
On = true;
|
|
814
846
|
this.openAPIpushChanges();
|
|
815
847
|
}
|
|
816
848
|
}
|
|
817
849
|
} catch (e: any) {
|
|
818
850
|
this.apiError(e);
|
|
819
|
-
this.errorLog(
|
|
820
|
-
|
|
821
|
-
` Connection, Error Message: ${JSON.stringify(e.message)}`,
|
|
822
|
-
);
|
|
851
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed openAPIpushChanges with ${this.device.connectionType}`
|
|
852
|
+
+ ` Connection, Error Message: ${JSON.stringify(e.message)}`);
|
|
823
853
|
}
|
|
824
854
|
} else {
|
|
825
|
-
this.debugLog(
|
|
826
|
-
|
|
827
|
-
`On: ${this.On}, ` +
|
|
828
|
-
`OnCached: ${this.accessory.context.On}`,
|
|
829
|
-
);
|
|
855
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} No openAPIpushChanges,`
|
|
856
|
+
+ ` On: ${On}, OnCached: ${this.accessory.context.On}`);
|
|
830
857
|
}
|
|
831
858
|
}
|
|
832
859
|
|
|
@@ -835,53 +862,105 @@ export class Bot {
|
|
|
835
862
|
*/
|
|
836
863
|
async OnSet(value: CharacteristicValue): Promise<void> {
|
|
837
864
|
if (this.botDeviceType === 'garagedoor') {
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
this.
|
|
841
|
-
|
|
842
|
-
|
|
865
|
+
if (this.GarageDoor) {
|
|
866
|
+
this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Set TargetDoorState: ${value}`);
|
|
867
|
+
if (value === this.hap.Characteristic.TargetDoorState.CLOSED) {
|
|
868
|
+
await this.setOn(false);
|
|
869
|
+
this.GarageDoor.On = false;
|
|
870
|
+
} else {
|
|
871
|
+
await this.setOn(true);
|
|
872
|
+
this.GarageDoor.On = true;
|
|
873
|
+
}
|
|
843
874
|
}
|
|
844
|
-
} else if (
|
|
845
|
-
this.
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
875
|
+
} else if (this.botDeviceType === 'door') {
|
|
876
|
+
if (this.Door) {
|
|
877
|
+
this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Set TargetPosition: ${value}`);
|
|
878
|
+
if (value === 0) {
|
|
879
|
+
await this.setOn(false);
|
|
880
|
+
this.Door.On = false;
|
|
881
|
+
} else {
|
|
882
|
+
await this.setOn(true);
|
|
883
|
+
this.Door.On = true;
|
|
884
|
+
}
|
|
885
|
+
}
|
|
886
|
+
} else if (this.botDeviceType === 'window') {
|
|
887
|
+
if (this.Window) {
|
|
888
|
+
this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Set TargetPosition: ${value}`);
|
|
889
|
+
if (value === 0) {
|
|
890
|
+
await this.setOn(false);
|
|
891
|
+
this.Window.On = false;
|
|
892
|
+
} else {
|
|
893
|
+
await this.setOn(true);
|
|
894
|
+
this.Window.On = true;
|
|
895
|
+
}
|
|
896
|
+
}
|
|
897
|
+
} else if (this.botDeviceType === 'windowcovering') {
|
|
898
|
+
if (this.WindowCovering) {
|
|
899
|
+
this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Set TargetPosition: ${value}`);
|
|
900
|
+
if (value === 0) {
|
|
901
|
+
await this.setOn(false);
|
|
902
|
+
this.WindowCovering.On = false;
|
|
903
|
+
} else {
|
|
904
|
+
await this.setOn(true);
|
|
905
|
+
this.WindowCovering.On = true;
|
|
906
|
+
}
|
|
854
907
|
}
|
|
855
908
|
} else if (this.botDeviceType === 'lock') {
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
this.
|
|
859
|
-
|
|
860
|
-
|
|
909
|
+
if (this.LockMechanism) {
|
|
910
|
+
this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Set LockTargetState: ${value}`);
|
|
911
|
+
if (value === this.hap.Characteristic.LockTargetState.SECURED) {
|
|
912
|
+
await this.setOn(false);
|
|
913
|
+
this.LockMechanism.On = false;
|
|
914
|
+
} else {
|
|
915
|
+
await this.setOn(true);
|
|
916
|
+
this.LockMechanism.On = true;
|
|
917
|
+
}
|
|
861
918
|
}
|
|
862
919
|
} else if (this.botDeviceType === 'faucet') {
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
this.
|
|
866
|
-
|
|
867
|
-
|
|
920
|
+
if (this.Faucet) {
|
|
921
|
+
this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Set Active: ${value}`);
|
|
922
|
+
if (value === this.hap.Characteristic.Active.INACTIVE) {
|
|
923
|
+
await this.setOn(false);
|
|
924
|
+
this.Faucet.On = false;
|
|
925
|
+
} else {
|
|
926
|
+
await this.setOn(true);
|
|
927
|
+
this.Faucet.On = true;
|
|
928
|
+
}
|
|
868
929
|
}
|
|
869
930
|
} else if (this.botDeviceType === 'stateful') {
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
931
|
+
if (this.StatefulProgrammableSwitch) {
|
|
932
|
+
this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Set ProgrammableSwitchOutputState: ${value}`);
|
|
933
|
+
if (value === 0) {
|
|
934
|
+
await this.setOn(false);
|
|
935
|
+
this.StatefulProgrammableSwitch.On = false;
|
|
936
|
+
} else {
|
|
937
|
+
await this.setOn(true);
|
|
938
|
+
this.StatefulProgrammableSwitch.On = true;
|
|
939
|
+
}
|
|
875
940
|
}
|
|
876
|
-
} else {
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
if (value ===
|
|
880
|
-
this.
|
|
881
|
-
this.
|
|
941
|
+
} else if (this.botDeviceType === 'switch') {
|
|
942
|
+
if (this.Switch) {
|
|
943
|
+
this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Set ProgrammableSwitchOutputState: ${value}`);
|
|
944
|
+
if (value === 0) {
|
|
945
|
+
await this.setOn(false);
|
|
946
|
+
this.Switch.On = false;
|
|
947
|
+
} else {
|
|
948
|
+
await this.setOn(true);
|
|
949
|
+
this.Switch.On = true;
|
|
882
950
|
}
|
|
883
951
|
}
|
|
884
|
-
|
|
952
|
+
} else {
|
|
953
|
+
if (this.Outlet) {
|
|
954
|
+
this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Set On: ${value}`);
|
|
955
|
+
await this.setOn(Boolean(value));
|
|
956
|
+
this.Outlet.On = value;
|
|
957
|
+
}
|
|
958
|
+
}
|
|
959
|
+
if (this.device.bot?.mode === 'multipress') {
|
|
960
|
+
if (value === true) {
|
|
961
|
+
this.multiPressCount++;
|
|
962
|
+
this.debugLog(`${this.device.deviceType} set to Multi-Press. Multi-Press count: ${this.multiPressCount}`);
|
|
963
|
+
}
|
|
885
964
|
}
|
|
886
965
|
this.doBotUpdate.next();
|
|
887
966
|
}
|
|
@@ -892,536 +971,352 @@ export class Bot {
|
|
|
892
971
|
async updateHomeKitCharacteristics(): Promise<void> {
|
|
893
972
|
// State
|
|
894
973
|
if (this.botDeviceType === 'garagedoor') {
|
|
895
|
-
if (this.On === undefined) {
|
|
896
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.On}`);
|
|
974
|
+
if (this.GarageDoor?.On === undefined) {
|
|
975
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.GarageDoor?.On}`);
|
|
897
976
|
} else {
|
|
898
|
-
if (this.On) {
|
|
899
|
-
this.
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
this.garageDoorService?.updateCharacteristic(
|
|
904
|
-
this.hap.Characteristic.CurrentDoorState,
|
|
905
|
-
this.hap.Characteristic.CurrentDoorState.OPEN,
|
|
906
|
-
);
|
|
907
|
-
this.debugLog(
|
|
908
|
-
`${this.device.deviceType}: ` + `${this.accessory.displayName} updateCharacteristic TargetDoorState: Open, CurrentDoorState: Open`,
|
|
909
|
-
);
|
|
977
|
+
if (this.GarageDoor.On) {
|
|
978
|
+
this.GarageDoor.Service.updateCharacteristic(this.hap.Characteristic.TargetDoorState, this.hap.Characteristic.TargetDoorState.OPEN);
|
|
979
|
+
this.GarageDoor.Service.updateCharacteristic(this.hap.Characteristic.CurrentDoorState, this.hap.Characteristic.CurrentDoorState.OPEN);
|
|
980
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic`
|
|
981
|
+
+ ` TargetDoorState: Open, CurrentDoorState: Open (${this.GarageDoor.On})`);
|
|
910
982
|
} else {
|
|
911
|
-
this.
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
this.garageDoorService?.updateCharacteristic(
|
|
916
|
-
this.hap.Characteristic.CurrentDoorState,
|
|
917
|
-
this.hap.Characteristic.CurrentDoorState.CLOSED,
|
|
918
|
-
);
|
|
919
|
-
this.debugLog(
|
|
920
|
-
`${this.device.deviceType}: ` + `${this.accessory.displayName} updateCharacteristic TargetDoorState: Open, CurrentDoorState: Open`,
|
|
921
|
-
);
|
|
983
|
+
this.GarageDoor.Service.updateCharacteristic(this.hap.Characteristic.TargetDoorState, this.hap.Characteristic.TargetDoorState.CLOSED);
|
|
984
|
+
this.GarageDoor.Service.updateCharacteristic(this.hap.Characteristic.CurrentDoorState, this.hap.Characteristic.CurrentDoorState.CLOSED);
|
|
985
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristicc`
|
|
986
|
+
+ ` TargetDoorState: Open, CurrentDoorState: Open (${this.GarageDoor.On})`);
|
|
922
987
|
}
|
|
923
988
|
}
|
|
924
|
-
this.
|
|
989
|
+
await this.setOn(Boolean(this.GarageDoor?.On));
|
|
990
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Garage Door On: ${this.GarageDoor?.On}`);
|
|
925
991
|
} else if (this.botDeviceType === 'door') {
|
|
926
|
-
if (this.On === undefined) {
|
|
927
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.On}`);
|
|
992
|
+
if (this.Door?.On === undefined) {
|
|
993
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.Door?.On}`);
|
|
928
994
|
} else {
|
|
929
|
-
if (this.On) {
|
|
930
|
-
this.
|
|
931
|
-
this.
|
|
932
|
-
this.
|
|
933
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}
|
|
995
|
+
if (this.Door.On) {
|
|
996
|
+
this.Door.Service.updateCharacteristic(this.hap.Characteristic.TargetPosition, 100);
|
|
997
|
+
this.Door.Service.updateCharacteristic(this.hap.Characteristic.CurrentPosition, 100);
|
|
998
|
+
this.Door.Service.updateCharacteristic(this.hap.Characteristic.PositionState, this.hap.Characteristic.PositionState.STOPPED);
|
|
999
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristicc`
|
|
1000
|
+
+ ` TargetPosition: 100, CurrentPosition: 100 (${this.Door.On})`);
|
|
934
1001
|
} else {
|
|
935
|
-
this.
|
|
936
|
-
this.
|
|
937
|
-
this.
|
|
938
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}
|
|
1002
|
+
this.Door.Service.updateCharacteristic(this.hap.Characteristic.TargetPosition, 0);
|
|
1003
|
+
this.Door.Service.updateCharacteristic(this.hap.Characteristic.CurrentPosition, 0);
|
|
1004
|
+
this.Door.Service.updateCharacteristic(this.hap.Characteristic.PositionState, this.hap.Characteristic.PositionState.STOPPED);
|
|
1005
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristicc`
|
|
1006
|
+
+ ` TargetPosition: 0, CurrentPosition: 0 (${this.Door.On})`);
|
|
939
1007
|
}
|
|
940
1008
|
}
|
|
941
|
-
this.
|
|
1009
|
+
await this.setOn(Boolean(this.Door?.On));
|
|
1010
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Door On: ${this.Door?.On}`);
|
|
942
1011
|
} else if (this.botDeviceType === 'window') {
|
|
943
|
-
if (this.On === undefined) {
|
|
944
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.On}`);
|
|
1012
|
+
if (this.Window?.On === undefined) {
|
|
1013
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.Window?.On}`);
|
|
945
1014
|
} else {
|
|
946
|
-
if (this.On) {
|
|
947
|
-
this.
|
|
948
|
-
this.
|
|
949
|
-
this.
|
|
950
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}
|
|
1015
|
+
if (this.Window.On) {
|
|
1016
|
+
this.Window.Service.updateCharacteristic(this.hap.Characteristic.TargetPosition, 100);
|
|
1017
|
+
this.Window.Service.updateCharacteristic(this.hap.Characteristic.CurrentPosition, 100);
|
|
1018
|
+
this.Window.Service.updateCharacteristic(this.hap.Characteristic.PositionState, this.hap.Characteristic.PositionState.STOPPED);
|
|
1019
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristicc`
|
|
1020
|
+
+ ` TargetPosition: 100, CurrentPosition: 100 (${this.Window.On})`);
|
|
951
1021
|
} else {
|
|
952
|
-
this.
|
|
953
|
-
this.
|
|
954
|
-
this.
|
|
955
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}
|
|
1022
|
+
this.Window.Service.updateCharacteristic(this.hap.Characteristic.TargetPosition, 0);
|
|
1023
|
+
this.Window.Service.updateCharacteristic(this.hap.Characteristic.CurrentPosition, 0);
|
|
1024
|
+
this.Window.Service.updateCharacteristic(this.hap.Characteristic.PositionState, this.hap.Characteristic.PositionState.STOPPED);
|
|
1025
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristicc`
|
|
1026
|
+
+ ` TargetPosition: 0, CurrentPosition: 0 (${this.Window.On})`);
|
|
956
1027
|
}
|
|
957
1028
|
}
|
|
958
|
-
this.
|
|
1029
|
+
await this.setOn(Boolean(this.Window?.On));
|
|
1030
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Window On: ${this.Window?.On}`);
|
|
959
1031
|
} else if (this.botDeviceType === 'windowcovering') {
|
|
960
|
-
if (this.On === undefined) {
|
|
961
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.On}`);
|
|
1032
|
+
if (this.WindowCovering?.On === undefined) {
|
|
1033
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.WindowCovering?.On}`);
|
|
962
1034
|
} else {
|
|
963
|
-
if (this.On) {
|
|
964
|
-
this.
|
|
965
|
-
this.
|
|
966
|
-
this.
|
|
967
|
-
|
|
968
|
-
this.
|
|
969
|
-
);
|
|
970
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic TargetPosition: 100, CurrentPosition: 100`);
|
|
1035
|
+
if (this.WindowCovering.On) {
|
|
1036
|
+
this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.TargetPosition, 100);
|
|
1037
|
+
this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.CurrentPosition, 100);
|
|
1038
|
+
this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.PositionState, this.hap.Characteristic.PositionState.STOPPED);
|
|
1039
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristicc`
|
|
1040
|
+
+ ` TargetPosition: 100, CurrentPosition: 100 (${this.WindowCovering.On})`);
|
|
971
1041
|
} else {
|
|
972
|
-
this.
|
|
973
|
-
this.
|
|
974
|
-
this.
|
|
975
|
-
|
|
976
|
-
this.
|
|
977
|
-
);
|
|
978
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic TargetPosition: 0, CurrentPosition: 0`);
|
|
1042
|
+
this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.TargetPosition, 0);
|
|
1043
|
+
this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.CurrentPosition, 0);
|
|
1044
|
+
this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.PositionState, this.hap.Characteristic.PositionState.STOPPED);
|
|
1045
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristicc`
|
|
1046
|
+
+ ` TargetPosition: 0, CurrentPosition: 0 (${this.WindowCovering.On})`);
|
|
979
1047
|
}
|
|
980
1048
|
}
|
|
981
|
-
this.
|
|
1049
|
+
await this.setOn(Boolean(this.WindowCovering?.On));
|
|
1050
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Window Covering On: ${this.WindowCovering?.On}`);
|
|
982
1051
|
} else if (this.botDeviceType === 'lock') {
|
|
983
|
-
if (this.On === undefined) {
|
|
984
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.On}`);
|
|
1052
|
+
if (this.LockMechanism?.On === undefined) {
|
|
1053
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.LockMechanism?.On}`);
|
|
985
1054
|
} else {
|
|
986
|
-
if (this.On) {
|
|
987
|
-
this.
|
|
988
|
-
this.hap.Characteristic.LockTargetState
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
this.
|
|
992
|
-
this.
|
|
993
|
-
this.hap.Characteristic.LockCurrentState.UNSECURED,
|
|
994
|
-
);
|
|
995
|
-
this.debugLog(
|
|
996
|
-
`${this.device.deviceType}: ` +
|
|
997
|
-
`${this.accessory.displayName} updateCharacteristic LockTargetState: UNSECURED, LockCurrentState: UNSECURED`,
|
|
998
|
-
);
|
|
1055
|
+
if (this.LockMechanism.On) {
|
|
1056
|
+
this.LockMechanism.Service.updateCharacteristic(this.hap.Characteristic.LockTargetState,
|
|
1057
|
+
this.hap.Characteristic.LockTargetState.UNSECURED);
|
|
1058
|
+
this.LockMechanism.Service.updateCharacteristic(this.hap.Characteristic.LockCurrentState,
|
|
1059
|
+
this.hap.Characteristic.LockCurrentState.UNSECURED);
|
|
1060
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristicc`
|
|
1061
|
+
+ ` LockTargetState: UNSECURED, LockCurrentState: UNSECURED (${this.LockMechanism.On})`);
|
|
999
1062
|
} else {
|
|
1000
|
-
this.
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
this.hap.Characteristic.LockCurrentState.SECURED
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
`${this.device.deviceType}: ` + `${this.accessory.displayName} updateCharacteristic LockTargetState: SECURED, LockCurrentState: SECURED`,
|
|
1007
|
-
);
|
|
1063
|
+
this.LockMechanism.Service.updateCharacteristic(this.hap.Characteristic.LockTargetState,
|
|
1064
|
+
this.hap.Characteristic.LockTargetState.SECURED);
|
|
1065
|
+
this.LockMechanism.Service.updateCharacteristic(this.hap.Characteristic.LockCurrentState,
|
|
1066
|
+
this.hap.Characteristic.LockCurrentState.SECURED);
|
|
1067
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic`
|
|
1068
|
+
+ ` LockTargetState: SECURED, LockCurrentState: SECURED (${this.LockMechanism.On})`);
|
|
1008
1069
|
}
|
|
1009
1070
|
}
|
|
1010
|
-
this.
|
|
1071
|
+
await this.setOn(Boolean(this.LockMechanism?.On));
|
|
1072
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Lock On: ${this.LockMechanism?.On}`);
|
|
1011
1073
|
} else if (this.botDeviceType === 'faucet') {
|
|
1012
|
-
if (this.On === undefined) {
|
|
1013
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.On}`);
|
|
1074
|
+
if (this.Faucet?.On === undefined) {
|
|
1075
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.Faucet?.On}`);
|
|
1014
1076
|
} else {
|
|
1015
|
-
if (this.On) {
|
|
1016
|
-
this.
|
|
1017
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic Active: ${this.On}`);
|
|
1077
|
+
if (this.Faucet.On) {
|
|
1078
|
+
this.Faucet.Service.updateCharacteristic(this.hap.Characteristic.Active, this.hap.Characteristic.Active.ACTIVE);
|
|
1079
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic Active: ${this.Faucet.On}`);
|
|
1018
1080
|
} else {
|
|
1019
|
-
this.
|
|
1020
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic Active: ${this.On}`);
|
|
1081
|
+
this.Faucet.Service.updateCharacteristic(this.hap.Characteristic.Active, this.hap.Characteristic.Active.INACTIVE);
|
|
1082
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic Active: ${this.Faucet.On}`);
|
|
1021
1083
|
}
|
|
1022
1084
|
}
|
|
1023
|
-
this.
|
|
1085
|
+
await this.setOn(Boolean(this.Faucet?.On));
|
|
1086
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Faucet On: ${this.Faucet?.On}`);
|
|
1024
1087
|
} else if (this.botDeviceType === 'fan') {
|
|
1025
|
-
if (this.On === undefined) {
|
|
1026
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.On}`);
|
|
1088
|
+
if (this.Fan?.On === undefined) {
|
|
1089
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.Fan?.On}`);
|
|
1027
1090
|
} else {
|
|
1028
|
-
if (this.On) {
|
|
1029
|
-
this.
|
|
1030
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic On: ${this.On}`);
|
|
1091
|
+
if (this.Fan.On) {
|
|
1092
|
+
this.Fan.Service.updateCharacteristic(this.hap.Characteristic.On, this.Fan.On);
|
|
1093
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic On: ${this.Fan.On}`);
|
|
1031
1094
|
} else {
|
|
1032
|
-
this.
|
|
1033
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic On: ${this.On}`);
|
|
1095
|
+
this.Fan.Service.updateCharacteristic(this.hap.Characteristic.On, this.Fan.On);
|
|
1096
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic On: ${this.Fan.On}`);
|
|
1034
1097
|
}
|
|
1035
1098
|
}
|
|
1036
|
-
this.
|
|
1099
|
+
await this.setOn(Boolean(this.Fan?.On));
|
|
1100
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Fan On: ${this.Fan?.On}`);
|
|
1037
1101
|
} else if (this.botDeviceType === 'stateful') {
|
|
1038
|
-
if (this.On === undefined) {
|
|
1039
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.On}`);
|
|
1102
|
+
if (this.StatefulProgrammableSwitch?.On === undefined) {
|
|
1103
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.StatefulProgrammableSwitch?.On}`);
|
|
1040
1104
|
} else {
|
|
1041
|
-
if (this.On) {
|
|
1042
|
-
this.
|
|
1043
|
-
this.hap.Characteristic.ProgrammableSwitchEvent
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
this.debugLog(
|
|
1048
|
-
`${this.device.deviceType}: ` +
|
|
1049
|
-
`${this.accessory.displayName} updateCharacteristic ProgrammableSwitchEvent: SINGLE, ProgrammableSwitchOutputState: 1`,
|
|
1050
|
-
);
|
|
1105
|
+
if (this.StatefulProgrammableSwitch.On) {
|
|
1106
|
+
this.StatefulProgrammableSwitch.Service.updateCharacteristic(this.hap.Characteristic.ProgrammableSwitchEvent,
|
|
1107
|
+
this.hap.Characteristic.ProgrammableSwitchEvent.SINGLE_PRESS);
|
|
1108
|
+
this.StatefulProgrammableSwitch.Service.updateCharacteristic(this.hap.Characteristic.ProgrammableSwitchOutputState, 1);
|
|
1109
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic`
|
|
1110
|
+
+ ` ProgrammableSwitchEvent: SINGLE, ProgrammableSwitchOutputState: 1 (${this.StatefulProgrammableSwitch.On})`);
|
|
1051
1111
|
} else {
|
|
1052
|
-
this.
|
|
1053
|
-
this.hap.Characteristic.ProgrammableSwitchEvent
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
this.debugLog(
|
|
1058
|
-
`${this.device.deviceType}: ` +
|
|
1059
|
-
`${this.accessory.displayName} updateCharacteristic ProgrammableSwitchEvent: SINGLE, ProgrammableSwitchOutputState: 0`,
|
|
1060
|
-
);
|
|
1112
|
+
this.StatefulProgrammableSwitch.Service.updateCharacteristic(this.hap.Characteristic.ProgrammableSwitchEvent,
|
|
1113
|
+
this.hap.Characteristic.ProgrammableSwitchEvent.SINGLE_PRESS);
|
|
1114
|
+
this.StatefulProgrammableSwitch.Service.updateCharacteristic(this.hap.Characteristic.ProgrammableSwitchOutputState, 0);
|
|
1115
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic`
|
|
1116
|
+
+ ` ProgrammableSwitchEvent: SINGLE, ProgrammableSwitchOutputState: 0 (${this.StatefulProgrammableSwitch.On})`);
|
|
1061
1117
|
}
|
|
1062
1118
|
}
|
|
1063
|
-
this.
|
|
1119
|
+
await this.setOn(Boolean(this.StatefulProgrammableSwitch?.On));
|
|
1120
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} StatefulProgrammableSwitch On: ${this.StatefulProgrammableSwitch?.On}`);
|
|
1064
1121
|
} else if (this.botDeviceType === 'switch') {
|
|
1065
|
-
if (this.On === undefined) {
|
|
1066
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.On}`);
|
|
1122
|
+
if (this.Switch?.On === undefined) {
|
|
1123
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.Switch?.On}`);
|
|
1067
1124
|
} else {
|
|
1068
|
-
this.
|
|
1069
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic On: ${this.On}`);
|
|
1125
|
+
this.Switch.Service.updateCharacteristic(this.hap.Characteristic.On, this.Switch.On);
|
|
1126
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic On: ${this.Switch.On}`);
|
|
1070
1127
|
}
|
|
1128
|
+
await this.setOn(Boolean(this.Switch?.On));
|
|
1071
1129
|
} else {
|
|
1072
|
-
if (this.On === undefined) {
|
|
1073
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.On}`);
|
|
1130
|
+
if (this.Outlet?.On === undefined) {
|
|
1131
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.Outlet?.On}`);
|
|
1074
1132
|
} else {
|
|
1075
|
-
this.
|
|
1076
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic On: ${this.On}`);
|
|
1133
|
+
this.Outlet.Service.updateCharacteristic(this.hap.Characteristic.On, this.Outlet.On);
|
|
1134
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic On: ${this.Outlet.On}`);
|
|
1077
1135
|
}
|
|
1136
|
+
await this.setOn(Boolean(this.Outlet?.On));
|
|
1078
1137
|
}
|
|
1079
|
-
this.accessory.context.On = this.
|
|
1138
|
+
this.accessory.context.On = await this.getOn();
|
|
1080
1139
|
// BatteryLevel
|
|
1081
|
-
if (this.BatteryLevel === undefined) {
|
|
1082
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.BatteryLevel}`);
|
|
1140
|
+
if (this.Battery.BatteryLevel === undefined) {
|
|
1141
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.Battery.BatteryLevel}`);
|
|
1083
1142
|
} else {
|
|
1084
|
-
this.accessory.context.BatteryLevel = this.BatteryLevel;
|
|
1085
|
-
this.
|
|
1086
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic BatteryLevel: ${this.BatteryLevel}`);
|
|
1143
|
+
this.accessory.context.BatteryLevel = this.Battery.BatteryLevel;
|
|
1144
|
+
this.Battery.Service.updateCharacteristic(this.hap.Characteristic.BatteryLevel, this.Battery.BatteryLevel);
|
|
1145
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic BatteryLevel: ${this.Battery.BatteryLevel}`);
|
|
1087
1146
|
}
|
|
1088
1147
|
// StatusLowBattery
|
|
1089
|
-
if (this.StatusLowBattery === undefined) {
|
|
1090
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} StatusLowBattery: ${this.StatusLowBattery}`);
|
|
1148
|
+
if (this.Battery.StatusLowBattery === undefined) {
|
|
1149
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} StatusLowBattery: ${this.Battery.StatusLowBattery}`);
|
|
1091
1150
|
} else {
|
|
1092
|
-
this.accessory.context.StatusLowBattery = this.StatusLowBattery;
|
|
1093
|
-
this.
|
|
1094
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic
|
|
1151
|
+
this.accessory.context.StatusLowBattery = this.Battery.StatusLowBattery;
|
|
1152
|
+
this.Battery.Service.updateCharacteristic(this.hap.Characteristic.StatusLowBattery, this.Battery.StatusLowBattery);
|
|
1153
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic`
|
|
1154
|
+
+ ` StatusLowBattery: ${this.Battery.StatusLowBattery}`);
|
|
1095
1155
|
}
|
|
1096
1156
|
}
|
|
1097
1157
|
|
|
1098
1158
|
async removeOutletService(accessory: PlatformAccessory): Promise<void> {
|
|
1099
1159
|
// If outletService still present, then remove first
|
|
1100
|
-
|
|
1101
|
-
|
|
1160
|
+
if (this.Outlet?.Service) {
|
|
1161
|
+
this.Outlet.Service = this.accessory.getService(this.hap.Service.Outlet) as Service;
|
|
1102
1162
|
this.warnLog(`${this.device.deviceType}: ${accessory.displayName} Removing Leftover Outlet Service`);
|
|
1163
|
+
accessory.removeService(this.Outlet.Service);
|
|
1103
1164
|
}
|
|
1104
|
-
accessory.removeService(this.outletService!);
|
|
1105
1165
|
}
|
|
1106
1166
|
|
|
1107
1167
|
async removeGarageDoorService(accessory: PlatformAccessory): Promise<void> {
|
|
1108
1168
|
// If garageDoorService still present, then remove first
|
|
1109
|
-
|
|
1110
|
-
|
|
1169
|
+
if (this.GarageDoor?.Service) {
|
|
1170
|
+
this.GarageDoor.Service = this.accessory.getService(this.hap.Service.GarageDoorOpener) as Service;
|
|
1111
1171
|
this.warnLog(`${this.device.deviceType}: ${accessory.displayName} Removing Leftover Garage Door Service`);
|
|
1172
|
+
accessory.removeService(this.GarageDoor.Service);
|
|
1112
1173
|
}
|
|
1113
|
-
accessory.removeService(this.garageDoorService!);
|
|
1114
1174
|
}
|
|
1115
1175
|
|
|
1116
1176
|
async removeDoorService(accessory: PlatformAccessory): Promise<void> {
|
|
1117
1177
|
// If doorService still present, then remove first
|
|
1118
|
-
|
|
1119
|
-
|
|
1178
|
+
if (this.Door?.Service) {
|
|
1179
|
+
this.Door.Service = this.accessory.getService(this.hap.Service.Door) as Service;
|
|
1120
1180
|
this.warnLog(`${this.device.deviceType}: ${accessory.displayName} Removing Leftover Door Service`);
|
|
1181
|
+
accessory.removeService(this.Door.Service);
|
|
1121
1182
|
}
|
|
1122
|
-
accessory.removeService(this.doorService!);
|
|
1123
1183
|
}
|
|
1124
1184
|
|
|
1125
1185
|
async removeLockService(accessory: PlatformAccessory): Promise<void> {
|
|
1126
1186
|
// If lockService still present, then remove first
|
|
1127
|
-
|
|
1128
|
-
|
|
1187
|
+
if (this.LockMechanism?.Service) {
|
|
1188
|
+
this.LockMechanism.Service = this.accessory.getService(this.hap.Service.LockMechanism) as Service;
|
|
1129
1189
|
this.warnLog(`${this.device.deviceType}: ${accessory.displayName} Removing Leftover Lock Service`);
|
|
1190
|
+
accessory.removeService(this.LockMechanism.Service);
|
|
1130
1191
|
}
|
|
1131
|
-
accessory.removeService(this.lockService!);
|
|
1132
1192
|
}
|
|
1133
1193
|
|
|
1134
1194
|
async removeFaucetService(accessory: PlatformAccessory): Promise<void> {
|
|
1135
1195
|
// If faucetService still present, then remove first
|
|
1136
|
-
|
|
1137
|
-
|
|
1196
|
+
if (this.Faucet?.Service) {
|
|
1197
|
+
this.Faucet.Service = this.accessory.getService(this.hap.Service.Faucet) as Service;
|
|
1138
1198
|
this.warnLog(`${this.device.deviceType}: ${accessory.displayName} Removing Leftover Faucet Service`);
|
|
1199
|
+
accessory.removeService(this.Faucet.Service);
|
|
1139
1200
|
}
|
|
1140
|
-
accessory.removeService(this.faucetService!);
|
|
1141
1201
|
}
|
|
1142
1202
|
|
|
1143
1203
|
async removeFanService(accessory: PlatformAccessory): Promise<void> {
|
|
1144
1204
|
// If fanService still present, then remove first
|
|
1145
|
-
|
|
1146
|
-
|
|
1205
|
+
if (this.Fan?.Service) {
|
|
1206
|
+
this.Fan.Service = this.accessory.getService(this.hap.Service.Fanv2) as Service;
|
|
1147
1207
|
this.warnLog(`${this.device.deviceType}: ${accessory.displayName} Removing Leftover Fan Service`);
|
|
1208
|
+
accessory.removeService(this.Fan.Service);
|
|
1148
1209
|
}
|
|
1149
|
-
accessory.removeService(this.fanService!);
|
|
1150
1210
|
}
|
|
1151
1211
|
|
|
1152
1212
|
async removeWindowService(accessory: PlatformAccessory): Promise<void> {
|
|
1153
1213
|
// If windowService still present, then remove first
|
|
1154
|
-
|
|
1155
|
-
|
|
1214
|
+
if (this.Window?.Service) {
|
|
1215
|
+
this.Window.Service = this.accessory.getService(this.hap.Service.Window) as Service;
|
|
1156
1216
|
this.warnLog(`${this.device.deviceType}: ${accessory.displayName} Removing Leftover Window Service`);
|
|
1217
|
+
accessory.removeService(this.Window.Service);
|
|
1157
1218
|
}
|
|
1158
|
-
accessory.removeService(this.windowService!);
|
|
1159
1219
|
}
|
|
1160
1220
|
|
|
1161
1221
|
async removeWindowCoveringService(accessory: PlatformAccessory): Promise<void> {
|
|
1162
1222
|
// If windowCoveringService still present, then remove first
|
|
1163
|
-
|
|
1164
|
-
|
|
1223
|
+
if (this.WindowCovering?.Service) {
|
|
1224
|
+
this.WindowCovering.Service = this.accessory.getService(this.hap.Service.WindowCovering) as Service;
|
|
1165
1225
|
this.warnLog(`${this.device.deviceType}: ${accessory.displayName} Removing Leftover Window Covering Service`);
|
|
1226
|
+
accessory.removeService(this.WindowCovering.Service);
|
|
1166
1227
|
}
|
|
1167
|
-
accessory.removeService(this.windowCoveringService!);
|
|
1168
1228
|
}
|
|
1169
1229
|
|
|
1170
1230
|
async removeStatefulProgrammableSwitchService(accessory: PlatformAccessory): Promise<void> {
|
|
1171
1231
|
// If statefulProgrammableSwitchService still present, then remove first
|
|
1172
|
-
|
|
1173
|
-
|
|
1232
|
+
if (this.StatefulProgrammableSwitch?.Service) {
|
|
1233
|
+
this.StatefulProgrammableSwitch.Service = this.accessory.getService(this.hap.Service.StatefulProgrammableSwitch) as Service;
|
|
1174
1234
|
this.warnLog(`${this.device.deviceType}: ${accessory.displayName} Removing Leftover Stateful Programmable Switch Service`);
|
|
1235
|
+
accessory.removeService(this.StatefulProgrammableSwitch.Service);
|
|
1175
1236
|
}
|
|
1176
|
-
accessory.removeService(this.statefulProgrammableSwitchService!);
|
|
1177
1237
|
}
|
|
1178
1238
|
|
|
1179
1239
|
async removeSwitchService(accessory: PlatformAccessory): Promise<void> {
|
|
1180
1240
|
// If switchService still present, then remove first
|
|
1181
|
-
|
|
1182
|
-
|
|
1241
|
+
if (this.Switch?.Service) {
|
|
1242
|
+
this.Switch.Service = this.accessory.getService(this.hap.Service.Switch) as Service;
|
|
1183
1243
|
this.warnLog(`${this.device.deviceType}: ${accessory.displayName} Removing Leftover Switch Service`);
|
|
1184
|
-
|
|
1185
|
-
accessory.removeService(this.switchService!);
|
|
1186
|
-
}
|
|
1187
|
-
|
|
1188
|
-
private DoublePress(device: device & devicesConfig) {
|
|
1189
|
-
if (device.bot?.doublePress) {
|
|
1190
|
-
this.doublePress = device.bot?.doublePress;
|
|
1191
|
-
this.accessory.context.doublePress = this.doublePress;
|
|
1192
|
-
} else {
|
|
1193
|
-
this.doublePress = 1;
|
|
1194
|
-
}
|
|
1195
|
-
}
|
|
1196
|
-
|
|
1197
|
-
async stopScanning(switchbot: any) {
|
|
1198
|
-
switchbot.stopScan();
|
|
1199
|
-
if (this.BLE_IsConnected) {
|
|
1200
|
-
await this.BLEparseStatus();
|
|
1201
|
-
await this.updateHomeKitCharacteristics();
|
|
1202
|
-
} else {
|
|
1203
|
-
await this.BLERefreshConnection(switchbot);
|
|
1204
|
-
}
|
|
1205
|
-
}
|
|
1206
|
-
|
|
1207
|
-
async getCustomBLEAddress(switchbot: any) {
|
|
1208
|
-
if (this.device.customBLEaddress && this.deviceLogging.includes('debug')) {
|
|
1209
|
-
(async () => {
|
|
1210
|
-
// Start to monitor advertisement packets
|
|
1211
|
-
await switchbot.startScan({
|
|
1212
|
-
model: 'H',
|
|
1213
|
-
});
|
|
1214
|
-
// Set an event handler
|
|
1215
|
-
switchbot.onadvertisement = (ad: any) => {
|
|
1216
|
-
this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} ad: ${JSON.stringify(ad, null, ' ')}`);
|
|
1217
|
-
};
|
|
1218
|
-
await sleep(10000);
|
|
1219
|
-
// Stop to monitor
|
|
1220
|
-
switchbot.stopScan();
|
|
1221
|
-
})();
|
|
1222
|
-
}
|
|
1223
|
-
}
|
|
1224
|
-
|
|
1225
|
-
async BLEPushConnection() {
|
|
1226
|
-
if (this.platform.config.credentials?.token && this.device.connectionType === 'BLE/OpenAPI') {
|
|
1227
|
-
this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} Using OpenAPI Connection to Push Changes`);
|
|
1228
|
-
await this.openAPIpushChanges();
|
|
1229
|
-
}
|
|
1230
|
-
}
|
|
1231
|
-
|
|
1232
|
-
async BLERefreshConnection(switchbot: any): Promise<void> {
|
|
1233
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} wasn't able to establish BLE Connection, node-switchbot:`
|
|
1234
|
-
+ ` ${JSON.stringify(switchbot)}`);
|
|
1235
|
-
if (this.platform.config.credentials?.token && this.device.connectionType === 'BLE/OpenAPI') {
|
|
1236
|
-
this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} Using OpenAPI Connection to Refresh Status`);
|
|
1237
|
-
await this.openAPIRefreshStatus();
|
|
1238
|
-
}
|
|
1239
|
-
}
|
|
1240
|
-
|
|
1241
|
-
async retry({ max, fn }: { max: number; fn: { (): any; (): Promise<any> } }): Promise<null> {
|
|
1242
|
-
return fn().catch(async (e: any) => {
|
|
1243
|
-
if (max === 0) {
|
|
1244
|
-
throw e;
|
|
1245
|
-
}
|
|
1246
|
-
this.infoLog(e);
|
|
1247
|
-
this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Retrying`);
|
|
1248
|
-
await sleep(1000);
|
|
1249
|
-
return this.retry({ max: max - 1, fn });
|
|
1250
|
-
});
|
|
1251
|
-
}
|
|
1252
|
-
|
|
1253
|
-
maxRetry(): number {
|
|
1254
|
-
if (this.device.maxRetry) {
|
|
1255
|
-
return this.device.maxRetry;
|
|
1256
|
-
} else {
|
|
1257
|
-
return 5;
|
|
1244
|
+
accessory.removeService(this.Switch.Service);
|
|
1258
1245
|
}
|
|
1259
1246
|
}
|
|
1260
1247
|
|
|
1261
|
-
async
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
} else if (
|
|
1270
|
-
this.
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
} else {
|
|
1276
|
-
|
|
1277
|
-
}
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
if (device.bot?.allowPush) {
|
|
1282
|
-
this.allowPush = true;
|
|
1248
|
+
async getOn(): Promise<boolean> {
|
|
1249
|
+
let On: boolean;
|
|
1250
|
+
if (this.botDeviceType === 'garagedoor') {
|
|
1251
|
+
On = this.GarageDoor?.On ? true : false;
|
|
1252
|
+
} else if (this.botDeviceType === 'door') {
|
|
1253
|
+
On = this.Door?.On ? true : false;
|
|
1254
|
+
} else if (this.botDeviceType === 'window') {
|
|
1255
|
+
On = this.Window?.On ? true : false;
|
|
1256
|
+
} else if (this.botDeviceType === 'windowcovering') {
|
|
1257
|
+
On = this.WindowCovering?.On ? true : false;
|
|
1258
|
+
} else if (this.botDeviceType === 'lock') {
|
|
1259
|
+
On = this.LockMechanism?.On ? true : false;
|
|
1260
|
+
} else if (this.botDeviceType === 'faucet') {
|
|
1261
|
+
On = this.Faucet?.On ? true : false;
|
|
1262
|
+
} else if (this.botDeviceType === 'fan') {
|
|
1263
|
+
On = this.Fan?.On ? true : false;
|
|
1264
|
+
} else if (this.botDeviceType === 'stateful') {
|
|
1265
|
+
On = this.StatefulProgrammableSwitch?.On ? true : false;
|
|
1266
|
+
} else if (this.botDeviceType === 'switch') {
|
|
1267
|
+
On = this.Switch?.On ? true : false;
|
|
1283
1268
|
} else {
|
|
1284
|
-
this.
|
|
1269
|
+
On = this.Outlet?.On ? true : false;
|
|
1285
1270
|
}
|
|
1286
|
-
|
|
1271
|
+
return On;
|
|
1287
1272
|
}
|
|
1288
1273
|
|
|
1289
|
-
async
|
|
1290
|
-
if (device.scanDuration) {
|
|
1291
|
-
this.scanDuration = this.accessory.context.scanDuration = device.scanDuration;
|
|
1292
|
-
if (this.BLE) {
|
|
1293
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Config scanDuration: ${this.scanDuration}`);
|
|
1294
|
-
}
|
|
1295
|
-
} else {
|
|
1296
|
-
this.scanDuration = this.accessory.context.scanDuration = 1;
|
|
1297
|
-
if (this.BLE) {
|
|
1298
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Default scanDuration: ${this.scanDuration}`);
|
|
1299
|
-
}
|
|
1300
|
-
}
|
|
1301
|
-
}
|
|
1302
|
-
|
|
1303
|
-
async statusCode(statusCode: number): Promise<void> {
|
|
1304
|
-
switch (statusCode) {
|
|
1305
|
-
case 151:
|
|
1306
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command not supported by this deviceType, statusCode: ${statusCode}`);
|
|
1307
|
-
break;
|
|
1308
|
-
case 152:
|
|
1309
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device not found, statusCode: ${statusCode}`);
|
|
1310
|
-
break;
|
|
1311
|
-
case 160:
|
|
1312
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command is not supported, statusCode: ${statusCode}`);
|
|
1313
|
-
break;
|
|
1314
|
-
case 161:
|
|
1315
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device is offline, statusCode: ${statusCode}`);
|
|
1316
|
-
this.offlineOff();
|
|
1317
|
-
break;
|
|
1318
|
-
case 171:
|
|
1319
|
-
this.errorLog(
|
|
1320
|
-
`${this.device.deviceType}: ${this.accessory.displayName} Hub Device is offline, statusCode: ${statusCode}. ` +
|
|
1321
|
-
`Hub: ${this.device.hubDeviceId}`,
|
|
1322
|
-
);
|
|
1323
|
-
this.offlineOff();
|
|
1324
|
-
break;
|
|
1325
|
-
case 190:
|
|
1326
|
-
this.errorLog(
|
|
1327
|
-
`${this.device.deviceType}: ${this.accessory.displayName} Device internal error due to device states not synchronized with server,` +
|
|
1328
|
-
` Or command format is invalid, statusCode: ${statusCode}`,
|
|
1329
|
-
);
|
|
1330
|
-
break;
|
|
1331
|
-
case 100:
|
|
1332
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Command successfully sent, statusCode: ${statusCode}`);
|
|
1333
|
-
break;
|
|
1334
|
-
case 200:
|
|
1335
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Request successful, statusCode: ${statusCode}`);
|
|
1336
|
-
break;
|
|
1337
|
-
case 400:
|
|
1338
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Bad Request, The client has issued an invalid request. `
|
|
1339
|
-
+ `This is commonly used to specify validation errors in a request payload, statusCode: ${statusCode}`);
|
|
1340
|
-
break;
|
|
1341
|
-
case 401:
|
|
1342
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Unauthorized, Authorization for the API is required, `
|
|
1343
|
-
+ `but the request has not been authenticated, statusCode: ${statusCode}`);
|
|
1344
|
-
break;
|
|
1345
|
-
case 403:
|
|
1346
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Forbidden, The request has been authenticated but does not `
|
|
1347
|
-
+ `have appropriate permissions, or a requested resource is not found, statusCode: ${statusCode}`);
|
|
1348
|
-
break;
|
|
1349
|
-
case 404:
|
|
1350
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Not Found, Specifies the requested path does not exist, `
|
|
1351
|
-
+ `statusCode: ${statusCode}`);
|
|
1352
|
-
break;
|
|
1353
|
-
case 406:
|
|
1354
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Not Acceptable, The client has requested a MIME type via `
|
|
1355
|
-
+ `the Accept header for a value not supported by the server, statusCode: ${statusCode}`);
|
|
1356
|
-
break;
|
|
1357
|
-
case 415:
|
|
1358
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Unsupported Media Type, The client has defined a contentType `
|
|
1359
|
-
+ `header that is not supported by the server, statusCode: ${statusCode}`);
|
|
1360
|
-
break;
|
|
1361
|
-
case 422:
|
|
1362
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Unprocessable Entity, The client has made a valid request, `
|
|
1363
|
-
+ `but the server cannot process it. This is often used for APIs for which certain limits have been exceeded, statusCode: ${statusCode}`);
|
|
1364
|
-
break;
|
|
1365
|
-
case 429:
|
|
1366
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Too Many Requests, The client has exceeded the number of `
|
|
1367
|
-
+ `requests allowed for a given time window, statusCode: ${statusCode}`);
|
|
1368
|
-
break;
|
|
1369
|
-
case 500:
|
|
1370
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Internal Server Error, An unexpected error on the SmartThings `
|
|
1371
|
-
+ `servers has occurred. These errors should be rare, statusCode: ${statusCode}`);
|
|
1372
|
-
break;
|
|
1373
|
-
default:
|
|
1374
|
-
this.infoLog(
|
|
1375
|
-
`${this.device.deviceType}: ${this.accessory.displayName} Unknown statusCode: ` +
|
|
1376
|
-
`${statusCode}, Submit Bugs Here: ' + 'https://tinyurl.com/SwitchBotBug`,
|
|
1377
|
-
);
|
|
1378
|
-
}
|
|
1379
|
-
}
|
|
1380
|
-
|
|
1381
|
-
async offlineOff(): Promise<void> {
|
|
1382
|
-
if (this.device.offline) {
|
|
1383
|
-
await this.deviceContext();
|
|
1384
|
-
await this.updateHomeKitCharacteristics();
|
|
1385
|
-
}
|
|
1386
|
-
}
|
|
1387
|
-
|
|
1388
|
-
async apiError(e: any): Promise<void> {
|
|
1274
|
+
async setOn(On: boolean): Promise<void> {
|
|
1389
1275
|
if (this.botDeviceType === 'garagedoor') {
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1276
|
+
if (this.GarageDoor) {
|
|
1277
|
+
this.GarageDoor.On = On;
|
|
1278
|
+
}
|
|
1393
1279
|
} else if (this.botDeviceType === 'door') {
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1280
|
+
if (this.Door) {
|
|
1281
|
+
this.Door.On = On;
|
|
1282
|
+
}
|
|
1397
1283
|
} else if (this.botDeviceType === 'window') {
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1284
|
+
if (this.Window) {
|
|
1285
|
+
this.Window.On = On;
|
|
1286
|
+
}
|
|
1401
1287
|
} else if (this.botDeviceType === 'windowcovering') {
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1288
|
+
if (this.WindowCovering) {
|
|
1289
|
+
this.WindowCovering.On = On;
|
|
1290
|
+
}
|
|
1405
1291
|
} else if (this.botDeviceType === 'lock') {
|
|
1406
|
-
|
|
1407
|
-
|
|
1292
|
+
if (this.LockMechanism) {
|
|
1293
|
+
this.LockMechanism.On = On;
|
|
1294
|
+
}
|
|
1408
1295
|
} else if (this.botDeviceType === 'faucet') {
|
|
1409
|
-
|
|
1296
|
+
if (this.Faucet) {
|
|
1297
|
+
this.Faucet.On = On;
|
|
1298
|
+
}
|
|
1410
1299
|
} else if (this.botDeviceType === 'fan') {
|
|
1411
|
-
|
|
1300
|
+
if (this.Fan) {
|
|
1301
|
+
this.Fan.On = On;
|
|
1302
|
+
}
|
|
1412
1303
|
} else if (this.botDeviceType === 'stateful') {
|
|
1413
|
-
|
|
1414
|
-
|
|
1304
|
+
if (this.StatefulProgrammableSwitch) {
|
|
1305
|
+
this.StatefulProgrammableSwitch.On = On;
|
|
1306
|
+
}
|
|
1415
1307
|
} else if (this.botDeviceType === 'switch') {
|
|
1416
|
-
|
|
1308
|
+
if (this.Switch) {
|
|
1309
|
+
this.Switch.On = On;
|
|
1310
|
+
}
|
|
1417
1311
|
} else {
|
|
1418
|
-
|
|
1312
|
+
if (this.Outlet) {
|
|
1313
|
+
this.Outlet.On = On;
|
|
1314
|
+
}
|
|
1419
1315
|
}
|
|
1420
|
-
this.batteryService?.updateCharacteristic(this.hap.Characteristic.BatteryLevel, e);
|
|
1421
|
-
this.batteryService?.updateCharacteristic(this.hap.Characteristic.StatusLowBattery, e);
|
|
1422
1316
|
}
|
|
1423
1317
|
|
|
1424
|
-
async
|
|
1318
|
+
async getBotConfigSettings(device: device & devicesConfig) {
|
|
1319
|
+
//Bot Device Type
|
|
1425
1320
|
if (!device.bot?.deviceType && this.accessory.context.deviceType) {
|
|
1426
1321
|
this.botDeviceType = this.accessory.context.deviceType;
|
|
1427
1322
|
this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Type: ${this.botDeviceType}, from Accessory Cache.`);
|
|
@@ -1435,41 +1330,33 @@ export class Bot {
|
|
|
1435
1330
|
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} No Device Type Set, deviceType: ${this.device.bot?.deviceType}`);
|
|
1436
1331
|
this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} Using default deviceType: ${this.botDeviceType}`);
|
|
1437
1332
|
}
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
this.
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
this.
|
|
1446
|
-
}
|
|
1447
|
-
|
|
1448
|
-
this.
|
|
1333
|
+
// Bot Mode
|
|
1334
|
+
if (!device.bot?.mode) {
|
|
1335
|
+
this.botMode = 'switch';
|
|
1336
|
+
this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} does not have bot mode set in the Plugin's SwitchBot Device Settings,`);
|
|
1337
|
+
this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} is defaulting to "${this.botMode}" mode, you may experience issues.`);
|
|
1338
|
+
} else if (device.bot?.mode === 'switch') {
|
|
1339
|
+
this.botMode = 'switch';
|
|
1340
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Bot Mode: ${this.botMode}`);
|
|
1341
|
+
} else if (device.bot?.mode === 'press') {
|
|
1342
|
+
this.botMode = 'press';
|
|
1343
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Bot Mode: ${this.botMode}`);
|
|
1344
|
+
} else if (device.bot?.mode === 'multipress') {
|
|
1345
|
+
this.botMode = 'multipress';
|
|
1346
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Bot Mode: ${this.botMode}`);
|
|
1449
1347
|
} else {
|
|
1450
|
-
this.
|
|
1348
|
+
throw new Error(`${this.device.deviceType}: ${this.accessory.displayName} Bot Mode: ${this.botMode}`);
|
|
1451
1349
|
}
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1350
|
+
|
|
1351
|
+
// Bot Double Press
|
|
1352
|
+
if (device.bot?.doublePress) {
|
|
1353
|
+
this.doublePress = device.bot?.doublePress;
|
|
1354
|
+
this.accessory.context.doublePress = this.doublePress;
|
|
1455
1355
|
} else {
|
|
1456
|
-
this.
|
|
1457
|
-
}
|
|
1458
|
-
if (this.FirmwareRevision === undefined) {
|
|
1459
|
-
this.FirmwareRevision = this.platform.version;
|
|
1460
|
-
this.accessory.context.FirmwareRevision = this.FirmwareRevision;
|
|
1356
|
+
this.doublePress = 1;
|
|
1461
1357
|
}
|
|
1462
|
-
}
|
|
1463
1358
|
|
|
1464
|
-
|
|
1465
|
-
if (device.refreshRate) {
|
|
1466
|
-
this.deviceRefreshRate = this.accessory.context.refreshRate = device.refreshRate;
|
|
1467
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Config refreshRate: ${this.deviceRefreshRate}`);
|
|
1468
|
-
} else if (this.platform.config.options!.refreshRate) {
|
|
1469
|
-
this.deviceRefreshRate = this.accessory.context.refreshRate = this.platform.config.options!.refreshRate;
|
|
1470
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Platform Config refreshRate: ${this.deviceRefreshRate}`);
|
|
1471
|
-
}
|
|
1472
|
-
// pushRatePress
|
|
1359
|
+
// Bot Press PushRate
|
|
1473
1360
|
if (device?.bot?.pushRatePress) {
|
|
1474
1361
|
this.pushRatePress = device?.bot?.pushRatePress;
|
|
1475
1362
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Config Bot pushRatePress: ${this.pushRatePress}`);
|
|
@@ -1477,106 +1364,144 @@ export class Bot {
|
|
|
1477
1364
|
this.pushRatePress = 15;
|
|
1478
1365
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Default Bot pushRatePress: ${this.pushRatePress}`);
|
|
1479
1366
|
}
|
|
1480
|
-
}
|
|
1481
|
-
|
|
1482
|
-
async deviceConfig(device: device & devicesConfig): Promise<void> {
|
|
1483
|
-
let config = {};
|
|
1484
|
-
if (device.bot) {
|
|
1485
|
-
config = device.bot;
|
|
1486
|
-
}
|
|
1487
|
-
if (device.connectionType !== undefined) {
|
|
1488
|
-
config['connectionType'] = device.connectionType;
|
|
1489
|
-
}
|
|
1490
|
-
if (device.external !== undefined) {
|
|
1491
|
-
config['external'] = device.external;
|
|
1492
|
-
}
|
|
1493
|
-
if (device.logging !== undefined) {
|
|
1494
|
-
config['logging'] = device.logging;
|
|
1495
|
-
}
|
|
1496
|
-
if (device.refreshRate !== undefined) {
|
|
1497
|
-
config['refreshRate'] = device.refreshRate;
|
|
1498
|
-
}
|
|
1499
|
-
if (device.scanDuration !== undefined) {
|
|
1500
|
-
config['scanDuration'] = device.scanDuration;
|
|
1501
|
-
}
|
|
1502
|
-
if (device.offline !== undefined) {
|
|
1503
|
-
config['offline'] = device.offline;
|
|
1504
|
-
}
|
|
1505
|
-
if (device.maxRetry !== undefined) {
|
|
1506
|
-
config['maxRetry'] = device.maxRetry;
|
|
1507
|
-
}
|
|
1508
|
-
if (device.webhook !== undefined) {
|
|
1509
|
-
config['webhook'] = device.webhook;
|
|
1510
|
-
}
|
|
1511
|
-
if (Object.entries(config).length !== 0) {
|
|
1512
|
-
this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} Config: ${JSON.stringify(config)}`);
|
|
1513
|
-
}
|
|
1514
|
-
}
|
|
1515
1367
|
|
|
1516
|
-
|
|
1517
|
-
if (
|
|
1518
|
-
this.
|
|
1519
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Debug Mode Logging: ${this.deviceLogging}`);
|
|
1520
|
-
} else if (device.logging) {
|
|
1521
|
-
this.deviceLogging = this.accessory.context.logging = device.logging;
|
|
1522
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Config Logging: ${this.deviceLogging}`);
|
|
1523
|
-
} else if (this.platform.config.options?.logging) {
|
|
1524
|
-
this.deviceLogging = this.accessory.context.logging = this.platform.config.options?.logging;
|
|
1525
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Platform Config Logging: ${this.deviceLogging}`);
|
|
1368
|
+
// Bot Allow Push
|
|
1369
|
+
if (device.bot?.allowPush) {
|
|
1370
|
+
this.allowPush = true;
|
|
1526
1371
|
} else {
|
|
1527
|
-
this.
|
|
1528
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Logging Not Set, Using: ${this.deviceLogging}`);
|
|
1372
|
+
this.allowPush = false;
|
|
1529
1373
|
}
|
|
1374
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Allowing Push Changes: ${this.allowPush}`);
|
|
1375
|
+
// Bot Multi Press Count
|
|
1376
|
+
this.multiPressCount = 0;
|
|
1530
1377
|
}
|
|
1531
1378
|
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
if (this.enablingDeviceLogging()) {
|
|
1537
|
-
this.platform.log.info(String(...log));
|
|
1379
|
+
async BLEPushConnection() {
|
|
1380
|
+
if (this.platform.config.credentials?.token && this.device.connectionType === 'BLE/OpenAPI') {
|
|
1381
|
+
this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} Using OpenAPI Connection to Push Changes`);
|
|
1382
|
+
await this.openAPIpushChanges();
|
|
1538
1383
|
}
|
|
1539
1384
|
}
|
|
1540
1385
|
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1386
|
+
async BLERefreshConnection(switchbot: any): Promise<void> {
|
|
1387
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} wasn't able to establish BLE Connection, node-switchbot:`
|
|
1388
|
+
+ ` ${JSON.stringify(switchbot)}`);
|
|
1389
|
+
if (this.platform.config.credentials?.token && this.device.connectionType === 'BLE/OpenAPI') {
|
|
1390
|
+
this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} Using OpenAPI Connection to Refresh Status`);
|
|
1391
|
+
await this.openAPIRefreshStatus();
|
|
1544
1392
|
}
|
|
1545
1393
|
}
|
|
1546
1394
|
|
|
1547
|
-
|
|
1548
|
-
if (this.
|
|
1549
|
-
if (this.
|
|
1550
|
-
this.
|
|
1395
|
+
async offlineOff(): Promise<void> {
|
|
1396
|
+
if (this.device.offline) {
|
|
1397
|
+
if (this.botDeviceType === 'garagedoor') {
|
|
1398
|
+
if (this.GarageDoor) {
|
|
1399
|
+
this.GarageDoor.Service.updateCharacteristic(this.hap.Characteristic.TargetDoorState, this.hap.Characteristic.TargetDoorState.CLOSED);
|
|
1400
|
+
this.GarageDoor.Service.updateCharacteristic(this.hap.Characteristic.CurrentDoorState, this.hap.Characteristic.CurrentDoorState.CLOSED);
|
|
1401
|
+
this.GarageDoor.Service.updateCharacteristic(this.hap.Characteristic.ObstructionDetected, false);
|
|
1402
|
+
}
|
|
1403
|
+
} else if (this.botDeviceType === 'door') {
|
|
1404
|
+
if (this.Door) {
|
|
1405
|
+
this.Door.Service.updateCharacteristic(this.hap.Characteristic.TargetPosition, 0);
|
|
1406
|
+
this.Door.Service.updateCharacteristic(this.hap.Characteristic.CurrentPosition, 0);
|
|
1407
|
+
this.Door.Service.updateCharacteristic(this.hap.Characteristic.PositionState, this.hap.Characteristic.PositionState.STOPPED);
|
|
1408
|
+
}
|
|
1409
|
+
} else if (this.botDeviceType === 'window') {
|
|
1410
|
+
if (this.Window) {
|
|
1411
|
+
this.Window.Service.updateCharacteristic(this.hap.Characteristic.TargetPosition, 0);
|
|
1412
|
+
this.Window.Service.updateCharacteristic(this.hap.Characteristic.CurrentPosition, 0);
|
|
1413
|
+
this.Window.Service.updateCharacteristic(this.hap.Characteristic.PositionState, this.hap.Characteristic.PositionState.STOPPED);
|
|
1414
|
+
}
|
|
1415
|
+
} else if (this.botDeviceType === 'windowcovering') {
|
|
1416
|
+
if (this.WindowCovering) {
|
|
1417
|
+
this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.TargetPosition, 0);
|
|
1418
|
+
this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.CurrentPosition, 0);
|
|
1419
|
+
this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.PositionState, this.hap.Characteristic.PositionState.STOPPED);
|
|
1420
|
+
}
|
|
1421
|
+
} else if (this.botDeviceType === 'lock') {
|
|
1422
|
+
if (this.LockMechanism) {
|
|
1423
|
+
this.LockMechanism.Service.updateCharacteristic(this.hap.Characteristic.LockTargetState, this.hap.Characteristic.LockTargetState.SECURED);
|
|
1424
|
+
this.LockMechanism.Service.updateCharacteristic(this.hap.Characteristic.LockCurrentState, this.hap.Characteristic.LockCurrentState.SECURED);
|
|
1425
|
+
}
|
|
1426
|
+
} else if (this.botDeviceType === 'faucet') {
|
|
1427
|
+
if (this.Faucet) {
|
|
1428
|
+
this.Faucet.Service.updateCharacteristic(this.hap.Characteristic.Active, this.hap.Characteristic.Active.INACTIVE);
|
|
1429
|
+
}
|
|
1430
|
+
} else if (this.botDeviceType === 'fan') {
|
|
1431
|
+
if (this.Fan) {
|
|
1432
|
+
this.Fan.Service.updateCharacteristic(this.hap.Characteristic.On, false);
|
|
1433
|
+
}
|
|
1434
|
+
} else if (this.botDeviceType === 'stateful') {
|
|
1435
|
+
if (this.StatefulProgrammableSwitch) {
|
|
1436
|
+
this.StatefulProgrammableSwitch.Service.updateCharacteristic(this.hap.Characteristic.ProgrammableSwitchEvent,
|
|
1437
|
+
this.hap.Characteristic.ProgrammableSwitchEvent.SINGLE_PRESS);
|
|
1438
|
+
this.StatefulProgrammableSwitch.Service.updateCharacteristic(this.hap.Characteristic.ProgrammableSwitchOutputState, 0);
|
|
1439
|
+
}
|
|
1440
|
+
} else if (this.botDeviceType === 'switch') {
|
|
1441
|
+
if (this.Switch) {
|
|
1442
|
+
this.Switch.Service.updateCharacteristic(this.hap.Characteristic.On, false);
|
|
1443
|
+
}
|
|
1444
|
+
} else {
|
|
1445
|
+
if (this.Outlet) {
|
|
1446
|
+
this.Outlet.Service.updateCharacteristic(this.hap.Characteristic.On, false);
|
|
1447
|
+
}
|
|
1551
1448
|
}
|
|
1552
1449
|
}
|
|
1553
1450
|
}
|
|
1554
1451
|
|
|
1555
|
-
|
|
1556
|
-
if (this.
|
|
1557
|
-
this.
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
debugErrorLog(...log: any[]): void {
|
|
1562
|
-
if (this.enablingDeviceLogging()) {
|
|
1563
|
-
if (this.deviceLogging?.includes('debug')) {
|
|
1564
|
-
this.platform.log.error('[DEBUG]', String(...log));
|
|
1452
|
+
async apiError(e: any): Promise<void> {
|
|
1453
|
+
if (this.botDeviceType === 'garagedoor') {
|
|
1454
|
+
if (this.GarageDoor) {
|
|
1455
|
+
this.GarageDoor.Service.updateCharacteristic(this.hap.Characteristic.TargetDoorState, e);
|
|
1456
|
+
this.GarageDoor.Service.updateCharacteristic(this.hap.Characteristic.CurrentDoorState, e);
|
|
1457
|
+
this.GarageDoor.Service.updateCharacteristic(this.hap.Characteristic.ObstructionDetected, e);
|
|
1565
1458
|
}
|
|
1566
|
-
}
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
this.
|
|
1459
|
+
} else if (this.botDeviceType === 'door') {
|
|
1460
|
+
if (this.Door) {
|
|
1461
|
+
this.Door.Service.updateCharacteristic(this.hap.Characteristic.TargetPosition, e);
|
|
1462
|
+
this.Door.Service.updateCharacteristic(this.hap.Characteristic.CurrentPosition, e);
|
|
1463
|
+
this.Door.Service.updateCharacteristic(this.hap.Characteristic.PositionState, e);
|
|
1464
|
+
}
|
|
1465
|
+
} else if (this.botDeviceType === 'window') {
|
|
1466
|
+
if (this.Window) {
|
|
1467
|
+
this.Window.Service.updateCharacteristic(this.hap.Characteristic.TargetPosition, e);
|
|
1468
|
+
this.Window.Service.updateCharacteristic(this.hap.Characteristic.CurrentPosition, e);
|
|
1469
|
+
this.Window.Service.updateCharacteristic(this.hap.Characteristic.PositionState, e);
|
|
1470
|
+
}
|
|
1471
|
+
} else if (this.botDeviceType === 'windowcovering') {
|
|
1472
|
+
if (this.WindowCovering) {
|
|
1473
|
+
this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.TargetPosition, e);
|
|
1474
|
+
this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.CurrentPosition, e);
|
|
1475
|
+
this.WindowCovering.Service.updateCharacteristic(this.hap.Characteristic.PositionState, e);
|
|
1476
|
+
}
|
|
1477
|
+
} else if (this.botDeviceType === 'lock') {
|
|
1478
|
+
if (this.LockMechanism) {
|
|
1479
|
+
this.LockMechanism.Service.updateCharacteristic(this.hap.Characteristic.LockTargetState, e);
|
|
1480
|
+
this.LockMechanism.Service.updateCharacteristic(this.hap.Characteristic.LockCurrentState, e);
|
|
1481
|
+
}
|
|
1482
|
+
} else if (this.botDeviceType === 'faucet') {
|
|
1483
|
+
if (this.Faucet) {
|
|
1484
|
+
this.Faucet.Service.updateCharacteristic(this.hap.Characteristic.Active, e);
|
|
1485
|
+
}
|
|
1486
|
+
} else if (this.botDeviceType === 'fan') {
|
|
1487
|
+
if (this.Fan) {
|
|
1488
|
+
this.Fan.Service.updateCharacteristic(this.hap.Characteristic.On, e);
|
|
1489
|
+
}
|
|
1490
|
+
} else if (this.botDeviceType === 'stateful') {
|
|
1491
|
+
if (this.StatefulProgrammableSwitch) {
|
|
1492
|
+
this.StatefulProgrammableSwitch.Service.updateCharacteristic(this.hap.Characteristic.ProgrammableSwitchEvent, e);
|
|
1493
|
+
this.StatefulProgrammableSwitch.Service.updateCharacteristic(this.hap.Characteristic.ProgrammableSwitchOutputState, e);
|
|
1494
|
+
}
|
|
1495
|
+
} else if (this.botDeviceType === 'switch') {
|
|
1496
|
+
if (this.Switch) {
|
|
1497
|
+
this.Switch.Service.updateCharacteristic(this.hap.Characteristic.On, e);
|
|
1498
|
+
}
|
|
1499
|
+
} else {
|
|
1500
|
+
if (this.Outlet) {
|
|
1501
|
+
this.Outlet.Service.updateCharacteristic(this.hap.Characteristic.On, e);
|
|
1575
1502
|
}
|
|
1576
1503
|
}
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
enablingDeviceLogging(): boolean {
|
|
1580
|
-
return this.deviceLogging.includes('debug') || this.deviceLogging === 'standard';
|
|
1504
|
+
this.Battery.Service.updateCharacteristic(this.hap.Characteristic.BatteryLevel, e);
|
|
1505
|
+
this.Battery.Service.updateCharacteristic(this.hap.Characteristic.StatusLowBattery, e);
|
|
1581
1506
|
}
|
|
1582
1507
|
}
|