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