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