@switchbot/homebridge-switchbot 3.5.0-beta.23 → 3.5.0-beta.24

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