@homebridge-plugins/homebridge-ewelink 12.3.3

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 (113) hide show
  1. package/CHANGELOG.md +1363 -0
  2. package/LICENSE +21 -0
  3. package/README.md +68 -0
  4. package/config.schema.json +1757 -0
  5. package/eslint.config.js +15 -0
  6. package/lib/connection/api.js +508 -0
  7. package/lib/connection/http.js +304 -0
  8. package/lib/connection/lan.js +318 -0
  9. package/lib/connection/ws.js +414 -0
  10. package/lib/device/curtain.js +324 -0
  11. package/lib/device/diffuser.js +473 -0
  12. package/lib/device/fan.js +349 -0
  13. package/lib/device/group.js +106 -0
  14. package/lib/device/humidifier.js +199 -0
  15. package/lib/device/index.js +61 -0
  16. package/lib/device/light-cct.js +333 -0
  17. package/lib/device/light-dimmer.js +257 -0
  18. package/lib/device/light-rgb-cct.js +809 -0
  19. package/lib/device/light-rgb.js +272 -0
  20. package/lib/device/motor.js +363 -0
  21. package/lib/device/outlet-multi.js +417 -0
  22. package/lib/device/outlet-single-inched.js +409 -0
  23. package/lib/device/outlet-single.js +384 -0
  24. package/lib/device/panel.js +382 -0
  25. package/lib/device/rf-bridge.js +321 -0
  26. package/lib/device/rf-button.js +125 -0
  27. package/lib/device/rf-sensor.js +173 -0
  28. package/lib/device/sensor-ambient.js +311 -0
  29. package/lib/device/sensor-contact.js +140 -0
  30. package/lib/device/sensor-temp-humi.js +182 -0
  31. package/lib/device/simulation/blind.js +253 -0
  32. package/lib/device/simulation/cooler.js +312 -0
  33. package/lib/device/simulation/door.js +253 -0
  34. package/lib/device/simulation/doorbell.js +190 -0
  35. package/lib/device/simulation/garage-eachen.js +235 -0
  36. package/lib/device/simulation/garage-four.js +176 -0
  37. package/lib/device/simulation/garage-od-switch.js +36 -0
  38. package/lib/device/simulation/garage-one.js +395 -0
  39. package/lib/device/simulation/garage-two.js +394 -0
  40. package/lib/device/simulation/gate-one.js +327 -0
  41. package/lib/device/simulation/heater.js +389 -0
  42. package/lib/device/simulation/index.js +75 -0
  43. package/lib/device/simulation/light-fan.js +258 -0
  44. package/lib/device/simulation/lock-eachen.js +163 -0
  45. package/lib/device/simulation/lock-one.js +366 -0
  46. package/lib/device/simulation/p-button.js +223 -0
  47. package/lib/device/simulation/purifier.js +289 -0
  48. package/lib/device/simulation/rf-blind.js +192 -0
  49. package/lib/device/simulation/rf-door.js +180 -0
  50. package/lib/device/simulation/rf-window.js +180 -0
  51. package/lib/device/simulation/sensor-hidden.js +105 -0
  52. package/lib/device/simulation/sensor-leak.js +123 -0
  53. package/lib/device/simulation/sensor-visible.js +231 -0
  54. package/lib/device/simulation/sensor.js +300 -0
  55. package/lib/device/simulation/switch-valve.js +351 -0
  56. package/lib/device/simulation/tap-one.js +283 -0
  57. package/lib/device/simulation/tap-two.js +266 -0
  58. package/lib/device/simulation/th-cooler.js +443 -0
  59. package/lib/device/simulation/th-dehumidifier.js +424 -0
  60. package/lib/device/simulation/th-heater.js +449 -0
  61. package/lib/device/simulation/th-humidifier.js +424 -0
  62. package/lib/device/simulation/th-thermostat.js +611 -0
  63. package/lib/device/simulation/tv.js +252 -0
  64. package/lib/device/simulation/valve-four.js +232 -0
  65. package/lib/device/simulation/valve-one.js +345 -0
  66. package/lib/device/simulation/valve-two.js +340 -0
  67. package/lib/device/simulation/window.js +253 -0
  68. package/lib/device/switch-man.js +106 -0
  69. package/lib/device/switch-mate.js +82 -0
  70. package/lib/device/switch-multi.js +411 -0
  71. package/lib/device/switch-single-inched.js +332 -0
  72. package/lib/device/switch-single.js +307 -0
  73. package/lib/device/template.js +43 -0
  74. package/lib/device/thermostat.js +286 -0
  75. package/lib/device/zigbee/index.js +27 -0
  76. package/lib/device/zigbee/light-cct.js +263 -0
  77. package/lib/device/zigbee/light-dimmer.js +148 -0
  78. package/lib/device/zigbee/light-rgb-cct.js +400 -0
  79. package/lib/device/zigbee/motor.js +301 -0
  80. package/lib/device/zigbee/sensor-ambient.js +177 -0
  81. package/lib/device/zigbee/sensor-contact.js +137 -0
  82. package/lib/device/zigbee/sensor-leak.js +119 -0
  83. package/lib/device/zigbee/sensor-motion.js +119 -0
  84. package/lib/device/zigbee/sensor-occupancy.js +119 -0
  85. package/lib/device/zigbee/sensor-smoke.js +96 -0
  86. package/lib/device/zigbee/switch-stateless.js +104 -0
  87. package/lib/device/zigbee/thermostat.js +323 -0
  88. package/lib/fakegato/LICENSE +21 -0
  89. package/lib/fakegato/fakegato-history.js +813 -0
  90. package/lib/fakegato/fakegato-storage.js +108 -0
  91. package/lib/fakegato/fakegato-timer.js +125 -0
  92. package/lib/fakegato/uuid.js +27 -0
  93. package/lib/homebridge-ui/public/index.html +365 -0
  94. package/lib/homebridge-ui/server.js +46 -0
  95. package/lib/index.js +7 -0
  96. package/lib/node-dns-sd/LICENSE +21 -0
  97. package/lib/node-dns-sd/README.md +613 -0
  98. package/lib/node-dns-sd/lib/dns-sd-classes.json +6 -0
  99. package/lib/node-dns-sd/lib/dns-sd-composer.js +83 -0
  100. package/lib/node-dns-sd/lib/dns-sd-parser.js +344 -0
  101. package/lib/node-dns-sd/lib/dns-sd-types.json +52 -0
  102. package/lib/node-dns-sd/lib/dns-sd.js +580 -0
  103. package/lib/platform.js +2156 -0
  104. package/lib/utils/colour.js +552 -0
  105. package/lib/utils/constants.js +589 -0
  106. package/lib/utils/custom-chars.js +33 -0
  107. package/lib/utils/eve-chars.js +130 -0
  108. package/lib/utils/functions.js +42 -0
  109. package/lib/utils/lang-en.js +160 -0
  110. package/lib/utils/lang-fr.js +163 -0
  111. package/lib/utils/lang-th.js +160 -0
  112. package/lib/utils/lang.js +5 -0
  113. package/package.json +75 -0
@@ -0,0 +1,473 @@
1
+ import { hs2rgb, rgb2hs } from '../utils/colour.js'
2
+ import { generateRandomString, hasProperty, sleep } from '../utils/functions.js'
3
+
4
+ export default class {
5
+ constructor(platform, accessory) {
6
+ // Set up variables from the platform
7
+ this.hapChar = platform.api.hap.Characteristic
8
+ this.hapErr = platform.api.hap.HapStatusError
9
+ this.hapServ = platform.api.hap.Service
10
+ this.lang = platform.lang
11
+ this.log = platform.log
12
+ this.platform = platform
13
+
14
+ // Set up variables from the accessory
15
+ this.name = accessory.displayName
16
+ this.accessory = accessory
17
+
18
+ // Initially set the online flag as true (to be then updated as false if necessary)
19
+ this.isOnline = true
20
+
21
+ // Set up custom variables for this device type
22
+ const deviceConf = platform.deviceConf[accessory.context.eweDeviceId] || {}
23
+
24
+ // Set the correct logging variables for this accessory
25
+ switch (deviceConf.overrideLogging) {
26
+ case 'standard':
27
+ this.enableLogging = true
28
+ this.enableDebugLogging = false
29
+ break
30
+ case 'debug':
31
+ this.enableLogging = true
32
+ this.enableDebugLogging = true
33
+ break
34
+ case 'disable':
35
+ this.enableLogging = false
36
+ this.enableDebugLogging = false
37
+ break
38
+ default:
39
+ this.enableLogging = !platform.config.disableDeviceLogging
40
+ this.enableDebugLogging = platform.config.debug
41
+ break
42
+ }
43
+
44
+ // Add the fan service if it doesn't already exist
45
+ this.fanService = this.accessory.getService('Diffuser')
46
+ || this.accessory.addService(this.hapServ.Fan, 'Diffuser', 'diffuser')
47
+
48
+ // Add the lightbulb service if it doesn't already exist
49
+ this.lightService = this.accessory.getService('Light')
50
+ || this.accessory.addService(this.hapServ.Lightbulb, 'Light', 'light')
51
+
52
+ // Add the set handler to the fan on/off characteristic
53
+ this.fanService
54
+ .getCharacteristic(this.hapChar.On)
55
+ .onSet(async value => this.internalDiffuserOnOffUpdate(value))
56
+
57
+ // Add the set handler to the fan rotation characteristic
58
+ this.fanService
59
+ .getCharacteristic(this.hapChar.RotationSpeed)
60
+ .setProps({ minStep: 50 })
61
+ .onSet(async value => this.internalDiffuserSpeedUpdate(value))
62
+
63
+ // Add the set handler to the lightbulb on/off characteristic
64
+ this.lightService
65
+ .getCharacteristic(this.hapChar.On)
66
+ .onSet(async value => this.internalLightStateUpdate(value))
67
+
68
+ // Add the set handler to the lightbulb brightness characteristic
69
+ this.lightService
70
+ .getCharacteristic(this.hapChar.Brightness)
71
+ .onSet(async value => this.internalLightBrightnessUpdate(value))
72
+
73
+ // Add the set handler to the lightbulb hue characteristic
74
+ this.lightService
75
+ .getCharacteristic(this.hapChar.Hue)
76
+ .onSet(async value => this.internalLightColourUpdate(value))
77
+
78
+ // Add the get handlers only if the user hasn't disabled the disableNoResponse setting
79
+ if (!platform.config.disableNoResponse) {
80
+ this.fanService.getCharacteristic(this.hapChar.On).onGet(() => {
81
+ if (!this.isOnline) {
82
+ throw new this.hapErr(-70402)
83
+ }
84
+ return this.fanService.getCharacteristic(this.hapChar.On).value
85
+ })
86
+ this.fanService.getCharacteristic(this.hapChar.RotationSpeed).onGet(() => {
87
+ if (!this.isOnline) {
88
+ throw new this.hapErr(-70402)
89
+ }
90
+ return this.fanService.getCharacteristic(this.hapChar.RotationSpeed).value
91
+ })
92
+ this.lightService.getCharacteristic(this.hapChar.On).onGet(() => {
93
+ if (!this.isOnline) {
94
+ throw new this.hapErr(-70402)
95
+ }
96
+ return this.lightService.getCharacteristic(this.hapChar.On).value
97
+ })
98
+ this.lightService.getCharacteristic(this.hapChar.Brightness).onGet(() => {
99
+ if (!this.isOnline) {
100
+ throw new this.hapErr(-70402)
101
+ }
102
+ return this.lightService.getCharacteristic(this.hapChar.Brightness).value
103
+ })
104
+ this.lightService.getCharacteristic(this.hapChar.Hue).onGet(() => {
105
+ if (!this.isOnline) {
106
+ throw new this.hapErr(-70402)
107
+ }
108
+ return this.lightService.getCharacteristic(this.hapChar.Hue).value
109
+ })
110
+ }
111
+
112
+ // Output the customised options to the log
113
+ const normalLogging = this.enableLogging ? 'standard' : 'disable'
114
+ const opts = JSON.stringify({
115
+ logging: this.enableDebugLogging ? 'debug' : normalLogging,
116
+ })
117
+ this.log('[%s] %s %s.', this.name, this.lang.devInitOpts, opts)
118
+ }
119
+
120
+ async internalDiffuserOnOffUpdate(value) {
121
+ try {
122
+ // Don't continue if the requested new state is the same as the current state
123
+ const newValue = value ? 'on' : 'off'
124
+ if (this.cacheState === newValue) {
125
+ return
126
+ }
127
+
128
+ // Create the params object to send
129
+ const params = { switch: newValue }
130
+
131
+ // Set up a five second timeout for the plugin to ignore incoming updates
132
+ const timerKey = generateRandomString(5)
133
+ this.updateTimeout = timerKey
134
+ setTimeout(() => {
135
+ if (this.updateTimeout === timerKey) {
136
+ this.updateTimeout = false
137
+ }
138
+ }, 5000)
139
+
140
+ // Send the device update
141
+ await this.platform.sendDeviceUpdate(this.accessory, params)
142
+
143
+ // Update the cache with the new state
144
+ this.cacheState = newValue
145
+
146
+ // Log the update if appropriate
147
+ if (this.enableLogging) {
148
+ this.log('[%s] %s [%s].', this.name, this.lang.curState, this.cacheState)
149
+ }
150
+ } catch (err) {
151
+ // Catch any errors and let the platform display them
152
+ this.platform.deviceUpdateError(this.accessory, err, true)
153
+ setTimeout(() => {
154
+ this.fanService.updateCharacteristic(this.hapChar.On, this.cacheState === 'on')
155
+ }, 2000)
156
+ throw new this.hapErr(-70402)
157
+ }
158
+ }
159
+
160
+ async internalDiffuserSpeedUpdate(value) {
161
+ try {
162
+ // Don't continue if turning off as this will be handled by on/off handler
163
+ if (value === 0) {
164
+ return
165
+ }
166
+
167
+ // The new speed can be {50, 100} so use rounding on the new value
168
+ const newValue = value <= 50 ? 50 : 100
169
+
170
+ // Check the rounded speed against the current cache value
171
+ if (newValue === this.cacheSpeed) {
172
+ return
173
+ }
174
+
175
+ // Create the params object, mapping the state to {50, 100} -> {1, 2}
176
+ const params = { state: newValue / 50 }
177
+
178
+ // This acts like a debounce function when endlessly sliding the brightness scale
179
+ const updateKeySpeed = generateRandomString(5)
180
+ this.updateKeySpeed = updateKeySpeed
181
+ await sleep(450)
182
+ if (updateKeySpeed !== this.updateKeySpeed) {
183
+ return
184
+ }
185
+
186
+ // Set up a five second timeout for the plugin to ignore incoming updates
187
+ this.updateTimeout = updateKeySpeed
188
+ setTimeout(() => {
189
+ if (this.updateTimeout === updateKeySpeed) {
190
+ this.updateTimeout = false
191
+ }
192
+ }, 5000)
193
+
194
+ // Send the device update
195
+ await this.platform.sendDeviceUpdate(this.accessory, params)
196
+
197
+ // Update the cache value with the new speed
198
+ this.cacheSpeed = newValue
199
+
200
+ // Log the update if appropriate
201
+ if (this.enableLogging) {
202
+ this.log('[%s] %s [%s%].', this.name, this.lang.curSpeed, this.cacheSpeed)
203
+ }
204
+ } catch (err) {
205
+ // Catch any errors and let the platform display them
206
+ this.platform.deviceUpdateError(this.accessory, err, true)
207
+ setTimeout(() => {
208
+ this.fanService.updateCharacteristic(this.hapChar.RotationSpeed, this.cacheSpeed)
209
+ }, 2000)
210
+ throw new this.hapErr(-70402)
211
+ }
212
+ }
213
+
214
+ async internalLightStateUpdate(value) {
215
+ try {
216
+ // Don't continue if the new value is the same as before
217
+ const newValue = value ? 1 : 0
218
+ if (this.cacheLight === newValue) {
219
+ return
220
+ }
221
+
222
+ // Create the params object
223
+ const params = { lightswitch: this.cacheLight }
224
+
225
+ // Set up a five second timeout for the plugin to ignore incoming updates
226
+ const updateKeyLight = generateRandomString(5)
227
+ this.updateTimeout = updateKeyLight
228
+ setTimeout(() => {
229
+ if (this.updateTimeout === updateKeyLight) {
230
+ this.updateTimeout = false
231
+ }
232
+ }, 5000)
233
+
234
+ // Send the device update
235
+ await this.platform.sendDeviceUpdate(this.accessory, params)
236
+
237
+ // Update the cache value
238
+ this.cacheLight = newValue
239
+
240
+ // Log the update if appropriate
241
+ if (this.enableLogging) {
242
+ this.log('[%s] %s [%s%].', this.name, this.lang.curLight, value === 1 ? 'on' : 'off')
243
+ }
244
+ } catch (err) {
245
+ // Catch any errors and let the platform display them
246
+ this.platform.deviceUpdateError(this.accessory, err, true)
247
+ setTimeout(() => {
248
+ this.lightService.updateCharacteristic(this.hapChar.On, this.cacheLight === 'on')
249
+ }, 2000)
250
+ throw new this.hapErr(-70402)
251
+ }
252
+ }
253
+
254
+ async internalLightBrightnessUpdate(value) {
255
+ try {
256
+ // Don't continue if the new value is the same as before
257
+ if (this.cacheBright === value) {
258
+ return
259
+ }
260
+
261
+ // Create the params object
262
+ const params = { lightbright: value }
263
+
264
+ // This acts like a debounce function when endlessly sliding the brightness scale
265
+ const updateKeyBright = generateRandomString(5)
266
+ this.updateKeyBright = updateKeyBright
267
+ await sleep(500)
268
+ if (updateKeyBright !== this.updateKeyBright) {
269
+ return
270
+ }
271
+
272
+ // Set up a five second timeout for the plugin to ignore incoming updates
273
+ this.updateTimeout = updateKeyBright
274
+ setTimeout(() => {
275
+ if (this.updateTimeout === updateKeyBright) {
276
+ this.updateTimeout = false
277
+ }
278
+ }, 5000)
279
+
280
+ // Send the device update
281
+ await this.platform.sendDeviceUpdate(this.accessory, params)
282
+
283
+ // Update the cache value
284
+ this.cacheBright = value
285
+
286
+ // Log the update if appropriate
287
+ if (this.enableLogging) {
288
+ this.log('[%s] %s [%s%].', this.name, this.lang.curBright, this.cacheBright)
289
+ }
290
+ } catch (err) {
291
+ // Catch any errors and let the platform display them
292
+ this.platform.deviceUpdateError(this.accessory, err, true)
293
+ setTimeout(() => {
294
+ this.lightService.updateCharacteristic(this.hapChar.Brightness, this.cacheBright)
295
+ }, 2000)
296
+ throw new this.hapErr(-70402)
297
+ }
298
+ }
299
+
300
+ async internalLightColourUpdate(value) {
301
+ try {
302
+ // Don't continue if the light is off or the new value is the same as before
303
+ if (this.cacheState !== 'on' || this.cacheHue === value) {
304
+ return
305
+ }
306
+
307
+ // Create the params object
308
+ const sat = this.lightService.getCharacteristic(this.hapChar.Saturation).value
309
+ const newRGB = hs2rgb(value, sat)
310
+ const params = {
311
+ lightRcolor: newRGB[0],
312
+ lightGcolor: newRGB[1],
313
+ lightBcolor: newRGB[2],
314
+ }
315
+
316
+ // This acts like a debounce function when endlessly sliding the colour wheel
317
+ const updateKeyColour = generateRandomString(5)
318
+ this.updateKeyColour = updateKeyColour
319
+ await sleep(400)
320
+ if (updateKeyColour !== this.updateKeyColour) {
321
+ return
322
+ }
323
+
324
+ // Set up a five second timeout for the plugin to ignore incoming updates
325
+ this.updateTimeout = updateKeyColour
326
+ setTimeout(() => {
327
+ if (this.updateTimeout === updateKeyColour) {
328
+ this.updateTimeout = false
329
+ }
330
+ }, 5000)
331
+
332
+ // Send the device update
333
+ await this.platform.sendDeviceUpdate(this.accessory, params)
334
+
335
+ // Update the cache values
336
+ this.cacheHue = value;
337
+ [this.cacheR, this.cacheG, this.cacheB] = newRGB
338
+
339
+ // Log the update if appropriate
340
+ if (this.enableLogging) {
341
+ this.log(
342
+ '[%s] %s [rgb %s].',
343
+ this.name,
344
+ this.lang.curColour,
345
+ `${this.cacheR} ${this.cacheG} ${this.cacheB}`,
346
+ )
347
+ }
348
+ } catch (err) {
349
+ // Catch any errors and let the platform display them
350
+ this.platform.deviceUpdateError(this.accessory, err, true)
351
+ setTimeout(() => {
352
+ this.lightService.updateCharacteristic(this.hapChar.Hue, this.cacheHue)
353
+ }, 2000)
354
+ throw new this.hapErr(-70402)
355
+ }
356
+ }
357
+
358
+ async externalUpdate(params) {
359
+ try {
360
+ // We can often receive old info when updating new values so ignore during timeout
361
+ if (this.updateTimeout) {
362
+ return
363
+ }
364
+
365
+ // Check to see if we are provided new and different on/off information
366
+ if (params.switch && params.switch !== this.cacheState) {
367
+ // Update the cache value
368
+ this.cacheState = params.switch
369
+
370
+ // Update the HomeKit value
371
+ this.fanService.updateCharacteristic(this.hapChar.On, this.cacheState === 'on')
372
+
373
+ // If the diffuser is on but no speed provided, then update speed with the cache
374
+ if (this.cacheState === 'on' && !hasProperty(params, 'state')) {
375
+ this.fanService.updateCharacteristic(this.hapChar.RotationSpeed, this.cacheSpeed)
376
+ }
377
+
378
+ // Log if appropriate
379
+ if (params.updateSource && this.enableLogging) {
380
+ this.log('[%s] %s [%s%].', this.name, this.lang.curState, this.cacheState)
381
+ }
382
+ }
383
+
384
+ // Check to see if we are provided new and different speed information
385
+ if (hasProperty(params, 'state') && params.state * 50 !== this.cacheSpeed) {
386
+ // State is {0, 1, 2} corresponding to {0, 50, 100} rotation speed
387
+ this.cacheSpeed = params.state * 50
388
+
389
+ // Update the HomeKit value
390
+ this.fanService.updateCharacteristic(this.hapChar.RotationSpeed, this.cacheSpeed)
391
+
392
+ // Log if appropriate
393
+ if (params.updateSource && this.enableLogging) {
394
+ this.log('[%s] %s [%s%].', this.name, this.lang.curSpeed, this.cacheSpeed)
395
+ }
396
+ }
397
+
398
+ // Check to see if we are provided new and different light on/off information
399
+ if (hasProperty(params, 'lightswitch') && this.cacheLight !== params.lightswitch) {
400
+ // Lightswitch is {0, 1} corresponding to {false, true} off/on state
401
+ this.cacheLight = params.lightswitch
402
+
403
+ // Update the HomeKit value
404
+ this.lightService.updateCharacteristic(this.hapChar.On, params.lightswitch === 1)
405
+
406
+ // Log if appropriate
407
+ if (params.updateSource && this.enableLogging) {
408
+ this.log(
409
+ '[%s] %s [%s%].',
410
+ this.name,
411
+ this.lang.curLight,
412
+ params.lightswitch === 1 ? 'on' : 'off',
413
+ )
414
+ }
415
+ }
416
+
417
+ // Check to see if we are provided new and different light brightness information
418
+ if (
419
+ hasProperty(params, 'lightbright')
420
+ && this.cacheBright !== params.lightbright
421
+ ) {
422
+ // Lightbright is [0, 100] corresponding to [0, 100] brightness
423
+ this.cacheBright = params.lightbright
424
+
425
+ // Update the HomeKit value
426
+ this.lightService.updateCharacteristic(this.hapChar.Brightness, params.lightbright)
427
+
428
+ // Log if appropriate
429
+ if (params.updateSource && this.enableLogging) {
430
+ this.log('[%s] %s [%s%].', this.name, this.lang.curBright, this.cacheBright)
431
+ }
432
+ }
433
+
434
+ // Check to see if we are provided new and different light colour information
435
+ if (
436
+ hasProperty(params, 'lightRcolor')
437
+ && (this.cacheR !== params.lightRcolor
438
+ || this.cacheG !== params.lightGcolor
439
+ || this.cacheB !== params.lightBcolor)
440
+ ) {
441
+ // Lightcolor is provided as [0, 255] corresponding to RGB values
442
+ this.cacheR = params.lightRcolor
443
+ this.cacheG = params.lightGcolor
444
+ this.cacheB = params.lightBcolor
445
+
446
+ // Get the Hue information from the RGB colour (saturation is always 100)
447
+ const newColour = rgb2hs(this.cacheR, this.cacheG, this.cacheB);
448
+ [this.cacheHue] = newColour
449
+
450
+ // Update the HomeKit values
451
+ this.lightService.updateCharacteristic(this.hapChar.Hue, this.cacheHue)
452
+ this.lightService.updateCharacteristic(this.hapChar.Saturation, 100)
453
+
454
+ // Log if appropriate
455
+ if (params.updateSource && this.enableLogging) {
456
+ this.log(
457
+ '[%s] %s [rgb %s].',
458
+ this.name,
459
+ this.lang.curColour,
460
+ `${this.cacheR} ${this.cacheG} ${this.cacheB}`,
461
+ )
462
+ }
463
+ }
464
+ } catch (err) {
465
+ // Catch any errors and let the platform display them
466
+ this.platform.deviceUpdateError(this.accessory, err, false)
467
+ }
468
+ }
469
+
470
+ markStatus(isOnline) {
471
+ this.isOnline = isOnline
472
+ }
473
+ }