@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,389 @@
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.temperatureSource = deviceConf.temperatureSource
24
+
25
+ // Set the correct logging variables for this accessory
26
+ switch (deviceConf.overrideLogging) {
27
+ case 'standard':
28
+ this.enableLogging = true
29
+ this.enableDebugLogging = false
30
+ break
31
+ case 'debug':
32
+ this.enableLogging = true
33
+ this.enableDebugLogging = true
34
+ break
35
+ case 'disable':
36
+ this.enableLogging = false
37
+ this.enableDebugLogging = false
38
+ break
39
+ default:
40
+ this.enableLogging = !platform.config.disableDeviceLogging
41
+ this.enableDebugLogging = platform.config.debug
42
+ break
43
+ }
44
+
45
+ // If the accessory has a switch service then remove it
46
+ if (this.accessory.getService(this.hapServ.Switch)) {
47
+ this.accessory.removeService(this.accessory.getService(this.hapServ.Switch))
48
+ }
49
+
50
+ // Set up the accessory with default target temp when added the first time
51
+ if (!hasProperty(this.accessory.context, 'cacheTarget')) {
52
+ this.accessory.context.cacheTarget = 20
53
+ }
54
+
55
+ // Check to make sure user has not switched from cooler to heater
56
+ if (this.accessory.context.cacheType !== 'heater') {
57
+ // Remove and re-setup as a HeaterCooler
58
+ if (this.accessory.getService(this.hapServ.HeaterCooler)) {
59
+ this.accessory.removeService(this.accessory.getService(this.hapServ.HeaterCooler))
60
+ }
61
+ this.accessory.context.cacheType = 'heater'
62
+ this.accessory.context.cacheTarget = 20
63
+ }
64
+
65
+ // Set up the device type and power readings if necessary
66
+ if (platformConsts.devices.switchSingle.includes(this.accessory.context.eweUIID)) {
67
+ this.setup = 'switchSingle'
68
+ } else if (platformConsts.devices.switchSinglePower.includes(this.accessory.context.eweUIID)) {
69
+ this.setup = 'switchSingle'
70
+ } else if (platformConsts.devices.switchMulti.includes(this.accessory.context.eweUIID)) {
71
+ this.setup = 'switchMulti'
72
+ } else if (platformConsts.devices.switchSCM.includes(this.accessory.context.eweUIID)) {
73
+ this.setup = 'switchMulti'
74
+ } else if (platformConsts.devices.switchSCMPower.includes(this.accessory.context.eweUIID)) {
75
+ this.setup = 'switchMulti'
76
+ }
77
+
78
+ // Add the heater service if it doesn't already exist
79
+ this.service = this.accessory.getService(this.hapServ.HeaterCooler)
80
+ || this.accessory.addService(this.hapServ.HeaterCooler)
81
+
82
+ // Set custom properties of the current temperature characteristic
83
+ this.service.getCharacteristic(this.hapChar.CurrentTemperature).setProps({
84
+ minStep: 0.1,
85
+ })
86
+ this.cacheTemp = this.service.getCharacteristic(this.hapChar.CurrentTemperature).value
87
+
88
+ // Add the set handler to the heater active characteristic
89
+ this.service
90
+ .getCharacteristic(this.hapChar.Active)
91
+ .onSet(async value => this.internalStateUpdate(value))
92
+
93
+ // Add options to the target state characteristic
94
+ this.service.getCharacteristic(this.hapChar.TargetHeaterCoolerState).setProps({
95
+ minValue: 0,
96
+ maxValue: 0,
97
+ validValues: [0],
98
+ })
99
+
100
+ // Add the set handler to the target temperature characteristic
101
+ this.service
102
+ .getCharacteristic(this.hapChar.HeatingThresholdTemperature)
103
+ .updateValue(this.accessory.context.cacheTarget)
104
+ .setProps({ minStep: 0.5 })
105
+ .onSet(async value => this.internalTargetTempUpdate(value))
106
+
107
+ // Add the get handlers only if the user hasn't disabled the disableNoResponse setting
108
+ if (!platform.config.disableNoResponse) {
109
+ this.service.getCharacteristic(this.hapChar.CurrentTemperature).onGet(() => {
110
+ if (!this.isOnline) {
111
+ throw new this.hapErr(-70402)
112
+ }
113
+ return this.service.getCharacteristic(this.hapChar.CurrentTemperature).value
114
+ })
115
+ this.service.getCharacteristic(this.hapChar.Active).onGet(() => {
116
+ if (!this.isOnline) {
117
+ throw new this.hapErr(-70402)
118
+ }
119
+ return this.service.getCharacteristic(this.hapChar.Active).value
120
+ })
121
+ this.service.getCharacteristic(this.hapChar.TargetHeaterCoolerState).onGet(() => {
122
+ if (!this.isOnline) {
123
+ throw new this.hapErr(-70402)
124
+ }
125
+ return this.service.getCharacteristic(this.hapChar.TargetHeaterCoolerState).value
126
+ })
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
+ this.service.getCharacteristic(this.hapChar.HeatingThresholdTemperature).onGet(() => {
134
+ if (!this.isOnline) {
135
+ throw new this.hapErr(-70402)
136
+ }
137
+ return this.service.getCharacteristic(this.hapChar.HeatingThresholdTemperature).value
138
+ })
139
+ }
140
+
141
+ // Initialise these caches now since they aren't determined by the initial externalUpdate()
142
+ this.cacheState = this.service.getCharacteristic(this.hapChar.Active).value === 1 ? 'on' : 'off'
143
+ this.cacheHeat = this.cacheState === 'on'
144
+ && this.service.getCharacteristic(this.hapChar.CurrentHeaterCoolerState).value === 2
145
+ ? 'on'
146
+ : 'off'
147
+
148
+ // Pass the accessory to Fakegato to set up with Eve
149
+ this.accessory.eveService = new platform.eveService('custom', this.accessory, {
150
+ log: () => {},
151
+ })
152
+
153
+ // Set up an interval to get regular temperature updates
154
+ setTimeout(() => {
155
+ this.getTemperature()
156
+ this.intervalPoll = setInterval(() => this.getTemperature(), 120000)
157
+ }, 5000)
158
+
159
+ // Stop the intervals on Homebridge shutdown
160
+ platform.api.on('shutdown', () => {
161
+ clearInterval(this.intervalPoll)
162
+ })
163
+
164
+ // Output the customised options to the log
165
+ const normalLogging = this.enableLogging ? 'standard' : 'disable'
166
+ const opts = JSON.stringify({
167
+ logging: this.enableDebugLogging ? 'debug' : normalLogging,
168
+ showAs: 'heater',
169
+ temperatureSource: this.temperatureSource,
170
+ })
171
+ this.log('[%s] %s %s.', this.name, this.lang.devInitOpts, opts)
172
+ }
173
+
174
+ async internalStateUpdate(value) {
175
+ try {
176
+ let newState
177
+ let newHeat
178
+ const params = {}
179
+ if (value === 0) {
180
+ if (this.setup === 'switchSingle') {
181
+ params.switch = 'off'
182
+ } else { // switchMulti
183
+ params.switches = [
184
+ {
185
+ switch: 'off',
186
+ outlet: 0,
187
+ },
188
+ ]
189
+ }
190
+ newState = 'off'
191
+ newHeat = 'off'
192
+ } else if (this.cacheTemp < this.accessory.context.cacheTarget) {
193
+ if (this.setup === 'switchSingle') {
194
+ params.switch = 'on'
195
+ } else { // switchMulti
196
+ params.switches = [
197
+ {
198
+ switch: 'on',
199
+ outlet: 0,
200
+ },
201
+ ]
202
+ }
203
+ newState = 'on'
204
+ newHeat = 'on'
205
+ } else {
206
+ if (this.setup === 'switchSingle') {
207
+ params.switch = 'off'
208
+ } else { // switchMulti
209
+ params.switches = [
210
+ {
211
+ switch: 'off',
212
+ outlet: 0,
213
+ },
214
+ ]
215
+ }
216
+ newState = 'on'
217
+ newHeat = 'off'
218
+ }
219
+
220
+ // Only send the update if either:
221
+ // * The new value (state) is OFF and the cacheHeat was ON
222
+ // * The new value (state) is ON and newHeat is 'on'
223
+ if ((value === 0 && this.cacheHeat === 'on') || (value === 1 && newHeat === 'on')) {
224
+ await this.platform.sendDeviceUpdate(this.accessory, params)
225
+ }
226
+ if (newState !== this.cacheState) {
227
+ this.cacheState = newState
228
+ if (this.enableLogging) {
229
+ this.log('[%s] %s [%s].', this.name, this.lang.curState, this.cacheState)
230
+ }
231
+ }
232
+ if (newHeat !== this.cacheHeat) {
233
+ this.cacheHeat = newHeat
234
+ if (this.enableLogging) {
235
+ this.log('[%s] %s [%s].', this.name, this.lang.curHeat, this.cacheHeat)
236
+ }
237
+ }
238
+ const hapState = this.cacheHeat === 'on' ? 2 : 1
239
+ this.service.updateCharacteristic(
240
+ this.hapChar.CurrentHeaterCoolerState,
241
+ value === 1 ? hapState : 0,
242
+ )
243
+ } catch (err) {
244
+ this.platform.deviceUpdateError(this.accessory, err, true)
245
+ setTimeout(() => {
246
+ this.service.updateCharacteristic(this.hapChar.Active, this.cacheState === 'on' ? 1 : 0)
247
+ }, 2000)
248
+ throw new this.hapErr(-70402)
249
+ }
250
+ }
251
+
252
+ async internalTargetTempUpdate(value) {
253
+ try {
254
+ if (value === this.accessory.context.cacheTarget) {
255
+ return
256
+ }
257
+ this.accessory.context.cacheTarget = value
258
+ if (this.enableLogging) {
259
+ this.log('[%s] %s [%s°C].', this.name, this.lang.curTarg, value)
260
+ }
261
+ if (this.cacheState === 'off') {
262
+ return
263
+ }
264
+ const params = {}
265
+ let newHeat
266
+ if (this.cacheTemp < value) {
267
+ if (this.setup === 'switchSingle') {
268
+ params.switch = 'on'
269
+ } else { // switchMulti
270
+ params.switches = [
271
+ {
272
+ switch: 'on',
273
+ outlet: 0,
274
+ },
275
+ ]
276
+ }
277
+ newHeat = 'on'
278
+ } else {
279
+ if (this.setup === 'switchSingle') {
280
+ params.switch = 'off'
281
+ } else { // switchMulti
282
+ params.switches = [
283
+ {
284
+ switch: 'off',
285
+ outlet: 0,
286
+ },
287
+ ]
288
+ }
289
+ newHeat = 'off'
290
+ }
291
+ if (newHeat === this.cacheHeat) {
292
+ return
293
+ }
294
+ await this.platform.sendDeviceUpdate(this.accessory, params)
295
+ this.cacheHeat = newHeat
296
+ if (this.enableLogging) {
297
+ this.log('[%s] %s [%s].', this.name, this.lang.curHeat, this.cacheHeat)
298
+ }
299
+ this.service.updateCharacteristic(
300
+ this.hapChar.CurrentHeaterCoolerState,
301
+ this.cacheHeat === 'on' ? 2 : 1,
302
+ )
303
+ } catch (err) {
304
+ this.platform.deviceUpdateError(this.accessory, err, true)
305
+ setTimeout(() => {
306
+ this.service.updateCharacteristic(
307
+ this.hapChar.HeatingThresholdTemperature,
308
+ this.accessory.context.cacheTarget,
309
+ )
310
+ }, 2000)
311
+ throw new this.hapErr(-70402)
312
+ }
313
+ }
314
+
315
+ async internalCurrentTempUpdate() {
316
+ try {
317
+ if (this.cacheState === 'off') {
318
+ return
319
+ }
320
+ const params = {}
321
+ let newHeat
322
+ if (this.cacheTemp < this.accessory.context.cacheTarget) {
323
+ if (this.setup === 'switchSingle') {
324
+ params.switch = 'on'
325
+ } else { // switchMulti
326
+ params.switches = [
327
+ {
328
+ switch: 'on',
329
+ outlet: 0,
330
+ },
331
+ ]
332
+ }
333
+ newHeat = 'on'
334
+ } else {
335
+ if (this.setup === 'switchSingle') {
336
+ params.switch = 'off'
337
+ } else { // switchMulti
338
+ params.switches = [
339
+ {
340
+ switch: 'off',
341
+ outlet: 0,
342
+ },
343
+ ]
344
+ }
345
+ newHeat = 'off'
346
+ }
347
+ if (newHeat === this.cacheHeat) {
348
+ return
349
+ }
350
+ await this.platform.sendDeviceUpdate(this.accessory, params)
351
+ this.cacheHeat = newHeat
352
+ if (this.enableLogging) {
353
+ this.log('[%s] %s [%s].', this.name, this.lang.curHeat, this.cacheHeat)
354
+ }
355
+ this.service.updateCharacteristic(
356
+ this.hapChar.CurrentHeaterCoolerState,
357
+ this.cacheHeat === 'on' ? 2 : 1,
358
+ )
359
+ } catch (err) {
360
+ this.log.warn('[%s] %s.', this.name, parseError(err))
361
+ }
362
+ }
363
+
364
+ async getTemperature() {
365
+ try {
366
+ // Skip polling if device isn't online or if the storage hasn't initialised properly
367
+ if (!this.isOnline || !this.platform.storageClientData) {
368
+ return
369
+ }
370
+
371
+ const newTemp = await this.platform.storageData.getItem(`${this.temperatureSource}_temp`)
372
+ if (newTemp && newTemp !== this.cacheTemp) {
373
+ this.cacheTemp = newTemp
374
+ this.service.updateCharacteristic(this.hapChar.CurrentTemperature, this.cacheTemp)
375
+ this.accessory.eveService.addEntry({ temp: this.cacheTemp })
376
+ if (this.enableLogging) {
377
+ this.log('[%s] %s [%s°C].', this.name, this.lang.curTemp, this.cacheTemp)
378
+ }
379
+ this.internalCurrentTempUpdate()
380
+ }
381
+ } catch (err) {
382
+ this.log.warn('[%s] %s.', this.name, parseError(err))
383
+ }
384
+ }
385
+
386
+ markStatus(isOnline) {
387
+ this.isOnline = isOnline
388
+ }
389
+ }
@@ -0,0 +1,75 @@
1
+ import deviceBlind from './blind.js'
2
+ import deviceCooler from './cooler.js'
3
+ import deviceDoor from './door.js'
4
+ import deviceDoorbell from './doorbell.js'
5
+ import deviceGarageEachen from './garage-eachen.js'
6
+ import deviceGarageFour from './garage-four.js'
7
+ import deviceGarageOdSwitch from './garage-od-switch.js'
8
+ import deviceGarageOne from './garage-one.js'
9
+ import deviceGarageTwo from './garage-two.js'
10
+ import deviceGateOne from './gate-one.js'
11
+ import deviceHeater from './heater.js'
12
+ import deviceLightFan from './light-fan.js'
13
+ import deviceLockEachen from './lock-eachen.js'
14
+ import deviceLockOne from './lock-one.js'
15
+ import devicePButton from './p-button.js'
16
+ import devicePurifier from './purifier.js'
17
+ import deviceRfBlind from './rf-blind.js'
18
+ import deviceRfDoor from './rf-door.js'
19
+ import deviceRfWindow from './rf-window.js'
20
+ import deviceSensor from './sensor.js'
21
+ import deviceSensorHidden from './sensor-hidden.js'
22
+ import deviceSensorLeak from './sensor-leak.js'
23
+ import deviceSensorVisible from './sensor-visible.js'
24
+ import deviceSwitchValve from './switch-valve.js'
25
+ import deviceTapOne from './tap-one.js'
26
+ import deviceTapTwo from './tap-two.js'
27
+ import deviceThCooler from './th-cooler.js'
28
+ import deviceThDehumidifier from './th-dehumidifier.js'
29
+ import deviceThHeater from './th-heater.js'
30
+ import deviceThHumidifier from './th-humidifier.js'
31
+ import deviceThThermostat from './th-thermostat.js'
32
+ import deviceTv from './tv.js'
33
+ import deviceValveFour from './valve-four.js'
34
+ import deviceValveOne from './valve-one.js'
35
+ import deviceValveTwo from './valve-two.js'
36
+ import deviceWindow from './window.js'
37
+
38
+ export default {
39
+ deviceBlind,
40
+ deviceCooler,
41
+ deviceDoor,
42
+ deviceDoorbell,
43
+ deviceGarageEachen,
44
+ deviceGarageFour,
45
+ deviceGarageOdSwitch,
46
+ deviceGarageOne,
47
+ deviceGarageTwo,
48
+ deviceGateOne,
49
+ deviceHeater,
50
+ deviceLightFan,
51
+ deviceLockEachen,
52
+ deviceLockOne,
53
+ devicePButton,
54
+ devicePurifier,
55
+ deviceRfBlind,
56
+ deviceRfDoor,
57
+ deviceRfWindow,
58
+ deviceSensor,
59
+ deviceSensorHidden,
60
+ deviceSensorLeak,
61
+ deviceSensorVisible,
62
+ deviceSwitchValve,
63
+ deviceTapOne,
64
+ deviceTapTwo,
65
+ deviceThCooler,
66
+ deviceThDehumidifier,
67
+ deviceThHeater,
68
+ deviceThHumidifier,
69
+ deviceThThermostat,
70
+ deviceTv,
71
+ deviceValveFour,
72
+ deviceValveOne,
73
+ deviceValveTwo,
74
+ deviceWindow,
75
+ }