@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,148 @@
|
|
|
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
|
+
// Set up custom variables for this device type
|
|
19
|
+
const deviceConf = platform.deviceConf[accessory.context.eweDeviceId] || {}
|
|
20
|
+
this.brightStep = deviceConf.brightnessStep
|
|
21
|
+
? Math.min(deviceConf.brightnessStep, 100)
|
|
22
|
+
: platformConsts.defaultValues.brightnessStep
|
|
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 lightbulb service if it doesn't already exist
|
|
45
|
+
this.service = this.accessory.getService(this.hapServ.Lightbulb)
|
|
46
|
+
|| this.accessory.addService(this.hapServ.Lightbulb)
|
|
47
|
+
|
|
48
|
+
// Add the get/set handler to the lightbulb on/off characteristic
|
|
49
|
+
this.service
|
|
50
|
+
.getCharacteristic(this.hapChar.On)
|
|
51
|
+
.onGet(() => {
|
|
52
|
+
if (this.isOnline) {
|
|
53
|
+
return this.service.getCharacteristic(this.hapChar.On).value
|
|
54
|
+
}
|
|
55
|
+
throw new this.hapErr(-70402)
|
|
56
|
+
})
|
|
57
|
+
.onSet(async value => this.internalStateUpdate(value))
|
|
58
|
+
|
|
59
|
+
// Add the set handler to the lightbulb brightness characteristic
|
|
60
|
+
this.service
|
|
61
|
+
.getCharacteristic(this.hapChar.Brightness)
|
|
62
|
+
.setProps({ minStep: this.brightStep })
|
|
63
|
+
.onSet(async value => this.internalBrightnessUpdate(value))
|
|
64
|
+
|
|
65
|
+
// Output the customised options to the log
|
|
66
|
+
const normalLogging = this.enableLogging ? 'standard' : 'disable'
|
|
67
|
+
const opts = JSON.stringify({
|
|
68
|
+
brightnessStep: this.brightStep,
|
|
69
|
+
logging: this.enableDebugLogging ? 'debug' : normalLogging,
|
|
70
|
+
})
|
|
71
|
+
this.log('[%s] %s %s.', this.name, this.lang.devInitOpts, opts)
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
async internalStateUpdate(value) {
|
|
75
|
+
try {
|
|
76
|
+
const newValue = value ? 'on' : 'off'
|
|
77
|
+
await this.platform.sendDeviceUpdate(this.accessory, {
|
|
78
|
+
switch: newValue,
|
|
79
|
+
})
|
|
80
|
+
this.cacheState = newValue
|
|
81
|
+
if (this.enableLogging) {
|
|
82
|
+
this.log('[%s] %s [%s].', this.name, this.lang.curState, this.cacheState)
|
|
83
|
+
}
|
|
84
|
+
} catch (err) {
|
|
85
|
+
this.platform.deviceUpdateError(this.accessory, err, true)
|
|
86
|
+
setTimeout(() => {
|
|
87
|
+
this.service.updateCharacteristic(this.hapChar.On, this.cacheState === 'on')
|
|
88
|
+
}, 2000)
|
|
89
|
+
throw new this.hapErr(-70402)
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
async internalBrightnessUpdate(value) {
|
|
94
|
+
try {
|
|
95
|
+
if (this.cacheBright === value || value === 0) {
|
|
96
|
+
return
|
|
97
|
+
}
|
|
98
|
+
const updateKey = generateRandomString(5)
|
|
99
|
+
this.updateKey = updateKey
|
|
100
|
+
await sleep(500)
|
|
101
|
+
if (updateKey !== this.updateKey) {
|
|
102
|
+
return
|
|
103
|
+
}
|
|
104
|
+
const params = {
|
|
105
|
+
switch: 'on',
|
|
106
|
+
brightness: value,
|
|
107
|
+
}
|
|
108
|
+
await this.platform.sendDeviceUpdate(this.accessory, params)
|
|
109
|
+
this.cacheBright = value
|
|
110
|
+
if (this.enableLogging) {
|
|
111
|
+
this.log('[%s] %s [%s%].', this.name, this.lang.curBright, this.cacheBright)
|
|
112
|
+
}
|
|
113
|
+
} catch (err) {
|
|
114
|
+
this.platform.deviceUpdateError(this.accessory, err, true)
|
|
115
|
+
setTimeout(() => {
|
|
116
|
+
this.service.updateCharacteristic(this.hapChar.Brightness, this.cacheBright)
|
|
117
|
+
}, 2000)
|
|
118
|
+
throw new this.hapErr(-70402)
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
async externalUpdate(params) {
|
|
123
|
+
try {
|
|
124
|
+
if (params.switch && params.switch !== this.cacheState) {
|
|
125
|
+
this.cacheState = params.switch
|
|
126
|
+
this.service.updateCharacteristic(this.hapChar.On, this.cacheState === 'on')
|
|
127
|
+
if (params.updateSource && this.enableLogging) {
|
|
128
|
+
this.log('[%s] %s [%s].', this.name, this.lang.curState, this.cacheState)
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
if (hasProperty(params, 'brightness')) {
|
|
132
|
+
if (params.brightness !== this.cacheBright) {
|
|
133
|
+
this.cacheBright = params.brightness
|
|
134
|
+
this.service.updateCharacteristic(this.hapChar.Brightness, this.cacheBright)
|
|
135
|
+
if (params.updateSource && this.enableLogging) {
|
|
136
|
+
this.log('[%s] %s [%s%].', this.name, this.lang.curBright, this.cacheBright)
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
} catch (err) {
|
|
141
|
+
this.platform.deviceUpdateError(this.accessory, err, false)
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
markStatus(isOnline) {
|
|
146
|
+
this.isOnline = isOnline
|
|
147
|
+
}
|
|
148
|
+
}
|
|
@@ -0,0 +1,400 @@
|
|
|
1
|
+
import { m2hs } from '../../utils/colour.js'
|
|
2
|
+
import platformConsts from '../../utils/constants.js'
|
|
3
|
+
import { generateRandomString, hasProperty, sleep } from '../../utils/functions.js'
|
|
4
|
+
|
|
5
|
+
export default class {
|
|
6
|
+
constructor(platform, accessory) {
|
|
7
|
+
// Set up variables from the platform
|
|
8
|
+
this.hapChar = platform.api.hap.Characteristic
|
|
9
|
+
this.hapErr = platform.api.hap.HapStatusError
|
|
10
|
+
this.hapServ = platform.api.hap.Service
|
|
11
|
+
this.lang = platform.lang
|
|
12
|
+
this.log = platform.log
|
|
13
|
+
this.platform = platform
|
|
14
|
+
|
|
15
|
+
// Set up variables from the accessory
|
|
16
|
+
this.name = accessory.displayName
|
|
17
|
+
this.accessory = accessory
|
|
18
|
+
|
|
19
|
+
// Set up custom variables for this device type
|
|
20
|
+
const deviceConf = platform.deviceConf[accessory.context.eweDeviceId] || {}
|
|
21
|
+
this.brightStep = deviceConf.brightnessStep
|
|
22
|
+
? Math.min(deviceConf.brightnessStep, 100)
|
|
23
|
+
: platformConsts.defaultValues.brightnessStep
|
|
24
|
+
|
|
25
|
+
// Different bulbs have different colour temperature ranges
|
|
26
|
+
this.minK = 2700
|
|
27
|
+
this.maxK = 6500
|
|
28
|
+
|
|
29
|
+
// Set the correct logging variables for this accessory
|
|
30
|
+
switch (deviceConf.overrideLogging) {
|
|
31
|
+
case 'standard':
|
|
32
|
+
this.enableLogging = true
|
|
33
|
+
this.enableDebugLogging = false
|
|
34
|
+
break
|
|
35
|
+
case 'debug':
|
|
36
|
+
this.enableLogging = true
|
|
37
|
+
this.enableDebugLogging = true
|
|
38
|
+
break
|
|
39
|
+
case 'disable':
|
|
40
|
+
this.enableLogging = false
|
|
41
|
+
this.enableDebugLogging = false
|
|
42
|
+
break
|
|
43
|
+
default:
|
|
44
|
+
this.enableLogging = !platform.config.disableDeviceLogging
|
|
45
|
+
this.enableDebugLogging = platform.config.debug
|
|
46
|
+
break
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Add the lightbulb service if it doesn't already exist
|
|
50
|
+
this.service = this.accessory.getService(this.hapServ.Lightbulb)
|
|
51
|
+
|| this.accessory.addService(this.hapServ.Lightbulb)
|
|
52
|
+
|
|
53
|
+
// If adaptive lighting has just been disabled then remove and re-add service to hide AL icon
|
|
54
|
+
if (this.alShift === -1 && this.accessory.context.adaptiveLighting) {
|
|
55
|
+
this.accessory.removeService(this.service)
|
|
56
|
+
this.service = this.accessory.addService(this.hapServ.Lightbulb)
|
|
57
|
+
this.accessory.context.adaptiveLighting = false
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Add the get/set handler to the lightbulb on/off characteristic
|
|
61
|
+
this.service
|
|
62
|
+
.getCharacteristic(this.hapChar.On)
|
|
63
|
+
.onSet(async value => this.internalStateUpdate(value))
|
|
64
|
+
|
|
65
|
+
// Add the set handler to the lightbulb brightness characteristic
|
|
66
|
+
this.service
|
|
67
|
+
.getCharacteristic(this.hapChar.Brightness)
|
|
68
|
+
.setProps({ minStep: this.brightStep })
|
|
69
|
+
.onSet(async value => this.internalBrightnessUpdate(value))
|
|
70
|
+
|
|
71
|
+
// This is needed as sometimes we need to send the brightness with a cct update
|
|
72
|
+
this.cacheBright = this.service.getCharacteristic(this.hapChar.Brightness).value
|
|
73
|
+
|
|
74
|
+
// Add the set handler to the lightbulb hue characteristic
|
|
75
|
+
this.service
|
|
76
|
+
.getCharacteristic(this.hapChar.Hue)
|
|
77
|
+
.onSet(async value => this.internalColourUpdate(value))
|
|
78
|
+
this.cacheSat = this.service.getCharacteristic(this.hapChar.Saturation).value
|
|
79
|
+
|
|
80
|
+
// Add the set handler to the lightbulb colour temperature characteristic
|
|
81
|
+
this.service.getCharacteristic(this.hapChar.ColorTemperature).onSet(async value => this.internalCTUpdate(value))
|
|
82
|
+
|
|
83
|
+
// Set up the adaptive lighting controller if not disabled by user
|
|
84
|
+
if (this.alShift !== -1) {
|
|
85
|
+
this.accessory.alController = new platform.api.hap.AdaptiveLightingController(this.service, {
|
|
86
|
+
customTemperatureAdjustment: this.alShift,
|
|
87
|
+
})
|
|
88
|
+
this.accessory.configureController(this.accessory.alController)
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// Add the get handlers only if the user hasn't disabled the disableNoResponse setting
|
|
92
|
+
if (!platform.config.disableNoResponse) {
|
|
93
|
+
this.service.getCharacteristic(this.hapChar.On).onGet(() => {
|
|
94
|
+
if (!this.isOnline) {
|
|
95
|
+
throw new this.hapErr(-70402)
|
|
96
|
+
}
|
|
97
|
+
return this.service.getCharacteristic(this.hapChar.On).value
|
|
98
|
+
})
|
|
99
|
+
this.service
|
|
100
|
+
.getCharacteristic(this.hapChar.Brightness)
|
|
101
|
+
.onGet(() => {
|
|
102
|
+
if (!this.isOnline) {
|
|
103
|
+
throw new this.hapErr(-70402)
|
|
104
|
+
}
|
|
105
|
+
return this.service.getCharacteristic(this.hapChar.Brightness).value
|
|
106
|
+
})
|
|
107
|
+
this.service.getCharacteristic(this.hapChar.Hue).onGet(() => {
|
|
108
|
+
if (!this.isOnline) {
|
|
109
|
+
throw new this.hapErr(-70402)
|
|
110
|
+
}
|
|
111
|
+
return this.service.getCharacteristic(this.hapChar.Hue).value
|
|
112
|
+
})
|
|
113
|
+
this.service.getCharacteristic(this.hapChar.ColorTemperature).onGet(() => {
|
|
114
|
+
if (!this.isOnline) {
|
|
115
|
+
throw new this.hapErr(-70402)
|
|
116
|
+
}
|
|
117
|
+
return this.service.getCharacteristic(this.hapChar.ColorTemperature).value
|
|
118
|
+
})
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// Output the customised options to the log
|
|
122
|
+
const normalLogging = this.enableLogging ? 'standard' : 'disable'
|
|
123
|
+
const opts = JSON.stringify({
|
|
124
|
+
adaptiveLightingShift: this.alShift,
|
|
125
|
+
brightnessStep: this.brightStep,
|
|
126
|
+
logging: this.enableDebugLogging ? 'debug' : normalLogging,
|
|
127
|
+
})
|
|
128
|
+
this.log('[%s] %s %s.', this.name, this.lang.devInitOpts, opts)
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
async internalStateUpdate(value) {
|
|
132
|
+
try {
|
|
133
|
+
const newValue = value ? 'on' : 'off'
|
|
134
|
+
await this.platform.sendDeviceUpdate(this.accessory, {
|
|
135
|
+
switch: newValue,
|
|
136
|
+
})
|
|
137
|
+
this.cacheState = newValue
|
|
138
|
+
if (this.enableLogging) {
|
|
139
|
+
this.log('[%s] %s [%s].', this.name, this.lang.curState, this.cacheState)
|
|
140
|
+
}
|
|
141
|
+
} catch (err) {
|
|
142
|
+
this.platform.deviceUpdateError(this.accessory, err, true)
|
|
143
|
+
setTimeout(() => {
|
|
144
|
+
this.service.updateCharacteristic(this.hapChar.On, this.cacheState === 'on')
|
|
145
|
+
}, 2000)
|
|
146
|
+
throw new this.hapErr(-70402)
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
async internalBrightnessUpdate(value) {
|
|
151
|
+
try {
|
|
152
|
+
if (this.cacheBright === value || value === 0) {
|
|
153
|
+
return
|
|
154
|
+
}
|
|
155
|
+
const updateKey = generateRandomString(5)
|
|
156
|
+
this.updateKeyBright = updateKey
|
|
157
|
+
await sleep(500)
|
|
158
|
+
if (updateKey !== this.updateKeyBright) {
|
|
159
|
+
return
|
|
160
|
+
}
|
|
161
|
+
const params = {}
|
|
162
|
+
switch (this.cacheMode) {
|
|
163
|
+
case 'color':
|
|
164
|
+
params.rgbBrightness = value
|
|
165
|
+
break
|
|
166
|
+
case 'white':
|
|
167
|
+
params.cctBrightness = value
|
|
168
|
+
break
|
|
169
|
+
default:
|
|
170
|
+
throw new Error('Color mode not set')
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
await this.platform.sendDeviceUpdate(this.accessory, params)
|
|
174
|
+
this.cacheBright = value
|
|
175
|
+
if (this.enableLogging) {
|
|
176
|
+
this.log('[%s] %s [%s%].', this.name, this.lang.curBright, this.cacheBright)
|
|
177
|
+
}
|
|
178
|
+
} catch (err) {
|
|
179
|
+
this.platform.deviceUpdateError(this.accessory, err, true)
|
|
180
|
+
setTimeout(() => {
|
|
181
|
+
this.service.updateCharacteristic(this.hapChar.Brightness, this.cacheBright)
|
|
182
|
+
}, 2000)
|
|
183
|
+
throw new this.hapErr(-70402)
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
async internalColourUpdate(value) {
|
|
188
|
+
try {
|
|
189
|
+
if (this.cacheHue === value) {
|
|
190
|
+
return
|
|
191
|
+
}
|
|
192
|
+
const updateKey = generateRandomString(5)
|
|
193
|
+
this.updateKey = updateKey
|
|
194
|
+
await sleep(400)
|
|
195
|
+
if (updateKey !== this.updateKey) {
|
|
196
|
+
return
|
|
197
|
+
}
|
|
198
|
+
this.updateTimeout = updateKey
|
|
199
|
+
setTimeout(() => {
|
|
200
|
+
if (this.updateTimeout === updateKey) {
|
|
201
|
+
this.updateTimeout = false
|
|
202
|
+
}
|
|
203
|
+
}, 5000)
|
|
204
|
+
this.service.updateCharacteristic(this.hapChar.ColorTemperature, 140)
|
|
205
|
+
const params = {
|
|
206
|
+
hue: value,
|
|
207
|
+
saturation: this.cacheSat,
|
|
208
|
+
}
|
|
209
|
+
if (this.cacheMode !== 'color') {
|
|
210
|
+
params.colorMode = 'rgb'
|
|
211
|
+
}
|
|
212
|
+
await this.platform.sendDeviceUpdate(this.accessory, params)
|
|
213
|
+
this.cacheHue = value
|
|
214
|
+
this.cacheSat = this.service.getCharacteristic(this.hapChar.Saturation).value
|
|
215
|
+
this.cacheMired = 0
|
|
216
|
+
this.cacheCT = 0
|
|
217
|
+
this.cacheMode = 'color'
|
|
218
|
+
if (this.enableLogging) {
|
|
219
|
+
this.log(
|
|
220
|
+
'[%s] %s [hue %s saturation %s].',
|
|
221
|
+
this.name,
|
|
222
|
+
this.lang.curColour,
|
|
223
|
+
`${this.cacheHue} ${this.cacheSat}`,
|
|
224
|
+
)
|
|
225
|
+
}
|
|
226
|
+
} catch (err) {
|
|
227
|
+
this.platform.deviceUpdateError(this.accessory, err, true)
|
|
228
|
+
setTimeout(() => {
|
|
229
|
+
this.service.updateCharacteristic(this.hapChar.Hue, this.cacheHue)
|
|
230
|
+
}, 2000)
|
|
231
|
+
throw new this.hapErr(-70402)
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
async internalCTUpdate(value) {
|
|
236
|
+
try {
|
|
237
|
+
if (this.cacheMired === value) {
|
|
238
|
+
return
|
|
239
|
+
}
|
|
240
|
+
if (
|
|
241
|
+
this.accessory.alController
|
|
242
|
+
&& this.accessory.alController.isAdaptiveLightingActive()
|
|
243
|
+
&& (this.cacheState !== 'on')
|
|
244
|
+
) {
|
|
245
|
+
return
|
|
246
|
+
}
|
|
247
|
+
const updateKey = generateRandomString(5)
|
|
248
|
+
this.updateKeyCT = updateKey
|
|
249
|
+
await sleep(400)
|
|
250
|
+
if (updateKey !== this.updateKeyCT) {
|
|
251
|
+
return
|
|
252
|
+
}
|
|
253
|
+
const hs = m2hs(value)
|
|
254
|
+
this.service.updateCharacteristic(this.hapChar.Hue, hs[0])
|
|
255
|
+
this.service.updateCharacteristic(this.hapChar.Saturation, hs[1])
|
|
256
|
+
const mToK = Math.max(Math.min(Math.round(1000000 / value), 6500), 2700)
|
|
257
|
+
const kelvin = Math.round(1000000 / value)
|
|
258
|
+
const scaledK = Math.max(Math.min(kelvin, this.maxK), this.minK)
|
|
259
|
+
const scaledCT = Math.round(((scaledK - this.minK) / (this.maxK - this.minK)) * 100)
|
|
260
|
+
const params = {
|
|
261
|
+
colorTemp: scaledCT,
|
|
262
|
+
}
|
|
263
|
+
if (this.cacheMode !== 'white') {
|
|
264
|
+
params.colorMode = 'cct'
|
|
265
|
+
}
|
|
266
|
+
await this.platform.sendDeviceUpdate(this.accessory, params)
|
|
267
|
+
this.cacheMired = value
|
|
268
|
+
this.cacheCT = scaledCT
|
|
269
|
+
if (this.enableLogging) {
|
|
270
|
+
if (this.accessory.alController && this.accessory.alController.isAdaptiveLightingActive()) {
|
|
271
|
+
this.log('[%s] %s [%sK] %s.', this.name, this.lang.curColour, mToK, this.lang.viaAL)
|
|
272
|
+
} else {
|
|
273
|
+
this.log('[%s] %s [%sK].', this.name, this.lang.curColour, mToK)
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
} catch (err) {
|
|
277
|
+
this.platform.deviceUpdateError(this.accessory, err, true)
|
|
278
|
+
setTimeout(() => {
|
|
279
|
+
this.service.updateCharacteristic(this.hapChar.ColorTemperature, this.cacheMired)
|
|
280
|
+
}, 2000)
|
|
281
|
+
throw new this.hapErr(-70402)
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
async externalUpdate(params) {
|
|
286
|
+
try {
|
|
287
|
+
if (params.switch && params.switch !== this.cacheState) {
|
|
288
|
+
this.cacheState = params.switch
|
|
289
|
+
this.service.updateCharacteristic(this.hapChar.On, this.cacheState === 'on')
|
|
290
|
+
if (params.updateSource && this.enableLogging) {
|
|
291
|
+
this.log('[%s] %s [%s].', this.name, this.lang.curState, this.cacheState)
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
// How to tell which mode the bulb is in
|
|
296
|
+
// params.colorMode can be "rgb" or "cct"
|
|
297
|
+
// params.rgbBrightness is the brightness of the bulb when in rgb mode 0-100
|
|
298
|
+
// params.cctBrightness is the brightness of the bulb when in cct mode 0-100
|
|
299
|
+
// params.colorTemp is the colour temperature of the bulb when in cct mode 0-100
|
|
300
|
+
// params.hue is the hue of the bulb when in rgb mode 0-360
|
|
301
|
+
// params.saturation is the saturation of the bulb when in rgb mode 0-100
|
|
302
|
+
// when the plugin first loads we will have all the info
|
|
303
|
+
|
|
304
|
+
if (
|
|
305
|
+
params.colorMode === 'rgb'
|
|
306
|
+
|| (
|
|
307
|
+
this.cacheMode === 'color'
|
|
308
|
+
&& (
|
|
309
|
+
hasProperty(params, 'rgbBrightness')
|
|
310
|
+
|| hasProperty(params, 'hue')
|
|
311
|
+
|| hasProperty(params, 'saturation')
|
|
312
|
+
)
|
|
313
|
+
)
|
|
314
|
+
) {
|
|
315
|
+
this.cacheMode = 'color'
|
|
316
|
+
if (
|
|
317
|
+
this.accessory.alController
|
|
318
|
+
&& this.accessory.alController.isAdaptiveLightingActive()
|
|
319
|
+
) {
|
|
320
|
+
this.accessory.alController.disableAdaptiveLighting()
|
|
321
|
+
if (this.enableLogging) {
|
|
322
|
+
this.log('[%s] %s.', this.name, this.lang.disabledAL)
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
if (hasProperty(params, 'rgbBrightness') && params.rgbBrightness !== this.cacheBright) {
|
|
327
|
+
this.cacheBright = params.rgbBrightness
|
|
328
|
+
this.service.updateCharacteristic(this.hapChar.Brightness, this.cacheBright)
|
|
329
|
+
if (params.updateSource && this.enableLogging) {
|
|
330
|
+
this.log('[%s] %s [%s%].', this.name, this.lang.curBright, this.cacheBright)
|
|
331
|
+
}
|
|
332
|
+
this.cacheBright = params.rgbBrightness
|
|
333
|
+
this.service.updateCharacteristic(this.hapChar.Brightness, this.cacheBright)
|
|
334
|
+
}
|
|
335
|
+
if (
|
|
336
|
+
(hasProperty(params, 'hue') && params.hue !== this.cacheHue)
|
|
337
|
+
|| (hasProperty(params, 'saturation') && params.saturation !== this.cacheSat)
|
|
338
|
+
) {
|
|
339
|
+
this.cacheHue = hasProperty(params, 'hue') ? params.hue : this.cacheHue
|
|
340
|
+
this.cacheSat = hasProperty(params, 'saturation') ? params.saturation : this.cacheSat
|
|
341
|
+
this.service.updateCharacteristic(this.hapChar.Hue, this.cacheHue)
|
|
342
|
+
this.service.updateCharacteristic(this.hapChar.Saturation, this.cacheSat)
|
|
343
|
+
if (params.updateSource && this.enableLogging) {
|
|
344
|
+
this.log(
|
|
345
|
+
'[%s] %s [hue %s saturation %s].',
|
|
346
|
+
this.name,
|
|
347
|
+
this.lang.curColour,
|
|
348
|
+
`${this.cacheHue} ${this.cacheSat}`,
|
|
349
|
+
)
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
} else if (
|
|
353
|
+
params.colorMode === 'cct'
|
|
354
|
+
|| (
|
|
355
|
+
this.cacheMode === 'white'
|
|
356
|
+
&& (
|
|
357
|
+
hasProperty(params, 'cctBrightness')
|
|
358
|
+
|| hasProperty(params, 'colorTemp')
|
|
359
|
+
)
|
|
360
|
+
)
|
|
361
|
+
) {
|
|
362
|
+
this.cacheMode = 'white'
|
|
363
|
+
if (hasProperty(params, 'cctBrightness') && params.cctBrightness !== this.cacheBright) {
|
|
364
|
+
this.cacheBright = params.cctBrightness
|
|
365
|
+
this.service.updateCharacteristic(this.hapChar.Brightness, this.cacheBright)
|
|
366
|
+
if (params.updateSource && this.enableLogging) {
|
|
367
|
+
this.log('[%s] %s [%s%].', this.name, this.lang.curBright, this.cacheBright)
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
if (hasProperty(params, 'colorTemp') && params.colorTemp !== this.cacheCT) {
|
|
371
|
+
const ctDiff = Math.abs(params.colorTemp - this.cacheCT)
|
|
372
|
+
this.cacheCT = params.colorTemp
|
|
373
|
+
const kelvin = Math.round(((this.cacheCT / 100) * (this.maxK - this.minK)) + this.minK)
|
|
374
|
+
this.cacheMired = Math.round(1000000 / kelvin)
|
|
375
|
+
this.service.updateCharacteristic(this.hapChar.ColorTemperature, this.cacheMired)
|
|
376
|
+
if (
|
|
377
|
+
this.accessory.alController
|
|
378
|
+
&& this.accessory.alController.isAdaptiveLightingActive()
|
|
379
|
+
&& ctDiff > 20
|
|
380
|
+
) {
|
|
381
|
+
// Look for a variation greater than twenty
|
|
382
|
+
this.accessory.alController.disableAdaptiveLighting()
|
|
383
|
+
if (this.enableLogging) {
|
|
384
|
+
this.log('[%s] %s.', this.name, this.lang.disabledAL)
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
if (params.updateSource && this.enableLogging) {
|
|
388
|
+
this.log('[%s] %s [%sK].', this.name, this.lang.curColour, kelvin)
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
} catch (err) {
|
|
393
|
+
this.platform.deviceUpdateError(this.accessory, err, false)
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
markStatus(isOnline) {
|
|
398
|
+
this.isOnline = isOnline
|
|
399
|
+
}
|
|
400
|
+
}
|