@switchbot/homebridge-switchbot 3.5.0-beta.4 → 3.5.0-beta.40

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 (168) hide show
  1. package/CHANGELOG.md +4 -1
  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 +349 -756
  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 +584 -759
  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 +211 -587
  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 +252 -632
  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 +206 -531
  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 +337 -786
  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 +671 -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 +503 -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 +244 -596
  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 +209 -571
  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 +176 -584
  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 +254 -568
  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 +212 -542
  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 +172 -577
  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 +161 -577
  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 +138 -518
  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 +84 -452
  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 +142 -451
  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 +123 -664
  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 +343 -198
  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/package.json +16 -15
  134. package/src/custom.d.ts +2 -1
  135. package/src/device/blindtilt.ts +375 -782
  136. package/src/device/bot.ts +618 -844
  137. package/src/device/ceilinglight.ts +224 -607
  138. package/src/device/colorbulb.ts +266 -656
  139. package/src/device/contact.ts +231 -553
  140. package/src/device/curtain.ts +357 -810
  141. package/src/device/device.ts +699 -0
  142. package/src/device/fan.ts +552 -0
  143. package/src/device/hub.ts +271 -624
  144. package/src/device/humidifier.ts +239 -618
  145. package/src/device/iosensor.ts +202 -610
  146. package/src/device/lightstrip.ts +275 -596
  147. package/src/device/lock.ts +249 -582
  148. package/src/device/meter.ts +198 -601
  149. package/src/device/meterplus.ts +186 -602
  150. package/src/device/motion.ts +158 -541
  151. package/src/device/plug.ts +94 -480
  152. package/src/device/robotvacuumcleaner.ts +163 -477
  153. package/src/device/waterdetector.ts +141 -689
  154. package/src/homebridge-ui/public/index.html +2 -2
  155. package/src/index.ts +1 -1
  156. package/src/irdevice/airconditioner.ts +330 -446
  157. package/src/irdevice/airpurifier.ts +89 -321
  158. package/src/irdevice/camera.ts +42 -293
  159. package/src/irdevice/fan.ts +78 -327
  160. package/src/irdevice/irdevice.ts +528 -0
  161. package/src/irdevice/light.ts +32 -287
  162. package/src/irdevice/other.ts +396 -615
  163. package/src/irdevice/tv.ts +100 -339
  164. package/src/irdevice/vacuumcleaner.ts +49 -305
  165. package/src/irdevice/waterheater.ts +50 -310
  166. package/src/platform.ts +353 -206
  167. package/src/settings.ts +57 -566
  168. 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,77 @@ 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
521
  // FirmwareRevision
511
- this.FirmwareRevision = this.OpenAPI_FirmwareRevision!;
512
- this.accessory.context.FirmwareRevision = this.FirmwareRevision;
522
+ if (deviceStatus.body.version) {
523
+ this.accessory.context.version = deviceStatus.body.version;
524
+ this.accessory
525
+ .getService(this.hap.Service.AccessoryInformation)!
526
+ .setCharacteristic(this.hap.Characteristic.FirmwareRevision, this.accessory.context.version)
527
+ .getCharacteristic(this.hap.Characteristic.FirmwareRevision)
528
+ .updateValue(this.accessory.context.version);
529
+ }
513
530
  }
514
531
 
515
532
  /**
@@ -544,99 +561,43 @@ export class Bot {
544
561
  // Start to monitor advertisement packets
545
562
  (async () => {
546
563
  // Start to monitor advertisement packets
547
- await switchbot.startScan({
548
- model: 'H',
549
- id: this.device.bleMac,
550
- });
564
+ await switchbot.startScan({ model: this.device.bleModel, id: this.device.bleMac });
551
565
  // Set an event handler
552
566
  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') {
567
+ if (this.device.bleMac === ad.address && ad.model === this.device.bleModel) {
568
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} ${JSON.stringify(ad, null, ' ')}`);
569
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} address: ${ad.address}, model: ${ad.model}`);
556
570
  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
571
  } else {
561
572
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${JSON.stringify(ad.serviceData)}`);
562
573
  }
563
574
  };
564
- // Wait 1 seconds
575
+ // Wait 10 seconds
565
576
  await switchbot.wait(this.scanDuration * 1000);
566
577
  // Stop to monitor
567
578
  await switchbot.stopScan();
568
579
  // Update HomeKit
569
- await this.BLEparseStatus();
580
+ await this.BLEparseStatus(switchbot.onadvertisement.serviceData);
570
581
  await this.updateHomeKitCharacteristics();
571
582
  })();
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 {
583
+ if (switchbot === undefined) {
619
584
  await this.BLERefreshConnection(switchbot);
620
- }*/
585
+ }
621
586
  }
622
587
 
623
588
  async openAPIRefreshStatus(): Promise<void> {
624
589
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus`);
625
590
  try {
626
- const { body, statusCode } = await request(`${Devices}/${this.device.deviceId}/status`, {
627
- headers: this.platform.generateHeaders(),
628
- });
591
+ const { body, statusCode } = await this.platform.retryRequest(this.deviceMaxRetries, this.deviceDelayBetweenRetries,
592
+ `${Devices}/${this.device.deviceId}/status`, { headers: this.platform.generateHeaders() });
629
593
  this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} statusCode: ${statusCode}`);
630
594
  const deviceStatus: any = await body.json();
631
595
  this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus: ${JSON.stringify(deviceStatus)}`);
632
596
  this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus statusCode: ${deviceStatus.statusCode}`);
633
597
  if ((statusCode === 200 || statusCode === 100) && (deviceStatus.statusCode === 200 || deviceStatus.statusCode === 100)) {
634
- this.debugErrorLog(`${this.device.deviceType}: ${this.accessory.displayName} `
598
+ this.debugSuccessLog(`${this.device.deviceType}: ${this.accessory.displayName} `
635
599
  + `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();
600
+ this.openAPIparseStatus(deviceStatus);
640
601
  this.updateHomeKitCharacteristics();
641
602
  } else {
642
603
  this.statusCode(statusCode);
@@ -682,8 +643,9 @@ export class Bot {
682
643
 
683
644
  async BLEpushChanges(): Promise<void> {
684
645
  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}`);
646
+ const On = await this.getOn();
647
+ if (On !== this.accessory.context.On || this.allowPush) {
648
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLEpushChanges On: ${On} OnCached: ${this.accessory.context.On}`);
687
649
  const switchbot = await this.platform.connectBLE();
688
650
  // Convert to BLE Address
689
651
  this.device.bleMac = this.device
@@ -697,19 +659,21 @@ export class Bot {
697
659
  switchbot
698
660
  .discover({ model: 'H', quick: true, id: this.device.bleMac })
699
661
  .then(async (device_list: { press: (arg0: { id: string | undefined }) => any }[]) => {
700
- this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.On}`);
662
+ this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${On}`);
701
663
  return await device_list[0].press({ id: this.device.bleMac });
702
664
  })
703
665
  .then(() => {
704
666
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Done.`);
705
- this.accessory.context.On = this.On;
667
+ this.successLog(`${this.device.deviceType}: ${this.accessory.displayName} `
668
+ + `On: ${On} sent over BLE, sent successfully`);
669
+ this.accessory.context.On = On;
706
670
  setTimeout(() => {
707
671
  if (this.botDeviceType === 'switch') {
708
- this.switchService?.getCharacteristic(this.hap.Characteristic.On).updateValue(this.On);
672
+ this.Switch!.Service.getCharacteristic(this.hap.Characteristic.On).updateValue(On);
709
673
  } else {
710
- this.outletService?.getCharacteristic(this.hap.Characteristic.On).updateValue(this.On);
674
+ this.Outlet!.Service.getCharacteristic(this.hap.Characteristic.On).updateValue(On);
711
675
  }
712
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.On}, Switch Timeout`);
676
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${On}, Switch Timeout`);
713
677
  }, 500);
714
678
  })
715
679
  .catch(async (e: any) => {
@@ -725,11 +689,11 @@ export class Bot {
725
689
  switchbot
726
690
  .discover({ model: 'H', quick: true, id: this.device.bleMac })
727
691
  .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(),
692
+ this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${On}`);
693
+ return await this.retryBLE({
694
+ max: await this.maxRetryBLE(),
731
695
  fn: async () => {
732
- if (this.On) {
696
+ if (On) {
733
697
  return await device_list[0].turnOn({ id: this.device.bleMac });
734
698
  } else {
735
699
  return await device_list[0].turnOff({ id: this.device.bleMac });
@@ -739,46 +703,43 @@ export class Bot {
739
703
  })
740
704
  .then(() => {
741
705
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Done.`);
742
- this.accessory.context.On = this.On;
706
+ this.accessory.context.On = On;
743
707
  })
744
708
  .catch(async (e: any) => {
745
709
  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
- );
710
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed BLEpushChanges with ${this.device.connectionType}`
711
+ + ` Connection & botMode: ${this.botMode}, Error Message: ${JSON.stringify(e.message)}`);
750
712
  await this.BLEPushConnection();
751
713
  });
752
714
  } else {
753
715
  this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Bot Mode: ${this.botMode}`);
754
716
  }
755
717
  } else {
756
- this.debugLog(
757
- `${this.device.deviceType}: ${this.accessory.displayName} No BLEpushChanges.` + `On: ${this.On}, ` + `OnCached: ${this.accessory.context.On}`,
758
- );
718
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} No BLEpushChanges, On: ${On}, OnCached: ${this.accessory.context.On}`);
759
719
  }
760
720
  }
761
721
 
762
722
  async openAPIpushChanges(): Promise<void> {
763
723
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIpushChanges`);
724
+ let On = await this.getOn();
764
725
  if (this.multiPressCount > 0) {
765
726
  this.debugLog(`${this.device.deviceType}: ${this.multiPressCount} request(s) queued.`);
766
- this.On = true;
727
+ On = true;
767
728
  }
768
- if (this.On !== this.accessory.context.On || this.allowPush || this.multiPressCount > 0) {
729
+ if (On !== this.accessory.context.On || this.allowPush || this.multiPressCount > 0) {
769
730
  let command = '';
770
- if (this.botMode === 'switch' && this.On) {
731
+ if (this.botMode === 'switch' && On) {
771
732
  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) {
733
+ On = true;
734
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Switch Mode, Turning ${On}`);
735
+ } else if (this.botMode === 'switch' && !On) {
775
736
  command = 'turnOff';
776
- this.On = false;
777
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Switch Mode, Turning ${this.On}`);
737
+ On = false;
738
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Switch Mode, Turning ${On}`);
778
739
  } else if (this.botMode === 'press' || this.botMode === 'multipress') {
779
740
  command = 'press';
780
741
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Press Mode`);
781
- this.On = false;
742
+ On = false;
782
743
  } else {
783
744
  throw new Error(`${this.device.deviceType}: ${this.accessory.displayName} Device Parameters not set for this Bot.`);
784
745
  }
@@ -800,8 +761,10 @@ export class Bot {
800
761
  this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus body: ${JSON.stringify(deviceStatus.body)}`);
801
762
  this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus statusCode: ${deviceStatus.statusCode}`);
802
763
  if ((statusCode === 200 || statusCode === 100) && (deviceStatus.statusCode === 200 || deviceStatus.statusCode === 100)) {
803
- this.debugErrorLog(`${this.device.deviceType}: ${this.accessory.displayName} `
764
+ this.debugSuccessLog(`${this.device.deviceType}: ${this.accessory.displayName} `
804
765
  + `statusCode: ${statusCode} & deviceStatus StatusCode: ${deviceStatus.statusCode}`);
766
+ this.successLog(`${this.device.deviceType}: ${this.accessory.displayName} `
767
+ + `request to SwitchBot API, body: ${JSON.stringify(bodyChange)} sent successfully`);
805
768
  } else {
806
769
  this.statusCode(statusCode);
807
770
  this.statusCode(deviceStatus.statusCode);
@@ -810,23 +773,18 @@ export class Bot {
810
773
  this.multiPressCount--;
811
774
  if (this.multiPressCount > 0) {
812
775
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Multi Press Count: ${this.multiPressCount}`);
813
- this.On = true;
776
+ On = true;
814
777
  this.openAPIpushChanges();
815
778
  }
816
779
  }
817
780
  } catch (e: any) {
818
781
  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
- );
782
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed openAPIpushChanges with ${this.device.connectionType}`
783
+ + ` Connection, Error Message: ${JSON.stringify(e.message)}`);
823
784
  }
824
785
  } else {
825
- this.debugLog(
826
- `${this.device.deviceType}: ${this.accessory.displayName} No openAPIpushChanges.` +
827
- `On: ${this.On}, ` +
828
- `OnCached: ${this.accessory.context.On}`,
829
- );
786
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} No openAPIpushChanges,`
787
+ + ` On: ${On}, OnCached: ${this.accessory.context.On}`);
830
788
  }
831
789
  }
832
790
 
@@ -837,51 +795,85 @@ export class Bot {
837
795
  if (this.botDeviceType === 'garagedoor') {
838
796
  this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Set TargetDoorState: ${value}`);
839
797
  if (value === this.hap.Characteristic.TargetDoorState.CLOSED) {
840
- this.On = false;
798
+ await this.setOn(false);
799
+ this.GarageDoor!.On = false;
841
800
  } else {
842
- this.On = true;
801
+ await this.setOn(true);
802
+ this.GarageDoor!.On = true;
843
803
  }
844
- } else if (
845
- this.botDeviceType === 'door' ||
846
- this.botDeviceType === 'window' ||
847
- this.botDeviceType === 'windowcovering'
848
- ) {
804
+ } else if (this.botDeviceType === 'door') {
849
805
  this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Set TargetPosition: ${value}`);
850
806
  if (value === 0) {
851
- this.On = false;
807
+ await this.setOn(false);
808
+ this.Door!.On = false;
852
809
  } else {
853
- this.On = true;
810
+ await this.setOn(true);
811
+ this.Door!.On = true;
812
+ }
813
+ } else if (this.botDeviceType === 'window') {
814
+ this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Set TargetPosition: ${value}`);
815
+ if (value === 0) {
816
+ await this.setOn(false);
817
+ this.Window!.On = false;
818
+ } else {
819
+ await this.setOn(true);
820
+ this.Window!.On = true;
821
+ }
822
+ } else if (this.botDeviceType === 'windowcovering') {
823
+ this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Set TargetPosition: ${value}`);
824
+ if (value === 0) {
825
+ await this.setOn(false);
826
+ this.WindowCovering!.On = false;
827
+ } else {
828
+ await this.setOn(true);
829
+ this.WindowCovering!.On = true;
854
830
  }
855
831
  } else if (this.botDeviceType === 'lock') {
856
832
  this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Set LockTargetState: ${value}`);
857
833
  if (value === this.hap.Characteristic.LockTargetState.SECURED) {
858
- this.On = false;
834
+ await this.setOn(false);
835
+ this.Lock!.On = false;
859
836
  } else {
860
- this.On = true;
837
+ await this.setOn(true);
838
+ this.Lock!.On = true;
861
839
  }
862
840
  } else if (this.botDeviceType === 'faucet') {
863
841
  this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Set Active: ${value}`);
864
842
  if (value === this.hap.Characteristic.Active.INACTIVE) {
865
- this.On = false;
843
+ await this.setOn(false);
844
+ this.Faucet!.On = false;
866
845
  } else {
867
- this.On = true;
846
+ await this.setOn(true);
847
+ this.Faucet!.On = true;
868
848
  }
869
849
  } else if (this.botDeviceType === 'stateful') {
870
850
  this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Set ProgrammableSwitchOutputState: ${value}`);
871
851
  if (value === 0) {
872
- this.On = false;
852
+ await this.setOn(false);
853
+ this.StatefulProgrammableSwitch!.On = false;
873
854
  } else {
874
- this.On = true;
855
+ await this.setOn(true);
856
+ this.StatefulProgrammableSwitch!.On = true;
857
+ }
858
+ } else if (this.botDeviceType === 'switch') {
859
+ this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Set ProgrammableSwitchOutputState: ${value}`);
860
+ if (value === 0) {
861
+ await this.setOn(false);
862
+ this.Switch!.On = false;
863
+ } else {
864
+ await this.setOn(true);
865
+ this.Switch!.On = true;
875
866
  }
876
867
  } else {
877
868
  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
- }
869
+ await this.setOn(Boolean(value));
870
+ this.Outlet!.On = value;
871
+ }
872
+ if (this.device.bot?.mode === 'multipress') {
873
+ if (value === true) {
874
+ this.multiPressCount++;
875
+ this.debugLog(`${this.device.deviceType} set to Multi-Press. Multi-Press count: ${this.multiPressCount}`);
883
876
  }
884
- this.On = value;
885
877
  }
886
878
  this.doBotUpdate.next();
887
879
  }
@@ -892,536 +884,328 @@ export class Bot {
892
884
  async updateHomeKitCharacteristics(): Promise<void> {
893
885
  // State
894
886
  if (this.botDeviceType === 'garagedoor') {
895
- if (this.On === undefined) {
896
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.On}`);
887
+ if (this.GarageDoor!.On === undefined) {
888
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.GarageDoor!.On}`);
897
889
  } 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
- );
890
+ if (this.GarageDoor!.On) {
891
+ this.GarageDoor!.Service.updateCharacteristic(this.hap.Characteristic.TargetDoorState, this.hap.Characteristic.TargetDoorState.OPEN);
892
+ this.GarageDoor!.Service.updateCharacteristic(this.hap.Characteristic.CurrentDoorState, this.hap.Characteristic.CurrentDoorState.OPEN);
893
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic`
894
+ + ` TargetDoorState: Open, CurrentDoorState: Open (${this.GarageDoor!.On})`);
910
895
  } 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
- );
896
+ this.GarageDoor!.Service.updateCharacteristic(this.hap.Characteristic.TargetDoorState, this.hap.Characteristic.TargetDoorState.CLOSED);
897
+ this.GarageDoor!.Service.updateCharacteristic(this.hap.Characteristic.CurrentDoorState, this.hap.Characteristic.CurrentDoorState.CLOSED);
898
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristicc`
899
+ + ` TargetDoorState: Open, CurrentDoorState: Open (${this.GarageDoor!.On})`);
922
900
  }
923
901
  }
924
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Garage Door On: ${this.On}`);
902
+ await this.setOn(Boolean(this.GarageDoor!.On));
903
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Garage Door On: ${this.GarageDoor!.On}`);
925
904
  } else if (this.botDeviceType === 'door') {
926
- if (this.On === undefined) {
927
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.On}`);
905
+ if (this.Door!.On === undefined) {
906
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.Door!.On}`);
928
907
  } 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`);
908
+ if (this.Door!.On) {
909
+ this.Door!.Service.updateCharacteristic(this.hap.Characteristic.TargetPosition, 100);
910
+ this.Door!.Service.updateCharacteristic(this.hap.Characteristic.CurrentPosition, 100);
911
+ this.Door!.Service.updateCharacteristic(this.hap.Characteristic.PositionState, this.hap.Characteristic.PositionState.STOPPED);
912
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristicc`
913
+ + ` TargetPosition: 100, CurrentPosition: 100 (${this.Door!.On})`);
934
914
  } 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`);
915
+ this.Door!.Service.updateCharacteristic(this.hap.Characteristic.TargetPosition, 0);
916
+ this.Door!.Service.updateCharacteristic(this.hap.Characteristic.CurrentPosition, 0);
917
+ this.Door!.Service.updateCharacteristic(this.hap.Characteristic.PositionState, this.hap.Characteristic.PositionState.STOPPED);
918
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristicc`
919
+ + ` TargetPosition: 0, CurrentPosition: 0 (${this.Door!.On})`);
939
920
  }
940
921
  }
941
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Door On: ${this.On}`);
922
+ await this.setOn(Boolean(this.Door!.On));
923
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Door On: ${this.Door!.On}`);
942
924
  } else if (this.botDeviceType === 'window') {
943
- if (this.On === undefined) {
944
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.On}`);
925
+ if (this.Window!.On === undefined) {
926
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.Window!.On}`);
945
927
  } 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`);
928
+ if (this.Window!.On) {
929
+ this.Window!.Service.updateCharacteristic(this.hap.Characteristic.TargetPosition, 100);
930
+ this.Window!.Service.updateCharacteristic(this.hap.Characteristic.CurrentPosition, 100);
931
+ this.Window!.Service.updateCharacteristic(this.hap.Characteristic.PositionState, this.hap.Characteristic.PositionState.STOPPED);
932
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristicc`
933
+ + ` TargetPosition: 100, CurrentPosition: 100 (${this.Window!.On})`);
951
934
  } 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`);
935
+ this.Window!.Service.updateCharacteristic(this.hap.Characteristic.TargetPosition, 0);
936
+ this.Window!.Service.updateCharacteristic(this.hap.Characteristic.CurrentPosition, 0);
937
+ this.Window!.Service.updateCharacteristic(this.hap.Characteristic.PositionState, this.hap.Characteristic.PositionState.STOPPED);
938
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristicc`
939
+ + ` TargetPosition: 0, CurrentPosition: 0 (${this.Window!.On})`);
956
940
  }
957
941
  }
958
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Window On: ${this.On}`);
942
+ await this.setOn(Boolean(this.Window!.On));
943
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Window On: ${this.Window!.On}`);
959
944
  } else if (this.botDeviceType === 'windowcovering') {
960
- if (this.On === undefined) {
961
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.On}`);
945
+ if (this.WindowCovering!.On === undefined) {
946
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.WindowCovering!.On}`);
962
947
  } 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`);
948
+ if (this.WindowCovering!.On) {
949
+ this.WindowCovering!.Service.updateCharacteristic(this.hap.Characteristic.TargetPosition, 100);
950
+ this.WindowCovering!.Service.updateCharacteristic(this.hap.Characteristic.CurrentPosition, 100);
951
+ this.WindowCovering!.Service.updateCharacteristic(this.hap.Characteristic.PositionState, this.hap.Characteristic.PositionState.STOPPED);
952
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristicc`
953
+ + ` TargetPosition: 100, CurrentPosition: 100 (${this.WindowCovering!.On})`);
971
954
  } 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`);
955
+ this.WindowCovering!.Service.updateCharacteristic(this.hap.Characteristic.TargetPosition, 0);
956
+ this.WindowCovering!.Service.updateCharacteristic(this.hap.Characteristic.CurrentPosition, 0);
957
+ this.WindowCovering!.Service.updateCharacteristic(this.hap.Characteristic.PositionState, this.hap.Characteristic.PositionState.STOPPED);
958
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristicc`
959
+ + ` TargetPosition: 0, CurrentPosition: 0 (${this.WindowCovering!.On})`);
979
960
  }
980
961
  }
981
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Window Covering On: ${this.On}`);
962
+ await this.setOn(Boolean(this.WindowCovering!.On));
963
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Window Covering On: ${this.WindowCovering!.On}`);
982
964
  } else if (this.botDeviceType === 'lock') {
983
- if (this.On === undefined) {
984
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.On}`);
965
+ if (this.Lock!.On === undefined) {
966
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.Lock!.On}`);
985
967
  } 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
- );
968
+ if (this.Lock!.On) {
969
+ this.Lock!.Service.updateCharacteristic(this.hap.Characteristic.LockTargetState, this.hap.Characteristic.LockTargetState.UNSECURED);
970
+ this.Lock!.Service.updateCharacteristic(this.hap.Characteristic.LockCurrentState, this.hap.Characteristic.LockCurrentState.UNSECURED);
971
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristicc`
972
+ + ` LockTargetState: UNSECURED, LockCurrentState: UNSECURED (${this.Lock!.On})`);
999
973
  } 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
- );
974
+ this.Lock!.Service.updateCharacteristic(this.hap.Characteristic.LockTargetState, this.hap.Characteristic.LockTargetState.SECURED);
975
+ this.Lock!.Service.updateCharacteristic(this.hap.Characteristic.LockCurrentState, this.hap.Characteristic.LockCurrentState.SECURED);
976
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic`
977
+ + ` LockTargetState: SECURED, LockCurrentState: SECURED (${this.Lock!.On})`);
1008
978
  }
1009
979
  }
1010
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Lock On: ${this.On}`);
980
+ await this.setOn(Boolean(this.Lock!.On));
981
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Lock On: ${this.Lock!.On}`);
1011
982
  } else if (this.botDeviceType === 'faucet') {
1012
- if (this.On === undefined) {
1013
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.On}`);
983
+ if (this.Faucet!.On === undefined) {
984
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.Faucet!.On}`);
1014
985
  } 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}`);
986
+ if (this.Faucet!.On) {
987
+ this.Faucet!.Service.updateCharacteristic(this.hap.Characteristic.Active, this.hap.Characteristic.Active.ACTIVE);
988
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic Active: ${this.Faucet!.On}`);
1018
989
  } 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}`);
990
+ this.Faucet!.Service.updateCharacteristic(this.hap.Characteristic.Active, this.hap.Characteristic.Active.INACTIVE);
991
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic Active: ${this.Faucet!.On}`);
1021
992
  }
1022
993
  }
1023
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Faucet On: ${this.On}`);
994
+ await this.setOn(Boolean(this.Faucet!.On));
995
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Faucet On: ${this.Faucet!.On}`);
1024
996
  } else if (this.botDeviceType === 'fan') {
1025
- if (this.On === undefined) {
1026
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.On}`);
997
+ if (this.Fan!.On === undefined) {
998
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.Fan!.On}`);
1027
999
  } 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}`);
1000
+ if (this.Fan!.On) {
1001
+ this.Fan!.Service.updateCharacteristic(this.hap.Characteristic.On, this.Fan!.On);
1002
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic On: ${this.Fan!.On}`);
1031
1003
  } else {
1032
- this.fanService?.updateCharacteristic(this.hap.Characteristic.On, this.On);
1033
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic On: ${this.On}`);
1004
+ this.Fan!.Service.updateCharacteristic(this.hap.Characteristic.On, this.Fan!.On);
1005
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic On: ${this.Fan!.On}`);
1034
1006
  }
1035
1007
  }
1036
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Fan On: ${this.On}`);
1008
+ await this.setOn(Boolean(this.Fan!.On));
1009
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Fan On: ${this.Fan!.On}`);
1037
1010
  } else if (this.botDeviceType === 'stateful') {
1038
- if (this.On === undefined) {
1039
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.On}`);
1011
+ if (this.StatefulProgrammableSwitch!.On === undefined) {
1012
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.StatefulProgrammableSwitch!.On}`);
1040
1013
  } 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
- );
1014
+ if (this.StatefulProgrammableSwitch!.On) {
1015
+ this.StatefulProgrammableSwitch!.Service.updateCharacteristic(this.hap.Characteristic.ProgrammableSwitchEvent,
1016
+ this.hap.Characteristic.ProgrammableSwitchEvent.SINGLE_PRESS);
1017
+ this.StatefulProgrammableSwitch!.Service.updateCharacteristic(this.hap.Characteristic.ProgrammableSwitchOutputState, 1);
1018
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic`
1019
+ + ` ProgrammableSwitchEvent: SINGLE, ProgrammableSwitchOutputState: 1 (${this.StatefulProgrammableSwitch!.On})`);
1051
1020
  } 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
- );
1021
+ this.StatefulProgrammableSwitch!.Service.updateCharacteristic(this.hap.Characteristic.ProgrammableSwitchEvent,
1022
+ this.hap.Characteristic.ProgrammableSwitchEvent.SINGLE_PRESS);
1023
+ this.StatefulProgrammableSwitch!.Service.updateCharacteristic(this.hap.Characteristic.ProgrammableSwitchOutputState, 0);
1024
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic`
1025
+ + ` ProgrammableSwitchEvent: SINGLE, ProgrammableSwitchOutputState: 0 (${this.StatefulProgrammableSwitch!.On})`);
1061
1026
  }
1062
1027
  }
1063
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} StatefulProgrammableSwitch On: ${this.On}`);
1028
+ await this.setOn(Boolean(this.StatefulProgrammableSwitch!.On));
1029
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} StatefulProgrammableSwitch On: ${this.StatefulProgrammableSwitch!.On}`);
1064
1030
  } else if (this.botDeviceType === 'switch') {
1065
- if (this.On === undefined) {
1066
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.On}`);
1031
+ if (this.Switch!.On === undefined) {
1032
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.Switch!.On}`);
1067
1033
  } else {
1068
- this.switchService?.updateCharacteristic(this.hap.Characteristic.On, this.On);
1069
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic On: ${this.On}`);
1034
+ this.Switch!.Service.updateCharacteristic(this.hap.Characteristic.On, this.Switch!.On);
1035
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic On: ${this.Switch!.On}`);
1036
+ await this.setOn(Boolean(this.Switch!.On));
1070
1037
  }
1071
1038
  } else {
1072
- if (this.On === undefined) {
1073
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.On}`);
1039
+ if (this.Outlet!.On === undefined) {
1040
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.Outlet!.On}`);
1074
1041
  } else {
1075
- this.outletService?.updateCharacteristic(this.hap.Characteristic.On, this.On);
1076
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic On: ${this.On}`);
1042
+ this.Outlet!.Service.updateCharacteristic(this.hap.Characteristic.On, this.Outlet!.On);
1043
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic On: ${this.Outlet!.On}`);
1077
1044
  }
1078
1045
  }
1079
- this.accessory.context.On = this.On;
1046
+ await this.setOn(Boolean(this.Outlet!.On));
1047
+ this.accessory.context.On = await this.getOn();
1080
1048
  // BatteryLevel
1081
- if (this.BatteryLevel === undefined) {
1082
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.BatteryLevel}`);
1049
+ if (this.Battery.BatteryLevel === undefined) {
1050
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.Battery.BatteryLevel}`);
1083
1051
  } 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}`);
1052
+ this.accessory.context.BatteryLevel = this.Battery.BatteryLevel;
1053
+ this.Battery!.Service.updateCharacteristic(this.hap.Characteristic.BatteryLevel, this.Battery.BatteryLevel);
1054
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic BatteryLevel: ${this.Battery.BatteryLevel}`);
1087
1055
  }
1088
1056
  // StatusLowBattery
1089
- if (this.StatusLowBattery === undefined) {
1090
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} StatusLowBattery: ${this.StatusLowBattery}`);
1057
+ if (this.Battery.StatusLowBattery === undefined) {
1058
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} StatusLowBattery: ${this.Battery.StatusLowBattery}`);
1091
1059
  } 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}`);
1060
+ this.accessory.context.StatusLowBattery = this.Battery.StatusLowBattery;
1061
+ this.Battery!.Service.updateCharacteristic(this.hap.Characteristic.StatusLowBattery, this.Battery.StatusLowBattery);
1062
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic`
1063
+ + ` StatusLowBattery: ${this.Battery.StatusLowBattery}`);
1095
1064
  }
1096
1065
  }
1097
1066
 
1098
1067
  async removeOutletService(accessory: PlatformAccessory): Promise<void> {
1099
1068
  // If outletService still present, then remove first
1100
- this.outletService = this.accessory.getService(this.hap.Service.Outlet);
1101
- if (this.outletService) {
1069
+ if (this.Outlet?.Service) {
1070
+ this.Outlet!.Service = this.accessory.getService(this.hap.Service.Outlet) as Service;
1102
1071
  this.warnLog(`${this.device.deviceType}: ${accessory.displayName} Removing Leftover Outlet Service`);
1072
+ accessory.removeService(this.Outlet!.Service);
1103
1073
  }
1104
- accessory.removeService(this.outletService!);
1105
1074
  }
1106
1075
 
1107
1076
  async removeGarageDoorService(accessory: PlatformAccessory): Promise<void> {
1108
1077
  // If garageDoorService still present, then remove first
1109
- this.garageDoorService = this.accessory.getService(this.hap.Service.GarageDoorOpener);
1110
- if (this.garageDoorService) {
1078
+ if (this.GarageDoor?.Service) {
1079
+ this.GarageDoor!.Service = this.accessory.getService(this.hap.Service.GarageDoorOpener) as Service;
1111
1080
  this.warnLog(`${this.device.deviceType}: ${accessory.displayName} Removing Leftover Garage Door Service`);
1081
+ accessory.removeService(this.GarageDoor!.Service);
1112
1082
  }
1113
- accessory.removeService(this.garageDoorService!);
1114
1083
  }
1115
1084
 
1116
1085
  async removeDoorService(accessory: PlatformAccessory): Promise<void> {
1117
1086
  // If doorService still present, then remove first
1118
- this.doorService = this.accessory.getService(this.hap.Service.Door);
1119
- if (this.doorService) {
1087
+ if (this.Door?.Service) {
1088
+ this.Door!.Service = this.accessory.getService(this.hap.Service.Door) as Service;
1120
1089
  this.warnLog(`${this.device.deviceType}: ${accessory.displayName} Removing Leftover Door Service`);
1090
+ accessory.removeService(this.Door!.Service);
1121
1091
  }
1122
- accessory.removeService(this.doorService!);
1123
1092
  }
1124
1093
 
1125
1094
  async removeLockService(accessory: PlatformAccessory): Promise<void> {
1126
1095
  // If lockService still present, then remove first
1127
- this.lockService = this.accessory.getService(this.hap.Service.LockMechanism);
1128
- if (this.lockService) {
1096
+ if (this.Lock?.Service) {
1097
+ this.Lock!.Service = this.accessory.getService(this.hap.Service.LockMechanism) as Service;
1129
1098
  this.warnLog(`${this.device.deviceType}: ${accessory.displayName} Removing Leftover Lock Service`);
1099
+ accessory.removeService(this.Lock!.Service);
1130
1100
  }
1131
- accessory.removeService(this.lockService!);
1132
1101
  }
1133
1102
 
1134
1103
  async removeFaucetService(accessory: PlatformAccessory): Promise<void> {
1135
1104
  // If faucetService still present, then remove first
1136
- this.faucetService = this.accessory.getService(this.hap.Service.Faucet);
1137
- if (this.faucetService) {
1105
+ if (this.Faucet?.Service) {
1106
+ this.Faucet!.Service = this.accessory.getService(this.hap.Service.Faucet) as Service;
1138
1107
  this.warnLog(`${this.device.deviceType}: ${accessory.displayName} Removing Leftover Faucet Service`);
1108
+ accessory.removeService(this.Faucet!.Service);
1139
1109
  }
1140
- accessory.removeService(this.faucetService!);
1141
1110
  }
1142
1111
 
1143
1112
  async removeFanService(accessory: PlatformAccessory): Promise<void> {
1144
1113
  // If fanService still present, then remove first
1145
- this.fanService = this.accessory.getService(this.hap.Service.Fan);
1146
- if (this.fanService) {
1114
+ if (this.Fan?.Service) {
1115
+ this.Fan!.Service = this.accessory.getService(this.hap.Service.Fanv2) as Service;
1147
1116
  this.warnLog(`${this.device.deviceType}: ${accessory.displayName} Removing Leftover Fan Service`);
1117
+ accessory.removeService(this.Fan!.Service);
1148
1118
  }
1149
- accessory.removeService(this.fanService!);
1150
1119
  }
1151
1120
 
1152
1121
  async removeWindowService(accessory: PlatformAccessory): Promise<void> {
1153
1122
  // If windowService still present, then remove first
1154
- this.windowService = this.accessory.getService(this.hap.Service.Window);
1155
- if (this.windowService) {
1123
+ if (this.Window?.Service) {
1124
+ this.Window!.Service = this.accessory.getService(this.hap.Service.Window) as Service;
1156
1125
  this.warnLog(`${this.device.deviceType}: ${accessory.displayName} Removing Leftover Window Service`);
1126
+ accessory.removeService(this.Window!.Service);
1157
1127
  }
1158
- accessory.removeService(this.windowService!);
1159
1128
  }
1160
1129
 
1161
1130
  async removeWindowCoveringService(accessory: PlatformAccessory): Promise<void> {
1162
1131
  // If windowCoveringService still present, then remove first
1163
- this.windowCoveringService = this.accessory.getService(this.hap.Service.WindowCovering);
1164
- if (this.windowCoveringService) {
1132
+ if (this.WindowCovering?.Service) {
1133
+ this.WindowCovering!.Service = this.accessory.getService(this.hap.Service.WindowCovering) as Service;
1165
1134
  this.warnLog(`${this.device.deviceType}: ${accessory.displayName} Removing Leftover Window Covering Service`);
1135
+ accessory.removeService(this.WindowCovering!.Service);
1166
1136
  }
1167
- accessory.removeService(this.windowCoveringService!);
1168
1137
  }
1169
1138
 
1170
1139
  async removeStatefulProgrammableSwitchService(accessory: PlatformAccessory): Promise<void> {
1171
1140
  // If statefulProgrammableSwitchService still present, then remove first
1172
- this.statefulProgrammableSwitchService = this.accessory.getService(this.hap.Service.StatefulProgrammableSwitch);
1173
- if (this.statefulProgrammableSwitchService) {
1141
+ if (this.StatefulProgrammableSwitch?.Service) {
1142
+ this.StatefulProgrammableSwitch!.Service = this.accessory.getService(this.hap.Service.StatefulProgrammableSwitch) as Service;
1174
1143
  this.warnLog(`${this.device.deviceType}: ${accessory.displayName} Removing Leftover Stateful Programmable Switch Service`);
1144
+ accessory.removeService(this.StatefulProgrammableSwitch!.Service);
1175
1145
  }
1176
- accessory.removeService(this.statefulProgrammableSwitchService!);
1177
1146
  }
1178
1147
 
1179
1148
  async removeSwitchService(accessory: PlatformAccessory): Promise<void> {
1180
1149
  // If switchService still present, then remove first
1181
- this.switchService = this.accessory.getService(this.hap.Service.Switch);
1182
- if (this.switchService) {
1150
+ if (this.Switch?.Service) {
1151
+ this.Switch!.Service = this.accessory.getService(this.hap.Service.Switch) as Service;
1183
1152
  this.warnLog(`${this.device.deviceType}: ${accessory.displayName} Removing Leftover Switch Service`);
1153
+ accessory.removeService(this.Switch!.Service);
1184
1154
  }
1185
- accessory.removeService(this.switchService!);
1186
1155
  }
1187
1156
 
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
- }
1157
+ async getOn(): Promise<boolean> {
1158
+ let On: boolean;
1159
+ if (this.botDeviceType === 'garagedoor') {
1160
+ On = this.GarageDoor!.On ? true : false;
1161
+ } else if (this.botDeviceType === 'door') {
1162
+ On = this.Door!.On ? true : false;
1163
+ } else if (this.botDeviceType === 'window') {
1164
+ On = this.Window!.On ? true : false;
1165
+ } else if (this.botDeviceType === 'windowcovering') {
1166
+ On = this.WindowCovering!.On ? true : false;
1167
+ } else if (this.botDeviceType === 'lock') {
1168
+ On = this.Lock!.On ? true : false;
1169
+ } else if (this.botDeviceType === 'faucet') {
1170
+ On = this.Faucet!.On ? true : false;
1171
+ } else if (this.botDeviceType === 'fan') {
1172
+ On = this.Fan!.On ? true : false;
1173
+ } else if (this.botDeviceType === 'stateful') {
1174
+ On = this.StatefulProgrammableSwitch!.On ? true : false;
1175
+ } else if (this.botDeviceType === 'switch') {
1176
+ On = this.Switch!.On ? true : false;
1295
1177
  } 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
- }
1178
+ On = this.Outlet!.On ? true : false;
1300
1179
  }
1180
+ return On;
1301
1181
  }
1302
1182
 
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> {
1183
+ async setOn(On: boolean): Promise<void> {
1389
1184
  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);
1185
+ this.GarageDoor!.On = On;
1393
1186
  } 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);
1187
+ this.Door!.On = On;
1397
1188
  } 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);
1189
+ this.Window!.On = On;
1401
1190
  } 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);
1191
+ this.WindowCovering!.On = On;
1405
1192
  } else if (this.botDeviceType === 'lock') {
1406
- this.doorService?.updateCharacteristic(this.hap.Characteristic.LockTargetState, e);
1407
- this.doorService?.updateCharacteristic(this.hap.Characteristic.LockCurrentState, e);
1193
+ this.Lock!.On = On;
1408
1194
  } else if (this.botDeviceType === 'faucet') {
1409
- this.faucetService?.updateCharacteristic(this.hap.Characteristic.Active, e);
1195
+ this.Faucet!.On = On;
1410
1196
  } else if (this.botDeviceType === 'fan') {
1411
- this.fanService?.updateCharacteristic(this.hap.Characteristic.On, e);
1197
+ this.Fan!.On = On;
1412
1198
  } else if (this.botDeviceType === 'stateful') {
1413
- this.statefulProgrammableSwitchService?.updateCharacteristic(this.hap.Characteristic.ProgrammableSwitchEvent, e);
1414
- this.statefulProgrammableSwitchService?.updateCharacteristic(this.hap.Characteristic.ProgrammableSwitchOutputState, e);
1199
+ this.StatefulProgrammableSwitch!.On = On;
1415
1200
  } else if (this.botDeviceType === 'switch') {
1416
- this.switchService?.updateCharacteristic(this.hap.Characteristic.On, e);
1201
+ this.Switch!.On = On;
1417
1202
  } else {
1418
- this.outletService?.updateCharacteristic(this.hap.Characteristic.On, e);
1203
+ this.Outlet!.On = On;
1419
1204
  }
1420
- this.batteryService?.updateCharacteristic(this.hap.Characteristic.BatteryLevel, e);
1421
- this.batteryService?.updateCharacteristic(this.hap.Characteristic.StatusLowBattery, e);
1422
1205
  }
1423
1206
 
1424
- async deviceType(device: device & devicesConfig): Promise<void> {
1207
+ async getBotConfigSettings(device: device & devicesConfig) {
1208
+ //Bot Device Type
1425
1209
  if (!device.bot?.deviceType && this.accessory.context.deviceType) {
1426
1210
  this.botDeviceType = this.accessory.context.deviceType;
1427
1211
  this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Type: ${this.botDeviceType}, from Accessory Cache.`);
@@ -1435,41 +1219,33 @@ export class Bot {
1435
1219
  this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} No Device Type Set, deviceType: ${this.device.bot?.deviceType}`);
1436
1220
  this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} Using default deviceType: ${this.botDeviceType}`);
1437
1221
  }
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;
1222
+ // Bot Mode
1223
+ if (!device.bot?.mode) {
1224
+ this.botMode = 'switch';
1225
+ this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} does not have bot mode set in the Plugin's SwitchBot Device Settings,`);
1226
+ this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} is defaulting to "${this.botMode}" mode, you may experience issues.`);
1227
+ } else if (device.bot?.mode === 'switch') {
1228
+ this.botMode = 'switch';
1229
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Bot Mode: ${this.botMode}`);
1230
+ } else if (device.bot?.mode === 'press') {
1231
+ this.botMode = 'press';
1232
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Bot Mode: ${this.botMode}`);
1233
+ } else if (device.bot?.mode === 'multipress') {
1234
+ this.botMode = 'multipress';
1235
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Bot Mode: ${this.botMode}`);
1449
1236
  } else {
1450
- this.BatteryLevel = this.accessory.context.BatteryLevel;
1237
+ throw new Error(`${this.device.deviceType}: ${this.accessory.displayName} Bot Mode: ${this.botMode}`);
1451
1238
  }
1452
- if (this.StatusLowBattery === undefined) {
1453
- this.StatusLowBattery = this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
1454
- this.accessory.context.StatusLowBattery = this.StatusLowBattery;
1239
+
1240
+ // Bot Double Press
1241
+ if (device.bot?.doublePress) {
1242
+ this.doublePress = device.bot?.doublePress;
1243
+ this.accessory.context.doublePress = this.doublePress;
1455
1244
  } 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;
1245
+ this.doublePress = 1;
1461
1246
  }
1462
- }
1463
1247
 
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
1248
+ // Bot Press PushRate
1473
1249
  if (device?.bot?.pushRatePress) {
1474
1250
  this.pushRatePress = device?.bot?.pushRatePress;
1475
1251
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Config Bot pushRatePress: ${this.pushRatePress}`);
@@ -1477,106 +1253,104 @@ export class Bot {
1477
1253
  this.pushRatePress = 15;
1478
1254
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Default Bot pushRatePress: ${this.pushRatePress}`);
1479
1255
  }
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
1256
 
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}`);
1257
+ // Bot Allow Push
1258
+ if (device.bot?.allowPush) {
1259
+ this.allowPush = true;
1526
1260
  } 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
- }
1261
+ this.allowPush = false;
1552
1262
  }
1263
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Allowing Push Changes: ${this.allowPush}`);
1264
+ // Bot Multi Press Count
1265
+ this.multiPressCount = 0;
1553
1266
  }
1554
1267
 
1555
- errorLog(...log: any[]): void {
1556
- if (this.enablingDeviceLogging()) {
1557
- this.platform.log.error(String(...log));
1268
+ async BLEPushConnection() {
1269
+ if (this.platform.config.credentials?.token && this.device.connectionType === 'BLE/OpenAPI') {
1270
+ this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} Using OpenAPI Connection to Push Changes`);
1271
+ await this.openAPIpushChanges();
1558
1272
  }
1559
1273
  }
1560
1274
 
1561
- debugErrorLog(...log: any[]): void {
1562
- if (this.enablingDeviceLogging()) {
1563
- if (this.deviceLogging?.includes('debug')) {
1564
- this.platform.log.error('[DEBUG]', String(...log));
1565
- }
1275
+ async BLERefreshConnection(switchbot: any): Promise<void> {
1276
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} wasn't able to establish BLE Connection, node-switchbot:`
1277
+ + ` ${JSON.stringify(switchbot)}`);
1278
+ if (this.platform.config.credentials?.token && this.device.connectionType === 'BLE/OpenAPI') {
1279
+ this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} Using OpenAPI Connection to Refresh Status`);
1280
+ await this.openAPIRefreshStatus();
1566
1281
  }
1567
1282
  }
1568
1283
 
1569
- debugLog(...log: any[]): void {
1570
- if (this.enablingDeviceLogging()) {
1571
- if (this.deviceLogging === 'debug') {
1572
- this.platform.log.info('[DEBUG]', String(...log));
1284
+ async offlineOff(): Promise<void> {
1285
+ if (this.device.offline) {
1286
+ if (this.botDeviceType === 'garagedoor') {
1287
+ this.GarageDoor!.Service.updateCharacteristic(this.hap.Characteristic.TargetDoorState, this.hap.Characteristic.TargetDoorState.CLOSED);
1288
+ this.GarageDoor!.Service.updateCharacteristic(this.hap.Characteristic.CurrentDoorState, this.hap.Characteristic.CurrentDoorState.CLOSED);
1289
+ this.GarageDoor!.Service.updateCharacteristic(this.hap.Characteristic.ObstructionDetected, false);
1290
+ } else if (this.botDeviceType === 'door') {
1291
+ this.Door!.Service.updateCharacteristic(this.hap.Characteristic.TargetPosition, 0);
1292
+ this.Door!.Service.updateCharacteristic(this.hap.Characteristic.CurrentPosition, 0);
1293
+ this.Door!.Service.updateCharacteristic(this.hap.Characteristic.PositionState, this.hap.Characteristic.PositionState.STOPPED);
1294
+ } else if (this.botDeviceType === 'window') {
1295
+ this.Window!.Service.updateCharacteristic(this.hap.Characteristic.TargetPosition, 0);
1296
+ this.Window!.Service.updateCharacteristic(this.hap.Characteristic.CurrentPosition, 0);
1297
+ this.Window!.Service.updateCharacteristic(this.hap.Characteristic.PositionState, this.hap.Characteristic.PositionState.STOPPED);
1298
+ } else if (this.botDeviceType === 'windowcovering') {
1299
+ this.WindowCovering!.Service.updateCharacteristic(this.hap.Characteristic.TargetPosition, 0);
1300
+ this.WindowCovering!.Service.updateCharacteristic(this.hap.Characteristic.CurrentPosition, 0);
1301
+ this.WindowCovering!.Service.updateCharacteristic(this.hap.Characteristic.PositionState, this.hap.Characteristic.PositionState.STOPPED);
1302
+ } else if (this.botDeviceType === 'lock') {
1303
+ this.Door!.Service.updateCharacteristic(this.hap.Characteristic.LockTargetState, this.hap.Characteristic.LockTargetState.SECURED);
1304
+ this.Door!.Service.updateCharacteristic(this.hap.Characteristic.LockCurrentState, this.hap.Characteristic.LockCurrentState.SECURED);
1305
+ } else if (this.botDeviceType === 'faucet') {
1306
+ this.Faucet!.Service.updateCharacteristic(this.hap.Characteristic.Active, this.hap.Characteristic.Active.INACTIVE);
1307
+ } else if (this.botDeviceType === 'fan') {
1308
+ this.Fan!.Service.updateCharacteristic(this.hap.Characteristic.On, false);
1309
+ } else if (this.botDeviceType === 'stateful') {
1310
+ this.StatefulProgrammableSwitch!.Service.updateCharacteristic(this.hap.Characteristic.ProgrammableSwitchEvent,
1311
+ this.hap.Characteristic.ProgrammableSwitchEvent.SINGLE_PRESS);
1312
+ this.StatefulProgrammableSwitch!.Service.updateCharacteristic(this.hap.Characteristic.ProgrammableSwitchOutputState, 0);
1313
+ } else if (this.botDeviceType === 'switch') {
1314
+ this.Switch!.Service.updateCharacteristic(this.hap.Characteristic.On, false);
1573
1315
  } else {
1574
- this.platform.log.debug(String(...log));
1316
+ this.Outlet!.Service.updateCharacteristic(this.hap.Characteristic.On, false);
1575
1317
  }
1576
1318
  }
1577
1319
  }
1578
1320
 
1579
- enablingDeviceLogging(): boolean {
1580
- return this.deviceLogging.includes('debug') || this.deviceLogging === 'standard';
1321
+ async apiError(e: any): Promise<void> {
1322
+ if (this.botDeviceType === 'garagedoor') {
1323
+ this.GarageDoor!.Service.updateCharacteristic(this.hap.Characteristic.TargetDoorState, e);
1324
+ this.GarageDoor!.Service.updateCharacteristic(this.hap.Characteristic.CurrentDoorState, e);
1325
+ this.GarageDoor!.Service.updateCharacteristic(this.hap.Characteristic.ObstructionDetected, e);
1326
+ } else if (this.botDeviceType === 'door') {
1327
+ this.Door!.Service.updateCharacteristic(this.hap.Characteristic.TargetPosition, e);
1328
+ this.Door!.Service.updateCharacteristic(this.hap.Characteristic.CurrentPosition, e);
1329
+ this.Door!.Service.updateCharacteristic(this.hap.Characteristic.PositionState, e);
1330
+ } else if (this.botDeviceType === 'window') {
1331
+ this.Window!.Service.updateCharacteristic(this.hap.Characteristic.TargetPosition, e);
1332
+ this.Window!.Service.updateCharacteristic(this.hap.Characteristic.CurrentPosition, e);
1333
+ this.Window!.Service.updateCharacteristic(this.hap.Characteristic.PositionState, e);
1334
+ } else if (this.botDeviceType === 'windowcovering') {
1335
+ this.WindowCovering!.Service.updateCharacteristic(this.hap.Characteristic.TargetPosition, e);
1336
+ this.WindowCovering!.Service.updateCharacteristic(this.hap.Characteristic.CurrentPosition, e);
1337
+ this.WindowCovering!.Service.updateCharacteristic(this.hap.Characteristic.PositionState, e);
1338
+ } else if (this.botDeviceType === 'lock') {
1339
+ this.Door!.Service.updateCharacteristic(this.hap.Characteristic.LockTargetState, e);
1340
+ this.Door!.Service.updateCharacteristic(this.hap.Characteristic.LockCurrentState, e);
1341
+ } else if (this.botDeviceType === 'faucet') {
1342
+ this.Faucet!.Service.updateCharacteristic(this.hap.Characteristic.Active, e);
1343
+ } else if (this.botDeviceType === 'fan') {
1344
+ this.Fan!.Service.updateCharacteristic(this.hap.Characteristic.On, e);
1345
+ } else if (this.botDeviceType === 'stateful') {
1346
+ this.StatefulProgrammableSwitch!.Service.updateCharacteristic(this.hap.Characteristic.ProgrammableSwitchEvent, e);
1347
+ this.StatefulProgrammableSwitch!.Service.updateCharacteristic(this.hap.Characteristic.ProgrammableSwitchOutputState, e);
1348
+ } else if (this.botDeviceType === 'switch') {
1349
+ this.Switch!.Service.updateCharacteristic(this.hap.Characteristic.On, e);
1350
+ } else {
1351
+ this.Outlet!.Service.updateCharacteristic(this.hap.Characteristic.On, e);
1352
+ }
1353
+ this.Battery.Service.updateCharacteristic(this.hap.Characteristic.BatteryLevel, e);
1354
+ this.Battery.Service.updateCharacteristic(this.hap.Characteristic.StatusLowBattery, e);
1581
1355
  }
1582
1356
  }