@switchbot/homebridge-switchbot 3.5.0-beta.7 → 3.5.0-beta.70

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