@homebridge-plugins/homebridge-wemo 7.0.0
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 +809 -0
- package/LICENSE +21 -0
- package/README.md +66 -0
- package/config.schema.json +814 -0
- package/eslint.config.js +50 -0
- package/lib/connection/http.js +174 -0
- package/lib/connection/upnp.js +155 -0
- package/lib/device/coffee.js +167 -0
- package/lib/device/crockpot.js +380 -0
- package/lib/device/dimmer.js +280 -0
- package/lib/device/heater.js +416 -0
- package/lib/device/humidifier.js +379 -0
- package/lib/device/index.js +39 -0
- package/lib/device/insight.js +353 -0
- package/lib/device/lightswitch.js +154 -0
- package/lib/device/link-bulb.js +467 -0
- package/lib/device/link-hub.js +63 -0
- package/lib/device/maker-garage.js +426 -0
- package/lib/device/maker-switch.js +202 -0
- package/lib/device/motion.js +148 -0
- package/lib/device/outlet.js +148 -0
- package/lib/device/purifier.js +468 -0
- package/lib/device/simulation/purifier-insight.js +357 -0
- package/lib/device/simulation/purifier.js +159 -0
- package/lib/device/simulation/switch-insight.js +315 -0
- package/lib/device/simulation/switch.js +154 -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 +315 -0
- package/lib/homebridge-ui/server.js +10 -0
- package/lib/index.js +8 -0
- package/lib/platform.js +1423 -0
- package/lib/utils/colour.js +135 -0
- package/lib/utils/constants.js +129 -0
- package/lib/utils/eve-chars.js +130 -0
- package/lib/utils/functions.js +52 -0
- package/lib/utils/lang-en.js +125 -0
- package/package.json +70 -0
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
import platformConsts from '../../utils/constants.js'
|
|
2
|
+
import { hasProperty, parseError } from '../../utils/functions.js'
|
|
3
|
+
import platformLang from '../../utils/lang-en.js'
|
|
4
|
+
|
|
5
|
+
export default class {
|
|
6
|
+
constructor(platform, accessory) {
|
|
7
|
+
// Set up variables from the platform
|
|
8
|
+
this.eveChar = platform.eveChar
|
|
9
|
+
this.hapChar = platform.api.hap.Characteristic
|
|
10
|
+
this.hapErr = platform.api.hap.HapStatusError
|
|
11
|
+
this.hapServ = platform.api.hap.Service
|
|
12
|
+
this.platform = platform
|
|
13
|
+
|
|
14
|
+
// Set up variables from the accessory
|
|
15
|
+
this.accessory = accessory
|
|
16
|
+
|
|
17
|
+
// Set up custom variables for this device type
|
|
18
|
+
const deviceConf = platform.deviceConf[accessory.context.serialNumber] || {}
|
|
19
|
+
this.showTodayTC = deviceConf.showTodayTC
|
|
20
|
+
this.wattDiff = deviceConf.wattDiff || platformConsts.defaultValues.wattDiff
|
|
21
|
+
this.timeDiff = deviceConf.timeDiff || platformConsts.defaultValues.timeDiff
|
|
22
|
+
if (this.timeDiff === 1) {
|
|
23
|
+
this.timeDiff = false
|
|
24
|
+
}
|
|
25
|
+
this.skipTimeDiff = false
|
|
26
|
+
|
|
27
|
+
if (!hasProperty(this.accessory.context, 'cacheLastWM')) {
|
|
28
|
+
this.accessory.context.cacheLastWM = 0
|
|
29
|
+
}
|
|
30
|
+
if (!hasProperty(this.accessory.context, 'cacheLastTC')) {
|
|
31
|
+
this.accessory.context.cacheLastTC = 0
|
|
32
|
+
}
|
|
33
|
+
if (!hasProperty(this.accessory.context, 'cacheTotalTC')) {
|
|
34
|
+
this.accessory.context.cacheTotalTC = 0
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// If the accessory has an air purifier service then remove it
|
|
38
|
+
if (this.accessory.getService(this.hapServ.AirPurifier)) {
|
|
39
|
+
this.accessory.removeService(this.accessory.getService(this.hapServ.AirPurifier))
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// If the accessory has an outlet service then remove it
|
|
43
|
+
if (this.accessory.getService(this.hapServ.Outlet)) {
|
|
44
|
+
this.accessory.removeService(this.accessory.getService(this.hapServ.Outlet))
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Add the switch service if it doesn't already exist
|
|
48
|
+
this.service = this.accessory.getService(this.hapServ.Switch)
|
|
49
|
+
if (!this.service) {
|
|
50
|
+
this.service = this.accessory.addService(this.hapServ.Switch)
|
|
51
|
+
this.service.addCharacteristic(this.eveChar.CurrentConsumption)
|
|
52
|
+
this.service.addCharacteristic(this.eveChar.TotalConsumption)
|
|
53
|
+
this.service.addCharacteristic(this.eveChar.ResetTotal)
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Add the set handler to the switch on/off characteristic
|
|
57
|
+
this.service
|
|
58
|
+
.getCharacteristic(this.hapChar.On)
|
|
59
|
+
.removeOnSet()
|
|
60
|
+
.onSet(async value => this.internalStateUpdate(value))
|
|
61
|
+
|
|
62
|
+
// Add the set handler to the switch reset (eve) characteristic
|
|
63
|
+
this.service.getCharacteristic(this.eveChar.ResetTotal).onSet(() => {
|
|
64
|
+
this.accessory.context.cacheLastWM = 0
|
|
65
|
+
this.accessory.context.cacheLastTC = 0
|
|
66
|
+
this.accessory.context.cacheTotalTC = 0
|
|
67
|
+
this.service.updateCharacteristic(this.eveChar.TotalConsumption, 0)
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
// Pass the accessory to fakegato to set up the Eve info service
|
|
71
|
+
this.accessory.historyService = new platform.eveService('switch', this.accessory, {
|
|
72
|
+
log: () => {},
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
// Output the customised options to the log
|
|
76
|
+
const opts = JSON.stringify({
|
|
77
|
+
showAs: 'switch',
|
|
78
|
+
showTodayTC: this.showTodayTC,
|
|
79
|
+
timeDiff: this.timeDiff,
|
|
80
|
+
wattDiff: this.wattDiff,
|
|
81
|
+
})
|
|
82
|
+
platform.log('[%s] %s %s.', accessory.displayName, platformLang.devInitOpts, opts)
|
|
83
|
+
|
|
84
|
+
// Request a device update immediately
|
|
85
|
+
this.requestDeviceUpdate()
|
|
86
|
+
|
|
87
|
+
// Start a polling interval if the user has disabled upnp
|
|
88
|
+
if (this.accessory.context.connection === 'http') {
|
|
89
|
+
this.pollingInterval = setInterval(
|
|
90
|
+
() => this.requestDeviceUpdate(),
|
|
91
|
+
platform.config.pollingInterval * 1000,
|
|
92
|
+
)
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
receiveDeviceUpdate(attribute) {
|
|
97
|
+
// Log the receiving update if debug is enabled
|
|
98
|
+
this.accessory.logDebug(`${platformLang.recUpd} [${attribute.name}: ${JSON.stringify(attribute.value)}]`)
|
|
99
|
+
|
|
100
|
+
// Let's see which attribute has been provided
|
|
101
|
+
switch (attribute.name) {
|
|
102
|
+
case 'BinaryState': {
|
|
103
|
+
// BinaryState is reported as 0=off, 1=on, 8=standby
|
|
104
|
+
// Send a HomeKit needed true/false argument (0=false, 1,8=true)
|
|
105
|
+
this.externalStateUpdate(attribute.value !== 0)
|
|
106
|
+
break
|
|
107
|
+
}
|
|
108
|
+
case 'InsightParams':
|
|
109
|
+
// Send the insight data straight to the function
|
|
110
|
+
this.externalInsightUpdate(
|
|
111
|
+
attribute.value.state,
|
|
112
|
+
attribute.value.power,
|
|
113
|
+
attribute.value.todayWm,
|
|
114
|
+
attribute.value.todayOnSeconds,
|
|
115
|
+
)
|
|
116
|
+
break
|
|
117
|
+
default:
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
async sendDeviceUpdate(value) {
|
|
122
|
+
// Log the sending update if debug is enabled
|
|
123
|
+
this.accessory.logDebug(`${platformLang.senUpd} ${JSON.stringify(value)}`)
|
|
124
|
+
|
|
125
|
+
// Send the update
|
|
126
|
+
await this.platform.httpClient.sendDeviceUpdate(
|
|
127
|
+
this.accessory,
|
|
128
|
+
'urn:Belkin:service:basicevent:1',
|
|
129
|
+
'SetBinaryState',
|
|
130
|
+
value,
|
|
131
|
+
)
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
async requestDeviceUpdate() {
|
|
135
|
+
try {
|
|
136
|
+
// Request the update
|
|
137
|
+
const data = await this.platform.httpClient.sendDeviceUpdate(
|
|
138
|
+
this.accessory,
|
|
139
|
+
'urn:Belkin:service:basicevent:1',
|
|
140
|
+
'GetBinaryState',
|
|
141
|
+
)
|
|
142
|
+
|
|
143
|
+
// Check for existence since BinaryState can be int 0
|
|
144
|
+
if (hasProperty(data, 'BinaryState')) {
|
|
145
|
+
this.receiveDeviceUpdate({
|
|
146
|
+
name: 'BinaryState',
|
|
147
|
+
value: Number.parseInt(data.BinaryState, 10),
|
|
148
|
+
})
|
|
149
|
+
}
|
|
150
|
+
} catch (err) {
|
|
151
|
+
const eText = parseError(err, [
|
|
152
|
+
platformLang.timeout,
|
|
153
|
+
platformLang.timeoutUnreach,
|
|
154
|
+
platformLang.noService,
|
|
155
|
+
])
|
|
156
|
+
this.accessory.logDebugWarn(`${platformLang.rduErr} ${eText}`)
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
async internalStateUpdate(value) {
|
|
161
|
+
try {
|
|
162
|
+
// Send the update
|
|
163
|
+
await this.sendDeviceUpdate({
|
|
164
|
+
BinaryState: value ? 1 : 0,
|
|
165
|
+
})
|
|
166
|
+
|
|
167
|
+
// Update the cache value
|
|
168
|
+
this.cacheState = value
|
|
169
|
+
|
|
170
|
+
// Log the change if appropriate
|
|
171
|
+
this.accessory.log(`${platformLang.curState} [${value ? 'on' : 'off'}]`)
|
|
172
|
+
|
|
173
|
+
// If turning the switch off then update the current consumption
|
|
174
|
+
if (!value) {
|
|
175
|
+
// Update the HomeKit characteristics
|
|
176
|
+
this.service.updateCharacteristic(this.eveChar.CurrentConsumption, 0)
|
|
177
|
+
|
|
178
|
+
// Add an Eve entry for no power
|
|
179
|
+
this.accessory.historyService.addEntry({ power: 0 })
|
|
180
|
+
|
|
181
|
+
// Log the change if appropriate
|
|
182
|
+
this.accessory.log(`${platformLang.curCons} [0W]`)
|
|
183
|
+
}
|
|
184
|
+
} catch (err) {
|
|
185
|
+
const eText = parseError(err, [platformLang.timeout, platformLang.timeoutUnreach])
|
|
186
|
+
this.accessory.logWarn(`${platformLang.cantCtl} ${eText}`)
|
|
187
|
+
|
|
188
|
+
// Throw a 'no response' error and set a timeout to revert this after 2 seconds
|
|
189
|
+
setTimeout(() => {
|
|
190
|
+
this.service.updateCharacteristic(this.hapChar.On, this.cacheState)
|
|
191
|
+
}, 2000)
|
|
192
|
+
throw new this.hapErr(-70402)
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
externalInsightUpdate(value, power, todayWm, todayOnSeconds) {
|
|
197
|
+
// Update whether the switch is ON (value=1) or OFF (value=0)
|
|
198
|
+
this.externalStateUpdate(value !== 0)
|
|
199
|
+
|
|
200
|
+
// Update the total consumption
|
|
201
|
+
this.externalTotalConsumptionUpdate(todayWm, todayOnSeconds)
|
|
202
|
+
|
|
203
|
+
// Update the current consumption
|
|
204
|
+
this.externalConsumptionUpdate(power)
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
externalStateUpdate(value) {
|
|
208
|
+
try {
|
|
209
|
+
// Check to see if the cache value is different
|
|
210
|
+
if (value === this.cacheState) {
|
|
211
|
+
return
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
// Update the HomeKit characteristics
|
|
215
|
+
this.service.updateCharacteristic(this.hapChar.On, value)
|
|
216
|
+
|
|
217
|
+
// Update the cache value
|
|
218
|
+
this.cacheState = value
|
|
219
|
+
|
|
220
|
+
// Log the change if appropriate
|
|
221
|
+
this.accessory.log(`${platformLang.curState} [${value ? 'on' : 'off'}]`)
|
|
222
|
+
|
|
223
|
+
// If the device has turned off then update the consumption
|
|
224
|
+
if (!value) {
|
|
225
|
+
this.externalConsumptionUpdate(0)
|
|
226
|
+
}
|
|
227
|
+
} catch (err) {
|
|
228
|
+
// Catch any errors
|
|
229
|
+
this.accessory.logWarn(`${platformLang.cantUpd} ${parseError(err)}`)
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
externalConsumptionUpdate(power) {
|
|
234
|
+
try {
|
|
235
|
+
// Divide by 1000 to get the power value in W
|
|
236
|
+
const powerInWatts = Math.round(power / 1000)
|
|
237
|
+
|
|
238
|
+
// Check to see if the cache value is different
|
|
239
|
+
if (powerInWatts === this.cachePowerInWatts) {
|
|
240
|
+
return
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
// Update the power in watts cache
|
|
244
|
+
this.cachePowerInWatts = powerInWatts
|
|
245
|
+
|
|
246
|
+
// Update the HomeKit characteristic
|
|
247
|
+
this.service.updateCharacteristic(this.eveChar.CurrentConsumption, this.cachePowerInWatts)
|
|
248
|
+
|
|
249
|
+
// Add the Eve wattage entry
|
|
250
|
+
this.accessory.historyService.addEntry({ power: this.cachePowerInWatts })
|
|
251
|
+
|
|
252
|
+
// Calculate a difference from the last reading
|
|
253
|
+
const diff = Math.abs(powerInWatts - this.cachePowerInWatts)
|
|
254
|
+
|
|
255
|
+
// Don't continue with logging if the user has set a timeout between entries or a min difference between entries
|
|
256
|
+
if (!this.skipTimeDiff && diff >= this.wattDiff) {
|
|
257
|
+
// Log the change if appropriate
|
|
258
|
+
this.accessory.log(`${platformLang.curCons} [${this.cachePowerInWatts}W]`)
|
|
259
|
+
|
|
260
|
+
// Set the time difference timeout if needed
|
|
261
|
+
if (this.timeDiff) {
|
|
262
|
+
this.skipTimeDiff = true
|
|
263
|
+
setTimeout(() => {
|
|
264
|
+
this.skipTimeDiff = false
|
|
265
|
+
}, this.timeDiff * 1000)
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
} catch (err) {
|
|
269
|
+
// Catch any errors
|
|
270
|
+
this.accessory.logWarn(`${platformLang.cantUpd} ${parseError(err)}`)
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
externalTotalConsumptionUpdate(todayWm, todayOnSeconds) {
|
|
275
|
+
try {
|
|
276
|
+
if (todayWm === this.accessory.context.cacheLastWM) {
|
|
277
|
+
return
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
// Update the cache last value
|
|
281
|
+
this.accessory.context.cacheLastWM = todayWm
|
|
282
|
+
|
|
283
|
+
// Convert to Wh (hours) from raw data of Wm (minutes)
|
|
284
|
+
const todayWh = Math.round(todayWm / 60000)
|
|
285
|
+
|
|
286
|
+
// Convert to kWh
|
|
287
|
+
const todaykWh = todayWh / 1000
|
|
288
|
+
|
|
289
|
+
// Convert to hours, minutes and seconds (HH:MM:SS)
|
|
290
|
+
const todayOnHours = new Date(todayOnSeconds * 1000).toISOString().substr(11, 8)
|
|
291
|
+
|
|
292
|
+
// Calculate the difference (ie extra usage from the last reading)
|
|
293
|
+
const difference = Math.max(todaykWh - this.accessory.context.cacheLastTC, 0)
|
|
294
|
+
|
|
295
|
+
// Update the caches
|
|
296
|
+
this.accessory.context.cacheTotalTC += difference
|
|
297
|
+
this.accessory.context.cacheLastTC = todaykWh
|
|
298
|
+
|
|
299
|
+
// Update the total consumption characteristic
|
|
300
|
+
this.service.updateCharacteristic(
|
|
301
|
+
this.eveChar.TotalConsumption,
|
|
302
|
+
this.showTodayTC ? todaykWh : this.accessory.context.cacheTotalTC,
|
|
303
|
+
)
|
|
304
|
+
|
|
305
|
+
if (!this.skipTimeDiff) {
|
|
306
|
+
this.accessory.log(
|
|
307
|
+
`${platformLang.insOnTime} [${todayOnHours}] ${platformLang.insCons} [${todaykWh.toFixed(3)} kWh] ${platformLang.insTC} [${this.accessory.context.cacheTotalTC.toFixed(3)} kWh]`,
|
|
308
|
+
)
|
|
309
|
+
}
|
|
310
|
+
} catch (err) {
|
|
311
|
+
// Catch any errors
|
|
312
|
+
this.accessory.logWarn(`${platformLang.cantUpd} ${parseError(err)}`)
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import { hasProperty, 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
|
+
// If the accessory has an outlet service then remove it
|
|
16
|
+
if (this.accessory.getService(this.hapServ.Outlet)) {
|
|
17
|
+
this.accessory.removeService(this.accessory.getService(this.hapServ.Outlet))
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// If the accessory has an air purifier service then remove it
|
|
21
|
+
if (this.accessory.getService(this.hapServ.AirPurifier)) {
|
|
22
|
+
this.accessory.removeService(this.accessory.getService(this.hapServ.AirPurifier))
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// Add the switch service if it doesn't already exist
|
|
26
|
+
this.service = this.accessory.getService(this.hapServ.Switch)
|
|
27
|
+
|| this.accessory.addService(this.hapServ.Switch)
|
|
28
|
+
|
|
29
|
+
// Add the set handler to the switch on/off characteristic
|
|
30
|
+
this.service
|
|
31
|
+
.getCharacteristic(this.hapChar.On)
|
|
32
|
+
.removeOnSet()
|
|
33
|
+
.onSet(async value => this.internalStateUpdate(value))
|
|
34
|
+
|
|
35
|
+
// Pass the accessory to fakegato to set up the eve info service
|
|
36
|
+
this.accessory.historyService = new platform.eveService('switch', this.accessory, {
|
|
37
|
+
log: () => {},
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
// Output the customised options to the log
|
|
41
|
+
const opts = JSON.stringify({
|
|
42
|
+
showAs: 'switch',
|
|
43
|
+
})
|
|
44
|
+
platform.log('[%s] %s %s.', accessory.displayName, platformLang.devInitOpts, opts)
|
|
45
|
+
|
|
46
|
+
// Request a device update immediately
|
|
47
|
+
this.requestDeviceUpdate()
|
|
48
|
+
|
|
49
|
+
// Start a polling interval if the user has disabled upnp
|
|
50
|
+
if (this.accessory.context.connection === 'http') {
|
|
51
|
+
this.pollingInterval = setInterval(
|
|
52
|
+
() => this.requestDeviceUpdate(),
|
|
53
|
+
platform.config.pollingInterval * 1000,
|
|
54
|
+
)
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
receiveDeviceUpdate(attribute) {
|
|
59
|
+
// Log the receiving update if debug is enabled
|
|
60
|
+
this.accessory.logDebug(`${platformLang.recUpd} [${attribute.name}: ${JSON.stringify(attribute.value)}]`)
|
|
61
|
+
|
|
62
|
+
// Send a HomeKit needed true/false argument
|
|
63
|
+
// attribute.value is 0 if and only if the switch is off
|
|
64
|
+
this.externalStateUpdate(attribute.value !== 0)
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
async sendDeviceUpdate(value) {
|
|
68
|
+
// Log the sending update if debug is enabled
|
|
69
|
+
this.accessory.logDebug(`${platformLang.senUpd} ${JSON.stringify(value)}`)
|
|
70
|
+
|
|
71
|
+
// Send the update
|
|
72
|
+
await this.platform.httpClient.sendDeviceUpdate(
|
|
73
|
+
this.accessory,
|
|
74
|
+
'urn:Belkin:service:basicevent:1',
|
|
75
|
+
'SetBinaryState',
|
|
76
|
+
value,
|
|
77
|
+
)
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
async requestDeviceUpdate() {
|
|
81
|
+
try {
|
|
82
|
+
// Request the update
|
|
83
|
+
const data = await this.platform.httpClient.sendDeviceUpdate(
|
|
84
|
+
this.accessory,
|
|
85
|
+
'urn:Belkin:service:basicevent:1',
|
|
86
|
+
'GetBinaryState',
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
// Check for existence since BinaryState can be int 0
|
|
90
|
+
if (hasProperty(data, 'BinaryState')) {
|
|
91
|
+
// Send the data to the receiver function
|
|
92
|
+
this.receiveDeviceUpdate({
|
|
93
|
+
name: 'BinaryState',
|
|
94
|
+
value: Number.parseInt(data.BinaryState, 10),
|
|
95
|
+
})
|
|
96
|
+
}
|
|
97
|
+
} catch (err) {
|
|
98
|
+
const eText = parseError(err, [
|
|
99
|
+
platformLang.timeout,
|
|
100
|
+
platformLang.timeoutUnreach,
|
|
101
|
+
platformLang.noService,
|
|
102
|
+
])
|
|
103
|
+
this.accessory.logDebugWarn(`${platformLang.rduErr} ${eText}`)
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
async internalStateUpdate(value) {
|
|
108
|
+
try {
|
|
109
|
+
// Send the update
|
|
110
|
+
await this.sendDeviceUpdate({
|
|
111
|
+
BinaryState: value ? 1 : 0,
|
|
112
|
+
})
|
|
113
|
+
|
|
114
|
+
// Update the cache value
|
|
115
|
+
this.cacheState = value
|
|
116
|
+
this.accessory.historyService.addEntry({ status: value ? 1 : 0 })
|
|
117
|
+
|
|
118
|
+
// Log the change if appropriate
|
|
119
|
+
this.accessory.log(`${platformLang.curState} [${value ? 'on' : 'off'}]`)
|
|
120
|
+
} catch (err) {
|
|
121
|
+
// Catch any errors
|
|
122
|
+
const eText = parseError(err, [platformLang.timeout, platformLang.timeoutUnreach])
|
|
123
|
+
this.accessory.logWarn(`${platformLang.cantCtl} ${eText}`)
|
|
124
|
+
|
|
125
|
+
// Throw a 'no response' error and set a timeout to revert this after 2 seconds
|
|
126
|
+
setTimeout(() => {
|
|
127
|
+
this.service.updateCharacteristic(this.hapChar.On, this.cacheState)
|
|
128
|
+
}, 2000)
|
|
129
|
+
throw new this.hapErr(-70402)
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
externalStateUpdate(value) {
|
|
134
|
+
try {
|
|
135
|
+
// Check to see if the cache value is different
|
|
136
|
+
if (value === this.cacheState) {
|
|
137
|
+
return
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// Update the HomeKit characteristic
|
|
141
|
+
this.service.updateCharacteristic(this.hapChar.On, value)
|
|
142
|
+
|
|
143
|
+
// Update the cache value
|
|
144
|
+
this.cacheState = value
|
|
145
|
+
|
|
146
|
+
// Log the change if appropriate
|
|
147
|
+
this.accessory.log(`${platformLang.curState} [${value ? 'on' : 'off'}]`)
|
|
148
|
+
this.accessory.historyService.addEntry({ status: value ? 1 : 0 })
|
|
149
|
+
} catch (err) {
|
|
150
|
+
// Catch any errors
|
|
151
|
+
this.accessory.logWarn(`${platformLang.cantUpd} ${parseError(err)}`)
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2017 simont77
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|