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