@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,61 @@
1
+ import deviceCurtain from './curtain.js'
2
+ import deviceDiffuser from './diffuser.js'
3
+ import deviceFan from './fan.js'
4
+ import deviceGroup from './group.js'
5
+ import deviceHumidifier from './humidifier.js'
6
+ import deviceLightCCT from './light-cct.js'
7
+ import deviceLightDimmer from './light-dimmer.js'
8
+ import deviceLightRGB from './light-rgb.js'
9
+ import deviceLightRGBCCT from './light-rgb-cct.js'
10
+ import deviceMotor from './motor.js'
11
+ import deviceOutletMulti from './outlet-multi.js'
12
+ import deviceOutletSingle from './outlet-single.js'
13
+ import deviceOutletSingleInched from './outlet-single-inched.js'
14
+ import devicePanel from './panel.js'
15
+ import deviceRfBridge from './rf-bridge.js'
16
+ import deviceRfButton from './rf-button.js'
17
+ import deviceRfSensor from './rf-sensor.js'
18
+ import deviceSensorAmbient from './sensor-ambient.js'
19
+ import deviceSensorContact from './sensor-contact.js'
20
+ import deviceSensorTempHumi from './sensor-temp-humi.js'
21
+ import sim from './simulation/index.js'
22
+ import deviceSwitchMan from './switch-man.js'
23
+ import deviceSwitchMate from './switch-mate.js'
24
+ import deviceSwitchMulti from './switch-multi.js'
25
+ import deviceSwitchSingle from './switch-single.js'
26
+ import deviceSwitchSingleInched from './switch-single-inched.js'
27
+ import deviceTemplate from './template.js'
28
+ import deviceThermostat from './thermostat.js'
29
+ import zb from './zigbee/index.js'
30
+
31
+ export default {
32
+ deviceCurtain,
33
+ deviceDiffuser,
34
+ deviceFan,
35
+ deviceGroup,
36
+ deviceHumidifier,
37
+ deviceLightCCT,
38
+ deviceLightDimmer,
39
+ deviceLightRGB,
40
+ deviceLightRGBCCT,
41
+ deviceMotor,
42
+ deviceOutletMulti,
43
+ deviceOutletSingle,
44
+ deviceOutletSingleInched,
45
+ devicePanel,
46
+ deviceRfBridge,
47
+ deviceRfButton,
48
+ deviceRfSensor,
49
+ deviceSensorAmbient,
50
+ deviceSensorContact,
51
+ deviceSensorTempHumi,
52
+ deviceSwitchMan,
53
+ deviceSwitchMate,
54
+ deviceSwitchMulti,
55
+ deviceSwitchSingle,
56
+ deviceSwitchSingleInched,
57
+ deviceTemplate,
58
+ deviceThermostat,
59
+ sim,
60
+ zb,
61
+ }
@@ -0,0 +1,333 @@
1
+ import platformConsts from '../utils/constants.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
+ this.deviceModel = deviceConf.deviceModel || 'bulbB02FA60'
24
+ this.alShift = deviceConf.adaptiveLightingShift || platformConsts.defaultValues.adaptiveLightingShift
25
+ this.brightStep = deviceConf.brightnessStep
26
+ ? Math.min(deviceConf.brightnessStep, 100)
27
+ : platformConsts.defaultValues.brightnessStep
28
+ this.offlineAsOff = deviceConf.offlineAsOff
29
+
30
+ // Set the correct logging variables for this accessory
31
+ switch (deviceConf.overrideLogging) {
32
+ case 'standard':
33
+ this.enableLogging = true
34
+ this.enableDebugLogging = false
35
+ break
36
+ case 'debug':
37
+ this.enableLogging = true
38
+ this.enableDebugLogging = true
39
+ break
40
+ case 'disable':
41
+ this.enableLogging = false
42
+ this.enableDebugLogging = false
43
+ break
44
+ default:
45
+ this.enableLogging = !platform.config.disableDeviceLogging
46
+ this.enableDebugLogging = platform.config.debug
47
+ break
48
+ }
49
+
50
+ // Different bulbs have different colour temperature ranges
51
+ switch (this.deviceModel) {
52
+ case 'bulbB02FST64':
53
+ this.minK = 1800
54
+ this.maxK = 5000
55
+ break
56
+ case 'bulbB02BA60':
57
+ this.minK = 2700
58
+ this.maxK = 6500
59
+ break
60
+ default:
61
+ this.minK = 2200
62
+ this.maxK = 6500
63
+ break
64
+ }
65
+
66
+ // Add the lightbulb service if it doesn't already exist
67
+ this.service = this.accessory.getService(this.hapServ.Lightbulb)
68
+ || this.accessory.addService(this.hapServ.Lightbulb)
69
+
70
+ // If adaptive lighting has just been disabled then remove and re-add service to hide AL icon
71
+ if (this.alShift === -1 && this.accessory.context.adaptiveLighting) {
72
+ this.accessory.removeService(this.service)
73
+ this.service = this.accessory.addService(this.hapServ.Lightbulb)
74
+ this.accessory.context.adaptiveLighting = false
75
+ }
76
+
77
+ // Add the set handler to the lightbulb on/off characteristic
78
+ this.service
79
+ .getCharacteristic(this.hapChar.On)
80
+ .onSet(async value => this.internalStateUpdate(value))
81
+
82
+ // Add the set handler to the lightbulb brightness characteristic
83
+ this.service
84
+ .getCharacteristic(this.hapChar.Brightness)
85
+ .setProps({ minStep: this.brightStep })
86
+ .onSet(async value => this.internalBrightnessUpdate(value))
87
+
88
+ // Add the set handler to the lightbulb colour temperature characteristic
89
+ this.service
90
+ .getCharacteristic(this.hapChar.ColorTemperature)
91
+ .onSet(async value => this.internalCTUpdate(value))
92
+
93
+ // This is needed as sometimes we need to send the brightness with a cct update
94
+ this.cacheBright = this.service.getCharacteristic(this.hapChar.Brightness).value
95
+
96
+ // Set up the adaptive lighting controller if not disabled by user
97
+ if (this.alShift !== -1) {
98
+ this.accessory.alController = new platform.api.hap.AdaptiveLightingController(this.service, {
99
+ customTemperatureAdjustment: this.alShift,
100
+ })
101
+ this.accessory.configureController(this.accessory.alController)
102
+ }
103
+
104
+ // Add the get handlers only if the user hasn't disabled the disableNoResponse setting
105
+ if (!platform.config.disableNoResponse) {
106
+ this.service.getCharacteristic(this.hapChar.On).onGet(() => {
107
+ if (!this.isOnline) {
108
+ throw new this.hapErr(-70402)
109
+ }
110
+ return this.service.getCharacteristic(this.hapChar.On).value
111
+ })
112
+ this.service.getCharacteristic(this.hapChar.Brightness).onGet(() => {
113
+ if (!this.isOnline) {
114
+ throw new this.hapErr(-70402)
115
+ }
116
+ return this.service.getCharacteristic(this.hapChar.Brightness).value
117
+ })
118
+ this.service.getCharacteristic(this.hapChar.ColorTemperature).onGet(() => {
119
+ if (!this.isOnline) {
120
+ throw new this.hapErr(-70402)
121
+ }
122
+ return this.service.getCharacteristic(this.hapChar.ColorTemperature).value
123
+ })
124
+ }
125
+
126
+ // Output the customised options to the log
127
+ const normalLogging = this.enableLogging ? 'standard' : 'disable'
128
+ const opts = JSON.stringify({
129
+ adaptiveLightingShift: this.alShift,
130
+ brightnessStep: this.brightStep,
131
+ deviceModel: this.deviceModel,
132
+ logging: this.enableDebugLogging ? 'debug' : normalLogging,
133
+ offlineAsOff: !!this.offlineAsOff,
134
+ })
135
+ this.log('[%s] %s %s.', this.name, this.lang.devInitOpts, opts)
136
+ }
137
+
138
+ async internalStateUpdate(value) {
139
+ try {
140
+ const newValue = value ? 'on' : 'off'
141
+ if (this.cacheState === newValue) {
142
+ return
143
+ }
144
+ const timerKey = generateRandomString(5)
145
+ this.updateTimeout = timerKey
146
+ setTimeout(() => {
147
+ if (this.updateTimeout === timerKey) {
148
+ this.updateTimeout = false
149
+ }
150
+ }, 5000)
151
+ await this.platform.sendDeviceUpdate(this.accessory, {
152
+ switch: newValue,
153
+ })
154
+ this.cacheState = newValue
155
+ if (this.enableLogging) {
156
+ this.log('[%s] %s [%s].', this.name, this.lang.curState, this.cacheState)
157
+ }
158
+ } catch (err) {
159
+ this.platform.deviceUpdateError(this.accessory, err, true)
160
+ setTimeout(() => {
161
+ this.service.updateCharacteristic(this.hapChar.On, this.cacheState === 'on')
162
+ }, 2000)
163
+ throw new this.hapErr(-70402)
164
+ }
165
+ }
166
+
167
+ async internalBrightnessUpdate(value) {
168
+ try {
169
+ if (this.cacheBright === value) {
170
+ return
171
+ }
172
+ const updateKey = generateRandomString(5)
173
+ this.updateKeyBright = updateKey
174
+ await sleep(500)
175
+ if (updateKey !== this.updateKeyBright) {
176
+ return
177
+ }
178
+ this.updateTimeout = updateKey
179
+ setTimeout(() => {
180
+ if (this.updateTimeout === updateKey) {
181
+ this.updateTimeout = false
182
+ }
183
+ }, 5000)
184
+ const params = {
185
+ white: {
186
+ br: value,
187
+ ct: this.cacheCT,
188
+ },
189
+ }
190
+ await this.platform.sendDeviceUpdate(this.accessory, params)
191
+ this.cacheBright = value
192
+ if (this.enableLogging) {
193
+ this.log('[%s] %s [%s%].', this.name, this.lang.curBright, this.cacheBright)
194
+ }
195
+ } catch (err) {
196
+ this.platform.deviceUpdateError(this.accessory, err, true)
197
+ setTimeout(() => {
198
+ this.service.updateCharacteristic(this.hapChar.Brightness, this.cacheBright)
199
+ }, 2000)
200
+ throw new this.hapErr(-70402)
201
+ }
202
+ }
203
+
204
+ async internalCTUpdate(value) {
205
+ try {
206
+ if (this.cacheMired === value) {
207
+ return
208
+ }
209
+ if (
210
+ this.accessory.alController
211
+ && this.accessory.alController.isAdaptiveLightingActive()
212
+ && (this.cacheState !== 'on' || !this.isOnline)
213
+ ) {
214
+ return
215
+ }
216
+ const updateKey = generateRandomString(5)
217
+ this.updateKeyCT = updateKey
218
+ await sleep(400)
219
+ if (updateKey !== this.updateKeyCT) {
220
+ return
221
+ }
222
+ this.updateTimeout = updateKey
223
+ setTimeout(() => {
224
+ if (this.updateTimeout === updateKey) {
225
+ this.updateTimeout = false
226
+ }
227
+ }, 5000)
228
+ const kelvin = Math.round(1000000 / value)
229
+ const scaledK = Math.max(Math.min(kelvin, this.maxK), this.minK)
230
+ const scaledCT = Math.round(((scaledK - this.minK) / (this.maxK - this.minK)) * 255)
231
+ const params = {
232
+ white: {
233
+ br: this.cacheBright,
234
+ ct: scaledCT,
235
+ },
236
+ }
237
+ await this.platform.sendDeviceUpdate(this.accessory, params)
238
+ this.cacheMired = value
239
+ this.cacheCT = scaledCT
240
+ if (this.enableLogging) {
241
+ if (this.accessory.alController && this.accessory.alController.isAdaptiveLightingActive()) {
242
+ this.log('[%s] %s [%sK] %s.', this.name, this.lang.curColour, scaledK, this.lang.viaAL)
243
+ } else {
244
+ this.log('[%s] %s [%sK].', this.name, this.lang.curColour, scaledK)
245
+ }
246
+ }
247
+ } catch (err) {
248
+ this.platform.deviceUpdateError(this.accessory, err, true)
249
+ setTimeout(() => {
250
+ this.service.updateCharacteristic(this.hapChar.ColorTemperature, this.cacheMired)
251
+ }, 2000)
252
+ throw new this.hapErr(-70402)
253
+ }
254
+ }
255
+
256
+ async externalUpdate(params) {
257
+ try {
258
+ if (this.updateTimeout) {
259
+ return
260
+ }
261
+ if (params.switch && params.switch !== this.cacheState) {
262
+ this.cacheState = params.switch
263
+ this.service.updateCharacteristic(this.hapChar.On, this.cacheState === 'on')
264
+ if (params.updateSource && this.enableLogging) {
265
+ this.log('[%s] %s [%s].', this.name, this.lang.curState, this.cacheState)
266
+ }
267
+ }
268
+ if (params.white) {
269
+ if (hasProperty(params.white, 'br') && this.cacheBright !== params.white.br) {
270
+ this.cacheBright = params.white.br
271
+ this.service.updateCharacteristic(this.hapChar.Brightness, this.cacheBright)
272
+ if (params.updateSource && this.enableLogging) {
273
+ this.log('[%s] %s [%s%].', this.name, this.lang.curBright, this.cacheBright)
274
+ }
275
+ }
276
+ if (hasProperty(params.white, 'ct') && this.cacheCT !== params.white.ct) {
277
+ const ctDiff = Math.abs(params.white.ct - this.cacheCT)
278
+ this.cacheCT = params.white.ct
279
+ const kelvin = (this.cacheCT / 255) * (this.maxK - this.minK) + this.minK
280
+ const scaledK = Math.round(kelvin)
281
+ this.cacheMired = Math.min(Math.max(Math.round(1000000 / scaledK), 140), 500)
282
+ this.service.updateCharacteristic(this.hapChar.ColorTemperature, this.cacheMired)
283
+ if (params.updateSource) {
284
+ if (this.enableLogging) {
285
+ this.log('[%s] %s [%sK].', this.name, this.lang.curColour, scaledK)
286
+ }
287
+ if (
288
+ this.accessory.alController
289
+ && this.accessory.alController.isAdaptiveLightingActive()
290
+ && ctDiff > 20
291
+ ) {
292
+ // Look for a variation greater than twenty
293
+ this.accessory.alController.disableAdaptiveLighting()
294
+ if (this.enableLogging) {
295
+ this.log('[%s] %s.', this.name, this.lang.disabledAL)
296
+ }
297
+ }
298
+ }
299
+ }
300
+ }
301
+ } catch (err) {
302
+ this.platform.deviceUpdateError(this.accessory, err, false)
303
+ }
304
+ }
305
+
306
+ markStatus(isOnline) {
307
+ this.isOnline = isOnline
308
+
309
+ // Show as off if offlineAsOff is enabled
310
+ if (this.offlineAsOff && !isOnline && this.cacheState !== 'off') {
311
+ this.service.updateCharacteristic(this.hapChar.On, false)
312
+ this.cacheState = 'off'
313
+ if (this.enableLogging) {
314
+ this.log('[%s] %s [%s - offline]', this.name, this.lang.curState, this.cacheState)
315
+ }
316
+ }
317
+ }
318
+
319
+ currentState() {
320
+ const toReturn = {}
321
+ toReturn.services = ['light']
322
+ toReturn.light = {
323
+ state: this.service.getCharacteristic(this.hapChar.On).value ? 'on' : 'off',
324
+ brightness: this.service.getCharacteristic(this.hapChar.Brightness).value,
325
+ colourtemperature: this.service.getCharacteristic(this.hapChar.ColorTemperature).value,
326
+ adaptivelighting:
327
+ this.accessory.alController && this.accessory.alController.isAdaptiveLightingActive()
328
+ ? 'on'
329
+ : 'off',
330
+ }
331
+ return toReturn
332
+ }
333
+ }
@@ -0,0 +1,257 @@
1
+ import platformConsts from '../utils/constants.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
+ this.brightStep = deviceConf.brightnessStep
24
+ ? Math.min(deviceConf.brightnessStep, 100)
25
+ : platformConsts.defaultValues.brightnessStep
26
+ this.offlineAsOff = deviceConf.offlineAsOff
27
+
28
+ // Set the correct logging variables for this accessory
29
+ switch (deviceConf.overrideLogging) {
30
+ case 'standard':
31
+ this.enableLogging = true
32
+ this.enableDebugLogging = false
33
+ break
34
+ case 'debug':
35
+ this.enableLogging = true
36
+ this.enableDebugLogging = true
37
+ break
38
+ case 'disable':
39
+ this.enableLogging = false
40
+ this.enableDebugLogging = false
41
+ break
42
+ default:
43
+ this.enableLogging = !platform.config.disableDeviceLogging
44
+ this.enableDebugLogging = platform.config.debug
45
+ break
46
+ }
47
+
48
+ // Remove any fan services from a similation
49
+ if (accessory.getService(this.hapServ.Fan)) {
50
+ accessory.removeService(accessory.getService(this.hapServ.Fan))
51
+ }
52
+
53
+ // Add the lightbulb service if it doesn't already exist
54
+ this.service = this.accessory.getService(this.hapServ.Lightbulb)
55
+ || this.accessory.addService(this.hapServ.Lightbulb)
56
+
57
+ // Add the set handler to the lightbulb on/off characteristic
58
+ this.service
59
+ .getCharacteristic(this.hapChar.On)
60
+ .onSet(async value => this.internalStateUpdate(value))
61
+
62
+ // Add the set handler to the lightbulb brightness characteristic
63
+ this.service
64
+ .getCharacteristic(this.hapChar.Brightness)
65
+ .setProps({ minStep: this.brightStep })
66
+ .onSet(async value => this.internalBrightnessUpdate(value))
67
+
68
+ // Add the get handlers only if the user hasn't disabled the disableNoResponse setting
69
+ if (!platform.config.disableNoResponse) {
70
+ this.service.getCharacteristic(this.hapChar.On).onGet(() => {
71
+ if (!this.isOnline) {
72
+ throw new this.hapErr(-70402)
73
+ }
74
+ return this.service.getCharacteristic(this.hapChar.On).value
75
+ })
76
+ this.service.getCharacteristic(this.hapChar.Brightness).onGet(() => {
77
+ if (!this.isOnline) {
78
+ throw new this.hapErr(-70402)
79
+ }
80
+ return this.service.getCharacteristic(this.hapChar.Brightness).value
81
+ })
82
+ }
83
+
84
+ // Output the customised options to the log
85
+ const normalLogging = this.enableLogging ? 'standard' : 'disable'
86
+ const opts = JSON.stringify({
87
+ brightnessStep: this.brightStep,
88
+ logging: this.enableDebugLogging ? 'debug' : normalLogging,
89
+ offlineAsOff: !!this.offlineAsOff,
90
+ })
91
+ this.log('[%s] %s %s.', this.name, this.lang.devInitOpts, opts)
92
+ }
93
+
94
+ async internalStateUpdate(value) {
95
+ try {
96
+ const newValue = value ? 'on' : 'off'
97
+ if (this.cacheState === newValue) {
98
+ return
99
+ }
100
+ const params = {}
101
+ switch (this.accessory.context.eweUIID) {
102
+ case 36:
103
+ case 44:
104
+ // KING-M4, D1
105
+ params.switch = newValue
106
+ break
107
+ case 57:
108
+ params.state = newValue
109
+ break
110
+ default:
111
+ return
112
+ }
113
+ await this.platform.sendDeviceUpdate(this.accessory, params)
114
+ this.cacheState = newValue
115
+ if (this.enableLogging) {
116
+ this.log('[%s] %s [%s].', this.name, this.lang.curState, this.cacheState)
117
+ }
118
+ } catch (err) {
119
+ this.platform.deviceUpdateError(this.accessory, err, true)
120
+ setTimeout(() => {
121
+ this.service.updateCharacteristic(this.hapChar.On, this.cacheState === 'on')
122
+ }, 2000)
123
+ throw new this.hapErr(-70402)
124
+ }
125
+ }
126
+
127
+ async internalBrightnessUpdate(value) {
128
+ try {
129
+ if (this.cacheBright === value) {
130
+ return
131
+ }
132
+ const updateKey = generateRandomString(5)
133
+ this.updateKeyBright = updateKey
134
+ await sleep(500)
135
+ if (updateKey !== this.updateKeyBright) {
136
+ return
137
+ }
138
+ const params = {}
139
+ switch (this.accessory.context.eweUIID) {
140
+ case 36:
141
+ params.bright = Math.round((value * 9) / 10 + 10)
142
+ // KING-M4 eWeLink scale is 10-100 and HomeKit scale is 0-100
143
+ break
144
+ case 44:
145
+ params.brightness = value
146
+ // D1 eWeLink scale matches HomeKit scale of 0-100
147
+ params.mode = 0
148
+ break
149
+ case 57:
150
+ params.channel0 = Math.round((value * 23) / 10 + 25).toString()
151
+ // Device eWeLink scale is 25-255 and HomeKit scale is 0-100.
152
+ break
153
+ default:
154
+ return
155
+ }
156
+ await this.platform.sendDeviceUpdate(this.accessory, params)
157
+ this.cacheBright = value
158
+ if (this.enableLogging) {
159
+ this.log('[%s] %s [%s%].', this.name, this.lang.curBright, this.cacheBright)
160
+ }
161
+ } catch (err) {
162
+ this.platform.deviceUpdateError(this.accessory, err, true)
163
+ setTimeout(() => {
164
+ this.service.updateCharacteristic(this.hapChar.Brightness, this.cacheBright)
165
+ }, 2000)
166
+ throw new this.hapErr(-70402)
167
+ }
168
+ }
169
+
170
+ async externalUpdate(params) {
171
+ try {
172
+ if (this.accessory.context.eweUIID === 57) {
173
+ if (params.state && params.state !== this.cacheState) {
174
+ this.service.updateCharacteristic(this.hapChar.On, params.state === 'on')
175
+ this.cacheState = params.state
176
+ if (params.updateSource && this.enableLogging) {
177
+ this.log('[%s] %s [%s].', this.name, this.lang.curState, this.cacheState)
178
+ }
179
+ }
180
+ } else if (params.switch && params.switch !== this.cacheState) {
181
+ this.service.updateCharacteristic(this.hapChar.On, params.switch === 'on')
182
+ this.cacheState = params.switch
183
+ if (params.updateSource && this.enableLogging) {
184
+ this.log('[%s] %s [%s].', this.name, this.lang.curState, this.cacheState)
185
+ }
186
+ }
187
+
188
+ switch (this.accessory.context.eweUIID) {
189
+ case 36:
190
+ // KING-M4 eWeLink scale is 10-100 and HomeKit scale is 0-100.
191
+ if (hasProperty(params, 'bright')) {
192
+ const nb = Math.round(((params.bright - 10) * 10) / 9)
193
+ if (nb !== this.cacheBright) {
194
+ this.service.updateCharacteristic(this.hapChar.Brightness, nb)
195
+ this.cacheBright = nb
196
+ if (params.updateSource && this.enableLogging) {
197
+ this.log('[%s] %s [%s%].', this.name, this.lang.curBright, nb)
198
+ }
199
+ }
200
+ }
201
+ break
202
+ case 44:
203
+ // D1 eWeLink scale matches HomeKit scale of 0-100
204
+ if (hasProperty(params, 'brightness')) {
205
+ const nb = params.brightness
206
+ if (nb !== this.cacheBright) {
207
+ this.service.updateCharacteristic(this.hapChar.Brightness, nb)
208
+ this.cacheBright = nb
209
+ if (params.updateSource && this.enableLogging) {
210
+ this.log('[%s] %s [%s%].', this.name, this.lang.curBright, nb)
211
+ }
212
+ }
213
+ }
214
+ break
215
+ case 57:
216
+ // Device eWeLink scale is 25-255 and HomeKit scale is 0-100.
217
+ if (hasProperty(params, 'channel0')) {
218
+ const nb = Math.round(((Number.parseInt(params.channel0, 10) - 25) * 10) / 23)
219
+ if (nb !== this.cacheBright) {
220
+ this.service.updateCharacteristic(this.hapChar.Brightness, nb)
221
+ this.cacheBright = nb
222
+ if (params.updateSource && this.enableLogging) {
223
+ this.log('[%s] %s [%s%].', this.name, this.lang.curBright, nb)
224
+ }
225
+ }
226
+ }
227
+ break
228
+ default:
229
+ }
230
+ } catch (err) {
231
+ this.platform.deviceUpdateError(this.accessory, err, false)
232
+ }
233
+ }
234
+
235
+ markStatus(isOnline) {
236
+ this.isOnline = isOnline
237
+
238
+ // Show as off if offlineAsOff is enabled
239
+ if (this.offlineAsOff && !isOnline && this.cacheState !== 'off') {
240
+ this.service.updateCharacteristic(this.hapChar.On, false)
241
+ this.cacheState = 'off'
242
+ if (this.enableLogging) {
243
+ this.log('[%s] %s [%s - offline]', this.name, this.lang.curState, this.cacheState)
244
+ }
245
+ }
246
+ }
247
+
248
+ currentState() {
249
+ const toReturn = {}
250
+ toReturn.services = ['light']
251
+ toReturn.light = {
252
+ state: this.service.getCharacteristic(this.hapChar.On).value ? 'on' : 'off',
253
+ brightness: this.service.getCharacteristic(this.hapChar.Brightness).value,
254
+ }
255
+ return toReturn
256
+ }
257
+ }