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