@switchbot/homebridge-switchbot 3.5.0-beta.6 → 3.5.0-beta.61

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