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

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 (65) hide show
  1. package/dist/device/blindtilt.d.ts.map +1 -1
  2. package/dist/device/blindtilt.js +4 -2
  3. package/dist/device/blindtilt.js.map +1 -1
  4. package/dist/device/bot.d.ts.map +1 -1
  5. package/dist/device/bot.js +2 -1
  6. package/dist/device/bot.js.map +1 -1
  7. package/dist/device/colorbulb.d.ts.map +1 -1
  8. package/dist/device/colorbulb.js +3 -1
  9. package/dist/device/colorbulb.js.map +1 -1
  10. package/dist/device/curtain.d.ts.map +1 -1
  11. package/dist/device/curtain.js +11 -8
  12. package/dist/device/curtain.js.map +1 -1
  13. package/dist/device/motion.js +1 -1
  14. package/dist/device/motion.js.map +1 -1
  15. package/dist/device/waterdetector.js +4 -4
  16. package/dist/device/waterdetector.js.map +1 -1
  17. package/dist/irdevice/airconditioner.d.ts +1 -1
  18. package/dist/irdevice/airconditioner.d.ts.map +1 -1
  19. package/dist/irdevice/airconditioner.js +65 -83
  20. package/dist/irdevice/airconditioner.js.map +1 -1
  21. package/dist/irdevice/airpurifier.d.ts.map +1 -1
  22. package/dist/irdevice/airpurifier.js +39 -17
  23. package/dist/irdevice/airpurifier.js.map +1 -1
  24. package/dist/irdevice/camera.d.ts.map +1 -1
  25. package/dist/irdevice/camera.js +14 -10
  26. package/dist/irdevice/camera.js.map +1 -1
  27. package/dist/irdevice/fan.d.ts.map +1 -1
  28. package/dist/irdevice/fan.js +27 -14
  29. package/dist/irdevice/fan.js.map +1 -1
  30. package/dist/irdevice/light.d.ts.map +1 -1
  31. package/dist/irdevice/light.js +55 -23
  32. package/dist/irdevice/light.js.map +1 -1
  33. package/dist/irdevice/other.d.ts +1 -1
  34. package/dist/irdevice/other.d.ts.map +1 -1
  35. package/dist/irdevice/other.js +198 -135
  36. package/dist/irdevice/other.js.map +1 -1
  37. package/dist/irdevice/tv.d.ts.map +1 -1
  38. package/dist/irdevice/tv.js +54 -59
  39. package/dist/irdevice/tv.js.map +1 -1
  40. package/dist/irdevice/vacuumcleaner.d.ts.map +1 -1
  41. package/dist/irdevice/vacuumcleaner.js +15 -10
  42. package/dist/irdevice/vacuumcleaner.js.map +1 -1
  43. package/dist/irdevice/waterheater.d.ts.map +1 -1
  44. package/dist/irdevice/waterheater.js +16 -13
  45. package/dist/irdevice/waterheater.js.map +1 -1
  46. package/dist/platform.d.ts.map +1 -1
  47. package/dist/platform.js +5 -8
  48. package/dist/platform.js.map +1 -1
  49. package/package.json +1 -1
  50. package/src/device/blindtilt.ts +4 -2
  51. package/src/device/bot.ts +2 -1
  52. package/src/device/colorbulb.ts +3 -2
  53. package/src/device/curtain.ts +11 -8
  54. package/src/device/motion.ts +1 -1
  55. package/src/device/waterdetector.ts +4 -4
  56. package/src/irdevice/airconditioner.ts +73 -85
  57. package/src/irdevice/airpurifier.ts +46 -21
  58. package/src/irdevice/camera.ts +15 -12
  59. package/src/irdevice/fan.ts +29 -17
  60. package/src/irdevice/light.ts +70 -42
  61. package/src/irdevice/other.ts +230 -153
  62. package/src/irdevice/tv.ts +61 -70
  63. package/src/irdevice/vacuumcleaner.ts +16 -12
  64. package/src/irdevice/waterheater.ts +17 -16
  65. package/src/platform.ts +5 -8
@@ -18,51 +18,61 @@ import type { CharacteristicValue, PlatformAccessory, Service } from 'homebridge
18
18
  export class Others extends irdeviceBase {
19
19
  // Services
20
20
  private Switch?: {
21
+ Name: CharacteristicValue;
21
22
  Service: Service;
22
23
  On: CharacteristicValue;
23
24
  };
24
25
 
25
26
  private GarageDoor?: {
27
+ Name: CharacteristicValue;
26
28
  Service: Service;
27
29
  On: CharacteristicValue;
28
30
  };
29
31
 
30
32
  private Door?: {
33
+ Name: CharacteristicValue;
31
34
  Service: Service;
32
35
  On: CharacteristicValue;
33
36
  };
34
37
 
35
38
  private Window?: {
39
+ Name: CharacteristicValue;
36
40
  Service: Service;
37
41
  On: CharacteristicValue;
38
42
  };
39
43
 
40
44
  private WindowCovering?: {
45
+ Name: CharacteristicValue;
41
46
  Service: Service;
42
47
  On: CharacteristicValue;
43
48
  };
44
49
 
45
- private Lock?: {
50
+ private LockMechanism?: {
51
+ Name: CharacteristicValue;
46
52
  Service: Service;
47
53
  On: CharacteristicValue;
48
54
  };
49
55
 
50
56
  private Faucet?: {
57
+ Name: CharacteristicValue;
51
58
  Service: Service;
52
59
  On: CharacteristicValue;
53
60
  };
54
61
 
55
62
  private Fan?: {
63
+ Name: CharacteristicValue;
56
64
  Service: Service;
57
65
  On: CharacteristicValue;
58
66
  };
59
67
 
60
68
  private StatefulProgrammableSwitch?: {
69
+ Name: CharacteristicValue;
61
70
  Service: Service;
62
71
  On: CharacteristicValue;
63
72
  };
64
73
 
65
74
  private Outlet?: {
75
+ Name: CharacteristicValue;
66
76
  Service: Service;
67
77
  On: CharacteristicValue;
68
78
  };
@@ -82,11 +92,27 @@ export class Others extends irdeviceBase {
82
92
 
83
93
  // deviceType
84
94
  if (this.otherDeviceType === 'switch') {
85
- // Initialize Switch property
95
+ // Initialize Switch Service
96
+ if (!accessory.context.Switch) {
97
+ accessory.context.Switch = {};
98
+ }
86
99
  this.Switch = {
87
- Service: accessory.getService(this.hap.Service.Switch) as Service,
88
- On: accessory.context.On || false,
100
+ Name: accessory.context.Name ?? `${accessory.displayName} Switch`,
101
+ Service: accessory.getService(this.hap.Service.Switch) ?? accessory.addService(this.hap.Service.Switch) as Service,
102
+ On: accessory.context.On ?? false,
89
103
  };
104
+ this.debugWarnLog(`${this.device.remoteType}: ${accessory.displayName} Displaying as Switch`);
105
+
106
+ this.Switch.Service
107
+ .setCharacteristic(this.hap.Characteristic.Name, accessory.displayName)
108
+ .getCharacteristic(this.hap.Characteristic.On)
109
+ .onGet(() => {
110
+ return this.Switch!.On;
111
+ })
112
+ .onSet(this.OnSet.bind(this));
113
+ accessory.context.Name = this.Switch.Name;
114
+
115
+ // Remove other services
90
116
  this.removeFanService(accessory);
91
117
  this.removeLockService(accessory);
92
118
  this.removeDoorService(accessory);
@@ -96,21 +122,29 @@ export class Others extends irdeviceBase {
96
122
  this.removeGarageDoorService(accessory);
97
123
  this.removeWindowCoveringService(accessory);
98
124
  this.removeStatefulProgrammableSwitchService(accessory);
99
-
100
- // Add Switch Service
101
- const SwitchService = `${accessory.displayName} Switch`;
102
- (this.Switch!.Service = accessory.getService(this.hap.Service.Switch) as Service
103
- || accessory.addService(this.hap.Service.Switch)), SwitchService;
104
- this.debugWarnLog(`${this.device.remoteType}: ${accessory.displayName} Displaying as Switch`);
105
-
106
- this.Switch!.Service.setCharacteristic(this.hap.Characteristic.Name, accessory.displayName);
107
- this.Switch!.Service.getCharacteristic(this.hap.Characteristic.On).onSet(this.OnSet.bind(this));
108
125
  } else if (this.otherDeviceType === 'garagedoor') {
109
- // Initialize Garage Door property
126
+ // Initialize Garage Door Service
127
+ if (!accessory.context.GarageDoor) {
128
+ accessory.context.GarageDoor = {};
129
+ }
110
130
  this.GarageDoor = {
111
- Service: accessory.getService(this.hap.Service.GarageDoorOpener) as Service,
112
- On: accessory.context.On || false,
131
+ Name: accessory.context.Name ?? `${accessory.displayName} Garage Door`,
132
+ Service: accessory.getService(this.hap.Service.GarageDoorOpener) ?? accessory.addService(this.hap.Service.GarageDoorOpener) as Service,
133
+ On: accessory.context.On ?? false,
113
134
  };
135
+ this.debugWarnLog(`${this.device.remoteType}: ${accessory.displayName} Displaying as Garage Door Opener`);
136
+
137
+ this.GarageDoor.Service
138
+ .setCharacteristic(this.hap.Characteristic.Name, accessory.displayName)
139
+ .setCharacteristic(this.hap.Characteristic.ObstructionDetected, false)
140
+ .getCharacteristic(this.hap.Characteristic.TargetDoorState)
141
+ .onGet(() => {
142
+ return this.GarageDoor!.On;
143
+ })
144
+ .onSet(this.OnSet.bind(this));
145
+ accessory.context.Name = this.GarageDoor.Name;
146
+
147
+ // Remove other services
114
148
  this.removeFanService(accessory);
115
149
  this.removeLockService(accessory);
116
150
  this.removeDoorService(accessory);
@@ -120,40 +154,21 @@ export class Others extends irdeviceBase {
120
154
  this.removeWindowService(accessory);
121
155
  this.removeWindowCoveringService(accessory);
122
156
  this.removeStatefulProgrammableSwitchService(accessory);
123
-
124
- // Add GarageDoor Service
125
- const GarageDoorService = `${accessory.displayName} Garage Door Opener`;
126
- (this.GarageDoor!.Service = accessory.getService(this.hap.Service.GarageDoorOpener) as Service
127
- || accessory.addService(this.hap.Service.GarageDoorOpener)), GarageDoorService;
128
- this.debugWarnLog(`${this.device.remoteType}: ${accessory.displayName} Displaying as Garage Door Opener`);
129
-
130
- this.GarageDoor!.Service.setCharacteristic(this.hap.Characteristic.Name, accessory.displayName);
131
- this.GarageDoor!.Service.getCharacteristic(this.hap.Characteristic.TargetDoorState).onSet(this.OnSet.bind(this));
132
- this.GarageDoor!.Service.setCharacteristic(this.hap.Characteristic.ObstructionDetected, false);
133
157
  } else if (this.otherDeviceType === 'door') {
134
- // Initialize Door property
158
+ // Initialize Door Service
159
+ if (!accessory.context.Door) {
160
+ accessory.context.Door = {};
161
+ }
135
162
  this.Door = {
136
- Service: accessory.getService(this.hap.Service.Door) as Service,
137
- On: accessory.context.On || false,
163
+ Name: accessory.context.Name ?? `${accessory.displayName} Door`,
164
+ Service: accessory.getService(this.hap.Service.Door) ?? accessory.addService(this.hap.Service.Door) as Service,
165
+ On: accessory.context.On ?? false,
138
166
  };
139
- this.removeFanService(accessory);
140
- this.removeLockService(accessory);
141
- this.removeOutletService(accessory);
142
- this.removeFaucetService(accessory);
143
- this.removeSwitchService(accessory);
144
- this.removeWindowService(accessory);
145
- this.removeGarageDoorService(accessory);
146
- this.removeWindowCoveringService(accessory);
147
- this.removeStatefulProgrammableSwitchService(accessory);
148
-
149
- // Add Door Service
150
- const DoorService = `${accessory.displayName} Door`;
151
- (this.Door!.Service = accessory.getService(this.hap.Service.Door) as Service
152
- || accessory.addService(this.hap.Service.Door)), DoorService;
153
167
  this.debugWarnLog(`${this.device.remoteType}: ${accessory.displayName} Displaying as Door`);
154
168
 
155
- this.Door!.Service.setCharacteristic(this.hap.Characteristic.Name, accessory.displayName);
156
169
  this.Door!.Service
170
+ .setCharacteristic(this.hap.Characteristic.Name, accessory.displayName)
171
+ .setCharacteristic(this.hap.Characteristic.PositionState, this.hap.Characteristic.PositionState.STOPPED)
157
172
  .getCharacteristic(this.hap.Characteristic.TargetPosition)
158
173
  .setProps({
159
174
  validValues: [0, 100],
@@ -161,32 +176,36 @@ export class Others extends irdeviceBase {
161
176
  maxValue: 100,
162
177
  minStep: 100,
163
178
  })
179
+ .onGet(() => {
180
+ return this.GarageDoor!.On;
181
+ })
164
182
  .onSet(this.OnSet.bind(this));
165
- this.Door!.Service.setCharacteristic(this.hap.Characteristic.PositionState, this.hap.Characteristic.PositionState.STOPPED);
166
- } else if (this.otherDeviceType === 'window') {
167
- // Initialize Window property
168
- this.Window = {
169
- Service: accessory.getService(this.hap.Service.Window) as Service,
170
- On: accessory.context.On || false,
171
- };
183
+ accessory.context.Name = this.Door.Name;
184
+
185
+ // Remove other services
172
186
  this.removeFanService(accessory);
173
187
  this.removeLockService(accessory);
174
- this.removeDoorService(accessory);
175
188
  this.removeOutletService(accessory);
176
189
  this.removeFaucetService(accessory);
177
190
  this.removeSwitchService(accessory);
191
+ this.removeWindowService(accessory);
178
192
  this.removeGarageDoorService(accessory);
179
193
  this.removeWindowCoveringService(accessory);
180
194
  this.removeStatefulProgrammableSwitchService(accessory);
181
-
182
- // Add Window Service
183
- const WindowService = `${accessory.displayName} Window`;
184
- (this.Window!.Service = accessory.getService(this.hap.Service.Window) as Service
185
- || accessory.addService(this.hap.Service.Window)), WindowService;
195
+ } else if (this.otherDeviceType === 'window') {
196
+ // Initialize Window Service
197
+ if (!accessory.context.Window) {
198
+ accessory.context.Window = {};
199
+ }
200
+ this.Window = {
201
+ Name: accessory.context.Name ?? `${accessory.displayName} Window`,
202
+ Service: accessory.getService(this.hap.Service.Window) ?? accessory.addService(this.hap.Service.Window) as Service,
203
+ On: accessory.context.On ?? false,
204
+ };
186
205
  this.debugWarnLog(`${this.device.remoteType}: ${accessory.displayName} Displaying as Window`);
187
206
 
188
- this.Window!.Service.setCharacteristic(this.hap.Characteristic.Name, accessory.displayName);
189
- this.Window!.Service
207
+ this.Window!.Service.setCharacteristic(this.hap.Characteristic.Name, accessory.displayName)
208
+ .setCharacteristic(this.hap.Characteristic.PositionState, this.hap.Characteristic.PositionState.STOPPED)
190
209
  .getCharacteristic(this.hap.Characteristic.TargetPosition)
191
210
  .setProps({
192
211
  validValues: [0, 100],
@@ -194,32 +213,36 @@ export class Others extends irdeviceBase {
194
213
  maxValue: 100,
195
214
  minStep: 100,
196
215
  })
216
+ .onGet(() => {
217
+ return this.GarageDoor!.On;
218
+ })
197
219
  .onSet(this.OnSet.bind(this));
198
- this.Window!.Service.setCharacteristic(this.hap.Characteristic.PositionState, this.hap.Characteristic.PositionState.STOPPED);
199
- } else if (this.otherDeviceType === 'windowcovering') {
200
- // Initialize WindowCovering property
201
- this.WindowCovering = {
202
- Service: accessory.getService(this.hap.Service.WindowCovering) as Service,
203
- On: accessory.context.On || false,
204
- };
220
+ accessory.context.Name = this.Window.Name;
221
+
222
+ // Remove other services
205
223
  this.removeFanService(accessory);
206
224
  this.removeLockService(accessory);
207
225
  this.removeDoorService(accessory);
208
226
  this.removeOutletService(accessory);
209
227
  this.removeFaucetService(accessory);
210
228
  this.removeSwitchService(accessory);
211
- this.removeWindowService(accessory);
212
229
  this.removeGarageDoorService(accessory);
230
+ this.removeWindowCoveringService(accessory);
213
231
  this.removeStatefulProgrammableSwitchService(accessory);
214
-
215
- // Add WindowCovering Service
216
- const WindowCoveringService = `${accessory.displayName} Window Covering`;
217
- (this.WindowCovering!.Service = accessory.getService(this.hap.Service.WindowCovering) as Service
218
- || accessory.addService(this.hap.Service.WindowCovering)), WindowCoveringService;
232
+ } else if (this.otherDeviceType === 'windowcovering') {
233
+ // Initialize WindowCovering Service
234
+ if (!accessory.context.WindowCovering) {
235
+ accessory.context.WindowCovering = {};
236
+ }
237
+ this.WindowCovering = {
238
+ Name: accessory.context.Name ?? `${accessory.displayName} Window Covering`,
239
+ Service: accessory.getService(this.hap.Service.WindowCovering) ?? accessory.addService(this.hap.Service.WindowCovering) as Service,
240
+ On: accessory.context.On ?? false,
241
+ };
219
242
  this.debugWarnLog(`${this.device.remoteType}: ${accessory.displayName} Displaying as Window Covering`);
220
243
 
221
- this.WindowCovering!.Service.setCharacteristic(this.hap.Characteristic.Name, accessory.displayName);
222
- this.WindowCovering!.Service
244
+ this.WindowCovering.Service.setCharacteristic(this.hap.Characteristic.Name, accessory.displayName);
245
+ this.WindowCovering.Service
223
246
  .getCharacteristic(this.hap.Characteristic.TargetPosition)
224
247
  .setProps({
225
248
  validValues: [0, 100],
@@ -227,14 +250,45 @@ export class Others extends irdeviceBase {
227
250
  maxValue: 100,
228
251
  minStep: 100,
229
252
  })
253
+ .onGet(() => {
254
+ return this.WindowCovering!.On;
255
+ })
230
256
  .onSet(this.OnSet.bind(this));
231
- this.WindowCovering!.Service.setCharacteristic(this.hap.Characteristic.PositionState, this.hap.Characteristic.PositionState.STOPPED);
257
+ this.WindowCovering.Service.setCharacteristic(this.hap.Characteristic.PositionState, this.hap.Characteristic.PositionState.STOPPED);
258
+ accessory.context.Name = this.WindowCovering.Name;
259
+
260
+ // Remove other services
261
+ this.removeFanService(accessory);
262
+ this.removeLockService(accessory);
263
+ this.removeDoorService(accessory);
264
+ this.removeOutletService(accessory);
265
+ this.removeFaucetService(accessory);
266
+ this.removeSwitchService(accessory);
267
+ this.removeWindowService(accessory);
268
+ this.removeGarageDoorService(accessory);
269
+ this.removeStatefulProgrammableSwitchService(accessory);
232
270
  } else if (this.otherDeviceType === 'lock') {
233
- // Initialize Lock property
234
- this.Lock = {
235
- Service: accessory.getService(this.hap.Service.LockMechanism) as Service,
236
- On: accessory.context.On || false,
271
+ // Initialize Lock Service
272
+ if (!accessory.context.LockMechanism) {
273
+ accessory.context.LockMechanism = {};
274
+ }
275
+ this.LockMechanism = {
276
+ Name: accessory.context.Name ?? `${accessory.displayName} Lock`,
277
+ Service: accessory.getService(this.hap.Service.LockMechanism) ?? accessory.addService(this.hap.Service.LockMechanism) as Service,
278
+ On: accessory.context.On ?? false,
237
279
  };
280
+ this.debugWarnLog(`${this.device.remoteType}: ${accessory.displayName} Displaying as Lock`);
281
+
282
+ this.LockMechanism.Service
283
+ .setCharacteristic(this.hap.Characteristic.Name, accessory.displayName)
284
+ .getCharacteristic(this.hap.Characteristic.LockTargetState)
285
+ .onGet(() => {
286
+ return this.LockMechanism!.On;
287
+ })
288
+ .onSet(this.OnSet.bind(this));
289
+ accessory.context.Name = this.LockMechanism.Name;
290
+
291
+ // Remove other services
238
292
  this.removeFanService(accessory);
239
293
  this.removeDoorService(accessory);
240
294
  this.removeOutletService(accessory);
@@ -244,21 +298,28 @@ export class Others extends irdeviceBase {
244
298
  this.removeGarageDoorService(accessory);
245
299
  this.removeWindowCoveringService(accessory);
246
300
  this.removeStatefulProgrammableSwitchService(accessory);
247
-
248
- // Add Lock Service
249
- const LockService = `${accessory.displayName} Lock`;
250
- (this.Lock!.Service = accessory.getService(this.hap.Service.LockMechanism) as Service
251
- || accessory.addService(this.hap.Service.LockMechanism)), LockService;
252
- this.debugWarnLog(`${this.device.remoteType}: ${accessory.displayName} Displaying as Lock`);
253
-
254
- this.Lock!.Service.setCharacteristic(this.hap.Characteristic.Name, accessory.displayName);
255
- this.Lock!.Service.getCharacteristic(this.hap.Characteristic.LockTargetState).onSet(this.OnSet.bind(this));
256
301
  } else if (this.otherDeviceType === 'faucet') {
257
- // Initialize Faucet property
302
+ // Initialize Faucet Service
303
+ if (!accessory.context.Faucet) {
304
+ accessory.context.Faucet = {};
305
+ }
258
306
  this.Faucet = {
259
- Service: accessory.getService(this.hap.Service.Faucet) as Service,
260
- On: accessory.context.On || false,
307
+ Name: accessory.context.Name ?? `${accessory.displayName} Faucet`,
308
+ Service: accessory.getService(this.hap.Service.Faucet) ?? accessory.addService(this.hap.Service.Faucet) as Service,
309
+ On: accessory.context.On ?? false,
261
310
  };
311
+ this.debugWarnLog(`${this.device.remoteType}: ${accessory.displayName} Displaying as Faucet`);
312
+
313
+ this.Faucet.Service
314
+ .setCharacteristic(this.hap.Characteristic.Name, accessory.displayName)
315
+ .getCharacteristic(this.hap.Characteristic.Active)
316
+ .onGet(() => {
317
+ return this.Faucet!.On;
318
+ })
319
+ .onSet(this.OnSet.bind(this));
320
+ accessory.context.Name = this.Faucet.Name;
321
+
322
+ // Remove other services
262
323
  this.removeFanService(accessory);
263
324
  this.removeLockService(accessory);
264
325
  this.removeDoorService(accessory);
@@ -268,21 +329,28 @@ export class Others extends irdeviceBase {
268
329
  this.removeGarageDoorService(accessory);
269
330
  this.removeWindowCoveringService(accessory);
270
331
  this.removeStatefulProgrammableSwitchService(accessory);
271
-
272
- // Add Faucet Service
273
- const FaucetService = `${accessory.displayName} Faucet`;
274
- (this.Faucet!.Service = accessory.getService(this.hap.Service.Faucet) as Service
275
- || accessory.addService(this.hap.Service.Faucet)), FaucetService;
276
- this.debugWarnLog(`${this.device.remoteType}: ${accessory.displayName} Displaying as Faucet`);
277
-
278
- this.Faucet!.Service.setCharacteristic(this.hap.Characteristic.Name, accessory.displayName);
279
- this.Faucet!.Service.getCharacteristic(this.hap.Characteristic.Active).onSet(this.OnSet.bind(this));
280
332
  } else if (this.otherDeviceType === 'fan') {
281
- // Initialize Fan property
333
+ // Initialize Fan Service
334
+ if (!accessory.context.Fan) {
335
+ accessory.context.Fan = {};
336
+ }
282
337
  this.Fan = {
283
- Service: accessory.getService(this.hap.Service.Fanv2) as Service,
284
- On: accessory.context.On || false,
338
+ Name: accessory.context.Name ?? `${accessory.displayName} Fan`,
339
+ Service: accessory.getService(this.hap.Service.Fanv2) ?? accessory.addService(this.hap.Service.Fanv2) as Service,
340
+ On: accessory.context.On ?? false,
285
341
  };
342
+ this.debugWarnLog(`${this.device.remoteType}: ${accessory.displayName} Displaying as Fan`);
343
+
344
+ this.Fan.Service
345
+ .setCharacteristic(this.hap.Characteristic.Name, accessory.displayName)
346
+ .getCharacteristic(this.hap.Characteristic.On)
347
+ .onGet(() => {
348
+ return this.Fan!.On;
349
+ })
350
+ .onSet(this.OnSet.bind(this));
351
+ accessory.context.Name = this.Fan.Name;
352
+
353
+ // Remove other services
286
354
  this.removeLockService(accessory);
287
355
  this.removeDoorService(accessory);
288
356
  this.removeFaucetService(accessory);
@@ -292,21 +360,30 @@ export class Others extends irdeviceBase {
292
360
  this.removeGarageDoorService(accessory);
293
361
  this.removeWindowCoveringService(accessory);
294
362
  this.removeStatefulProgrammableSwitchService(accessory);
295
-
296
- // Add Fan Service
297
- const FanService = `${accessory.displayName} Fan`;
298
- (this.Fan!.Service = accessory.getService(this.hap.Service.Fanv2) as Service
299
- || accessory.addService(this.hap.Service.Fanv2)), FanService;
300
- this.debugWarnLog(`${this.device.remoteType}: ${accessory.displayName} Displaying as Fan`);
301
-
302
- this.Fan!.Service.setCharacteristic(this.hap.Characteristic.Name, accessory.displayName);
303
- this.Fan!.Service.getCharacteristic(this.hap.Characteristic.On).onSet(this.OnSet.bind(this));
304
363
  } else if (this.otherDeviceType === 'stateful') {
364
+ // Initialize Lock Service
365
+ if (!accessory.context.StatefulProgrammableSwitch) {
366
+ accessory.context.StatefulProgrammableSwitch = {};
367
+ }
305
368
  // Initialize StatefulProgrammableSwitch property
306
369
  this.StatefulProgrammableSwitch = {
307
- Service: accessory.getService(this.hap.Service.StatefulProgrammableSwitch) as Service,
308
- On: accessory.context.On || false,
370
+ Name: accessory.context.Name ?? `${accessory.displayName} Stateful Programmable Switch`,
371
+ Service: accessory.getService(this.hap.Service.StatefulProgrammableSwitch)
372
+ ?? accessory.addService(this.hap.Service.StatefulProgrammableSwitch) as Service,
373
+ On: accessory.context.On ?? false,
309
374
  };
375
+ this.debugWarnLog(`${this.device.remoteType}: ${accessory.displayName} Displaying as Stateful Programmable Switch`);
376
+
377
+ this.StatefulProgrammableSwitch.Service
378
+ .setCharacteristic(this.hap.Characteristic.Name, accessory.displayName)
379
+ .getCharacteristic(this.hap.Characteristic.ProgrammableSwitchOutputState)
380
+ .onGet(() => {
381
+ return this.StatefulProgrammableSwitch!.On;
382
+ })
383
+ .onSet(this.OnSet.bind(this));
384
+ accessory.context.Name = this.StatefulProgrammableSwitch.Name;
385
+
386
+ // Remove other services
310
387
  this.removeFanService(accessory);
311
388
  this.removeLockService(accessory);
312
389
  this.removeDoorService(accessory);
@@ -316,23 +393,28 @@ export class Others extends irdeviceBase {
316
393
  this.removeWindowService(accessory);
317
394
  this.removeGarageDoorService(accessory);
318
395
  this.removeWindowCoveringService(accessory);
319
-
320
- // Add StatefulProgrammableSwitch.Service
321
- const StatefulProgrammableSwitchService = `${accessory.displayName} Stateful Programmable Switch`;
322
- (this.StatefulProgrammableSwitch!.Service = accessory.getService(this.hap.Service.StatefulProgrammableSwitch) as Service
323
- || accessory.addService(this.hap.Service.StatefulProgrammableSwitch)), StatefulProgrammableSwitchService;
324
- this.debugWarnLog(`${this.device.remoteType}: ${accessory.displayName} Displaying as Stateful Programmable Switch`);
325
-
326
- this.StatefulProgrammableSwitch!.Service.setCharacteristic(this.hap.Characteristic.Name, accessory.displayName);
327
- this.StatefulProgrammableSwitch!.Service
328
- .getCharacteristic(this.hap.Characteristic.ProgrammableSwitchOutputState)
329
- .onSet(this.OnSet.bind(this));
330
396
  } else {
331
- // Initialize Outlet property
397
+ // Initialize Outlet Service
398
+ if (!accessory.context.Outlet) {
399
+ accessory.context.Outlet = {};
400
+ }
332
401
  this.Outlet = {
333
- Service: accessory.getService(this.hap.Service.Outlet) as Service,
334
- On: accessory.context.On || false,
402
+ Name: accessory.context.Name ?? `${accessory.displayName} Outlet`,
403
+ Service: accessory.getService(this.hap.Service.Outlet) ?? accessory.addService(this.hap.Service.Outlet) as Service,
404
+ On: accessory.context.On ?? false,
335
405
  };
406
+ this.debugWarnLog(`${this.device.remoteType}: ${accessory.displayName} Displaying as Outlet`);
407
+
408
+ this.Outlet.Service
409
+ .setCharacteristic(this.hap.Characteristic.Name, accessory.displayName)
410
+ .getCharacteristic(this.hap.Characteristic.On)
411
+ .onGet(() => {
412
+ return this.Outlet!.On;
413
+ })
414
+ .onSet(this.OnSet.bind(this));
415
+ accessory.context.Name = this.Outlet.Name;
416
+
417
+ // Remove other services
336
418
  this.removeFanService(accessory);
337
419
  this.removeLockService(accessory);
338
420
  this.removeDoorService(accessory);
@@ -342,15 +424,6 @@ export class Others extends irdeviceBase {
342
424
  this.removeGarageDoorService(accessory);
343
425
  this.removeWindowCoveringService(accessory);
344
426
  this.removeStatefulProgrammableSwitchService(accessory);
345
-
346
- // Add Outlet.Service
347
- const OutletService = `${accessory.displayName} Outlet`;
348
- (this.Outlet!.Service = accessory.getService(this.hap.Service.Outlet) as Service
349
- || accessory.addService(this.hap.Service.Outlet)), OutletService;
350
- this.debugWarnLog(`${this.device.remoteType}: ${accessory.displayName} Displaying as Outlet`);
351
-
352
- this.Outlet!.Service.setCharacteristic(this.hap.Characteristic.Name, accessory.displayName);
353
- this.Outlet!.Service.getCharacteristic(this.hap.Characteristic.On).onSet(this.OnSet.bind(this));
354
427
  }
355
428
  }
356
429
 
@@ -394,11 +467,11 @@ export class Others extends irdeviceBase {
394
467
  } else if (this.otherDeviceType === 'lock') {
395
468
  this.infoLog(`${this.device.remoteType}: ${this.accessory.displayName} Set LockTargetState: ${value}`);
396
469
  if (value === this.hap.Characteristic.LockTargetState.SECURED) {
397
- this.Lock!.On = false;
470
+ this.LockMechanism!.On = false;
398
471
  } else {
399
- this.Lock!.On = true;
472
+ this.LockMechanism!.On = true;
400
473
  }
401
- On = this.Lock!.On;
474
+ On = this.LockMechanism!.On;
402
475
  } else if (this.otherDeviceType === 'faucet') {
403
476
  this.infoLog(`${this.device.remoteType}: ${this.accessory.displayName} Set Active: ${value}`);
404
477
  if (value === this.hap.Characteristic.Active.INACTIVE) {
@@ -589,22 +662,26 @@ export class Others extends irdeviceBase {
589
662
  }
590
663
  this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Window Covering On: ${this.WindowCovering!.On}`);
591
664
  } else if (this.otherDeviceType === 'lock') {
592
- if (this.Lock!.On === undefined) {
593
- this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} On: ${this.Lock!.On}`);
665
+ if (this.LockMechanism?.On === undefined) {
666
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} On: ${this.LockMechanism?.On}`);
594
667
  } else {
595
- if (this.Lock!.On) {
596
- this.Lock!.Service.updateCharacteristic(this.hap.Characteristic.LockTargetState, this.hap.Characteristic.LockTargetState.UNSECURED);
597
- this.Lock!.Service.updateCharacteristic(this.hap.Characteristic.LockCurrentState, this.hap.Characteristic.LockCurrentState.UNSECURED);
668
+ if (this.LockMechanism.On) {
669
+ this.LockMechanism.Service.updateCharacteristic(this.hap.Characteristic.LockTargetState,
670
+ this.hap.Characteristic.LockTargetState.UNSECURED);
671
+ this.LockMechanism.Service.updateCharacteristic(this.hap.Characteristic.LockCurrentState,
672
+ this.hap.Characteristic.LockCurrentState.UNSECURED);
598
673
  this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} updateCharacteristic`
599
- + ` LockTargetState: UNSECURED, LockCurrentState: UNSECURE (${this.Lock!.On})`);
674
+ + ` LockTargetState: UNSECURED, LockCurrentState: UNSECURE (${this.LockMechanism.On})`);
600
675
  } else {
601
- this.Lock!.Service.updateCharacteristic(this.hap.Characteristic.LockTargetState, this.hap.Characteristic.LockTargetState.SECURED);
602
- this.Lock!.Service.updateCharacteristic(this.hap.Characteristic.LockCurrentState, this.hap.Characteristic.LockCurrentState.SECURED);
676
+ this.LockMechanism.Service.updateCharacteristic(this.hap.Characteristic.LockTargetState,
677
+ this.hap.Characteristic.LockTargetState.SECURED);
678
+ this.LockMechanism.Service.updateCharacteristic(this.hap.Characteristic.LockCurrentState,
679
+ this.hap.Characteristic.LockCurrentState.SECURED);
603
680
  this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} updateCharacteristic`
604
- + ` LockTargetState: SECURED, LockCurrentState: SECURED (${this.Lock!.On})`);
681
+ + ` LockTargetState: SECURED, LockCurrentState: SECURED (${this.LockMechanism.On})`);
605
682
  }
606
683
  }
607
- this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Lock On: ${this.Lock!.On}`);
684
+ this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} Lock On: ${this.LockMechanism?.On}`);
608
685
  } else if (this.otherDeviceType === 'faucet') {
609
686
  if (this.Faucet!.On === undefined) {
610
687
  this.debugLog(`${this.device.remoteType}: ${this.accessory.displayName} On: ${this.Faucet!.On}`);
@@ -730,10 +807,10 @@ export class Others extends irdeviceBase {
730
807
 
731
808
  async removeLockService(accessory: PlatformAccessory): Promise<void> {
732
809
  // If Lock.Service still present, then remove first
733
- if (this.Lock?.Service) {
734
- this.Lock!.Service = this.accessory.getService(this.hap.Service.LockMechanism) as Service;
810
+ if (this.LockMechanism?.Service) {
811
+ this.LockMechanism!.Service = this.accessory.getService(this.hap.Service.LockMechanism) as Service;
735
812
  this.warnLog(`${this.device.remoteType}: ${accessory.displayName} Removing Leftover Lock Service`);
736
- accessory.removeService(this.Lock!.Service);
813
+ accessory.removeService(this.LockMechanism!.Service);
737
814
  }
738
815
  }
739
816