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