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