@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,443 @@
1
+ import platformConsts from '../../utils/constants.js'
2
+ import { hasProperty, parseError } 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
+ this.tempOffset = deviceConf.offset || platformConsts.defaultValues.offset
24
+ this.tempOffsetFactor = deviceConf.offsetFactor
25
+ this.humiOffset = deviceConf && deviceConf.humidityOffset
26
+ ? Number.parseInt(deviceConf.humidityOffset, 10)
27
+ : platformConsts.defaultValues.humidityOffset
28
+ this.humiOffsetFactor = deviceConf.humidityOffsetFactor
29
+ this.minTarget = deviceConf.minTarget || platformConsts.defaultValues.minTarget
30
+ this.maxTarget = deviceConf.maxTarget
31
+ ? Math.max(deviceConf.maxTarget, this.minTarget + 1)
32
+ : platformConsts.defaultValues.maxTarget
33
+
34
+ // Set the correct logging variables for this accessory
35
+ switch (deviceConf.overrideLogging) {
36
+ case 'standard':
37
+ this.enableLogging = true
38
+ this.enableDebugLogging = false
39
+ break
40
+ case 'debug':
41
+ this.enableLogging = true
42
+ this.enableDebugLogging = true
43
+ break
44
+ case 'disable':
45
+ this.enableLogging = false
46
+ this.enableDebugLogging = false
47
+ break
48
+ default:
49
+ this.enableLogging = !platform.config.disableDeviceLogging
50
+ this.enableDebugLogging = platform.config.debug
51
+ break
52
+ }
53
+
54
+ // If the accessory has a switch service then remove it
55
+ if (this.accessory.getService(this.hapServ.Switch)) {
56
+ this.accessory.removeService(this.accessory.getService(this.hapServ.Switch))
57
+ }
58
+
59
+ // If the accessory has a temperature sensor service then remove it
60
+ if (this.accessory.getService(this.hapServ.TemperatureSensor)) {
61
+ this.accessory.removeService(this.accessory.getService(this.hapServ.TemperatureSensor))
62
+ }
63
+
64
+ // Set up the accessory with default target temp when added the first time
65
+ if (!hasProperty(this.accessory.context, 'cacheTarget')) {
66
+ this.accessory.context.cacheTarget = 20
67
+ }
68
+
69
+ // Check to make sure user has not switched from heater to cooler
70
+ if (this.accessory.context.cacheType !== 'cooler') {
71
+ // Remove and re-setup as a HeaterCooler
72
+ if (this.accessory.getService(this.hapServ.HeaterCooler)) {
73
+ this.accessory.removeService(this.accessory.getService(this.hapServ.HeaterCooler))
74
+ }
75
+ this.accessory.context.cacheType = 'cooler'
76
+ this.accessory.context.cacheTarget = 20
77
+ }
78
+
79
+ // If the accessory has a thermostat service then remove it
80
+ if (this.accessory.getService(this.hapServ.Thermostat)) {
81
+ this.accessory.removeService(this.accessory.getService(this.hapServ.Thermostat))
82
+ }
83
+
84
+ // If the accessory has a humidifier service then remove it
85
+ if (this.accessory.getService(this.hapServ.HumidifierDehumidifier)) {
86
+ this.accessory.removeService(this.accessory.getService(this.hapServ.HumidifierDehumidifier))
87
+ }
88
+
89
+ // Add the heater service if it doesn't already exist
90
+ this.service = this.accessory.getService(this.hapServ.HeaterCooler)
91
+ || this.accessory.addService(this.hapServ.HeaterCooler)
92
+
93
+ // The DS18B20 sensor does not provide humidity readings
94
+ if (this.accessory.context.sensorType === 'DS18B20') {
95
+ if (this.accessory.getService(this.hapServ.HumiditySensor)) {
96
+ this.accessory.removeService(this.accessory.getService(this.hapServ.HumiditySensor))
97
+ }
98
+ } else {
99
+ // Add the humidity sensor service if it doesn't already exist
100
+ this.humiService = this.accessory.getService(this.hapServ.HumiditySensor)
101
+ || this.accessory.addService(this.hapServ.HumiditySensor)
102
+ }
103
+
104
+ // Set the heater as the primary service
105
+ this.service.setPrimaryService()
106
+
107
+ // Set custom properties of the current temperature characteristic
108
+ this.service.getCharacteristic(this.hapChar.CurrentTemperature).setProps({
109
+ minStep: 0.1,
110
+ })
111
+ this.cacheTemp = this.service.getCharacteristic(this.hapChar.CurrentTemperature).value
112
+ this.updateCache()
113
+
114
+ // Add the set handler to the heater active characteristic
115
+ this.service
116
+ .getCharacteristic(this.hapChar.Active)
117
+ .onSet(async value => this.internalStateUpdate(value))
118
+
119
+ // Add options to the target state characteristic
120
+ this.service.getCharacteristic(this.hapChar.TargetHeaterCoolerState).setProps({
121
+ minValue: 0,
122
+ maxValue: 0,
123
+ validValues: [0],
124
+ })
125
+
126
+ // Add a get handler to the current state characteristics
127
+ this.service.getCharacteristic(this.hapChar.CurrentHeaterCoolerState).onGet(() => {
128
+ if (!this.isOnline) {
129
+ throw new this.hapErr(-70402)
130
+ }
131
+ return this.service.getCharacteristic(this.hapChar.CurrentHeaterCoolerState).value
132
+ })
133
+
134
+ // Add the set handler to the target temperature characteristic
135
+ this.service
136
+ .getCharacteristic(this.hapChar.CoolingThresholdTemperature)
137
+ .updateValue(this.accessory.context.cacheTarget)
138
+ .setProps({
139
+ minValue: this.minTarget,
140
+ maxValue: this.maxTarget,
141
+ minStep: 0.5,
142
+ })
143
+ .onSet(async value => this.internalTargetTempUpdate(value))
144
+
145
+ // Add the get handlers only if the user hasn't disabled the disableNoResponse setting
146
+ if (!platform.config.disableNoResponse) {
147
+ if (this.humiService) {
148
+ this.humiService.getCharacteristic(this.hapChar.CurrentRelativeHumidity).onGet(() => {
149
+ if (!this.isOnline) {
150
+ throw new this.hapErr(-70402)
151
+ }
152
+ return this.humiService.getCharacteristic(this.hapChar.CurrentRelativeHumidity).value
153
+ })
154
+ }
155
+ this.service.getCharacteristic(this.hapChar.CurrentTemperature).onGet(() => {
156
+ if (!this.isOnline) {
157
+ throw new this.hapErr(-70402)
158
+ }
159
+ return this.service.getCharacteristic(this.hapChar.CurrentTemperature).value
160
+ })
161
+ this.service.getCharacteristic(this.hapChar.Active).onGet(() => {
162
+ if (!this.isOnline) {
163
+ throw new this.hapErr(-70402)
164
+ }
165
+ return this.service.getCharacteristic(this.hapChar.Active).value
166
+ })
167
+ this.service.getCharacteristic(this.hapChar.TargetHeaterCoolerState).onGet(() => {
168
+ if (!this.isOnline) {
169
+ throw new this.hapErr(-70402)
170
+ }
171
+ return this.service.getCharacteristic(this.hapChar.TargetHeaterCoolerState).value
172
+ })
173
+ this.service.getCharacteristic(this.hapChar.CoolingThresholdTemperature).onGet(() => {
174
+ if (!this.isOnline) {
175
+ throw new this.hapErr(-70402)
176
+ }
177
+ return this.service.getCharacteristic(this.hapChar.CoolingThresholdTemperature).value
178
+ })
179
+ }
180
+
181
+ // Initialise these caches now since they aren't determined by the initial externalUpdate()
182
+ this.cacheState = this.service.getCharacteristic(this.hapChar.Active).value === 1 ? 'on' : 'off'
183
+ this.cacheCool = this.cacheState === 'on'
184
+ && this.service.getCharacteristic(this.hapChar.CurrentHeaterCoolerState).value === 3
185
+ ? 'on'
186
+ : 'off'
187
+
188
+ // Pass the accessory to Fakegato to set up with Eve
189
+ this.accessory.eveService = new platform.eveService('custom', this.accessory, {
190
+ log: () => {},
191
+ })
192
+
193
+ // Set up an interval to get eWeLink to send regular temperature/humidity updates
194
+ if (platform.config.mode !== 'lan') {
195
+ setTimeout(() => {
196
+ this.internalUIUpdate()
197
+ this.intervalPoll = setInterval(() => this.internalUIUpdate(), 120000)
198
+ }, 5000)
199
+
200
+ // Stop the intervals on Homebridge shutdown
201
+ platform.api.on('shutdown', () => clearInterval(this.intervalPoll))
202
+ }
203
+
204
+ // Output the customised options to the log
205
+ const normalLogging = this.enableLogging ? 'standard' : 'disable'
206
+ const opts = JSON.stringify({
207
+ humidityOffset: this.humiOffset,
208
+ humidityOffsetFactor: this.humiOffsetFactor,
209
+ logging: this.enableDebugLogging ? 'debug' : normalLogging,
210
+ maxTarget: this.maxTarget,
211
+ minTarget: this.minTarget,
212
+ offset: this.tempOffset,
213
+ offsetFactor: this.tempOffsetFactor,
214
+ showAs: 'cooler',
215
+ })
216
+ this.log('[%s] %s %s.', this.name, this.lang.devInitOpts, opts)
217
+ }
218
+
219
+ async internalStateUpdate(value) {
220
+ try {
221
+ const params = { deviceType: 'normal' }
222
+ let newState
223
+ let newCool
224
+ if (value === 0) {
225
+ params.mainSwitch = 'off'
226
+ params.switch = 'off'
227
+ newState = 'off'
228
+ newCool = 'off'
229
+ } else if (this.cacheTemp > this.accessory.context.cacheTarget) {
230
+ params.mainSwitch = 'on'
231
+ params.switch = 'on'
232
+ newState = 'on'
233
+ newCool = 'on'
234
+ } else {
235
+ params.mainSwitch = 'off'
236
+ params.switch = 'off'
237
+ newState = 'on'
238
+ newCool = 'off'
239
+ }
240
+
241
+ // Only send the update if either:
242
+ // * The new value (state) is OFF and the cacheCool was ON
243
+ // * The new value (state) is ON and newCool is 'on'
244
+ if ((value === 0 && this.cacheCool === 'on') || (value === 1 && newCool === 'on')) {
245
+ await this.platform.sendDeviceUpdate(this.accessory, params)
246
+ }
247
+ if (newState !== this.cacheState) {
248
+ this.cacheState = newState
249
+ if (this.enableLogging) {
250
+ this.log('[%s] %s [%s].', this.name, this.lang.curState, this.cacheState)
251
+ }
252
+ }
253
+ if (newCool !== this.cacheCool) {
254
+ this.cacheCool = newCool
255
+ if (this.enableLogging) {
256
+ this.log('[%s] %s [%s].', this.name, this.lang.curCool, this.cacheCool)
257
+ }
258
+ }
259
+ const hapState = this.cacheCool === 'on' ? 3 : 1
260
+ this.service.updateCharacteristic(
261
+ this.hapChar.CurrentHeaterCoolerState,
262
+ value === 1 ? hapState : 0,
263
+ )
264
+ } catch (err) {
265
+ this.platform.deviceUpdateError(this.accessory, err, true)
266
+ setTimeout(() => {
267
+ this.service.updateCharacteristic(this.hapChar.Active, this.cacheState === 'on' ? 1 : 0)
268
+ }, 2000)
269
+ throw new this.hapErr(-70402)
270
+ }
271
+ }
272
+
273
+ async internalTargetTempUpdate(value) {
274
+ try {
275
+ if (value === this.accessory.context.cacheTarget) {
276
+ return
277
+ }
278
+ this.accessory.context.cacheTarget = value
279
+ if (this.enableLogging) {
280
+ this.log('[%s] %s [%s°C].', this.name, this.lang.curTarg, value)
281
+ }
282
+ if (this.cacheState === 'off') {
283
+ return
284
+ }
285
+ const params = { deviceType: 'normal' }
286
+ let newCool
287
+ if (this.cacheTemp > value) {
288
+ params.mainSwitch = 'on'
289
+ params.switch = 'on'
290
+ newCool = 'on'
291
+ } else {
292
+ params.mainSwitch = 'off'
293
+ params.switch = 'off'
294
+ newCool = 'off'
295
+ }
296
+ if (newCool === this.cacheCool) {
297
+ return
298
+ }
299
+ await this.platform.sendDeviceUpdate(this.accessory, params)
300
+ this.cacheCool = newCool
301
+ if (this.enableLogging) {
302
+ this.log('[%s] %s [%s].', this.name, this.lang.curCool, this.cacheCool)
303
+ }
304
+ this.service.updateCharacteristic(
305
+ this.hapChar.CurrentHeaterCoolerState,
306
+ this.cacheCool === 'on' ? 3 : 1,
307
+ )
308
+ } catch (err) {
309
+ this.platform.deviceUpdateError(this.accessory, err, true)
310
+ setTimeout(() => {
311
+ this.service.updateCharacteristic(
312
+ this.hapChar.CoolingThresholdTemperature,
313
+ this.accessory.context.cacheTarget,
314
+ )
315
+ }, 2000)
316
+ throw new this.hapErr(-70402)
317
+ }
318
+ }
319
+
320
+ async internalCurrentTempUpdate() {
321
+ try {
322
+ if (this.cacheState === 'off') {
323
+ return
324
+ }
325
+ const params = { deviceType: 'normal' }
326
+ let newCool
327
+ if (this.cacheTemp > this.accessory.context.cacheTarget) {
328
+ params.mainSwitch = 'on'
329
+ params.switch = 'on'
330
+ newCool = 'on'
331
+ } else {
332
+ params.mainSwitch = 'off'
333
+ params.switch = 'off'
334
+ newCool = 'off'
335
+ }
336
+ if (newCool === this.cacheCool) {
337
+ return
338
+ }
339
+ await this.platform.sendDeviceUpdate(this.accessory, params)
340
+ this.cacheCool = newCool
341
+ if (this.enableLogging) {
342
+ this.log('[%s] %s [%s].', this.name, this.lang.curCool, this.cacheCool)
343
+ }
344
+ this.service.updateCharacteristic(
345
+ this.hapChar.CurrentHeaterCoolerState,
346
+ this.cacheCool === 'on' ? 3 : 1,
347
+ )
348
+ } catch (err) {
349
+ // Suppress errors here
350
+ }
351
+ }
352
+
353
+ async internalUIUpdate() {
354
+ try {
355
+ // Skip polling if device isn't online
356
+ if (!this.isOnline) {
357
+ return
358
+ }
359
+
360
+ // Send the params to request the updates
361
+ await this.platform.sendDeviceUpdate(this.accessory, { uiActive: 120 })
362
+ } catch (err) {
363
+ // Suppress errors here
364
+ }
365
+ }
366
+
367
+ async externalUpdate(params) {
368
+ try {
369
+ if (
370
+ hasProperty(params, 'currentTemperature')
371
+ && params.currentTemperature !== 'unavailable'
372
+ ) {
373
+ let newTemp = Number(params.currentTemperature)
374
+ if (this.tempOffsetFactor) {
375
+ newTemp *= this.tempOffset
376
+ } else {
377
+ newTemp += this.tempOffset
378
+ }
379
+ if (newTemp !== this.cacheTemp) {
380
+ this.cacheTemp = newTemp
381
+ this.service.updateCharacteristic(this.hapChar.CurrentTemperature, this.cacheTemp)
382
+ this.accessory.eveService.addEntry({ temp: this.cacheTemp })
383
+ if (params.updateSource && this.enableLogging) {
384
+ this.log('[%s] %s [%s°C].', this.name, this.lang.curTemp, this.cacheTemp)
385
+ }
386
+
387
+ // Update the cache file with the new temperature
388
+ this.updateCache()
389
+ this.internalCurrentTempUpdate()
390
+ }
391
+ }
392
+ if (
393
+ hasProperty(params, 'currentHumidity')
394
+ && params.currentHumidity !== 'unavailable'
395
+ && this.humiService
396
+ ) {
397
+ let newHumi = Number.parseInt(params.currentHumidity, 10)
398
+ if (this.humiOffsetFactor) {
399
+ newHumi *= this.humiOffset
400
+ } else {
401
+ newHumi += this.humiOffset
402
+ }
403
+ newHumi = Math.max(Math.min(Number.parseInt(newHumi, 10), 100), 0)
404
+ if (newHumi !== this.cacheHumi) {
405
+ this.cacheHumi = newHumi
406
+ this.humiService.updateCharacteristic(
407
+ this.hapChar.CurrentRelativeHumidity,
408
+ this.cacheHumi,
409
+ )
410
+ this.accessory.eveService.addEntry({ humidity: this.cacheHumi })
411
+ if (params.updateSource && this.enableLogging) {
412
+ this.log('[%s] %s [%s%].', this.name, this.lang.curHumi, this.cacheHumi)
413
+ }
414
+ }
415
+ }
416
+ } catch (err) {
417
+ this.platform.deviceUpdateError(this.accessory, err, false)
418
+ }
419
+ }
420
+
421
+ async updateCache() {
422
+ // Don't continue if the storage client hasn't initialised properly
423
+ if (!this.platform.storageClientData) {
424
+ return
425
+ }
426
+
427
+ // Attempt to save the new temperature to the cache
428
+ try {
429
+ await this.platform.storageData.setItem(
430
+ `${this.accessory.context.eweDeviceId}_temp`,
431
+ this.cacheTemp,
432
+ )
433
+ } catch (err) {
434
+ if (this.enableLogging) {
435
+ this.log.warn('[%s] %s %s.', this.name, this.lang.storageWriteErr, parseError(err))
436
+ }
437
+ }
438
+ }
439
+
440
+ markStatus(isOnline) {
441
+ this.isOnline = isOnline
442
+ }
443
+ }