@homebridge-plugins/homebridge-govee 10.12.1
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 +1937 -0
- package/LICENSE +21 -0
- package/README.md +72 -0
- package/config.schema.json +1727 -0
- package/eslint.config.js +49 -0
- package/lib/connection/aws.js +174 -0
- package/lib/connection/ble.js +208 -0
- package/lib/connection/cert/AmazonRootCA1.pem +20 -0
- package/lib/connection/http.js +240 -0
- package/lib/connection/lan.js +284 -0
- package/lib/device/cooler-single.js +300 -0
- package/lib/device/dehumidifier-H7150.js +182 -0
- package/lib/device/dehumidifier-H7151.js +157 -0
- package/lib/device/diffuser-H7161.js +117 -0
- package/lib/device/diffuser-H7162.js +117 -0
- package/lib/device/fan-H7100.js +274 -0
- package/lib/device/fan-H7101.js +330 -0
- package/lib/device/fan-H7102.js +274 -0
- package/lib/device/fan-H7105.js +503 -0
- package/lib/device/fan-H7106.js +274 -0
- package/lib/device/fan-H7111.js +335 -0
- package/lib/device/heater-single.js +300 -0
- package/lib/device/heater1a.js +353 -0
- package/lib/device/heater1b.js +616 -0
- package/lib/device/heater2.js +838 -0
- package/lib/device/humidifier-H7140.js +224 -0
- package/lib/device/humidifier-H7141.js +257 -0
- package/lib/device/humidifier-H7142.js +522 -0
- package/lib/device/humidifier-H7143.js +157 -0
- package/lib/device/humidifier-H7148.js +157 -0
- package/lib/device/humidifier-H7160.js +446 -0
- package/lib/device/ice-maker-H7162.js +46 -0
- package/lib/device/index.js +105 -0
- package/lib/device/kettle.js +269 -0
- package/lib/device/light-switch.js +86 -0
- package/lib/device/light.js +617 -0
- package/lib/device/outlet-double.js +121 -0
- package/lib/device/outlet-single.js +172 -0
- package/lib/device/outlet-triple.js +160 -0
- package/lib/device/purifier-H7120.js +336 -0
- package/lib/device/purifier-H7121.js +336 -0
- package/lib/device/purifier-H7122.js +449 -0
- package/lib/device/purifier-H7123.js +411 -0
- package/lib/device/purifier-H7124.js +411 -0
- package/lib/device/purifier-H7126.js +296 -0
- package/lib/device/purifier-H7127.js +296 -0
- package/lib/device/purifier-H712C.js +296 -0
- package/lib/device/purifier-single.js +119 -0
- package/lib/device/sensor-button.js +22 -0
- package/lib/device/sensor-contact.js +22 -0
- package/lib/device/sensor-leak.js +87 -0
- package/lib/device/sensor-monitor.js +190 -0
- package/lib/device/sensor-presence.js +53 -0
- package/lib/device/sensor-thermo.js +144 -0
- package/lib/device/sensor-thermo4.js +55 -0
- package/lib/device/switch-double.js +121 -0
- package/lib/device/switch-single.js +95 -0
- package/lib/device/switch-triple.js +160 -0
- package/lib/device/tap-single.js +108 -0
- package/lib/device/template.js +43 -0
- package/lib/device/tv-single.js +84 -0
- package/lib/device/valve-single.js +155 -0
- package/lib/fakegato/LICENSE +21 -0
- package/lib/fakegato/fakegato-history.js +814 -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 +433 -0
- package/lib/homebridge-ui/server.js +10 -0
- package/lib/index.js +8 -0
- package/lib/platform.js +1967 -0
- package/lib/utils/colour.js +564 -0
- package/lib/utils/constants.js +579 -0
- package/lib/utils/custom-chars.js +225 -0
- package/lib/utils/eve-chars.js +68 -0
- package/lib/utils/functions.js +117 -0
- package/lib/utils/lang-en.js +131 -0
- package/package.json +75 -0
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { parseError } from '../utils/functions.js'
|
|
2
|
+
import platformLang from '../utils/lang-en.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.platform = platform
|
|
11
|
+
|
|
12
|
+
// Set up variables from the accessory
|
|
13
|
+
this.accessory = accessory
|
|
14
|
+
|
|
15
|
+
// Remove switch services if they exist
|
|
16
|
+
if (this.accessory.getService('Switch 1')) {
|
|
17
|
+
this.accessory.removeService(this.accessory.getService('Switch 1'))
|
|
18
|
+
}
|
|
19
|
+
if (this.accessory.getService('Switch 2')) {
|
|
20
|
+
this.accessory.removeService(this.accessory.getService('Switch 2'))
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// Add the outlet services if they don't already exist
|
|
24
|
+
this.service1 = this.accessory.getService('Outlet 1')
|
|
25
|
+
|| this.accessory.addService(this.hapServ.Outlet, 'Outlet 1', 'outlet1')
|
|
26
|
+
this.service2 = this.accessory.getService('Outlet 2')
|
|
27
|
+
|| this.accessory.addService(this.hapServ.Outlet, 'Outlet 2', 'outlet2')
|
|
28
|
+
|
|
29
|
+
if (!this.service1.testCharacteristic(this.hapChar.ConfiguredName)) {
|
|
30
|
+
this.service1.addCharacteristic(this.hapChar.ConfiguredName)
|
|
31
|
+
this.service1.updateCharacteristic(this.hapChar.ConfiguredName, 'Outlet 1')
|
|
32
|
+
}
|
|
33
|
+
if (!this.service1.testCharacteristic(this.hapChar.ServiceLabelIndex)) {
|
|
34
|
+
this.service1.addCharacteristic(this.hapChar.ServiceLabelIndex)
|
|
35
|
+
this.service1.updateCharacteristic(this.hapChar.ServiceLabelIndex, 1)
|
|
36
|
+
}
|
|
37
|
+
if (!this.service2.testCharacteristic(this.hapChar.ConfiguredName)) {
|
|
38
|
+
this.service2.addCharacteristic(this.hapChar.ConfiguredName)
|
|
39
|
+
this.service2.updateCharacteristic(this.hapChar.ConfiguredName, 'Outlet 2')
|
|
40
|
+
}
|
|
41
|
+
if (!this.service2.testCharacteristic(this.hapChar.ServiceLabelIndex)) {
|
|
42
|
+
this.service2.addCharacteristic(this.hapChar.ServiceLabelIndex)
|
|
43
|
+
this.service2.updateCharacteristic(this.hapChar.ServiceLabelIndex, 2)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Add the set handler to the switch on/off characteristic
|
|
47
|
+
this.service1.getCharacteristic(this.hapChar.On).onSet(async (value) => {
|
|
48
|
+
await this.internalStateUpdate(this.service1, value ? 17 : 16)
|
|
49
|
+
})
|
|
50
|
+
this.service1.cacheState = this.service1.getCharacteristic(this.hapChar.On).value ? 'on' : 'off'
|
|
51
|
+
this.service2.getCharacteristic(this.hapChar.On).onSet(async (value) => {
|
|
52
|
+
await this.internalStateUpdate(this.service2, value ? 34 : 32)
|
|
53
|
+
})
|
|
54
|
+
this.service2.cacheState = this.service2.getCharacteristic(this.hapChar.On).value ? 'on' : 'off'
|
|
55
|
+
|
|
56
|
+
// Output the customised options to the log
|
|
57
|
+
const opts = JSON.stringify({
|
|
58
|
+
showAs: 'outlet',
|
|
59
|
+
})
|
|
60
|
+
platform.log('[%s] %s %s.', accessory.displayName, platformLang.devInitOpts, opts)
|
|
61
|
+
|
|
62
|
+
// 51 turns BOTH ON
|
|
63
|
+
// 48 turns BOTH OFF
|
|
64
|
+
// 34 turns outlet 1 ON
|
|
65
|
+
// 32 turns outlet 1 OFF
|
|
66
|
+
// 17 turns outlet 2 ON
|
|
67
|
+
// 16 turns outlet 2 OFF
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
async internalStateUpdate(service, value) {
|
|
71
|
+
try {
|
|
72
|
+
const newValue = value % 16 === 0 ? 'off' : 'on'
|
|
73
|
+
|
|
74
|
+
// Don't continue if the new value is the same as before
|
|
75
|
+
if (service.cacheState === newValue) {
|
|
76
|
+
return
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Send the request to the platform sender function
|
|
80
|
+
await this.platform.sendDeviceUpdate(this.accessory, {
|
|
81
|
+
cmd: 'stateDual',
|
|
82
|
+
value,
|
|
83
|
+
})
|
|
84
|
+
|
|
85
|
+
// Cache the new state and log if appropriate
|
|
86
|
+
if (service.cacheState !== newValue) {
|
|
87
|
+
service.cacheState = newValue
|
|
88
|
+
this.accessory.log(`[${service.getCharacteristic(this.hapChar.ConfiguredName).value}] ${platformLang.curState} [${newValue}]`)
|
|
89
|
+
}
|
|
90
|
+
} catch (err) {
|
|
91
|
+
// Catch any errors during the process
|
|
92
|
+
this.accessory.logWarn(`${platformLang.devNotUpdated} ${parseError(err)}`)
|
|
93
|
+
|
|
94
|
+
// Throw a 'no response' error and set a timeout to revert this after 2 seconds
|
|
95
|
+
setTimeout(() => {
|
|
96
|
+
service.updateCharacteristic(this.hapChar.On, service.cacheState === 'on')
|
|
97
|
+
}, 2000)
|
|
98
|
+
throw new this.hapErr(-70402)
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
externalUpdate(params) {
|
|
103
|
+
if (!Array.isArray(params.state)) {
|
|
104
|
+
return
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
if (params.state[0] !== this.service1.cacheState) {
|
|
108
|
+
this.service1.cacheState = params.state[0]
|
|
109
|
+
this.service1.updateCharacteristic(this.hapChar.On, this.service1.cacheState === 'on')
|
|
110
|
+
|
|
111
|
+
this.accessory.log(`[${this.service1.getCharacteristic(this.hapChar.ConfiguredName).value}] ${platformLang.curState} [${this.service1.cacheState}]`)
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
if (params.state[1] !== this.service2.cacheState) {
|
|
115
|
+
this.service2.cacheState = params.state[1]
|
|
116
|
+
this.service2.updateCharacteristic(this.hapChar.On, this.service2.cacheState === 'on')
|
|
117
|
+
|
|
118
|
+
this.accessory.log(`[${this.service2.getCharacteristic(this.hapChar.ConfiguredName).value}] ${platformLang.curState} [${this.service2.cacheState}]`)
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import { base64ToHex, generateRandomString, getTwoItemPosition, hexToTwoItems, parseError } from '../utils/functions.js'
|
|
2
|
+
import platformLang from '../utils/lang-en.js'
|
|
3
|
+
|
|
4
|
+
export default class {
|
|
5
|
+
constructor(platform, accessory) {
|
|
6
|
+
// Set up variables from the platform
|
|
7
|
+
this.eveChar = platform.eveChar
|
|
8
|
+
this.hapChar = platform.api.hap.Characteristic
|
|
9
|
+
this.hapErr = platform.api.hap.HapStatusError
|
|
10
|
+
this.hapServ = platform.api.hap.Service
|
|
11
|
+
this.platform = platform
|
|
12
|
+
|
|
13
|
+
// Set up variables from the accessory
|
|
14
|
+
this.accessory = accessory;
|
|
15
|
+
|
|
16
|
+
// Remove any old services from simulations
|
|
17
|
+
['AirPurifier', 'HeaterCooler', 'Lightbulb', 'Switch', 'Valve'].forEach((service) => {
|
|
18
|
+
if (this.accessory.getService(this.hapServ[service])) {
|
|
19
|
+
this.accessory.removeService(this.accessory.getService(this.hapServ[service]))
|
|
20
|
+
}
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
// Add the outlet service if it doesn't already exist
|
|
24
|
+
this.service = this.accessory.getService(this.hapServ.Outlet)
|
|
25
|
+
|| this.accessory.addService(this.hapServ.Outlet)
|
|
26
|
+
|
|
27
|
+
// Add the set handler to the switch on/off characteristic
|
|
28
|
+
this.service.getCharacteristic(this.hapChar.On).onSet(async (value) => {
|
|
29
|
+
await this.internalStateUpdate(value)
|
|
30
|
+
})
|
|
31
|
+
this.cacheState = this.service.getCharacteristic(this.hapChar.On).value ? 'on' : 'off'
|
|
32
|
+
|
|
33
|
+
if (this.accessory.context.gvModel === 'H5086') {
|
|
34
|
+
// Power readings
|
|
35
|
+
if (!this.service.testCharacteristic(this.eveChar.CurrentConsumption)) {
|
|
36
|
+
this.service.addCharacteristic(this.eveChar.CurrentConsumption)
|
|
37
|
+
}
|
|
38
|
+
if (!this.service.testCharacteristic(this.eveChar.ElectricCurrent)) {
|
|
39
|
+
this.service.addCharacteristic(this.eveChar.ElectricCurrent)
|
|
40
|
+
}
|
|
41
|
+
if (!this.service.testCharacteristic(this.eveChar.Voltage)) {
|
|
42
|
+
this.service.addCharacteristic(this.eveChar.Voltage)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
this.cacheWatt = this.service.getCharacteristic(this.eveChar.CurrentConsumption).value || 0
|
|
46
|
+
this.cacheAmp = this.service.getCharacteristic(this.eveChar.ElectricCurrent).value || 0
|
|
47
|
+
this.cacheVolt = this.service.getCharacteristic(this.eveChar.Voltage).value || 0
|
|
48
|
+
|
|
49
|
+
// Pass the accessory to Fakegato to set up with Eve
|
|
50
|
+
this.accessory.eveService = new platform.eveService('energy', this.accessory, {
|
|
51
|
+
log: () => {},
|
|
52
|
+
})
|
|
53
|
+
} else {
|
|
54
|
+
// Pass the accessory to Fakegato to set up with Eve
|
|
55
|
+
this.accessory.eveService = new platform.eveService('switch', this.accessory, {
|
|
56
|
+
log: () => {},
|
|
57
|
+
})
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Output the customised options to the log
|
|
61
|
+
const opts = JSON.stringify({
|
|
62
|
+
showAs: 'outlet',
|
|
63
|
+
})
|
|
64
|
+
platform.log('[%s] %s %s.', accessory.displayName, platformLang.devInitOpts, opts)
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
async internalStateUpdate(value) {
|
|
68
|
+
try {
|
|
69
|
+
const newValue = value ? 'on' : 'off'
|
|
70
|
+
|
|
71
|
+
// Don't continue if the new value is the same as before
|
|
72
|
+
if (newValue === this.cacheState) {
|
|
73
|
+
return
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Set up a one-minute timeout for the plugin to ignore incoming updates
|
|
77
|
+
const timerKey = generateRandomString(5)
|
|
78
|
+
this.updateTimeout = timerKey
|
|
79
|
+
setTimeout(() => {
|
|
80
|
+
if (this.updateTimeout === timerKey) {
|
|
81
|
+
this.updateTimeout = false
|
|
82
|
+
}
|
|
83
|
+
}, 60000)
|
|
84
|
+
|
|
85
|
+
// Send the request to the platform sender function
|
|
86
|
+
await this.platform.sendDeviceUpdate(this.accessory, {
|
|
87
|
+
cmd: 'stateOutlet',
|
|
88
|
+
value: newValue,
|
|
89
|
+
})
|
|
90
|
+
|
|
91
|
+
// Cache the new state and log if appropriate
|
|
92
|
+
if (this.cacheState !== newValue) {
|
|
93
|
+
this.cacheState = newValue
|
|
94
|
+
this.accessory.log(`${platformLang.curState} [${this.cacheState}]`)
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Add the entry to the Eve history service
|
|
98
|
+
this.accessory.eveService.addEntry({ status: value ? 1 : 0 })
|
|
99
|
+
} catch (err) {
|
|
100
|
+
// Catch any errors during the process
|
|
101
|
+
this.accessory.logWarn(`${platformLang.devNotUpdated} ${parseError(err)}`)
|
|
102
|
+
|
|
103
|
+
// Throw a 'no response' error and set a timeout to revert this after 2 seconds
|
|
104
|
+
setTimeout(() => {
|
|
105
|
+
this.service.updateCharacteristic(this.hapChar.On, this.cacheState === 'on')
|
|
106
|
+
}, 2000)
|
|
107
|
+
throw new this.hapErr(-70402)
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
externalUpdate(params) {
|
|
112
|
+
// Check to see if the provided state is different from the cached state
|
|
113
|
+
if (params.state && params.state !== this.cacheState) {
|
|
114
|
+
// State is different so update Homebridge with new values
|
|
115
|
+
this.cacheState = params.state
|
|
116
|
+
this.service.updateCharacteristic(this.hapChar.On, this.cacheState === 'on')
|
|
117
|
+
|
|
118
|
+
// Log the change
|
|
119
|
+
this.accessory.log(`${platformLang.curState} [${this.cacheState}]`)
|
|
120
|
+
|
|
121
|
+
// Add the entry to the Eve history service
|
|
122
|
+
this.accessory.eveService.addEntry({
|
|
123
|
+
status: this.cacheState === 'on' ? 1 : 0,
|
|
124
|
+
})
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// Check for some other scene/mode change
|
|
128
|
+
(params.commands || []).forEach((command) => {
|
|
129
|
+
const hexString = base64ToHex(command)
|
|
130
|
+
const hexParts = hexToTwoItems(hexString)
|
|
131
|
+
|
|
132
|
+
// Return now if not a device query update code
|
|
133
|
+
if (getTwoItemPosition(hexParts, 1) !== 'aa') {
|
|
134
|
+
return
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
const deviceFunction = `${getTwoItemPosition(hexParts, 1)}${getTwoItemPosition(hexParts, 2)}`
|
|
138
|
+
|
|
139
|
+
switch (deviceFunction) {
|
|
140
|
+
case 'aa19': { // power readings
|
|
141
|
+
const hexWatt = `${getTwoItemPosition(hexParts, 13)}${getTwoItemPosition(hexParts, 14)}${getTwoItemPosition(hexParts, 15)}`
|
|
142
|
+
const hexAmp = `${getTwoItemPosition(hexParts, 11)}${getTwoItemPosition(hexParts, 12)}`
|
|
143
|
+
const hexVolt = `${getTwoItemPosition(hexParts, 9)}${getTwoItemPosition(hexParts, 10)}`
|
|
144
|
+
const newWatt = Number.parseInt(hexWatt, 16) / 100
|
|
145
|
+
const newAmp = Number.parseInt(hexAmp, 16) / 100
|
|
146
|
+
const newVolt = Number.parseInt(hexVolt, 16) / 100
|
|
147
|
+
|
|
148
|
+
if (this.cacheWatt !== newWatt) {
|
|
149
|
+
this.cacheWatt = newWatt
|
|
150
|
+
this.service.updateCharacteristic(this.eveChar.CurrentConsumption, this.cacheWatt)
|
|
151
|
+
this.accessory.eveService.addEntry({ power: newWatt })
|
|
152
|
+
this.accessory.log(`${platformLang.curWatt} [${this.cacheWatt}W]`)
|
|
153
|
+
}
|
|
154
|
+
if (this.cacheAmp !== newAmp) {
|
|
155
|
+
this.cacheAmp = newAmp
|
|
156
|
+
this.service.updateCharacteristic(this.eveChar.ElectricCurrent, this.cacheAmp)
|
|
157
|
+
this.accessory.log(`${platformLang.curAmp} [${this.cacheAmp}A]`)
|
|
158
|
+
}
|
|
159
|
+
if (this.cacheVolt !== newVolt) {
|
|
160
|
+
this.cacheVolt = newVolt
|
|
161
|
+
this.service.updateCharacteristic(this.eveChar.Voltage, this.cacheVolt)
|
|
162
|
+
this.accessory.log(`${platformLang.curVolt} [${this.cacheVolt}V]`)
|
|
163
|
+
}
|
|
164
|
+
break
|
|
165
|
+
}
|
|
166
|
+
default:
|
|
167
|
+
this.accessory.logDebugWarn(`${platformLang.newScene}: [${command}] [${hexString}]`)
|
|
168
|
+
break
|
|
169
|
+
}
|
|
170
|
+
})
|
|
171
|
+
}
|
|
172
|
+
}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { parseError } from '../utils/functions.js'
|
|
2
|
+
import platformLang from '../utils/lang-en.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.platform = platform
|
|
11
|
+
|
|
12
|
+
// Set up variables from the accessory
|
|
13
|
+
this.accessory = accessory
|
|
14
|
+
|
|
15
|
+
// Remove switch services if they exist
|
|
16
|
+
if (this.accessory.getService('Switch 1')) {
|
|
17
|
+
this.accessory.removeService(this.accessory.getService('Switch 1'))
|
|
18
|
+
}
|
|
19
|
+
if (this.accessory.getService('Switch 2')) {
|
|
20
|
+
this.accessory.removeService(this.accessory.getService('Switch 2'))
|
|
21
|
+
}
|
|
22
|
+
if (this.accessory.getService('Switch 3')) {
|
|
23
|
+
this.accessory.removeService(this.accessory.getService('Switch 3'))
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Add the outlet services if they don't already exist
|
|
27
|
+
this.service1 = this.accessory.getService('Outlet 1')
|
|
28
|
+
|| this.accessory.addService(this.hapServ.Outlet, 'Outlet 1', 'outlet1')
|
|
29
|
+
this.service2 = this.accessory.getService('Outlet 2')
|
|
30
|
+
|| this.accessory.addService(this.hapServ.Outlet, 'Outlet 2', 'outlet2')
|
|
31
|
+
this.service3 = this.accessory.getService('Outlet 3')
|
|
32
|
+
|| this.accessory.addService(this.hapServ.Outlet, 'Outlet 3', 'outlet3')
|
|
33
|
+
|
|
34
|
+
// Add the set handler to the switch on/off characteristic
|
|
35
|
+
this.service1.getCharacteristic(this.hapChar.On).onSet(async (value) => {
|
|
36
|
+
await this.internalStateUpdate(this.service1, value ? 17 : 16)
|
|
37
|
+
})
|
|
38
|
+
this.service1.cacheState = this.service1.getCharacteristic(this.hapChar.On).value ? 'on' : 'off'
|
|
39
|
+
this.service2.getCharacteristic(this.hapChar.On).onSet(async (value) => {
|
|
40
|
+
await this.internalStateUpdate(this.service2, value ? 34 : 32)
|
|
41
|
+
})
|
|
42
|
+
this.service2.cacheState = this.service2.getCharacteristic(this.hapChar.On).value ? 'on' : 'off'
|
|
43
|
+
this.service3.getCharacteristic(this.hapChar.On).onSet(async (value) => {
|
|
44
|
+
await this.internalStateUpdate(this.service3, value ? 68 : 64)
|
|
45
|
+
})
|
|
46
|
+
this.service3.cacheState = this.service3.getCharacteristic(this.hapChar.On).value ? 'on' : 'off'
|
|
47
|
+
|
|
48
|
+
// Output the customised options to the log
|
|
49
|
+
const opts = JSON.stringify({
|
|
50
|
+
showAs: 'outlet',
|
|
51
|
+
})
|
|
52
|
+
platform.log('[%s] %s %s.', accessory.displayName, platformLang.devInitOpts, opts)
|
|
53
|
+
|
|
54
|
+
// 119 turns BOTH ON
|
|
55
|
+
// 112 turns BOTH OFF
|
|
56
|
+
|
|
57
|
+
// 68 turns outlet 3 ON
|
|
58
|
+
// 64 turns outlet 3 OFF
|
|
59
|
+
|
|
60
|
+
// 34 turns outlet 2 ON
|
|
61
|
+
// 32 turns outlet 2 OFF
|
|
62
|
+
|
|
63
|
+
// 17 turns outlet 1 ON
|
|
64
|
+
// 16 turns outlet 1 OFF
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
async internalStateUpdate(service, value) {
|
|
68
|
+
try {
|
|
69
|
+
const newValue = value % 16 === 0 ? 'off' : 'on'
|
|
70
|
+
|
|
71
|
+
// Don't continue if the new value is the same as before
|
|
72
|
+
if (service.cacheState === newValue) {
|
|
73
|
+
return
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Send the request to the platform sender function
|
|
77
|
+
await this.platform.sendDeviceUpdate(this.accessory, {
|
|
78
|
+
cmd: 'stateDual',
|
|
79
|
+
value,
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
// Cache the new state and log if appropriate
|
|
83
|
+
service.cacheState = newValue
|
|
84
|
+
this.accessory.log(`[${service.displayName}] ${platformLang.curState} [${newValue}]`)
|
|
85
|
+
} catch (err) {
|
|
86
|
+
// Catch any errors during the process
|
|
87
|
+
this.accessory.logWarn(`${platformLang.devNotUpdated} ${parseError(err)}`)
|
|
88
|
+
|
|
89
|
+
// Throw a 'no response' error and set a timeout to revert this after 2 seconds
|
|
90
|
+
setTimeout(() => {
|
|
91
|
+
service.updateCharacteristic(this.hapChar.On, service.cacheState === 'on')
|
|
92
|
+
}, 2000)
|
|
93
|
+
throw new this.hapErr(-70402)
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
externalUpdate(params) {
|
|
98
|
+
// Check to see if the provided state is different from the cached state
|
|
99
|
+
if (!params.stateDual) {
|
|
100
|
+
return
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
if ([112, 119].includes(params.stateDual)) {
|
|
104
|
+
// 112 -> both off
|
|
105
|
+
// 119 -> both on
|
|
106
|
+
const newState = params.stateDual === 119 ? 'on' : 'off'
|
|
107
|
+
if (newState !== this.service1.cacheState) {
|
|
108
|
+
this.service1.cacheState = newState
|
|
109
|
+
this.service1.updateCharacteristic(this.hapChar.On, this.service1.cacheState === 'on')
|
|
110
|
+
|
|
111
|
+
// Log the change
|
|
112
|
+
this.accessory.log(`[${this.service1.displayName}] ${platformLang.curState} [${this.service1.cacheState}]`)
|
|
113
|
+
}
|
|
114
|
+
if (newState !== this.service2.cacheState) {
|
|
115
|
+
this.service2.cacheState = newState
|
|
116
|
+
this.service2.updateCharacteristic(this.hapChar.On, this.service2.cacheState === 'on')
|
|
117
|
+
|
|
118
|
+
// Log the change
|
|
119
|
+
this.accessory.log(`[${this.service2.displayName}] ${platformLang.curState} [${this.service2.cacheState}]`)
|
|
120
|
+
}
|
|
121
|
+
if (newState !== this.service3.cacheState) {
|
|
122
|
+
this.service3.cacheState = newState
|
|
123
|
+
this.service3.updateCharacteristic(this.hapChar.On, this.service3.cacheState === 'on')
|
|
124
|
+
|
|
125
|
+
// Log the change
|
|
126
|
+
this.accessory.log(`[${this.service3.displayName}] ${platformLang.curState} [${this.service3.cacheState}]`)
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
if ([16, 17].includes(params.stateDual)) {
|
|
130
|
+
const newState = params.stateDual === 17 ? 'on' : 'off'
|
|
131
|
+
if (newState !== this.service1.cacheState) {
|
|
132
|
+
this.service1.cacheState = newState
|
|
133
|
+
this.service1.updateCharacteristic(this.hapChar.On, this.service1.cacheState === 'on')
|
|
134
|
+
|
|
135
|
+
// Log the change
|
|
136
|
+
this.accessory.log(`[${this.service1.displayName}] ${platformLang.curState} [${this.service1.cacheState}]`)
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
if ([32, 34].includes(params.stateDual)) {
|
|
140
|
+
const newState = params.stateDual === 34 ? 'on' : 'off'
|
|
141
|
+
if (newState !== this.service2.cacheState) {
|
|
142
|
+
this.service2.cacheState = newState
|
|
143
|
+
this.service2.updateCharacteristic(this.hapChar.On, this.service2.cacheState === 'on')
|
|
144
|
+
|
|
145
|
+
// Log the change
|
|
146
|
+
this.accessory.log(`[${this.service2.displayName}] ${platformLang.curState} [${this.service2.cacheState}]`)
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
if ([64, 68].includes(params.stateDual)) {
|
|
150
|
+
const newState = params.stateDual === 68 ? 'on' : 'off'
|
|
151
|
+
if (newState !== this.service3.cacheState) {
|
|
152
|
+
this.service3.cacheState = newState
|
|
153
|
+
this.service3.updateCharacteristic(this.hapChar.On, this.service3.cacheState === 'on')
|
|
154
|
+
|
|
155
|
+
// Log the change
|
|
156
|
+
this.accessory.log(`[${this.service3.displayName}] ${platformLang.curState} [${this.service3.cacheState}]`)
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|