@switchbot/homebridge-switchbot 3.5.0-beta.57 → 3.5.0-beta.59

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 (164) hide show
  1. package/.vscode/settings.json +4 -1
  2. package/dist/device/blindtilt.d.ts +5 -5
  3. package/dist/device/blindtilt.d.ts.map +1 -1
  4. package/dist/device/blindtilt.js +103 -69
  5. package/dist/device/blindtilt.js.map +1 -1
  6. package/dist/device/bot.d.ts +4 -4
  7. package/dist/device/bot.d.ts.map +1 -1
  8. package/dist/device/bot.js +201 -154
  9. package/dist/device/bot.js.map +1 -1
  10. package/dist/device/ceilinglight.d.ts +3 -3
  11. package/dist/device/ceilinglight.d.ts.map +1 -1
  12. package/dist/device/ceilinglight.js +41 -36
  13. package/dist/device/ceilinglight.js.map +1 -1
  14. package/dist/device/colorbulb.d.ts +3 -3
  15. package/dist/device/colorbulb.d.ts.map +1 -1
  16. package/dist/device/colorbulb.js +36 -37
  17. package/dist/device/colorbulb.js.map +1 -1
  18. package/dist/device/contact.d.ts +4 -4
  19. package/dist/device/contact.d.ts.map +1 -1
  20. package/dist/device/contact.js +76 -55
  21. package/dist/device/contact.js.map +1 -1
  22. package/dist/device/curtain.d.ts +4 -4
  23. package/dist/device/curtain.d.ts.map +1 -1
  24. package/dist/device/curtain.js +99 -55
  25. package/dist/device/curtain.js.map +1 -1
  26. package/dist/device/device.d.ts +4 -4
  27. package/dist/device/device.d.ts.map +1 -1
  28. package/dist/device/device.js +11 -9
  29. package/dist/device/device.js.map +1 -1
  30. package/dist/device/fan.d.ts +3 -3
  31. package/dist/device/fan.d.ts.map +1 -1
  32. package/dist/device/fan.js +54 -24
  33. package/dist/device/fan.js.map +1 -1
  34. package/dist/device/hub.d.ts +4 -4
  35. package/dist/device/hub.d.ts.map +1 -1
  36. package/dist/device/hub.js +40 -57
  37. package/dist/device/hub.js.map +1 -1
  38. package/dist/device/humidifier.d.ts +3 -3
  39. package/dist/device/humidifier.d.ts.map +1 -1
  40. package/dist/device/humidifier.js +39 -39
  41. package/dist/device/humidifier.js.map +1 -1
  42. package/dist/device/iosensor.d.ts +3 -3
  43. package/dist/device/iosensor.d.ts.map +1 -1
  44. package/dist/device/iosensor.js +41 -50
  45. package/dist/device/iosensor.js.map +1 -1
  46. package/dist/device/lightstrip.d.ts +4 -4
  47. package/dist/device/lightstrip.d.ts.map +1 -1
  48. package/dist/device/lightstrip.js +36 -33
  49. package/dist/device/lightstrip.js.map +1 -1
  50. package/dist/device/lock.d.ts +3 -3
  51. package/dist/device/lock.d.ts.map +1 -1
  52. package/dist/device/lock.js +68 -59
  53. package/dist/device/lock.js.map +1 -1
  54. package/dist/device/meter.d.ts +3 -3
  55. package/dist/device/meter.d.ts.map +1 -1
  56. package/dist/device/meter.js +42 -51
  57. package/dist/device/meter.js.map +1 -1
  58. package/dist/device/meterplus.d.ts +3 -3
  59. package/dist/device/meterplus.d.ts.map +1 -1
  60. package/dist/device/meterplus.js +42 -51
  61. package/dist/device/meterplus.js.map +1 -1
  62. package/dist/device/motion.d.ts +3 -3
  63. package/dist/device/motion.d.ts.map +1 -1
  64. package/dist/device/motion.js +52 -40
  65. package/dist/device/motion.js.map +1 -1
  66. package/dist/device/plug.d.ts +3 -3
  67. package/dist/device/plug.d.ts.map +1 -1
  68. package/dist/device/plug.js +13 -13
  69. package/dist/device/plug.js.map +1 -1
  70. package/dist/device/robotvacuumcleaner.d.ts +4 -4
  71. package/dist/device/robotvacuumcleaner.d.ts.map +1 -1
  72. package/dist/device/robotvacuumcleaner.js +81 -98
  73. package/dist/device/robotvacuumcleaner.js.map +1 -1
  74. package/dist/device/waterdetector.d.ts +3 -3
  75. package/dist/device/waterdetector.d.ts.map +1 -1
  76. package/dist/device/waterdetector.js +39 -31
  77. package/dist/device/waterdetector.js.map +1 -1
  78. package/dist/homebridge-ui/public/index.html +20 -14
  79. package/dist/index.d.ts +1 -1
  80. package/dist/index.d.ts.map +1 -1
  81. package/dist/index.js +1 -1
  82. package/dist/index.js.map +1 -1
  83. package/dist/irdevice/airconditioner.d.ts +3 -3
  84. package/dist/irdevice/airconditioner.d.ts.map +1 -1
  85. package/dist/irdevice/airconditioner.js +9 -9
  86. package/dist/irdevice/airconditioner.js.map +1 -1
  87. package/dist/irdevice/airpurifier.d.ts +3 -3
  88. package/dist/irdevice/airpurifier.d.ts.map +1 -1
  89. package/dist/irdevice/airpurifier.js +1 -1
  90. package/dist/irdevice/airpurifier.js.map +1 -1
  91. package/dist/irdevice/camera.d.ts +3 -3
  92. package/dist/irdevice/camera.d.ts.map +1 -1
  93. package/dist/irdevice/camera.js +2 -2
  94. package/dist/irdevice/camera.js.map +1 -1
  95. package/dist/irdevice/fan.d.ts +6 -6
  96. package/dist/irdevice/fan.d.ts.map +1 -1
  97. package/dist/irdevice/fan.js +37 -29
  98. package/dist/irdevice/fan.js.map +1 -1
  99. package/dist/irdevice/irdevice.d.ts +3 -3
  100. package/dist/irdevice/irdevice.d.ts.map +1 -1
  101. package/dist/irdevice/irdevice.js.map +1 -1
  102. package/dist/irdevice/light.d.ts +9 -14
  103. package/dist/irdevice/light.d.ts.map +1 -1
  104. package/dist/irdevice/light.js +67 -88
  105. package/dist/irdevice/light.js.map +1 -1
  106. package/dist/irdevice/other.d.ts +3 -3
  107. package/dist/irdevice/other.d.ts.map +1 -1
  108. package/dist/irdevice/other.js +1 -1
  109. package/dist/irdevice/other.js.map +1 -1
  110. package/dist/irdevice/tv.d.ts +3 -3
  111. package/dist/irdevice/tv.d.ts.map +1 -1
  112. package/dist/irdevice/tv.js +3 -3
  113. package/dist/irdevice/tv.js.map +1 -1
  114. package/dist/irdevice/vacuumcleaner.d.ts +3 -3
  115. package/dist/irdevice/vacuumcleaner.d.ts.map +1 -1
  116. package/dist/irdevice/vacuumcleaner.js +2 -2
  117. package/dist/irdevice/vacuumcleaner.js.map +1 -1
  118. package/dist/irdevice/waterheater.d.ts +3 -3
  119. package/dist/irdevice/waterheater.d.ts.map +1 -1
  120. package/dist/irdevice/waterheater.js +2 -2
  121. package/dist/irdevice/waterheater.js.map +1 -1
  122. package/dist/platform.d.ts +7 -7
  123. package/dist/platform.d.ts.map +1 -1
  124. package/dist/platform.js +20 -23
  125. package/dist/platform.js.map +1 -1
  126. package/dist/settings.d.ts +24 -10
  127. package/dist/settings.d.ts.map +1 -1
  128. package/dist/settings.js +16 -0
  129. package/dist/settings.js.map +1 -1
  130. package/eslint.config.js +89 -78
  131. package/package.json +3 -3
  132. package/src/device/blindtilt.ts +120 -87
  133. package/src/device/bot.ts +238 -175
  134. package/src/device/ceilinglight.ts +49 -46
  135. package/src/device/colorbulb.ts +40 -43
  136. package/src/device/contact.ts +91 -65
  137. package/src/device/curtain.ts +113 -66
  138. package/src/device/device.ts +12 -13
  139. package/src/device/fan.ts +66 -29
  140. package/src/device/hub.ts +53 -60
  141. package/src/device/humidifier.ts +54 -56
  142. package/src/device/iosensor.ts +57 -56
  143. package/src/device/lightstrip.ts +43 -39
  144. package/src/device/lock.ts +79 -68
  145. package/src/device/meter.ts +54 -54
  146. package/src/device/meterplus.ts +54 -54
  147. package/src/device/motion.ts +62 -46
  148. package/src/device/plug.ts +19 -18
  149. package/src/device/robotvacuumcleaner.ts +89 -104
  150. package/src/device/waterdetector.ts +46 -34
  151. package/src/homebridge-ui/public/index.html +20 -14
  152. package/src/index.ts +3 -2
  153. package/src/irdevice/airconditioner.ts +13 -11
  154. package/src/irdevice/airpurifier.ts +5 -3
  155. package/src/irdevice/camera.ts +6 -4
  156. package/src/irdevice/fan.ts +42 -29
  157. package/src/irdevice/irdevice.ts +4 -5
  158. package/src/irdevice/light.ts +83 -103
  159. package/src/irdevice/other.ts +5 -3
  160. package/src/irdevice/tv.ts +7 -5
  161. package/src/irdevice/vacuumcleaner.ts +6 -4
  162. package/src/irdevice/waterheater.ts +6 -4
  163. package/src/platform.ts +59 -66
  164. package/src/settings.ts +73 -58
package/src/device/bot.ts CHANGED
@@ -5,10 +5,12 @@
5
5
  import { request } from 'undici';
6
6
  import { deviceBase } from './device.js';
7
7
  import { interval, Subject } from 'rxjs';
8
- import { SwitchBotPlatform } from '../platform.js';
8
+ import { Devices } from '../settings.js';
9
9
  import { debounceTime, skipWhile, take, tap } from 'rxjs/operators';
10
- import { Service, PlatformAccessory, CharacteristicValue } from 'homebridge';
11
- import { device, devicesConfig, serviceData, deviceStatus, Devices } from '../settings.js';
10
+
11
+ import type { SwitchBotPlatform } from '../platform.js';
12
+ import type { Service, PlatformAccessory, CharacteristicValue } from 'homebridge';
13
+ import type { device, devicesConfig, serviceData, deviceStatus } from '../settings.js';
12
14
 
13
15
  /**
14
16
  * Platform Accessory
@@ -17,58 +19,69 @@ import { device, devicesConfig, serviceData, deviceStatus, Devices } from '../se
17
19
  */
18
20
  export class Bot extends deviceBase {
19
21
  // Services
20
- private Battery!: {
22
+ private Battery: {
23
+ Name: CharacteristicValue;
21
24
  Service: Service;
22
25
  BatteryLevel: CharacteristicValue;
23
26
  StatusLowBattery: CharacteristicValue;
24
27
  };
25
28
 
26
29
  private Switch?: {
30
+ Name: CharacteristicValue;
27
31
  Service: Service;
28
32
  On: CharacteristicValue;
29
33
  };
30
34
 
31
35
  private GarageDoor?: {
36
+ Name: CharacteristicValue;
32
37
  Service: Service;
33
38
  On: CharacteristicValue;
34
39
  };
35
40
 
36
41
  private Door?: {
42
+ Name: CharacteristicValue;
37
43
  Service: Service;
38
44
  On: CharacteristicValue;
39
45
  };
40
46
 
41
47
  private Window?: {
48
+ Name: CharacteristicValue;
42
49
  Service: Service;
43
50
  On: CharacteristicValue;
44
51
  };
45
52
 
46
53
  private WindowCovering?: {
54
+ Name: CharacteristicValue;
47
55
  Service: Service;
48
56
  On: CharacteristicValue;
49
57
  };
50
58
 
51
- private Lock?: {
59
+ private LockMechanism?: {
60
+ Name: CharacteristicValue;
52
61
  Service: Service;
53
62
  On: CharacteristicValue;
54
63
  };
55
64
 
56
65
  private Faucet?: {
66
+ Name: CharacteristicValue;
57
67
  Service: Service;
58
68
  On: CharacteristicValue;
59
69
  };
60
70
 
61
71
  private Fan?: {
72
+ Name: CharacteristicValue;
62
73
  Service: Service;
63
74
  On: CharacteristicValue;
64
75
  };
65
76
 
66
77
  private StatefulProgrammableSwitch?: {
78
+ Name: CharacteristicValue;
67
79
  Service: Service;
68
80
  On: CharacteristicValue;
69
81
  };
70
82
 
71
83
  private Outlet?: {
84
+ Name: CharacteristicValue;
72
85
  Service: Service;
73
86
  On: CharacteristicValue;
74
87
  };
@@ -100,18 +113,41 @@ export class Bot extends deviceBase {
100
113
 
101
114
  // Initialize Battery property
102
115
  this.Battery = {
103
- Service: accessory.getService(this.hap.Service.Battery) as Service,
104
- BatteryLevel: accessory.context.BatteryLevel || 100,
105
- StatusLowBattery: accessory.context.StatusLowBattery || this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL,
116
+ Name: accessory.context.BatteryName ?? `${accessory.displayName} Battery`,
117
+ Service: accessory.getService(this.hap.Service.Battery) ?? accessory.addService(this.hap.Service.Battery) as Service,
118
+ BatteryLevel: accessory.context.BatteryLevel ?? 100,
119
+ StatusLowBattery: accessory.context.StatusLowBattery ?? this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL,
106
120
  };
107
121
 
122
+ // Initialize Battery Characteristics
123
+ this.Battery.Service
124
+ .setCharacteristic(this.hap.Characteristic.Name, this.Battery.Name)
125
+ .setCharacteristic(this.hap.Characteristic.StatusLowBattery, this.Battery.StatusLowBattery)
126
+ .setCharacteristic(this.hap.Characteristic.ChargingState, this.hap.Characteristic.ChargingState.NOT_CHARGEABLE);
127
+ accessory.context.Battery.Name = this.Battery.Name;
128
+
108
129
  // deviceType
109
130
  if (this.botDeviceType === 'switch') {
110
- // Initialize Switch property
131
+ // Initialize Switch Service
111
132
  this.Switch = {
112
- Service: accessory.getService(this.hap.Service.Switch) as Service,
113
- On: accessory.context.On || false,
133
+ Name: accessory.context.Name ?? accessory.displayName,
134
+ Service: accessory.getService(this.hap.Service.Switch) ?? accessory.addService(this.hap.Service.Switch) as Service,
135
+ On: accessory.context.On ?? false,
114
136
  };
137
+ this.debugWarnLog(`${this.device.deviceType}: ${accessory.displayName} Displaying as Switch`);
138
+
139
+ // Initialize Switch Characteristics
140
+ this.Switch.Service
141
+ .setCharacteristic(this.hap.Characteristic.Name, this.Switch.Name)
142
+ .setCharacteristic(this.hap.Characteristic.On, this.Switch.On)
143
+ .getCharacteristic(this.hap.Characteristic.On)
144
+ .onGet(() => {
145
+ return this.Switch!.On;
146
+ })
147
+ .onSet(this.OnSet.bind(this));
148
+ accessory.context.Name = this.Switch.Name;
149
+
150
+ // Remove other services
115
151
  this.removeFanService(accessory);
116
152
  this.removeLockService(accessory);
117
153
  this.removeDoorService(accessory);
@@ -121,21 +157,32 @@ export class Bot extends deviceBase {
121
157
  this.removeGarageDoorService(accessory);
122
158
  this.removeWindowCoveringService(accessory);
123
159
  this.removeStatefulProgrammableSwitchService(accessory);
124
-
125
- // Add switchService
126
- const switchService = `${accessory.displayName} Switch`;
127
- (this.Switch!.Service = accessory.getService(this.hap.Service.Switch)
128
- || accessory.addService(this.hap.Service.Switch)), switchService;
129
- this.debugWarnLog(`${this.device.deviceType}: ${accessory.displayName} Displaying as Switch`);
130
-
131
- this.Switch!.Service.setCharacteristic(this.hap.Characteristic.Name, accessory.displayName);
132
- this.Switch!.Service.getCharacteristic(this.hap.Characteristic.On).onSet(this.OnSet.bind(this));
133
160
  } else if (this.botDeviceType === 'garagedoor') {
134
- // Initialize Switch property
161
+ // Initialize GarageDoor Service
135
162
  this.GarageDoor = {
136
- Service: accessory.getService(this.hap.Service.GarageDoorOpener) as Service,
137
- On: accessory.context.On || false,
163
+ Name: accessory.context.Name ?? accessory.displayName,
164
+ Service: accessory.getService(this.hap.Service.GarageDoorOpener) ?? accessory.addService(this.hap.Service.GarageDoorOpener) as Service,
165
+ On: accessory.context.On ?? false,
138
166
  };
167
+ this.debugWarnLog(`${this.device.deviceType}: ${accessory.displayName} Displaying as Garage Door Opener`);
168
+
169
+ // Initialize GarageDoor Characteristics
170
+ this.GarageDoor.Service
171
+ .setCharacteristic(this.hap.Characteristic.Name, this.GarageDoor.Name)
172
+ .setCharacteristic(this.hap.Characteristic.ObstructionDetected, false)
173
+ .getCharacteristic(this.hap.Characteristic.TargetDoorState).setProps({
174
+ validValues: [0, 100],
175
+ minValue: 0,
176
+ maxValue: 100,
177
+ minStep: 100,
178
+ })
179
+ .onGet(() => {
180
+ return this.GarageDoor!.On;
181
+ })
182
+ .onSet(this.OnSet.bind(this));
183
+ accessory.context.Name = this.GarageDoor.Name;
184
+
185
+ // Remove other services
139
186
  this.removeFanService(accessory);
140
187
  this.removeLockService(accessory);
141
188
  this.removeDoorService(accessory);
@@ -145,22 +192,32 @@ export class Bot extends deviceBase {
145
192
  this.removeWindowService(accessory);
146
193
  this.removeWindowCoveringService(accessory);
147
194
  this.removeStatefulProgrammableSwitchService(accessory);
148
-
149
- // Add garageDoorService
150
- const garageDoorService = `${accessory.displayName} Garage Door Opener`;
151
- (this.GarageDoor!.Service = accessory.getService(this.hap.Service.GarageDoorOpener)
152
- || accessory.addService(this.hap.Service.GarageDoorOpener)), garageDoorService;
153
- this.debugWarnLog(`${this.device.deviceType}: ${accessory.displayName} Displaying as Garage Door Opener`);
154
-
155
- this.GarageDoor!.Service.setCharacteristic(this.hap.Characteristic.Name, accessory.displayName);
156
- this.GarageDoor!.Service.getCharacteristic(this.hap.Characteristic.TargetDoorState).onSet(this.OnSet.bind(this));
157
- this.GarageDoor!.Service.setCharacteristic(this.hap.Characteristic.ObstructionDetected, false);
158
195
  } else if (this.botDeviceType === 'door') {
159
- // Initialize Switch property
196
+ // Initialize Door Service
160
197
  this.Door = {
161
- Service: accessory.getService(this.hap.Service.Door) as Service,
162
- On: accessory.context.On || false,
198
+ Name: accessory.context.Name ?? accessory.displayName,
199
+ Service: accessory.getService(this.hap.Service.Door) ?? accessory.addService(this.hap.Service.Door) as Service,
200
+ On: accessory.context.On ?? false,
163
201
  };
202
+ this.debugWarnLog(`${this.device.deviceType}: ${accessory.displayName} Displaying as Door`);
203
+
204
+ // Initialize Door Characteristics
205
+ this.Door.Service
206
+ .setCharacteristic(this.hap.Characteristic.Name, this.Door.Name)
207
+ .setCharacteristic(this.hap.Characteristic.PositionState, this.hap.Characteristic.PositionState.STOPPED)
208
+ .getCharacteristic(this.hap.Characteristic.TargetPosition).setProps({
209
+ validValues: [0, 100],
210
+ minValue: 0,
211
+ maxValue: 100,
212
+ minStep: 100,
213
+ })
214
+ .onGet(() => {
215
+ return this.Door!.On;
216
+ })
217
+ .onSet(this.OnSet.bind(this));
218
+ accessory.context.Name = this.Door.Name;
219
+
220
+ // Remove other services
164
221
  this.removeFanService(accessory);
165
222
  this.removeLockService(accessory);
166
223
  this.removeOutletService(accessory);
@@ -170,30 +227,32 @@ export class Bot extends deviceBase {
170
227
  this.removeGarageDoorService(accessory);
171
228
  this.removeWindowCoveringService(accessory);
172
229
  this.removeStatefulProgrammableSwitchService(accessory);
230
+ } else if (this.botDeviceType === 'window') {
231
+ // Initialize Window Service
232
+ this.Window = {
233
+ Name: accessory.context.Name ?? accessory.displayName,
234
+ Service: accessory.getService(this.hap.Service.Window) ?? accessory.addService(this.hap.Service.Window) as Service,
235
+ On: accessory.context.On ?? false,
236
+ };
237
+ this.debugWarnLog(`${this.device.deviceType}: ${accessory.displayName} Displaying as Window`);
173
238
 
174
- // Add doorService
175
- const doorService = `${accessory.displayName} Door`;
176
- (this.Door!.Service = accessory.getService(this.hap.Service.Door)
177
- || accessory.addService(this.hap.Service.Door)), doorService;
178
- this.debugWarnLog(`${this.device.deviceType}: ${accessory.displayName} Displaying as Door`);
179
-
180
- this.Door!.Service.setCharacteristic(this.hap.Characteristic.Name, accessory.displayName);
181
- this.Door!.Service
182
- .getCharacteristic(this.hap.Characteristic.TargetPosition)
183
- .setProps({
239
+ // Initialize Window Characteristics
240
+ this.Window.Service
241
+ .setCharacteristic(this.hap.Characteristic.Name, this.Window.Name)
242
+ .setCharacteristic(this.hap.Characteristic.PositionState, this.hap.Characteristic.PositionState.STOPPED)
243
+ .getCharacteristic(this.hap.Characteristic.TargetPosition).setProps({
184
244
  validValues: [0, 100],
185
245
  minValue: 0,
186
246
  maxValue: 100,
187
247
  minStep: 100,
188
248
  })
249
+ .onGet(() => {
250
+ return this.Window!.On;
251
+ })
189
252
  .onSet(this.OnSet.bind(this));
190
- this.Door!.Service.setCharacteristic(this.hap.Characteristic.PositionState, this.hap.Characteristic.PositionState.STOPPED);
191
- } else if (this.botDeviceType === 'window') {
192
- // Initialize Switch property
193
- this.Window = {
194
- Service: accessory.getService(this.hap.Service.Window) as Service,
195
- On: accessory.context.On || false,
196
- };
253
+ accessory.context.Name = this.Window.Name;
254
+
255
+ // Remove other services
197
256
  this.removeFanService(accessory);
198
257
  this.removeLockService(accessory);
199
258
  this.removeDoorService(accessory);
@@ -203,30 +262,32 @@ export class Bot extends deviceBase {
203
262
  this.removeGarageDoorService(accessory);
204
263
  this.removeWindowCoveringService(accessory);
205
264
  this.removeStatefulProgrammableSwitchService(accessory);
265
+ } else if (this.botDeviceType === 'windowcovering') {
266
+ // Initialize WindowCovering Service
267
+ this.WindowCovering = {
268
+ Name: accessory.context.Name ?? accessory.displayName,
269
+ Service: accessory.getService(this.hap.Service.WindowCovering) ?? accessory.addService(this.hap.Service.WindowCovering) as Service,
270
+ On: accessory.context.On ?? false,
271
+ };
272
+ this.debugWarnLog(`${this.device.deviceType}: ${accessory.displayName} Displaying as Window Covering`);
206
273
 
207
- // Add windowService
208
- const windowService = `${accessory.displayName} Window`;
209
- (this.Window!.Service = accessory.getService(this.hap.Service.Window)
210
- || accessory.addService(this.hap.Service.Window)), windowService;
211
- this.debugWarnLog(`${this.device.deviceType}: ${accessory.displayName} Displaying as Window`);
212
-
213
- this.Window!.Service.setCharacteristic(this.hap.Characteristic.Name, accessory.displayName);
214
- this.Window!.Service
215
- .getCharacteristic(this.hap.Characteristic.TargetPosition)
216
- .setProps({
274
+ // Initialize WindowCovering Characteristics
275
+ this.WindowCovering.Service
276
+ .setCharacteristic(this.hap.Characteristic.Name, this.WindowCovering.Name)
277
+ .setCharacteristic(this.hap.Characteristic.PositionState, this.hap.Characteristic.PositionState.STOPPED)
278
+ .getCharacteristic(this.hap.Characteristic.TargetPosition).setProps({
217
279
  validValues: [0, 100],
218
280
  minValue: 0,
219
281
  maxValue: 100,
220
282
  minStep: 100,
221
283
  })
284
+ .onGet(() => {
285
+ return this.WindowCovering!.On;
286
+ })
222
287
  .onSet(this.OnSet.bind(this));
223
- this.Window!.Service.setCharacteristic(this.hap.Characteristic.PositionState, this.hap.Characteristic.PositionState.STOPPED);
224
- } else if (this.botDeviceType === 'windowcovering') {
225
- // Initialize Switch property
226
- this.WindowCovering = {
227
- Service: accessory.getService(this.hap.Service.WindowCovering) as Service,
228
- On: accessory.context.On || false,
229
- };
288
+ accessory.context.Name = this.WindowCovering.Name;
289
+
290
+ // Remove other services
230
291
  this.removeFanService(accessory);
231
292
  this.removeLockService(accessory);
232
293
  this.removeDoorService(accessory);
@@ -236,30 +297,26 @@ export class Bot extends deviceBase {
236
297
  this.removeWindowService(accessory);
237
298
  this.removeGarageDoorService(accessory);
238
299
  this.removeStatefulProgrammableSwitchService(accessory);
300
+ } else if (this.botDeviceType === 'lock') {
301
+ // Initialize Lock Service
302
+ this.LockMechanism = {
303
+ Name: accessory.context.Name ?? accessory.displayName,
304
+ Service: accessory.getService(this.hap.Service.LockMechanism) ?? accessory.addService(this.hap.Service.LockMechanism) as Service,
305
+ On: accessory.context.On ?? false,
306
+ };
307
+ this.debugWarnLog(`${this.device.deviceType}: ${accessory.displayName} Displaying as Lock`);
239
308
 
240
- // Add windowCoveringService
241
- const windowCoveringService = `${accessory.displayName} Window Covering`;
242
- (this.WindowCovering!.Service = accessory.getService(this.hap.Service.WindowCovering)
243
- || accessory.addService(this.hap.Service.WindowCovering)), windowCoveringService;
244
- this.debugWarnLog(`${this.device.deviceType}: ${accessory.displayName} Displaying as Window Covering`);
245
-
246
- this.WindowCovering!.Service.setCharacteristic(this.hap.Characteristic.Name, accessory.displayName);
247
- this.WindowCovering!.Service
248
- .getCharacteristic(this.hap.Characteristic.TargetPosition)
249
- .setProps({
250
- validValues: [0, 100],
251
- minValue: 0,
252
- maxValue: 100,
253
- minStep: 100,
309
+ // Initialize Lock Characteristics
310
+ this.LockMechanism.Service
311
+ .setCharacteristic(this.hap.Characteristic.Name, this.LockMechanism.Name)
312
+ .getCharacteristic(this.hap.Characteristic.LockTargetState)
313
+ .onGet(() => {
314
+ return this.LockMechanism!.On;
254
315
  })
255
316
  .onSet(this.OnSet.bind(this));
256
- this.WindowCovering!.Service.setCharacteristic(this.hap.Characteristic.PositionState, this.hap.Characteristic.PositionState.STOPPED);
257
- } else if (this.botDeviceType === 'lock') {
258
- // Initialize Switch property
259
- this.Lock = {
260
- Service: accessory.getService(this.hap.Service.LockMechanism) as Service,
261
- On: accessory.context.On || false,
262
- };
317
+ accessory.context.Name = this.LockMechanism.Name;
318
+
319
+ // Remove other services
263
320
  this.removeFanService(accessory);
264
321
  this.removeDoorService(accessory);
265
322
  this.removeOutletService(accessory);
@@ -269,21 +326,26 @@ export class Bot extends deviceBase {
269
326
  this.removeGarageDoorService(accessory);
270
327
  this.removeWindowCoveringService(accessory);
271
328
  this.removeStatefulProgrammableSwitchService(accessory);
272
-
273
- // Add lockService
274
- const lockService = `${accessory.displayName} Lock`;
275
- (this.Lock!.Service = accessory.getService(this.hap.Service.LockMechanism)
276
- || accessory.addService(this.hap.Service.LockMechanism)), lockService;
277
- this.debugWarnLog(`${this.device.deviceType}: ${accessory.displayName} Displaying as Lock`);
278
-
279
- this.Lock!.Service.setCharacteristic(this.hap.Characteristic.Name, accessory.displayName);
280
- this.Lock!.Service.getCharacteristic(this.hap.Characteristic.LockTargetState).onSet(this.OnSet.bind(this));
281
329
  } else if (this.botDeviceType === 'faucet') {
282
- // Initialize Switch property
330
+ // Initialize Faucet Service
283
331
  this.Faucet = {
284
- Service: accessory.getService(this.hap.Service.Faucet) as Service,
285
- On: accessory.context.On || false,
332
+ Name: accessory.context.Name ?? accessory.displayName,
333
+ Service: accessory.getService(this.hap.Service.Faucet) ?? accessory.addService(this.hap.Service.Faucet) as Service,
334
+ On: accessory.context.On ?? false,
286
335
  };
336
+ this.debugWarnLog(`${this.device.deviceType}: ${accessory.displayName} Displaying as Faucet`);
337
+
338
+ // Initialize Faucet Characteristics
339
+ this.Faucet.Service
340
+ .setCharacteristic(this.hap.Characteristic.Name, this.Faucet.Name)
341
+ .getCharacteristic(this.hap.Characteristic.Active)
342
+ .onGet(() => {
343
+ return this.Faucet!.On;
344
+ })
345
+ .onSet(this.OnSet.bind(this));
346
+ accessory.context.Name = this.Faucet.Name;
347
+
348
+ // Remove other services
287
349
  this.removeFanService(accessory);
288
350
  this.removeLockService(accessory);
289
351
  this.removeDoorService(accessory);
@@ -293,21 +355,26 @@ export class Bot extends deviceBase {
293
355
  this.removeGarageDoorService(accessory);
294
356
  this.removeWindowCoveringService(accessory);
295
357
  this.removeStatefulProgrammableSwitchService(accessory);
296
-
297
- // Add faucetService
298
- const faucetService = `${accessory.displayName} Faucet`;
299
- (this.Faucet!.Service = accessory.getService(this.hap.Service.Faucet)
300
- || accessory.addService(this.hap.Service.Faucet)), faucetService;
301
- this.debugWarnLog(`${this.device.deviceType}: ${accessory.displayName} Displaying as Faucet`);
302
-
303
- this.Faucet!.Service.setCharacteristic(this.hap.Characteristic.Name, accessory.displayName);
304
- this.Faucet!.Service.getCharacteristic(this.hap.Characteristic.Active).onSet(this.OnSet.bind(this));
305
358
  } else if (this.botDeviceType === 'fan') {
306
- // Initialize Switch property
359
+ // Initialize Fan Service
307
360
  this.Fan = {
308
- Service: accessory.getService(this.hap.Service.Fanv2) as Service,
309
- On: accessory.context.On || false,
361
+ Name: accessory.context.Name ?? accessory.displayName,
362
+ Service: accessory.getService(this.hap.Service.Fanv2) ?? accessory.addService(this.hap.Service.Fanv2) as Service,
363
+ On: accessory.context.On ?? false,
310
364
  };
365
+ this.debugWarnLog(`${this.device.deviceType}: ${accessory.displayName} Displaying as Fan`);
366
+
367
+ // Initialize Fan Characteristics
368
+ this.Fan.Service
369
+ .setCharacteristic(this.hap.Characteristic.Name, this.Fan.Name)
370
+ .getCharacteristic(this.hap.Characteristic.On)
371
+ .onGet(() => {
372
+ return this.Fan!.On;
373
+ })
374
+ .onSet(this.OnSet.bind(this));
375
+ accessory.context.Name = this.Fan.Name;
376
+
377
+ // Remove other services
311
378
  this.removeLockService(accessory);
312
379
  this.removeDoorService(accessory);
313
380
  this.removeFaucetService(accessory);
@@ -317,21 +384,27 @@ export class Bot extends deviceBase {
317
384
  this.removeGarageDoorService(accessory);
318
385
  this.removeWindowCoveringService(accessory);
319
386
  this.removeStatefulProgrammableSwitchService(accessory);
320
-
321
- // Add fanService
322
- const fanService = `${accessory.displayName} Fan`;
323
- (this.Fan!.Service = accessory.getService(this.hap.Service.Fanv2)
324
- || accessory.addService(this.hap.Service.Fanv2)), fanService;
325
- this.debugWarnLog(`${this.device.deviceType}: ${accessory.displayName} Displaying as Fan`);
326
-
327
- this.Fan!.Service.setCharacteristic(this.hap.Characteristic.Name, accessory.displayName);
328
- this.Fan!.Service.getCharacteristic(this.hap.Characteristic.On).onSet(this.OnSet.bind(this));
329
387
  } else if (this.botDeviceType === 'stateful') {
330
- // Initialize Switch property
388
+ // Initialize StatefulProgrammableSwitch Service
331
389
  this.StatefulProgrammableSwitch = {
332
- Service: accessory.getService(this.hap.Service.StatefulProgrammableSwitch) as Service,
333
- On: accessory.context.On || false,
390
+ Name: accessory.context.Name ?? accessory.displayName,
391
+ Service: accessory.getService(this.hap.Service.StatefulProgrammableSwitch)
392
+ ?? accessory.addService(this.hap.Service.StatefulProgrammableSwitch) as Service,
393
+ On: accessory.context.On ?? false,
334
394
  };
395
+ this.debugWarnLog(`${this.device.deviceType}: ${accessory.displayName} Displaying as Stateful Programmable Switch`);
396
+
397
+ // Initialize StatefulProgrammableSwitch Characteristics
398
+ this.StatefulProgrammableSwitch.Service
399
+ .setCharacteristic(this.hap.Characteristic.Name, this.StatefulProgrammableSwitch.Name)
400
+ .getCharacteristic(this.hap.Characteristic.ProgrammableSwitchOutputState)
401
+ .onGet(() => {
402
+ return this.StatefulProgrammableSwitch!.On;
403
+ })
404
+ .onSet(this.OnSet.bind(this));
405
+ accessory.context.Name = this.StatefulProgrammableSwitch.Name;
406
+
407
+ // Remove other services
335
408
  this.removeFanService(accessory);
336
409
  this.removeLockService(accessory);
337
410
  this.removeDoorService(accessory);
@@ -341,23 +414,26 @@ export class Bot extends deviceBase {
341
414
  this.removeWindowService(accessory);
342
415
  this.removeGarageDoorService(accessory);
343
416
  this.removeWindowCoveringService(accessory);
344
-
345
- // Add statefulProgrammableSwitchService
346
- const statefulProgrammableSwitchService = `${accessory.displayName} Stateful Programmable Switch`;
347
- (this.StatefulProgrammableSwitch!.Service = accessory.getService(this.hap.Service.StatefulProgrammableSwitch) ||
348
- accessory.addService(this.hap.Service.StatefulProgrammableSwitch)), statefulProgrammableSwitchService;
349
- this.debugWarnLog(`${this.device.deviceType}: ${accessory.displayName} Displaying as Stateful Programmable Switch`);
350
-
351
- this.StatefulProgrammableSwitch!.Service.setCharacteristic(this.hap.Characteristic.Name, accessory.displayName);
352
- this.StatefulProgrammableSwitch!.Service
353
- .getCharacteristic(this.hap.Characteristic.ProgrammableSwitchOutputState)
354
- .onSet(this.OnSet.bind(this));
355
417
  } else {
356
418
  // Initialize Switch property
357
419
  this.Outlet = {
358
- Service: accessory.getService(this.hap.Service.Outlet) as Service,
359
- On: accessory.context.On || false,
420
+ Name: accessory.context.Name ?? accessory.displayName,
421
+ Service: accessory.getService(this.hap.Service.Outlet) ?? accessory.addService(this.hap.Service.Outlet) as Service,
422
+ On: accessory.context.On ?? false,
360
423
  };
424
+ this.debugWarnLog(`${this.device.deviceType}: ${accessory.displayName} Displaying as Outlet`);
425
+
426
+ // Initialize Outlet Characteristics
427
+ this.Outlet.Service
428
+ .setCharacteristic(this.hap.Characteristic.Name, this.Outlet.Name)
429
+ .getCharacteristic(this.hap.Characteristic.On)
430
+ .onGet(() => {
431
+ return this.Outlet!.On;
432
+ })
433
+ .onSet(this.OnSet.bind(this));
434
+ accessory.context.Name = this.Outlet.Name;
435
+
436
+ // Remove other services
361
437
  this.removeFanService(accessory);
362
438
  this.removeLockService(accessory);
363
439
  this.removeDoorService(accessory);
@@ -367,28 +443,11 @@ export class Bot extends deviceBase {
367
443
  this.removeGarageDoorService(accessory);
368
444
  this.removeWindowCoveringService(accessory);
369
445
  this.removeStatefulProgrammableSwitchService(accessory);
370
-
371
- // Add outletService
372
- const outletService = `${accessory.displayName} Outlet`;
373
- (this.Outlet!.Service = accessory.getService(this.hap.Service.Outlet)
374
- || accessory.addService(this.hap.Service.Outlet)), outletService;
375
- this.debugWarnLog(`${this.device.deviceType}: ${accessory.displayName} Displaying as Outlet`);
376
-
377
- this.Outlet!.Service.setCharacteristic(this.hap.Characteristic.Name, accessory.displayName);
378
- this.Outlet!.Service.getCharacteristic(this.hap.Characteristic.On).onSet(this.OnSet.bind(this));
379
446
  }
380
447
 
381
448
  // Retrieve initial values and updateHomekit
382
449
  this.refreshStatus();
383
450
 
384
- // batteryService
385
- const batteryService = `${accessory.displayName} Battery`;
386
- (this.Battery.Service = this.accessory.getService(this.hap.Service.Battery)
387
- || accessory.addService(this.hap.Service.Battery)), batteryService;
388
-
389
- this.Battery.Service.setCharacteristic(this.hap.Characteristic.Name, `${accessory.displayName} Battery`);
390
- this.Battery.Service.setCharacteristic(this.hap.Characteristic.ChargingState, this.hap.Characteristic.ChargingState.NOT_CHARGEABLE);
391
-
392
451
  // Retrieve initial values and updateHomekit
393
452
  this.updateHomeKitCharacteristics();
394
453
 
@@ -834,10 +893,10 @@ export class Bot extends deviceBase {
834
893
  this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Set LockTargetState: ${value}`);
835
894
  if (value === this.hap.Characteristic.LockTargetState.SECURED) {
836
895
  await this.setOn(false);
837
- this.Lock!.On = false;
896
+ this.LockMechanism!.On = false;
838
897
  } else {
839
898
  await this.setOn(true);
840
- this.Lock!.On = true;
899
+ this.LockMechanism!.On = true;
841
900
  }
842
901
  } else if (this.botDeviceType === 'faucet') {
843
902
  this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Set Active: ${value}`);
@@ -964,23 +1023,27 @@ export class Bot extends deviceBase {
964
1023
  await this.setOn(Boolean(this.WindowCovering!.On));
965
1024
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Window Covering On: ${this.WindowCovering!.On}`);
966
1025
  } else if (this.botDeviceType === 'lock') {
967
- if (this.Lock!.On === undefined) {
968
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.Lock!.On}`);
1026
+ if (this.LockMechanism!.On === undefined) {
1027
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.LockMechanism!.On}`);
969
1028
  } else {
970
- if (this.Lock!.On) {
971
- this.Lock!.Service.updateCharacteristic(this.hap.Characteristic.LockTargetState, this.hap.Characteristic.LockTargetState.UNSECURED);
972
- this.Lock!.Service.updateCharacteristic(this.hap.Characteristic.LockCurrentState, this.hap.Characteristic.LockCurrentState.UNSECURED);
1029
+ if (this.LockMechanism!.On) {
1030
+ this.LockMechanism!.Service.updateCharacteristic(this.hap.Characteristic.LockTargetState,
1031
+ this.hap.Characteristic.LockTargetState.UNSECURED);
1032
+ this.LockMechanism!.Service.updateCharacteristic(this.hap.Characteristic.LockCurrentState,
1033
+ this.hap.Characteristic.LockCurrentState.UNSECURED);
973
1034
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristicc`
974
- + ` LockTargetState: UNSECURED, LockCurrentState: UNSECURED (${this.Lock!.On})`);
1035
+ + ` LockTargetState: UNSECURED, LockCurrentState: UNSECURED (${this.LockMechanism!.On})`);
975
1036
  } else {
976
- this.Lock!.Service.updateCharacteristic(this.hap.Characteristic.LockTargetState, this.hap.Characteristic.LockTargetState.SECURED);
977
- this.Lock!.Service.updateCharacteristic(this.hap.Characteristic.LockCurrentState, this.hap.Characteristic.LockCurrentState.SECURED);
1037
+ this.LockMechanism!.Service.updateCharacteristic(this.hap.Characteristic.LockTargetState,
1038
+ this.hap.Characteristic.LockTargetState.SECURED);
1039
+ this.LockMechanism!.Service.updateCharacteristic(this.hap.Characteristic.LockCurrentState,
1040
+ this.hap.Characteristic.LockCurrentState.SECURED);
978
1041
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic`
979
- + ` LockTargetState: SECURED, LockCurrentState: SECURED (${this.Lock!.On})`);
1042
+ + ` LockTargetState: SECURED, LockCurrentState: SECURED (${this.LockMechanism!.On})`);
980
1043
  }
981
1044
  }
982
- await this.setOn(Boolean(this.Lock!.On));
983
- this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Lock On: ${this.Lock!.On}`);
1045
+ await this.setOn(Boolean(this.LockMechanism!.On));
1046
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Lock On: ${this.LockMechanism!.On}`);
984
1047
  } else if (this.botDeviceType === 'faucet') {
985
1048
  if (this.Faucet!.On === undefined) {
986
1049
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.Faucet!.On}`);
@@ -1095,10 +1158,10 @@ export class Bot extends deviceBase {
1095
1158
 
1096
1159
  async removeLockService(accessory: PlatformAccessory): Promise<void> {
1097
1160
  // If lockService still present, then remove first
1098
- if (this.Lock?.Service) {
1099
- this.Lock!.Service = this.accessory.getService(this.hap.Service.LockMechanism) as Service;
1161
+ if (this.LockMechanism?.Service) {
1162
+ this.LockMechanism!.Service = this.accessory.getService(this.hap.Service.LockMechanism) as Service;
1100
1163
  this.warnLog(`${this.device.deviceType}: ${accessory.displayName} Removing Leftover Lock Service`);
1101
- accessory.removeService(this.Lock!.Service);
1164
+ accessory.removeService(this.LockMechanism!.Service);
1102
1165
  }
1103
1166
  }
1104
1167
 
@@ -1167,7 +1230,7 @@ export class Bot extends deviceBase {
1167
1230
  } else if (this.botDeviceType === 'windowcovering') {
1168
1231
  On = this.WindowCovering!.On ? true : false;
1169
1232
  } else if (this.botDeviceType === 'lock') {
1170
- On = this.Lock!.On ? true : false;
1233
+ On = this.LockMechanism!.On ? true : false;
1171
1234
  } else if (this.botDeviceType === 'faucet') {
1172
1235
  On = this.Faucet!.On ? true : false;
1173
1236
  } else if (this.botDeviceType === 'fan') {
@@ -1192,7 +1255,7 @@ export class Bot extends deviceBase {
1192
1255
  } else if (this.botDeviceType === 'windowcovering') {
1193
1256
  this.WindowCovering!.On = On;
1194
1257
  } else if (this.botDeviceType === 'lock') {
1195
- this.Lock!.On = On;
1258
+ this.LockMechanism!.On = On;
1196
1259
  } else if (this.botDeviceType === 'faucet') {
1197
1260
  this.Faucet!.On = On;
1198
1261
  } else if (this.botDeviceType === 'fan') {