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

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