@switchbot/homebridge-switchbot 3.5.0-beta.5 → 3.5.0-beta.51

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