homebridge-lib 5.2.0 → 5.2.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/lib/EveHomeKitTypes.js +5 -0
- package/lib/Platform.js +0 -1
- package/lib/ServiceDelegate/AccessoryInformation.js +111 -0
- package/lib/ServiceDelegate/Battery.js +87 -0
- package/lib/ServiceDelegate/Dummy.js +44 -0
- package/lib/ServiceDelegate/History/Consumption.js +114 -0
- package/lib/ServiceDelegate/History/Contact.js +100 -0
- package/lib/ServiceDelegate/History/Motion.js +121 -0
- package/lib/ServiceDelegate/History/On.js +86 -0
- package/lib/ServiceDelegate/History/Power.js +121 -0
- package/lib/ServiceDelegate/History/Room.js +115 -0
- package/lib/ServiceDelegate/History/Thermo.js +102 -0
- package/lib/ServiceDelegate/History/Weather.js +114 -0
- package/lib/ServiceDelegate/History/index.js +318 -0
- package/lib/ServiceDelegate/ServiceLabel.js +47 -0
- package/lib/ServiceDelegate/index.js +332 -0
- package/package.json +1 -1
- package/lib/ServiceDelegate.js +0 -1447
package/lib/ServiceDelegate.js
DELETED
|
@@ -1,1447 +0,0 @@
|
|
|
1
|
-
// homebridge-lib/lib/ServiceDelegate.js
|
|
2
|
-
//
|
|
3
|
-
// Library for Homebridge plugins.
|
|
4
|
-
// Copyright © 2017-2022 Erik Baauw. All rights reserved.
|
|
5
|
-
//
|
|
6
|
-
// The logic for handling Eve history was copied from Simone Tisa's
|
|
7
|
-
// fakagato-history repository, copyright © 2017 simont77.
|
|
8
|
-
// See https://github.com/simont77/fakegato-history.
|
|
9
|
-
|
|
10
|
-
'use strict'
|
|
11
|
-
|
|
12
|
-
const homebridgeLib = require('../index')
|
|
13
|
-
|
|
14
|
-
const util = require('util')
|
|
15
|
-
|
|
16
|
-
/** Delegate of a HomeKit service.
|
|
17
|
-
*
|
|
18
|
-
* This delegate sets up a HomeKit service with the following HomeKit
|
|
19
|
-
* characteristic:
|
|
20
|
-
*
|
|
21
|
-
* key | Characteristic
|
|
22
|
-
* ---------------- | -----------------------------------
|
|
23
|
-
* `name` | `Characteristics.hap.Name`
|
|
24
|
-
* `configuredName` | `Characteristics.hap.ConfiguredName`
|
|
25
|
-
* @abstract
|
|
26
|
-
* @extends Delegate
|
|
27
|
-
*/
|
|
28
|
-
class ServiceDelegate extends homebridgeLib.Delegate {
|
|
29
|
-
/** Create a new instance of a HomeKit service delegate.
|
|
30
|
-
*
|
|
31
|
-
* When the associated HomeKit service was restored from persistent
|
|
32
|
-
* storage, it is linked to the new delegate. Otherwise a new HomeKit
|
|
33
|
-
* service will be created, using the values from `params`.
|
|
34
|
-
* @param {!AccessoryDelegate} accessoryDelegate - Reference to the
|
|
35
|
-
* associated HomeKit accessory delegate.
|
|
36
|
-
* @param {!object} params - Properties of the HomeKit service.<br>
|
|
37
|
-
* Next to the fixed properties below, `params` also contains the value for
|
|
38
|
-
* each key specified in {@link ServiceDelegate#characteristics characteristics}.
|
|
39
|
-
* @param {!string} params.name - The (Siri) name of the service.
|
|
40
|
-
* Also used to prefix log and error messages.
|
|
41
|
-
* @param {!Service} params.Service - The type of the HomeKit service.
|
|
42
|
-
* @param {?string} params.subtype - The subtype of the HomeKit service.
|
|
43
|
-
* Needs to be specified when the accessory has multuple services of the
|
|
44
|
-
* same type.
|
|
45
|
-
* @params {?boolean} params.primaryService - This is the primary service
|
|
46
|
-
* for the accessory.
|
|
47
|
-
* @params {?ServiceDelegate} params.linkedServiceDelegate - The delegate
|
|
48
|
-
* of the service this service links to.
|
|
49
|
-
* @params {?boolean} params.hidden - Hidden service.
|
|
50
|
-
* @params {?boolean} params.exposeConfiguredName - Expose
|
|
51
|
-
* `Characteristics.hap.ConfiguredName`, so device name can be synced with
|
|
52
|
-
* HomeKit service name.
|
|
53
|
-
*/
|
|
54
|
-
constructor (accessoryDelegate, params = {}) {
|
|
55
|
-
if (!(accessoryDelegate instanceof homebridgeLib.AccessoryDelegate)) {
|
|
56
|
-
throw new TypeError('parent: not a AccessoryDelegate')
|
|
57
|
-
}
|
|
58
|
-
if (params.name == null) {
|
|
59
|
-
throw new SyntaxError('params.name: missing')
|
|
60
|
-
}
|
|
61
|
-
super(accessoryDelegate.platform, params.name)
|
|
62
|
-
if (
|
|
63
|
-
typeof params.Service !== 'function' ||
|
|
64
|
-
typeof params.Service.UUID !== 'string'
|
|
65
|
-
) {
|
|
66
|
-
throw new TypeError('params.Service: not a Service')
|
|
67
|
-
}
|
|
68
|
-
this._accessoryDelegate = accessoryDelegate
|
|
69
|
-
this._accessory = this._accessoryDelegate._accessory
|
|
70
|
-
this._key = params.Service.UUID
|
|
71
|
-
if (params.subtype != null) {
|
|
72
|
-
this._key += '.' + params.subtype
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
// Get or create associated Service.
|
|
76
|
-
this._service = params.subtype == null
|
|
77
|
-
? this._accessory.getService(params.Service)
|
|
78
|
-
: this._accessory.getServiceByUUIDAndSubType(params.Service, params.subtype)
|
|
79
|
-
if (this._service == null) {
|
|
80
|
-
this._service = this._accessory.addService(
|
|
81
|
-
new params.Service(this.name, params.subtype)
|
|
82
|
-
)
|
|
83
|
-
this._service.displayName = this.name
|
|
84
|
-
}
|
|
85
|
-
this._accessoryDelegate._linkServiceDelegate(this)
|
|
86
|
-
this._service.setPrimaryService(!!params.primaryService)
|
|
87
|
-
if (params.linkedServiceDelegate != null) {
|
|
88
|
-
params.linkedServiceDelegate._service.addLinkedService(this._service)
|
|
89
|
-
}
|
|
90
|
-
this._service.setHiddenService(!!params.hidden)
|
|
91
|
-
|
|
92
|
-
// Fix bug in homebridge-lib@<4.3.0 that caused the service context in
|
|
93
|
-
// ~/.homebridge/accessories/cachedAccessories to be stored under the
|
|
94
|
-
// wrong key.
|
|
95
|
-
if (
|
|
96
|
-
params.subtype == null &&
|
|
97
|
-
this._accessory.context[this._key + '.'] != null
|
|
98
|
-
) {
|
|
99
|
-
this._accessory.context[this._key] =
|
|
100
|
-
this._accessory.context[this._key + '.']
|
|
101
|
-
delete this._accessory.context[this._key + '.']
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
// Setup persisted storage in ~/.homebridge/accessories/cachedAccessories.
|
|
105
|
-
if (this._accessory.context[this._key] == null) {
|
|
106
|
-
this._accessory.context[this._key] = {}
|
|
107
|
-
}
|
|
108
|
-
this._context = this._accessory.context[this._key]
|
|
109
|
-
|
|
110
|
-
// Setup shortcut for characteristic values.
|
|
111
|
-
this._values = {} // by key
|
|
112
|
-
|
|
113
|
-
// Setup characteristics
|
|
114
|
-
this._characteristicDelegates = {} // by key
|
|
115
|
-
this._characteristics = {} // by uuid
|
|
116
|
-
|
|
117
|
-
if (!params.hidden) {
|
|
118
|
-
this.addCharacteristicDelegate({
|
|
119
|
-
key: 'name',
|
|
120
|
-
Characteristic: this.Characteristics.hap.Name,
|
|
121
|
-
silent: true,
|
|
122
|
-
value: params.name
|
|
123
|
-
})
|
|
124
|
-
if (params.exposeConfiguredName) {
|
|
125
|
-
this.addCharacteristicDelegate({
|
|
126
|
-
key: 'configuredName',
|
|
127
|
-
Characteristic: this.Characteristics.hap.ConfiguredName,
|
|
128
|
-
// silent: true,
|
|
129
|
-
props: {
|
|
130
|
-
perms: [
|
|
131
|
-
this.Characteristic.Perms.READ, this.Characteristic.Perms.WRITE
|
|
132
|
-
]
|
|
133
|
-
},
|
|
134
|
-
value: params.name
|
|
135
|
-
}).on('didSet', (value) => {
|
|
136
|
-
if (value.trim() !== '') {
|
|
137
|
-
this.name = value
|
|
138
|
-
this._service.displayName = value
|
|
139
|
-
this.values.name = value
|
|
140
|
-
for (const key in this._characteristicDelegates) {
|
|
141
|
-
this._characteristicDelegates[key].name = value
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
})
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
this.once('initialised', () => {
|
|
149
|
-
const staleCharacteristics = []
|
|
150
|
-
for (const uuid in this._service.characteristics) {
|
|
151
|
-
const characteristic = this._service.characteristics[uuid]
|
|
152
|
-
if (this._characteristics[characteristic.UUID] == null) {
|
|
153
|
-
staleCharacteristics.push(characteristic)
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
for (const characteristic of staleCharacteristics) {
|
|
157
|
-
this.log('remove stale characteristic %s', characteristic.displayName)
|
|
158
|
-
this._service.removeCharacteristic(characteristic)
|
|
159
|
-
}
|
|
160
|
-
const staleKeys = []
|
|
161
|
-
for (const key in this._context) {
|
|
162
|
-
if (key !== 'context' && this._characteristicDelegates[key] == null) {
|
|
163
|
-
staleKeys.push(key)
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
for (const key of staleKeys) {
|
|
167
|
-
this.log('remove stale value %s', key)
|
|
168
|
-
delete this._context[key]
|
|
169
|
-
}
|
|
170
|
-
})
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
/** Destroy the HomeKit service delegate.
|
|
174
|
-
*
|
|
175
|
-
* Destroys the associated HomeKit characteristic delegates.
|
|
176
|
-
* Removes the associated HomeKit service.
|
|
177
|
-
*/
|
|
178
|
-
destroy () {
|
|
179
|
-
this.debug('destroy %s (%s)', this._key, this._service.displayName)
|
|
180
|
-
this._accessoryDelegate._unlinkServiceDelegate(this)
|
|
181
|
-
this.removeAllListeners()
|
|
182
|
-
for (const key in this._characteristicDelegates) {
|
|
183
|
-
this._characteristicDelegates[key]._destroy()
|
|
184
|
-
}
|
|
185
|
-
this._accessory.removeService(this._service)
|
|
186
|
-
delete this._accessory.context[this._key]
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
/** Add a HomeKit characteristic delegate to the HomeKit service delegate.
|
|
190
|
-
*
|
|
191
|
-
* The characteristic delegate manages a value that:
|
|
192
|
-
* - Is persisted across homebridge restarts;
|
|
193
|
-
* - Can be monitored through homebridge's log output;
|
|
194
|
-
* - Can be monitored programmatially through `didSet` events; and
|
|
195
|
-
* - Mirrors the value of the optionally associated HomeKit characteristic.
|
|
196
|
-
*
|
|
197
|
-
* This value is accessed through {@link ServiceDelegate#values values}.
|
|
198
|
-
* The delegate is returned, but can also be accessed through
|
|
199
|
-
* {@link ServiceDelegate#characteristicDelegate characteristicDelegate()}.
|
|
200
|
-
*
|
|
201
|
-
* When the associated HomeKit characteristic was restored from persistent
|
|
202
|
-
* storage, it is linked to the new delegate. Otherwise a new HomeKit
|
|
203
|
-
* charactertistic will be created, using the values from `params`.
|
|
204
|
-
* @param {!object} params - Properties of the HomeKit characteristic.
|
|
205
|
-
* @param {!string} params.key - The key for the characteristic.
|
|
206
|
-
* @param {?*} params.value - The initial value when the characteristic
|
|
207
|
-
* is added.
|
|
208
|
-
* @param {?boolean} params.silent - Suppress set log messages.
|
|
209
|
-
* @param {?Characteristic} params.Characteristic - The type of the
|
|
210
|
-
* characteristic, from {@link Delegate#Characteristic Characteristic}.
|
|
211
|
-
* @param {?object} params.props - The properties of the HomeKit
|
|
212
|
-
* characteristic.<br>
|
|
213
|
-
* Overrides the properties from the characteristic type.
|
|
214
|
-
* @param {?string} params.unit - The unit of the value of the HomeKit
|
|
215
|
-
* characteristic.<br>
|
|
216
|
-
* Overrides the unit from the characteristic type.
|
|
217
|
-
* @param {?function} params.getter - Asynchronous function to be invoked
|
|
218
|
-
* when HomeKit reads the characteristic value.<br>
|
|
219
|
-
* This must be an `async` function returning a `Promise` to the new
|
|
220
|
-
* characteristic value.
|
|
221
|
-
* @param {?function} params.setter - Asynchronous function to be invoked
|
|
222
|
-
* when HomeKit writes the characteristic value.<br>
|
|
223
|
-
* This must be an `async` function returning a `Promise` that resolves
|
|
224
|
-
* when the corresonding device value has been updated.
|
|
225
|
-
* @returns {CharacteristicDelegate}
|
|
226
|
-
* @throws {TypeError} When a parameter has an invalid type.
|
|
227
|
-
* @throws {RangeError} When a parameter has an invalid value.
|
|
228
|
-
* @throws {SyntaxError} When a mandatory parameter is missing or an
|
|
229
|
-
* optional parameter is not applicable.
|
|
230
|
-
*/
|
|
231
|
-
addCharacteristicDelegate (params = {}) {
|
|
232
|
-
if (typeof params.key !== 'string') {
|
|
233
|
-
throw new TypeError(`params.key: ${params.key}: invalid key`)
|
|
234
|
-
}
|
|
235
|
-
if (params.key === '') {
|
|
236
|
-
throw new RangeError(`params.key: ${params.key}: invalid key`)
|
|
237
|
-
}
|
|
238
|
-
const key = params.key
|
|
239
|
-
if (this.values[key] !== undefined) {
|
|
240
|
-
throw new SyntaxError(`${key}: duplicate key`)
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
const characteristicDelegate = new homebridgeLib.CharacteristicDelegate(
|
|
244
|
-
this, params
|
|
245
|
-
)
|
|
246
|
-
this._characteristicDelegates[key] = characteristicDelegate
|
|
247
|
-
if (params.Characteristic != null) {
|
|
248
|
-
this._characteristics[params.Characteristic.UUID] = true
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
// Create shortcut for characteristic value.
|
|
252
|
-
Object.defineProperty(this.values, key, {
|
|
253
|
-
configurable: true, // make sure we can delete it again
|
|
254
|
-
writeable: true,
|
|
255
|
-
get () { return characteristicDelegate.value },
|
|
256
|
-
set (value) { characteristicDelegate.value = value }
|
|
257
|
-
})
|
|
258
|
-
|
|
259
|
-
return characteristicDelegate
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
removeCharacteristicDelegate (key) {
|
|
263
|
-
delete this.values[key]
|
|
264
|
-
const characteristicDelegate = this._characteristicDelegates[key]
|
|
265
|
-
if (characteristicDelegate._characteristic != null) {
|
|
266
|
-
const characteristic = characteristicDelegate._characteristic
|
|
267
|
-
delete this._characteristics[characteristic.UUID]
|
|
268
|
-
}
|
|
269
|
-
characteristicDelegate._destroy()
|
|
270
|
-
delete this._characteristicDelegates[key]
|
|
271
|
-
delete this._context[key]
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
/** Values of the HomeKit characteristics for the HomeKit service.
|
|
275
|
-
*
|
|
276
|
-
* Contains the key of each characteristic added by
|
|
277
|
-
* {@link ServiceDelegate#addCharacteristic addCharacteristic}.
|
|
278
|
-
* When the value is written, the value of the corresponding HomeKit
|
|
279
|
-
* characteristic is updated; when the characteristic value is changed from
|
|
280
|
-
* HomeKit, this value is updated.
|
|
281
|
-
* @type {object}
|
|
282
|
-
*/
|
|
283
|
-
get values () {
|
|
284
|
-
return this._values
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
/** Returns the HomeKit characteristic delegate correspondig to the key.
|
|
288
|
-
* @param {!string} key - The key for the characteristic.
|
|
289
|
-
* returns {CharacteristicDelegate}
|
|
290
|
-
*/
|
|
291
|
-
characteristicDelegate (key) {
|
|
292
|
-
return this._characteristicDelegates[key]
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
/** The corrresponding HomeKit accessory delegate.
|
|
296
|
-
* @type {AccessoryDelegate}
|
|
297
|
-
*/
|
|
298
|
-
get accessoryDelegate () {
|
|
299
|
-
return this._accessoryDelegate
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
/** Service context to be persisted across Homebridge restarts.
|
|
303
|
-
* @type {object}
|
|
304
|
-
*/
|
|
305
|
-
get context () {
|
|
306
|
-
if (this._context.context == null) {
|
|
307
|
-
this._context.context = {}
|
|
308
|
-
}
|
|
309
|
-
return this._context.context
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
/** Current log level (of the associated accessory delegate).
|
|
313
|
-
*
|
|
314
|
-
* The log level determines what type of messages are printed:
|
|
315
|
-
*
|
|
316
|
-
* 0. Print error and warning messages.
|
|
317
|
-
* 1. Print error, warning, and log messages.
|
|
318
|
-
* 2. Print error, warning, log, and debug messages.
|
|
319
|
-
* 3. Print error, warning, log, debug, and verbose debug messages.
|
|
320
|
-
*
|
|
321
|
-
* Note that debug messages (level 2 and 3) are only printed when
|
|
322
|
-
* Homebridge was started with the `-D` or `--debug` command line option.
|
|
323
|
-
*
|
|
324
|
-
* @type {!integer}
|
|
325
|
-
* @readonly
|
|
326
|
-
*/
|
|
327
|
-
get logLevel () {
|
|
328
|
-
return this._accessoryDelegate.logLevel
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
static get AccessoryInformation () { return AccessoryInformation }
|
|
332
|
-
static get Battery () { return Battery }
|
|
333
|
-
static get ServiceLabel () { return ServiceLabel }
|
|
334
|
-
static get Dummy () { return Dummy }
|
|
335
|
-
static get History () { return History }
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
/** Class for an _AccessoryInformation_ service delegate.
|
|
339
|
-
*
|
|
340
|
-
* This delegate sets up a `Services.hap.AccessoryInformation` HomeKit service
|
|
341
|
-
* with the following HomeKit characteristics:
|
|
342
|
-
*
|
|
343
|
-
* key | Characteristic | isOptional
|
|
344
|
-
* -------------- | -------------------------------------- | ----------
|
|
345
|
-
* `name` | `Characteristics.hap.Name` |
|
|
346
|
-
* `id` | `Characteristics.hap.SerialNumber` |
|
|
347
|
-
* `manufacturer` | `Characteristics.hap.Manufacturer` |
|
|
348
|
-
* `model` | `Characteristics.hap.Model` |
|
|
349
|
-
* `firmware` | `Characteristics.hap.FirmwareRevision` |
|
|
350
|
-
* `hardware` | `Characteristics.hap.HardwareRevision` | Y
|
|
351
|
-
* `software` | `Characteristics.hap.SoftwareRevision` | Y
|
|
352
|
-
* @extends ServiceDelegate
|
|
353
|
-
* @memberof ServiceDelegate
|
|
354
|
-
*/
|
|
355
|
-
class AccessoryInformation extends ServiceDelegate {
|
|
356
|
-
/** Create a new instance of an _AccessoryInformation_ service delegate.
|
|
357
|
-
* @param {!AccessoryDelegate} accessoryDelegate - The delegate of the
|
|
358
|
-
* corresponding HomeKit accessory.
|
|
359
|
-
* @param {!object} params - The parameters for the
|
|
360
|
-
* _AccessoryInformation_ HomeKit service.
|
|
361
|
-
* @param {!string} params.name - Initial value for
|
|
362
|
-
* `Characteristics.hap.Name`. Also used to prefix log and error messages.
|
|
363
|
-
* @param {!string} params.id - Initial value for
|
|
364
|
-
* `Characteristics.hap.SerialNumber`.
|
|
365
|
-
* @param {!string} params.manufacturer - Initial value for
|
|
366
|
-
* `Characteristics.hap.Manufacturer`.
|
|
367
|
-
* @param {!string} params.model - Initial value for
|
|
368
|
-
* `Characteristics.hap.Model`.
|
|
369
|
-
* @param {!string} params.firmware - Initial value for
|
|
370
|
-
* `Characteristics.hap.FirmwareRevision`.
|
|
371
|
-
* @param {?string} params.hardware - Initial value for
|
|
372
|
-
* `Characteristics.hap.HardwareRevision`.
|
|
373
|
-
* @param {?string} params.software - Initial value for
|
|
374
|
-
* `Characteristics.hap.SoftwareRevision`.
|
|
375
|
-
*/
|
|
376
|
-
constructor (accessoryDelegate, params = {}) {
|
|
377
|
-
params.name = accessoryDelegate.name
|
|
378
|
-
params.Service = accessoryDelegate.Services.hap.AccessoryInformation
|
|
379
|
-
super(accessoryDelegate, params)
|
|
380
|
-
this.addCharacteristicDelegate({
|
|
381
|
-
key: 'id',
|
|
382
|
-
Characteristic: this.Characteristics.hap.SerialNumber,
|
|
383
|
-
value: params.id
|
|
384
|
-
})
|
|
385
|
-
this.addCharacteristicDelegate({
|
|
386
|
-
key: 'identify',
|
|
387
|
-
Characteristic: this.Characteristics.hap.Identify
|
|
388
|
-
})
|
|
389
|
-
this.addCharacteristicDelegate({
|
|
390
|
-
key: 'manufacturer',
|
|
391
|
-
Characteristic: this.Characteristics.hap.Manufacturer,
|
|
392
|
-
value: params.manufacturer
|
|
393
|
-
})
|
|
394
|
-
this.addCharacteristicDelegate({
|
|
395
|
-
key: 'model',
|
|
396
|
-
Characteristic: this.Characteristics.hap.Model,
|
|
397
|
-
value: params.model
|
|
398
|
-
})
|
|
399
|
-
this.addCharacteristicDelegate({
|
|
400
|
-
key: 'firmware',
|
|
401
|
-
Characteristic: this.Characteristics.hap.FirmwareRevision,
|
|
402
|
-
value: params.firmware
|
|
403
|
-
})
|
|
404
|
-
if (params.hardware != null || this._context.hardware != null) {
|
|
405
|
-
this.addCharacteristicDelegate({
|
|
406
|
-
key: 'hardware',
|
|
407
|
-
Characteristic: this.Characteristics.hap.HardwareRevision,
|
|
408
|
-
value: params.hardware
|
|
409
|
-
})
|
|
410
|
-
}
|
|
411
|
-
if (params.software != null || this._context.software != null) {
|
|
412
|
-
this.addCharacteristicDelegate({
|
|
413
|
-
key: 'software',
|
|
414
|
-
Characteristic: this.Characteristics.hap.SoftwareRevision,
|
|
415
|
-
value: params.software
|
|
416
|
-
})
|
|
417
|
-
}
|
|
418
|
-
}
|
|
419
|
-
|
|
420
|
-
addCharacteristicDelegate (params = {}) {
|
|
421
|
-
const delegate = super.addCharacteristicDelegate(params)
|
|
422
|
-
Object.defineProperty(this.accessoryDelegate.values, params.key, {
|
|
423
|
-
configurable: true, // make sure we can delete it again
|
|
424
|
-
writeable: true,
|
|
425
|
-
get () { return delegate.value },
|
|
426
|
-
set (value) { delegate.value = value }
|
|
427
|
-
})
|
|
428
|
-
return delegate
|
|
429
|
-
}
|
|
430
|
-
|
|
431
|
-
removeCharacteristicDelegate (key) {
|
|
432
|
-
delete this.accessoryDelegate.values[key]
|
|
433
|
-
super.removeCharacteristicDelegate(key)
|
|
434
|
-
}
|
|
435
|
-
}
|
|
436
|
-
|
|
437
|
-
/** Class for a _Battery_ service delegate.
|
|
438
|
-
*
|
|
439
|
-
* This delegate sets up a `Services.hap.Battery` HomeKit service
|
|
440
|
-
* with the following HomeKit characteristics:
|
|
441
|
-
*
|
|
442
|
-
* key | Characteristic | isOptional
|
|
443
|
-
* ------------------ | -------------------------------------- | ----------
|
|
444
|
-
* `name` | `Characteristics.hap.Name` |
|
|
445
|
-
* `batteryLevel` | `Characteristics.hap.BatteryLevel` | Y
|
|
446
|
-
* `chargingState` | `Characteristics.hap.ChargingState` | Y
|
|
447
|
-
* `statusLowBattery` | `Characteristics.hap.StatusLowBattery` | Y
|
|
448
|
-
* `lowBatteryThreshold`| `Characteristics.my.LowBatteryThreshold` | Y
|
|
449
|
-
*
|
|
450
|
-
* @extends ServiceDelegate
|
|
451
|
-
* @memberof ServiceDelegate
|
|
452
|
-
*/
|
|
453
|
-
class Battery extends ServiceDelegate {
|
|
454
|
-
/** Create a new instance of an _Battery_ service delegate.
|
|
455
|
-
* @param {!AccessoryDelegate} accessoryDelegate - The delegate of the
|
|
456
|
-
* corresponding HomeKit accessory.
|
|
457
|
-
* @param {object} params - The parameters for the
|
|
458
|
-
* _AccessoryInformation_ HomeKit service.
|
|
459
|
-
* @param {integer} [params.batteryLevel=100] - Initial value for
|
|
460
|
-
* `Characteristics.hap.BatteryLevel`.
|
|
461
|
-
* @param {integer} [params.chargingState=NOT_CHARGEABLE] - Initial value for
|
|
462
|
-
* `Characteristics.hap.ChargingState`.
|
|
463
|
-
* @param {integer} [params.statusLowBattery=BATTERY_LEVEL_NORMAL] - Initial
|
|
464
|
-
* value for `Characteristics.hap.StatusLowBattery`.
|
|
465
|
-
* @param {integer} [params.lowBatteryThreshold=20] - Initial value for
|
|
466
|
-
* low battery threshold.
|
|
467
|
-
*/
|
|
468
|
-
constructor (accessoryDelegate, params = {}) {
|
|
469
|
-
params.name = accessoryDelegate.name + ' Battery'
|
|
470
|
-
params.Service = accessoryDelegate.Services.hap.BatteryService
|
|
471
|
-
super(accessoryDelegate, params)
|
|
472
|
-
this.addCharacteristicDelegate({
|
|
473
|
-
key: 'batteryLevel',
|
|
474
|
-
Characteristic: this.Characteristics.hap.BatteryLevel,
|
|
475
|
-
unit: '%',
|
|
476
|
-
value: params.batteryLevel != null ? params.batteryLevel : 100
|
|
477
|
-
}).on('didSet', (value) => {
|
|
478
|
-
this.updateStatusLowBattery()
|
|
479
|
-
})
|
|
480
|
-
this.addCharacteristicDelegate({
|
|
481
|
-
key: 'chargingState',
|
|
482
|
-
Characteristic: this.Characteristics.hap.ChargingState,
|
|
483
|
-
value: params.chargingState != null
|
|
484
|
-
? params.chargingState
|
|
485
|
-
: this.Characteristics.hap.ChargingState.NOT_CHARGEABLE
|
|
486
|
-
})
|
|
487
|
-
this.addCharacteristicDelegate({
|
|
488
|
-
key: 'statusLowBattery',
|
|
489
|
-
Characteristic: this.Characteristics.hap.StatusLowBattery,
|
|
490
|
-
value: params.statusLowBattery != null
|
|
491
|
-
? params.statusLowBattery
|
|
492
|
-
: this.Characteristics.hap.StatusLowBattery.BATTERY_LEVEL_NORMAL
|
|
493
|
-
})
|
|
494
|
-
this.addCharacteristicDelegate({
|
|
495
|
-
key: 'lowBatteryThreshold',
|
|
496
|
-
Characteristic: this.Characteristics.my.LowBatteryThreshold,
|
|
497
|
-
unit: '%',
|
|
498
|
-
value: params.lowBatteryThreshold != null ? params.lowBatteryThreshold : 20
|
|
499
|
-
}).on('didSet', (value) => {
|
|
500
|
-
this.updateStatusLowBattery()
|
|
501
|
-
})
|
|
502
|
-
}
|
|
503
|
-
|
|
504
|
-
updateStatusLowBattery () {
|
|
505
|
-
this.values.statusLowBattery =
|
|
506
|
-
this.values.batteryLevel <= this.values.lowBatteryThreshold
|
|
507
|
-
? this.Characteristics.hap.StatusLowBattery.BATTERY_LEVEL_LOW
|
|
508
|
-
: this.Characteristics.hap.StatusLowBattery.BATTERY_LEVEL_NORMAL
|
|
509
|
-
}
|
|
510
|
-
}
|
|
511
|
-
|
|
512
|
-
/** Class for a _ServiceLabel_ service delegate.
|
|
513
|
-
*
|
|
514
|
-
* This delegate sets up a `Services.hap.ServiceLabel` HomeKit service
|
|
515
|
-
* with the following HomeKit characteristics:
|
|
516
|
-
*
|
|
517
|
-
* key | Characteristic | isOptional
|
|
518
|
-
* -------------- | ------------------------------------------- | ----------
|
|
519
|
-
* `name` | `Characteristics.hap.Name` |
|
|
520
|
-
* `namespace` | `Characteristics.hap.ServiceLabelNamespace` |
|
|
521
|
-
* @extends ServiceDelegate
|
|
522
|
-
* @memberof ServiceDelegate
|
|
523
|
-
*/
|
|
524
|
-
class ServiceLabel extends ServiceDelegate {
|
|
525
|
-
/** Create a new instance of an _ServiceLabel_ service delegate.
|
|
526
|
-
* @param {!AccessoryDelegate} accessoryDelegate - The delegate of the
|
|
527
|
-
* corresponding HomeKit accessory.
|
|
528
|
-
* @param {!object} params - The parameters for the
|
|
529
|
-
* _AccessoryInformation_ HomeKit service.
|
|
530
|
-
* @param {!string} params.name - Initial value for
|
|
531
|
-
* `Characteristics.hap.Name`. Also used to prefix log and error messages.
|
|
532
|
-
* @param {!string} params.namespace - Initial value for
|
|
533
|
-
* `Characteristics.hap.ServiceLabelNamespace`.
|
|
534
|
-
*/
|
|
535
|
-
constructor (accessoryDelegate, params = {}) {
|
|
536
|
-
params.name = accessoryDelegate.name
|
|
537
|
-
params.Service = accessoryDelegate.Services.hap.ServiceLabel
|
|
538
|
-
super(accessoryDelegate, params)
|
|
539
|
-
this.addCharacteristicDelegate({
|
|
540
|
-
key: 'namespace',
|
|
541
|
-
Characteristic: this.Characteristics.hap.ServiceLabelNamespace,
|
|
542
|
-
value: params.namespace
|
|
543
|
-
})
|
|
544
|
-
}
|
|
545
|
-
}
|
|
546
|
-
|
|
547
|
-
/** Class for a delegate for a dummy _StatelessProgrammableSwitch_ service.
|
|
548
|
-
*
|
|
549
|
-
* This delegate sets up a dummy `Services.hap.StatelessProgrammableSwitch`
|
|
550
|
-
* HomeKit service with the following HomeKit characteristics:
|
|
551
|
-
*
|
|
552
|
-
* key | Characteristic | isOptional
|
|
553
|
-
* ------------------------- | --------------------------------------------- | ----------
|
|
554
|
-
* `name` | `Characteristics.hap.Name` |
|
|
555
|
-
* `programmableSwitchEvent` | `Characteristics.hap.ProgrammableSwitchEvent` |
|
|
556
|
-
*
|
|
557
|
-
* Including the dummy service prevents Home from showing a _Not Supported_
|
|
558
|
-
* tile, and causes Home on iOS14 to show the _Favorite_ setting.
|
|
559
|
-
* @extends ServiceDelegate
|
|
560
|
-
* @memberof ServiceDelegate
|
|
561
|
-
*/
|
|
562
|
-
class Dummy extends ServiceDelegate {
|
|
563
|
-
constructor (nbAccessory, params = {}) {
|
|
564
|
-
params.name = nbAccessory.name
|
|
565
|
-
params.Service = nbAccessory.Services.hap.StatelessProgrammableSwitch
|
|
566
|
-
super(nbAccessory, params)
|
|
567
|
-
|
|
568
|
-
this.addCharacteristicDelegate({
|
|
569
|
-
key: 'programmableSwitchEvent',
|
|
570
|
-
Characteristic: this.Characteristics.hap.ProgrammableSwitchEvent,
|
|
571
|
-
props: {
|
|
572
|
-
minValue: this.Characteristics.hap.ProgrammableSwitchEvent.SINGLE_PRESS,
|
|
573
|
-
maxValue: this.Characteristics.hap.ProgrammableSwitchEvent.SINGLE_PRESS
|
|
574
|
-
}
|
|
575
|
-
})
|
|
576
|
-
}
|
|
577
|
-
}
|
|
578
|
-
|
|
579
|
-
const epoch = Math.round(new Date('2001-01-01T00:00:00Z').valueOf() / 1000)
|
|
580
|
-
|
|
581
|
-
function hexToBase64 (value) {
|
|
582
|
-
if (value == null || typeof value !== 'string') {
|
|
583
|
-
throw new TypeError('value: not a string')
|
|
584
|
-
}
|
|
585
|
-
return Buffer.from((value).replace(/[^0-9A-F]/ig, ''), 'hex')
|
|
586
|
-
.toString('base64')
|
|
587
|
-
}
|
|
588
|
-
|
|
589
|
-
function base64ToHex (value) {
|
|
590
|
-
if (value == null || typeof value !== 'string') {
|
|
591
|
-
throw new TypeError('value: not a string')
|
|
592
|
-
}
|
|
593
|
-
return Buffer.from(value, 'base64').toString('hex')
|
|
594
|
-
}
|
|
595
|
-
|
|
596
|
-
function swap16 (value) {
|
|
597
|
-
return ((value & 0xFF) << 8) | ((value >>> 8) & 0xFF)
|
|
598
|
-
}
|
|
599
|
-
|
|
600
|
-
function swap32 (value) {
|
|
601
|
-
return ((value & 0xFF) << 24) | ((value & 0xFF00) << 8) |
|
|
602
|
-
((value >>> 8) & 0xFF00) | ((value >>> 24) & 0xFF)
|
|
603
|
-
}
|
|
604
|
-
|
|
605
|
-
function numToHex (value, length) {
|
|
606
|
-
let s = Number(value >>> 0).toString(16)
|
|
607
|
-
if (s.length % 2 !== 0) {
|
|
608
|
-
s = '0' + s
|
|
609
|
-
}
|
|
610
|
-
if (length) {
|
|
611
|
-
return ('0000000000000' + s).slice(-length)
|
|
612
|
-
}
|
|
613
|
-
return s
|
|
614
|
-
}
|
|
615
|
-
|
|
616
|
-
/** Abstract superclass for an Eve _History_ service delegate.
|
|
617
|
-
*
|
|
618
|
-
* This delegate sets up a `Services.eve.History` HomeKit service
|
|
619
|
-
* with keys for the following HomeKit characteristics:
|
|
620
|
-
*
|
|
621
|
-
* key | Characteristic
|
|
622
|
-
* ---------------- | ----------------------------------
|
|
623
|
-
* `name` | `Characteristics.hap.Name`
|
|
624
|
-
* `historyRequest` | `Characteristics.eve.HistoryRequest`
|
|
625
|
-
* `setTime` | `Characteristics.eve.SetTime`
|
|
626
|
-
* `historyStatus` | `Characteristics.eve.HistoryStatus`
|
|
627
|
-
* `historyEntries` | `Characteristics.eve.HistoryEntries`
|
|
628
|
-
* @abstract
|
|
629
|
-
* @extends ServiceDelegate
|
|
630
|
-
* @memberof ServiceDelegate
|
|
631
|
-
*/
|
|
632
|
-
class History extends ServiceDelegate {
|
|
633
|
-
/** Create a new instance of an Eve _History_ service delegate.
|
|
634
|
-
* @param {!AccessoryDelegate} accessoryDelegate - The delegate of the
|
|
635
|
-
* corresponding HomeKit accessory.
|
|
636
|
-
* @param {!object} params - The parameters for the
|
|
637
|
-
* _History_ HomeKit service.
|
|
638
|
-
*/
|
|
639
|
-
constructor (accessoryDelegate, params = {}) {
|
|
640
|
-
params.name = accessoryDelegate.name + ' History'
|
|
641
|
-
params.Service = accessoryDelegate.Services.eve.History
|
|
642
|
-
params.hidden = true
|
|
643
|
-
super(accessoryDelegate, params)
|
|
644
|
-
this._memorySize = 4032
|
|
645
|
-
this._transfer = false
|
|
646
|
-
this._restarted = true
|
|
647
|
-
|
|
648
|
-
this.addCharacteristicDelegate({
|
|
649
|
-
key: 'history',
|
|
650
|
-
silent: true
|
|
651
|
-
})
|
|
652
|
-
if (this.context._history != null) {
|
|
653
|
-
this.values.history = this.context._history
|
|
654
|
-
delete this.context._history
|
|
655
|
-
}
|
|
656
|
-
this._h = this.values.history
|
|
657
|
-
if (this._h == null) {
|
|
658
|
-
this.values.history = {
|
|
659
|
-
firstEntry: 0,
|
|
660
|
-
lastEntry: 0,
|
|
661
|
-
history: ['noValue'],
|
|
662
|
-
usedMemory: 0,
|
|
663
|
-
currentEntry: 1,
|
|
664
|
-
initialTime: 0
|
|
665
|
-
}
|
|
666
|
-
this._h = this.values.history
|
|
667
|
-
} else {
|
|
668
|
-
this.debug('restored %d history entries', this._h.usedMemory)
|
|
669
|
-
}
|
|
670
|
-
if (this._h.refTime != null) {
|
|
671
|
-
this._h.initialTime = this._h.refTime + epoch
|
|
672
|
-
delete this._h.refTime
|
|
673
|
-
}
|
|
674
|
-
|
|
675
|
-
this.addCharacteristicDelegate({
|
|
676
|
-
key: 'historyRequest',
|
|
677
|
-
Characteristic: this.Characteristics.eve.HistoryRequest,
|
|
678
|
-
value: params.historyRequest,
|
|
679
|
-
setter: this._onSetHistoryRequest.bind(this),
|
|
680
|
-
silent: true
|
|
681
|
-
})
|
|
682
|
-
this.addCharacteristicDelegate({
|
|
683
|
-
key: 'setTime',
|
|
684
|
-
Characteristic: this.Characteristics.eve.SetTime,
|
|
685
|
-
value: params.setTime,
|
|
686
|
-
silent: true
|
|
687
|
-
})
|
|
688
|
-
this.addCharacteristicDelegate({
|
|
689
|
-
key: 'historyStatus',
|
|
690
|
-
Characteristic: this.Characteristics.eve.HistoryStatus,
|
|
691
|
-
value: params.historyStatus,
|
|
692
|
-
silent: true
|
|
693
|
-
})
|
|
694
|
-
this.addCharacteristicDelegate({
|
|
695
|
-
key: 'historyEntries',
|
|
696
|
-
Characteristic: this.Characteristics.eve.HistoryEntries,
|
|
697
|
-
value: params.historyEntries,
|
|
698
|
-
getter: this._onGetEntries.bind(this),
|
|
699
|
-
silent: true
|
|
700
|
-
})
|
|
701
|
-
this._accessoryDelegate.heartbeatEnabled = true
|
|
702
|
-
this._accessoryDelegate
|
|
703
|
-
.once('heartbeat', (beat) => {
|
|
704
|
-
this._historyBeat = (beat % 600) + 5
|
|
705
|
-
})
|
|
706
|
-
.on('heartbeat', this._heartbeat.bind(this))
|
|
707
|
-
.on('shutdown', () => {
|
|
708
|
-
this.debug('saved %d history entries', this._h.usedMemory)
|
|
709
|
-
})
|
|
710
|
-
}
|
|
711
|
-
|
|
712
|
-
_addEntry (now = Math.round(new Date().valueOf() / 1000)) {
|
|
713
|
-
this._entry.time = now
|
|
714
|
-
if (this._h.usedMemory < this._memorySize) {
|
|
715
|
-
this._h.usedMemory++
|
|
716
|
-
this._h.firstEntry = 0
|
|
717
|
-
this._h.lastEntry = this._h.usedMemory
|
|
718
|
-
} else {
|
|
719
|
-
this._h.firstEntry++
|
|
720
|
-
this._h.lastEntry = this._h.firstEntry + this._h.usedMemory
|
|
721
|
-
if (this._restarted === true) {
|
|
722
|
-
this._h.history[this._h.lastEntry % this._memorySize] = {
|
|
723
|
-
time: this._entry.time,
|
|
724
|
-
setRefTime: 1
|
|
725
|
-
}
|
|
726
|
-
this._h.firstEntry++
|
|
727
|
-
this._h.lastEntry = this._h.firstEntry + this._h.usedMemory
|
|
728
|
-
this._restarted = false
|
|
729
|
-
}
|
|
730
|
-
}
|
|
731
|
-
|
|
732
|
-
if (this._h.initialTime === 0) {
|
|
733
|
-
this._h.history[this._h.lastEntry] = {
|
|
734
|
-
time: this._entry.time,
|
|
735
|
-
setRefTime: 1
|
|
736
|
-
}
|
|
737
|
-
this._h.initialTime = this._entry.time
|
|
738
|
-
this._h.lastEntry++
|
|
739
|
-
this._h.usedMemory++
|
|
740
|
-
}
|
|
741
|
-
|
|
742
|
-
this._h.history[this._h.lastEntry % this._memorySize] =
|
|
743
|
-
Object.assign({}, this._entry)
|
|
744
|
-
|
|
745
|
-
const usedMemeoryOffset = this._h.usedMemory < this._memorySize ? 1 : 0
|
|
746
|
-
const firstEntryOffset = this._h.usedMemory < this._memorySize ? 0 : 1
|
|
747
|
-
const value = util.format(
|
|
748
|
-
'%s 00000000 %s [%s] %s %s %s 000000000101',
|
|
749
|
-
numToHex(swap32(this._entry.time - this._h.initialTime), 8),
|
|
750
|
-
numToHex(swap32(this._h.initialTime - epoch), 8),
|
|
751
|
-
this._fingerPrint,
|
|
752
|
-
numToHex(swap16(this._h.usedMemory + usedMemeoryOffset), 4),
|
|
753
|
-
numToHex(swap16(this._memorySize), 4),
|
|
754
|
-
numToHex(swap32(this._h.firstEntry + firstEntryOffset), 8)
|
|
755
|
-
)
|
|
756
|
-
|
|
757
|
-
this.debug('add entry %d: %j', this._h.lastEntry, this._entry)
|
|
758
|
-
this.debug('set history status to: %s', value)
|
|
759
|
-
this.values.historyStatus = hexToBase64(value)
|
|
760
|
-
}
|
|
761
|
-
|
|
762
|
-
_heartbeat (beat) {
|
|
763
|
-
if (beat % 600 === this._historyBeat) {
|
|
764
|
-
this._addEntry()
|
|
765
|
-
}
|
|
766
|
-
}
|
|
767
|
-
|
|
768
|
-
async _onSetHistoryRequest (value) {
|
|
769
|
-
const entry = swap32(parseInt(base64ToHex(value).substring(4, 12), 16))
|
|
770
|
-
this.debug('request entry: %d', entry)
|
|
771
|
-
if (entry !== 0) {
|
|
772
|
-
this._h.currentEntry = entry
|
|
773
|
-
} else {
|
|
774
|
-
this._h.currentEntry = 1
|
|
775
|
-
}
|
|
776
|
-
this._transfer = true
|
|
777
|
-
}
|
|
778
|
-
|
|
779
|
-
async _onGetEntries () {
|
|
780
|
-
if (this._h.currentEntry > this._h.lastEntry || !this._transfer) {
|
|
781
|
-
this.debug('send data: 00')
|
|
782
|
-
this._transfer = false
|
|
783
|
-
return hexToBase64('00')
|
|
784
|
-
}
|
|
785
|
-
|
|
786
|
-
let dataStream = ''
|
|
787
|
-
for (let i = 0; i < 11; i++) {
|
|
788
|
-
const address = this._h.currentEntry % this._memorySize
|
|
789
|
-
if (
|
|
790
|
-
this._h.history[address].setRefTime === 1 ||
|
|
791
|
-
this._h.currentEntry === this._h.firstEntry + 1
|
|
792
|
-
) {
|
|
793
|
-
this.debug(
|
|
794
|
-
'entry: %s, address %s, reftime: %s (%s)', this._h.currentEntry,
|
|
795
|
-
address, this._h.initialTime - epoch,
|
|
796
|
-
new Date(1000 * this._h.initialTime).toString().slice(0, 24)
|
|
797
|
-
)
|
|
798
|
-
dataStream += util.format(
|
|
799
|
-
'|15 %s 0100000081 %s 00000000000000',
|
|
800
|
-
numToHex(swap32(this._h.currentEntry), 8),
|
|
801
|
-
numToHex(swap32(this._h.initialTime - epoch), 8))
|
|
802
|
-
} else {
|
|
803
|
-
this.debug(
|
|
804
|
-
'entry: %s, address: %s, time: %s (%s)', this._h.currentEntry,
|
|
805
|
-
address, this._h.history[address].time - this._h.initialTime,
|
|
806
|
-
new Date(1000 * this._h.history[address].time).toString().slice(0, 24)
|
|
807
|
-
)
|
|
808
|
-
dataStream += this._entryStream(this._h.history[address])
|
|
809
|
-
}
|
|
810
|
-
this._h.currentEntry++
|
|
811
|
-
if (this._h.currentEntry > this._h.lastEntry) {
|
|
812
|
-
break
|
|
813
|
-
}
|
|
814
|
-
}
|
|
815
|
-
this.debug('send data: %s', dataStream)
|
|
816
|
-
return hexToBase64(dataStream)
|
|
817
|
-
}
|
|
818
|
-
|
|
819
|
-
static get Consumption () { return Consumption }
|
|
820
|
-
|
|
821
|
-
static get Contact () { return Contact }
|
|
822
|
-
|
|
823
|
-
static get Motion () { return Motion }
|
|
824
|
-
|
|
825
|
-
static get On () { return On }
|
|
826
|
-
|
|
827
|
-
static get Power () { return Power }
|
|
828
|
-
|
|
829
|
-
static get Thermo () { return Thermo }
|
|
830
|
-
|
|
831
|
-
static get Weather () { return Weather }
|
|
832
|
-
}
|
|
833
|
-
|
|
834
|
-
/** Class for an Eve Energy _History_ service delegate.
|
|
835
|
-
*
|
|
836
|
-
* This delegate sets up a `Services.eve.History` HomeKit service
|
|
837
|
-
* with keys for the following HomeKit characteristics:
|
|
838
|
-
*
|
|
839
|
-
* key | Characteristic
|
|
840
|
-
* ---------------- | ----------------------------------
|
|
841
|
-
* `name` | `Characteristics.hap.Name`
|
|
842
|
-
* `historyRequest` | `Characteristics.eve.HistoryRequest`
|
|
843
|
-
* `setTime` | `Characteristics.eve.SetTime`
|
|
844
|
-
* `historyStatus` | `Characteristics.eve.HistoryStatus`
|
|
845
|
-
* `historyEntries` | `Characteristics.eve.HistoryEntries`
|
|
846
|
-
*
|
|
847
|
-
* This delegate is for sensors that report life-time consumption. The history
|
|
848
|
-
* is computed from the changes to the value of the associated
|
|
849
|
-
* `Characteristics.eve.TotalConsumption` characteristic. If the sensor doesn't
|
|
850
|
-
* also report power, this delegate can update the the value of the associated
|
|
851
|
-
* `Characteristics.eve.CurrentConsumption` characteristic.
|
|
852
|
-
*
|
|
853
|
-
* Note that the key in the history entry is called `power`, but its value
|
|
854
|
-
* is the consumption in Wh since the previous entry.
|
|
855
|
-
*
|
|
856
|
-
* @extends ServiceDelegate.History
|
|
857
|
-
* @memberof ServiceDelegate.History
|
|
858
|
-
*/
|
|
859
|
-
class Consumption extends ServiceDelegate.History {
|
|
860
|
-
/** Create a new instance of an Eve Energy _History_ service delegate.
|
|
861
|
-
* @param {!AccessoryDelegate} accessoryDelegate - The delegate of the
|
|
862
|
-
* corresponding HomeKit accessory.
|
|
863
|
-
* @param {!object} params - The parameters for the
|
|
864
|
-
* _History_ HomeKit service.
|
|
865
|
-
* @param {!CharacteristicDelegate} consumptionDelegate - A reference to the
|
|
866
|
-
* delegate of the associated `Characteristics.eve.TotalConsumption`
|
|
867
|
-
* characteristic.
|
|
868
|
-
* @param {?CharacteristicDelegate} powerDelegate - A reference to the
|
|
869
|
-
* delegate of the associated `Characteristics.eve.CurrentConsumption`
|
|
870
|
-
* characteristic.
|
|
871
|
-
*/
|
|
872
|
-
constructor (
|
|
873
|
-
accessoryDelegate, params, consumptionDelegate, powerDelegate
|
|
874
|
-
) {
|
|
875
|
-
super(accessoryDelegate, params)
|
|
876
|
-
if (!(consumptionDelegate instanceof homebridgeLib.CharacteristicDelegate)) {
|
|
877
|
-
throw new TypeError('consumptionDelegate: not a CharacteristicDelegate')
|
|
878
|
-
}
|
|
879
|
-
if (
|
|
880
|
-
powerDelegate != null &&
|
|
881
|
-
!(powerDelegate instanceof homebridgeLib.CharacteristicDelegate)
|
|
882
|
-
) {
|
|
883
|
-
throw new TypeError('powerDelegate: not a CharacteristicDelegate')
|
|
884
|
-
}
|
|
885
|
-
this.addCharacteristicDelegate({
|
|
886
|
-
key: 'consumption',
|
|
887
|
-
silent: true
|
|
888
|
-
})
|
|
889
|
-
this.addCharacteristicDelegate({
|
|
890
|
-
key: 'time',
|
|
891
|
-
silent: true
|
|
892
|
-
})
|
|
893
|
-
this._consumptionDelegate = consumptionDelegate
|
|
894
|
-
this._powerDelegate = powerDelegate
|
|
895
|
-
this._entry = { time: 0, power: 0 }
|
|
896
|
-
}
|
|
897
|
-
|
|
898
|
-
_addEntry () {
|
|
899
|
-
const now = Math.round(new Date().valueOf() / 1000)
|
|
900
|
-
// Sensor deliveres totalConsumption, optionally compute currentConsumption
|
|
901
|
-
if (this.values.consumption != null && this.values.time != null) {
|
|
902
|
-
const delta = this._consumptionDelegate.value - this.values.consumption // kWh
|
|
903
|
-
const period = now - this.values.time // s
|
|
904
|
-
const power = Math.round(1000 * 3600 * delta / period) // W
|
|
905
|
-
if (this._powerDelegate != null) {
|
|
906
|
-
this._powerDelegate.value = power
|
|
907
|
-
}
|
|
908
|
-
this._entry.power = power
|
|
909
|
-
super._addEntry(now)
|
|
910
|
-
}
|
|
911
|
-
this.values.consumption = this._consumptionDelegate.value
|
|
912
|
-
this.values.time = now
|
|
913
|
-
}
|
|
914
|
-
|
|
915
|
-
// get _fingerPrint () { return '04 0102 0202 0702 0f03' }
|
|
916
|
-
get _fingerPrint () { return '01 0702' }
|
|
917
|
-
|
|
918
|
-
_entryStream (entry) {
|
|
919
|
-
return util.format(
|
|
920
|
-
// '|14 %s %s 1f 0000 0000 %s 0000 0000',
|
|
921
|
-
'|0c %s %s 01 %s',
|
|
922
|
-
numToHex(swap32(this._h.currentEntry), 8),
|
|
923
|
-
numToHex(swap32(entry.time - this._h.initialTime), 8),
|
|
924
|
-
numToHex(swap16(entry.power * 10), 4)
|
|
925
|
-
)
|
|
926
|
-
}
|
|
927
|
-
}
|
|
928
|
-
|
|
929
|
-
/** Class for an Eve Door _History_ service delegate.
|
|
930
|
-
*
|
|
931
|
-
* This delegate sets up a `Services.eve.History` HomeKit service
|
|
932
|
-
* with keys for the following HomeKit characteristics:
|
|
933
|
-
*
|
|
934
|
-
* key | Characteristic
|
|
935
|
-
* ---------------- | ----------------------------------
|
|
936
|
-
* `name` | `Characteristics.hap.Name`
|
|
937
|
-
* `historyRequest` | `Characteristics.eve.HistoryRequest`
|
|
938
|
-
* `setTime` | `Characteristics.eve.SetTime`
|
|
939
|
-
* `historyStatus` | `Characteristics.eve.HistoryStatus`
|
|
940
|
-
* `historyEntries` | `Characteristics.eve.HistoryEntries`
|
|
941
|
-
* `resetTotal` | `Characteristics.eve.ResetTotal`
|
|
942
|
-
*
|
|
943
|
-
* This delegate creates the history from the associated
|
|
944
|
-
* `Characteristics.hap.ContactSensorState` characteristic. It updates the
|
|
945
|
-
* values of the associated `Characteristics.eve.TimesOpened` and
|
|
946
|
-
* `Characteristics.eve.LastActivation` characteristics.
|
|
947
|
-
* @extends ServiceDelegate.History
|
|
948
|
-
* @memberof ServiceDelegate.History
|
|
949
|
-
*/
|
|
950
|
-
class Contact extends ServiceDelegate.History {
|
|
951
|
-
/** Create a new instance of an Eve Door _History_ service delegate.
|
|
952
|
-
* @param {!AccessoryDelegate} accessoryDelegate - The delegate of the
|
|
953
|
-
* corresponding HomeKit accessory.
|
|
954
|
-
* @param {!object} params - The parameters for the
|
|
955
|
-
* _History_ HomeKit service.
|
|
956
|
-
* @param {!CharacteristicDelegate} contactDelegate - A reference to the
|
|
957
|
-
* delegate of the associated `Characteristics.hap.ContactSensorState`
|
|
958
|
-
* characteristic.
|
|
959
|
-
* @param {!CharacteristicDelegate} timesOpenedDelegate - A reference to the
|
|
960
|
-
* delegate of the associated `Characteristics.eve.TimesOpened`
|
|
961
|
-
* characteristic.
|
|
962
|
-
* @param {!CharacteristicDelegate} lastActivationDelegate - A reference to the
|
|
963
|
-
* delegate of the associated `Characteristics.eve.LastActivation`
|
|
964
|
-
* characteristic.
|
|
965
|
-
*/
|
|
966
|
-
constructor (
|
|
967
|
-
accessoryDelegate, params,
|
|
968
|
-
contactDelegate, timesOpenedDelegate, lastActivationDelegate
|
|
969
|
-
) {
|
|
970
|
-
super(accessoryDelegate, params)
|
|
971
|
-
if (!(contactDelegate instanceof homebridgeLib.CharacteristicDelegate)) {
|
|
972
|
-
throw new TypeError('contactDelegate: not a CharacteristicDelegate')
|
|
973
|
-
}
|
|
974
|
-
if (!(timesOpenedDelegate instanceof homebridgeLib.CharacteristicDelegate)) {
|
|
975
|
-
throw new TypeError('timesOpenedDelegate: not a CharacteristicDelegate')
|
|
976
|
-
}
|
|
977
|
-
if (!(lastActivationDelegate instanceof homebridgeLib.CharacteristicDelegate)) {
|
|
978
|
-
throw new TypeError('lastActivationDelegate: not a CharacteristicDelegate')
|
|
979
|
-
}
|
|
980
|
-
this._entry = { time: 0, status: contactDelegate.value }
|
|
981
|
-
contactDelegate.on('didSet', (value) => {
|
|
982
|
-
const now = Math.round(new Date().valueOf() / 1000)
|
|
983
|
-
timesOpenedDelegate.value += value
|
|
984
|
-
lastActivationDelegate.value = now - this._h.initialTime
|
|
985
|
-
this._entry.status = value
|
|
986
|
-
this._addEntry(now)
|
|
987
|
-
})
|
|
988
|
-
this.addCharacteristicDelegate({
|
|
989
|
-
key: 'resetTotal',
|
|
990
|
-
Characteristic: this.Characteristics.eve.ResetTotal,
|
|
991
|
-
value: params.resetTotal
|
|
992
|
-
})
|
|
993
|
-
this._characteristicDelegates.resetTotal.on('didSet', (value) => {
|
|
994
|
-
timesOpenedDelegate.value = 0
|
|
995
|
-
})
|
|
996
|
-
}
|
|
997
|
-
|
|
998
|
-
get _fingerPrint () { return '01 0601' }
|
|
999
|
-
|
|
1000
|
-
_entryStream (entry) {
|
|
1001
|
-
return util.format(
|
|
1002
|
-
'|0b %s %s 01 %s',
|
|
1003
|
-
numToHex(swap32(this._h.currentEntry), 8),
|
|
1004
|
-
numToHex(swap32(entry.time - this._h.initialTime), 8),
|
|
1005
|
-
numToHex(entry.status, 2)
|
|
1006
|
-
)
|
|
1007
|
-
}
|
|
1008
|
-
}
|
|
1009
|
-
|
|
1010
|
-
/** Class for an Eve Motion _History_ service delegate.
|
|
1011
|
-
*
|
|
1012
|
-
* This delegate sets up a `Services.eve.History` HomeKit service
|
|
1013
|
-
* with keys for the following HomeKit characteristics:
|
|
1014
|
-
*
|
|
1015
|
-
* key | Characteristic
|
|
1016
|
-
* ---------------- | ----------------------------------
|
|
1017
|
-
* `name` | `Characteristics.hap.Name`
|
|
1018
|
-
* `historyRequest` | `Characteristics.eve.HistoryRequest`
|
|
1019
|
-
* `setTime` | `Characteristics.eve.SetTime`
|
|
1020
|
-
* `historyStatus` | `Characteristics.eve.HistoryStatus`
|
|
1021
|
-
* `historyEntries` | `Characteristics.eve.HistoryEntries`
|
|
1022
|
-
* `resetTotal` | `Characteristics.eve.ResetTotal`
|
|
1023
|
-
*
|
|
1024
|
-
* This delegate creates the history from the associated
|
|
1025
|
-
* `Characteristics.hap.MotionDetected` characteristic. It updates the
|
|
1026
|
-
* value of the associated `Characteristics.eve.LastActivation` characteristic.
|
|
1027
|
-
* @extends ServiceDelegate.History
|
|
1028
|
-
* @memberof ServiceDelegate.History
|
|
1029
|
-
*/
|
|
1030
|
-
class Motion extends ServiceDelegate.History {
|
|
1031
|
-
/** Create a new instance of an Eve Motion _History_ service delegate.
|
|
1032
|
-
* @param {!AccessoryDelegate} accessoryDelegate - The delegate of the
|
|
1033
|
-
* corresponding HomeKit accessory.
|
|
1034
|
-
* @param {!object} params - The parameters for the
|
|
1035
|
-
* _History_ HomeKit service.
|
|
1036
|
-
* @param {!CharacteristicDelegate} motionDelegate - A reference to the
|
|
1037
|
-
* delegate of the associated `Characteristics.hap.MotionDetected`
|
|
1038
|
-
* characteristic.
|
|
1039
|
-
* @param {!CharacteristicDelegate} lastActivationDelegate - A reference to the
|
|
1040
|
-
* delegate of the associated `Characteristics.eve.LastActivation`
|
|
1041
|
-
* characteristic.
|
|
1042
|
-
* @param {?CharacteristicDelegate} temperatureDelegate - A reference to the
|
|
1043
|
-
* delegate of the associated `Characteristics.hap.CurrentTemperature`
|
|
1044
|
-
* characteristic. For PIR sensors (like the Hue motion sensor) that report
|
|
1045
|
-
* temperature in addition to motion.
|
|
1046
|
-
*/
|
|
1047
|
-
constructor (
|
|
1048
|
-
accessoryDelegate, params,
|
|
1049
|
-
motionDelegate, lastActivationDelegate, temperatureDelegate
|
|
1050
|
-
) {
|
|
1051
|
-
super(accessoryDelegate, params)
|
|
1052
|
-
if (!(motionDelegate instanceof homebridgeLib.CharacteristicDelegate)) {
|
|
1053
|
-
throw new TypeError('motionDelegate: not a CharacteristicDelegate')
|
|
1054
|
-
}
|
|
1055
|
-
if (!(lastActivationDelegate instanceof homebridgeLib.CharacteristicDelegate)) {
|
|
1056
|
-
throw new TypeError('lastActivationDelegate: not a CharacteristicDelegate')
|
|
1057
|
-
}
|
|
1058
|
-
if (
|
|
1059
|
-
temperatureDelegate != null &&
|
|
1060
|
-
!(temperatureDelegate instanceof homebridgeLib.CharacteristicDelegate)
|
|
1061
|
-
) {
|
|
1062
|
-
throw new TypeError('temperatureDelegate: not a CharacteristicDelegate')
|
|
1063
|
-
}
|
|
1064
|
-
this._entry = { time: 0, status: motionDelegate.value }
|
|
1065
|
-
motionDelegate.on('didSet', (value) => {
|
|
1066
|
-
const now = Math.round(new Date().valueOf() / 1000)
|
|
1067
|
-
lastActivationDelegate.value = now - this._h.initialTime
|
|
1068
|
-
this._entry.status = value
|
|
1069
|
-
if (this._entry.temp != null) {
|
|
1070
|
-
const temp = this._entry.temp
|
|
1071
|
-
this._entry.temp = null
|
|
1072
|
-
this._addEntry(now)
|
|
1073
|
-
this._entry.temp = temp
|
|
1074
|
-
} else {
|
|
1075
|
-
this._addEntry(now)
|
|
1076
|
-
}
|
|
1077
|
-
})
|
|
1078
|
-
if (temperatureDelegate != null) {
|
|
1079
|
-
this._entry.temp = temperatureDelegate.value
|
|
1080
|
-
temperatureDelegate.on('didSet', (value) => {
|
|
1081
|
-
this._entry.temp = value
|
|
1082
|
-
})
|
|
1083
|
-
}
|
|
1084
|
-
}
|
|
1085
|
-
|
|
1086
|
-
get _fingerPrint () {
|
|
1087
|
-
if (this._entry.temp != null) {
|
|
1088
|
-
return '02 1c01 0102'
|
|
1089
|
-
}
|
|
1090
|
-
return '01 1c01'
|
|
1091
|
-
}
|
|
1092
|
-
|
|
1093
|
-
_entryStream (entry) {
|
|
1094
|
-
if (this._entry.temp != null) {
|
|
1095
|
-
return util.format(
|
|
1096
|
-
'|0d %s %s 03 %s %s',
|
|
1097
|
-
numToHex(swap32(this._h.currentEntry), 8),
|
|
1098
|
-
numToHex(swap32(entry.time - this._h.initialTime), 8),
|
|
1099
|
-
numToHex(entry.status, 2),
|
|
1100
|
-
numToHex(swap16(entry.temp * 100), 4)
|
|
1101
|
-
)
|
|
1102
|
-
}
|
|
1103
|
-
return util.format(
|
|
1104
|
-
'|0b %s %s 01 %s',
|
|
1105
|
-
numToHex(swap32(this._h.currentEntry), 8),
|
|
1106
|
-
numToHex(swap32(entry.time - this._h.initialTime), 8),
|
|
1107
|
-
numToHex(entry.status, 2)
|
|
1108
|
-
)
|
|
1109
|
-
}
|
|
1110
|
-
}
|
|
1111
|
-
|
|
1112
|
-
/** Class for an Eve Energy _History_ service delegate.
|
|
1113
|
-
*
|
|
1114
|
-
* This delegate sets up a `Services.eve.History` HomeKit service
|
|
1115
|
-
* with keys for the following HomeKit characteristics:
|
|
1116
|
-
*
|
|
1117
|
-
* key | Characteristic
|
|
1118
|
-
* ---------------- | ----------------------------------
|
|
1119
|
-
* `name` | `Characteristics.hap.Name`
|
|
1120
|
-
* `historyRequest` | `Characteristics.eve.HistoryRequest`
|
|
1121
|
-
* `setTime` | `Characteristics.eve.SetTime`
|
|
1122
|
-
* `historyStatus` | `Characteristics.eve.HistoryStatus`
|
|
1123
|
-
* `historyEntries` | `Characteristics.eve.HistoryEntries`
|
|
1124
|
-
* `resetTotal` | `Characteristics.eve.ResetTotal`
|
|
1125
|
-
*
|
|
1126
|
-
* This delegate is for sensors that don't report life-time consumption. The
|
|
1127
|
-
* history from the value of the associated
|
|
1128
|
-
* `Characteristics.eve.CurrentConsumption` over time. It updates the value of
|
|
1129
|
-
* the associated `Characteristics.eve.TotalConsumption` characteristic.
|
|
1130
|
-
* @extends ServiceDelegate.History
|
|
1131
|
-
* @memberof ServiceDelegate.History
|
|
1132
|
-
*/
|
|
1133
|
-
class Power extends ServiceDelegate.History {
|
|
1134
|
-
/** Create a new instance of an Eve Energy _History_ service delegate.
|
|
1135
|
-
* @param {!AccessoryDelegate} accessoryDelegate - The delegate of the
|
|
1136
|
-
* corresponding HomeKit accessory.
|
|
1137
|
-
* @param {!object} params - The parameters for the
|
|
1138
|
-
* _History_ HomeKit service.
|
|
1139
|
-
* @param {!CharacteristicDelegate} powerDelegate - A reference to the
|
|
1140
|
-
* delegate of the associated `Characteristics.eve.CurrentConsumption`
|
|
1141
|
-
* characteristic.
|
|
1142
|
-
* @param {!CharacteristicDelegate} consumptionDelegate - A reference to the
|
|
1143
|
-
* delegate of the associated `Characteristics.eve.TotalConsumption`
|
|
1144
|
-
* characteristic.
|
|
1145
|
-
*/
|
|
1146
|
-
constructor (
|
|
1147
|
-
accessoryDelegate, params,
|
|
1148
|
-
powerDelegate, consumptionDelegate
|
|
1149
|
-
) {
|
|
1150
|
-
super(accessoryDelegate, params)
|
|
1151
|
-
if (!(powerDelegate instanceof homebridgeLib.CharacteristicDelegate)) {
|
|
1152
|
-
throw new TypeError('powerDelegate: not a CharacteristicDelegate')
|
|
1153
|
-
}
|
|
1154
|
-
if (!(consumptionDelegate instanceof homebridgeLib.CharacteristicDelegate)) {
|
|
1155
|
-
throw new TypeError('consumptionDelegate: not a CharacteristicDelegate')
|
|
1156
|
-
}
|
|
1157
|
-
this._powerDelegate = powerDelegate
|
|
1158
|
-
this._consumptionDelegate = consumptionDelegate
|
|
1159
|
-
this._entry = { time: 0, power: 0 }
|
|
1160
|
-
this._runningConsumption = 0 // 10-min-interval running value
|
|
1161
|
-
this._totalConsumption = consumptionDelegate.value // life-time value
|
|
1162
|
-
powerDelegate.on('didSet', (value) => {
|
|
1163
|
-
const now = Math.round(new Date().valueOf() / 1000)
|
|
1164
|
-
if (this._time != null) {
|
|
1165
|
-
const delta = this._power * (now - this._time) // Ws
|
|
1166
|
-
this._runningConsumption += Math.round(delta / 600.0) // W * 10 min
|
|
1167
|
-
this._totalConsumption += Math.round(delta / 3600.0) // Wh
|
|
1168
|
-
}
|
|
1169
|
-
this._power = value
|
|
1170
|
-
this._time = now
|
|
1171
|
-
})
|
|
1172
|
-
this.addCharacteristicDelegate({
|
|
1173
|
-
key: 'resetTotal',
|
|
1174
|
-
Characteristic: this.Characteristics.eve.ResetTotal,
|
|
1175
|
-
value: params.resetTotal
|
|
1176
|
-
})
|
|
1177
|
-
this._characteristicDelegates.resetTotal.on('didSet', (value) => {
|
|
1178
|
-
this._runningConsumption = 0
|
|
1179
|
-
this._totalConsumption = 0
|
|
1180
|
-
this._consumptionDelegate.value = this._totalConsumption
|
|
1181
|
-
})
|
|
1182
|
-
}
|
|
1183
|
-
|
|
1184
|
-
_addEntry () {
|
|
1185
|
-
// Sensor delivers currentConsumption, compute totalConsumption
|
|
1186
|
-
const now = Math.round(new Date().valueOf() / 1000)
|
|
1187
|
-
if (this._time != null) {
|
|
1188
|
-
const delta = this._power * (now - this._time) // Ws
|
|
1189
|
-
this._runningConsumption += Math.round(delta / 600.0) // W * 10 min
|
|
1190
|
-
this._totalConsumption += Math.round(delta / 3600.0) // Wh
|
|
1191
|
-
this._consumptionDelegate.value = this._totalConsumption
|
|
1192
|
-
this._entry.power = this._runningConsumption
|
|
1193
|
-
super._addEntry(now)
|
|
1194
|
-
}
|
|
1195
|
-
this._power = this._powerDelegate.value
|
|
1196
|
-
this._time = now
|
|
1197
|
-
this._runningConsumption = 0
|
|
1198
|
-
}
|
|
1199
|
-
|
|
1200
|
-
// get _fingerPrint () { return '04 0102 0202 0702 0f03' }
|
|
1201
|
-
get _fingerPrint () { return '01 0702' }
|
|
1202
|
-
|
|
1203
|
-
_entryStream (entry) {
|
|
1204
|
-
return util.format(
|
|
1205
|
-
// '|14 %s %s 1f 0000 0000 %s 0000 0000',
|
|
1206
|
-
'|0c %s %s 01 %s',
|
|
1207
|
-
numToHex(swap32(this._h.currentEntry), 8),
|
|
1208
|
-
numToHex(swap32(entry.time - this._h.initialTime), 8),
|
|
1209
|
-
numToHex(swap16(entry.power * 10), 4)
|
|
1210
|
-
)
|
|
1211
|
-
}
|
|
1212
|
-
}
|
|
1213
|
-
|
|
1214
|
-
/** Class for an Eve Thermo _History_ service delegate.
|
|
1215
|
-
*
|
|
1216
|
-
* This delegate sets up a `Services.eve.History` HomeKit service
|
|
1217
|
-
* with keys for the following HomeKit characteristics:
|
|
1218
|
-
*
|
|
1219
|
-
* key | Characteristic
|
|
1220
|
-
* ---------------- | ----------------------------------
|
|
1221
|
-
* `name` | `Characteristics.hap.Name`
|
|
1222
|
-
* `historyRequest` | `Characteristics.eve.HistoryRequest`
|
|
1223
|
-
* `setTime` | `Characteristics.eve.SetTime`
|
|
1224
|
-
* `historyStatus` | `Characteristics.eve.HistoryStatus`
|
|
1225
|
-
* `historyEntries` | `Characteristics.eve.HistoryEntries`
|
|
1226
|
-
*
|
|
1227
|
-
* This delegate creates the history from the associated
|
|
1228
|
-
* `Characteristics.hap.CurrentTemperature`,
|
|
1229
|
-
* `Characteristics.hap.TargetTemperature`, and
|
|
1230
|
-
* `Characteristics.eve.ValvePosition` characteristics.
|
|
1231
|
-
* @extends ServiceDelegate.History
|
|
1232
|
-
* @memberof ServiceDelegate.History
|
|
1233
|
-
*/
|
|
1234
|
-
class Thermo extends ServiceDelegate.History {
|
|
1235
|
-
/** Create a new instance of an Eve Thermo _History_ service delegate.
|
|
1236
|
-
* @param {!AccessoryDelegate} accessoryDelegate - The delegate of the
|
|
1237
|
-
* corresponding HomeKit accessory.
|
|
1238
|
-
* @param {!object} params - The parameters for the
|
|
1239
|
-
* _History_ HomeKit service.
|
|
1240
|
-
* @param {!CharacteristicDelegate} temperatureDelegate - A reference to the
|
|
1241
|
-
* delegate of the associated `Characteristics.hap.CurrentTemperature`
|
|
1242
|
-
* characteristic.
|
|
1243
|
-
* @param {!CharacteristicDelegate} targetTemperatureDelegate - A reference
|
|
1244
|
-
* to the delegate of the associated `Characteristics.hap.TargetTemperature`
|
|
1245
|
-
* characteristic.
|
|
1246
|
-
* @param {!CharacteristicDelegate} valvePositionDelegate - A reference to
|
|
1247
|
-
* the delegate of the associated `Characteristics.eve.ValvePosition`
|
|
1248
|
-
* characteristic.
|
|
1249
|
-
*/
|
|
1250
|
-
constructor (
|
|
1251
|
-
accessoryDelegate, params,
|
|
1252
|
-
temperatureDelegate, targetTemperatureDelegate, valvePositionDelegate
|
|
1253
|
-
) {
|
|
1254
|
-
super(accessoryDelegate, params)
|
|
1255
|
-
if (!(temperatureDelegate instanceof homebridgeLib.CharacteristicDelegate)) {
|
|
1256
|
-
throw new TypeError('temperatureDelegate: not a CharacteristicDelegate')
|
|
1257
|
-
}
|
|
1258
|
-
if (!(targetTemperatureDelegate instanceof homebridgeLib.CharacteristicDelegate)) {
|
|
1259
|
-
throw new TypeError('targetTemperatureDelegate: not a CharacteristicDelegate')
|
|
1260
|
-
}
|
|
1261
|
-
if (!(valvePositionDelegate instanceof homebridgeLib.CharacteristicDelegate)) {
|
|
1262
|
-
throw new TypeError('valvePositionDelegate: not a CharacteristicDelegate')
|
|
1263
|
-
}
|
|
1264
|
-
this._entry = {
|
|
1265
|
-
time: 0,
|
|
1266
|
-
currentTemp: temperatureDelegate.value,
|
|
1267
|
-
setTemp: targetTemperatureDelegate.value,
|
|
1268
|
-
valvePosition: valvePositionDelegate.value
|
|
1269
|
-
}
|
|
1270
|
-
temperatureDelegate
|
|
1271
|
-
.on('didSet', (value) => { this._entry.currentTemp = value })
|
|
1272
|
-
targetTemperatureDelegate
|
|
1273
|
-
.on('didSet', (value) => { this._entry.setTemp = value })
|
|
1274
|
-
valvePositionDelegate
|
|
1275
|
-
.on('didSet', (value) => { this._entry.valvePosition = value })
|
|
1276
|
-
}
|
|
1277
|
-
|
|
1278
|
-
// I think 1201 and 1d01 are for current mode and target more, but it doesn't
|
|
1279
|
-
// look like Eve displays any history for these.
|
|
1280
|
-
// As of v3.8.1, Eve no longer shows the valve position history.
|
|
1281
|
-
// get _fingerPrint () { return '05 0102 1102 1001 1201 1d01' }
|
|
1282
|
-
get _fingerPrint () { return '03 0102 1102 1001' }
|
|
1283
|
-
|
|
1284
|
-
_entryStream (entry) {
|
|
1285
|
-
return util.format(
|
|
1286
|
-
// '|11 %s %s 1f %s %s %s 00 00',
|
|
1287
|
-
'|0f %s %s 07 %s %s %s',
|
|
1288
|
-
numToHex(swap32(this._h.currentEntry), 8),
|
|
1289
|
-
numToHex(swap32(entry.time - this._h.initialTime), 8),
|
|
1290
|
-
numToHex(swap16(entry.currentTemp * 100), 4),
|
|
1291
|
-
numToHex(swap16(entry.setTemp * 100), 4),
|
|
1292
|
-
numToHex(entry.valvePosition, 2)
|
|
1293
|
-
)
|
|
1294
|
-
}
|
|
1295
|
-
}
|
|
1296
|
-
|
|
1297
|
-
/** Class for an Eve Weather _History_ service delegate.
|
|
1298
|
-
*
|
|
1299
|
-
* This delegate sets up a `Services.eve.History` HomeKit service
|
|
1300
|
-
* with keys for the following HomeKit characteristics:
|
|
1301
|
-
*
|
|
1302
|
-
* key | Characteristic
|
|
1303
|
-
* ---------------- | ----------------------------------
|
|
1304
|
-
* `name` | `Characteristics.hap.Name`
|
|
1305
|
-
* `historyRequest` | `Characteristics.eve.HistoryRequest`
|
|
1306
|
-
* `setTime` | `Characteristics.eve.SetTime`
|
|
1307
|
-
* `historyStatus` | `Characteristics.eve.HistoryStatus`
|
|
1308
|
-
* `historyEntries` | `Characteristics.eve.HistoryEntries`
|
|
1309
|
-
*
|
|
1310
|
-
* This delegate creates the history from the associated
|
|
1311
|
-
* `Characteristics.hap.CurrentTemperature`,
|
|
1312
|
-
* `Characteristics.hap.CurrentRelativeHumidity`, and
|
|
1313
|
-
* `Characteristics.eve.AirPressure` characteristics.
|
|
1314
|
-
* @extends ServiceDelegate.History
|
|
1315
|
-
* @memberof ServiceDelegate.History
|
|
1316
|
-
*/
|
|
1317
|
-
class Weather extends ServiceDelegate.History {
|
|
1318
|
-
/** Create a new instance of an Eve Weather _History_ service delegate.
|
|
1319
|
-
* @param {!AccessoryDelegate} accessoryDelegate - The delegate of the
|
|
1320
|
-
* corresponding HomeKit accessory.
|
|
1321
|
-
* @param {!object} params - The parameters for the
|
|
1322
|
-
* _History_ HomeKit service.
|
|
1323
|
-
* @param {!CharacteristicDelegate} temperatureDelegate - A reference to the
|
|
1324
|
-
* delegate of the associated `Characteristics.hap.CurrentTemperature`
|
|
1325
|
-
* characteristic.
|
|
1326
|
-
* @param {?CharacteristicDelegate} humidityDelegate - A reference to the
|
|
1327
|
-
* delegate of the associated `Characteristics.hap.CurrentRelativeHumidity`
|
|
1328
|
-
* characteristic.
|
|
1329
|
-
* @param {?CharacteristicDelegate} pressureDelegate - A reference to the
|
|
1330
|
-
* delegate of the associated `Characteristics.eve.AirPressure`
|
|
1331
|
-
* characteristic.
|
|
1332
|
-
*/
|
|
1333
|
-
constructor (
|
|
1334
|
-
accessoryDelegate, params,
|
|
1335
|
-
temperatureDelegate, humidityDelegate, pressureDelegate
|
|
1336
|
-
) {
|
|
1337
|
-
super(accessoryDelegate, params)
|
|
1338
|
-
if (!(temperatureDelegate instanceof homebridgeLib.CharacteristicDelegate)) {
|
|
1339
|
-
throw new TypeError('temperatureDelegate: not a CharacteristicDelegate')
|
|
1340
|
-
}
|
|
1341
|
-
if (
|
|
1342
|
-
humidityDelegate != null &&
|
|
1343
|
-
!(humidityDelegate instanceof homebridgeLib.CharacteristicDelegate)
|
|
1344
|
-
) {
|
|
1345
|
-
throw new TypeError('humidityDelegate: not a CharacteristicDelegate')
|
|
1346
|
-
}
|
|
1347
|
-
if (
|
|
1348
|
-
pressureDelegate != null &&
|
|
1349
|
-
!(pressureDelegate instanceof homebridgeLib.CharacteristicDelegate)
|
|
1350
|
-
) {
|
|
1351
|
-
throw new TypeError('pressureDelegate: not a CharacteristicDelegate')
|
|
1352
|
-
}
|
|
1353
|
-
this._entry = {
|
|
1354
|
-
time: 0,
|
|
1355
|
-
temp: temperatureDelegate.value,
|
|
1356
|
-
humidity: 0,
|
|
1357
|
-
pressure: 0
|
|
1358
|
-
}
|
|
1359
|
-
temperatureDelegate.on('didSet', (value) => {
|
|
1360
|
-
this._entry.temp = value
|
|
1361
|
-
})
|
|
1362
|
-
if (humidityDelegate != null) {
|
|
1363
|
-
this._entry.humidity = humidityDelegate.value
|
|
1364
|
-
humidityDelegate.on('didSet', (value) => {
|
|
1365
|
-
this._entry.humidity = value
|
|
1366
|
-
})
|
|
1367
|
-
if (pressureDelegate != null) {
|
|
1368
|
-
this._entry.pressure = pressureDelegate.value
|
|
1369
|
-
pressureDelegate.on('didSet', (value) => {
|
|
1370
|
-
this._entry.pressure = value
|
|
1371
|
-
})
|
|
1372
|
-
}
|
|
1373
|
-
}
|
|
1374
|
-
}
|
|
1375
|
-
|
|
1376
|
-
get _fingerPrint () {
|
|
1377
|
-
return '03 0102 0202 0302'
|
|
1378
|
-
}
|
|
1379
|
-
|
|
1380
|
-
_entryStream (entry) {
|
|
1381
|
-
return util.format(
|
|
1382
|
-
'|10 %s %s 07 %s %s %s',
|
|
1383
|
-
numToHex(swap32(this._h.currentEntry), 8),
|
|
1384
|
-
numToHex(swap32(entry.time - this._h.initialTime), 8),
|
|
1385
|
-
numToHex(swap16(entry.temp * 100), 4),
|
|
1386
|
-
numToHex(swap16(entry.humidity * 100), 4),
|
|
1387
|
-
numToHex(swap16(entry.pressure * 10), 4)
|
|
1388
|
-
)
|
|
1389
|
-
}
|
|
1390
|
-
}
|
|
1391
|
-
|
|
1392
|
-
/** Class for a Raspberry Pi _History_ service delegate.
|
|
1393
|
-
*
|
|
1394
|
-
* This delegate sets up a `Services.eve.History` HomeKit service
|
|
1395
|
-
* with keys for the following HomeKit characteristics:
|
|
1396
|
-
*
|
|
1397
|
-
* key | Characteristic
|
|
1398
|
-
* ---------------- | ----------------------------------
|
|
1399
|
-
* `name` | `Characteristics.hap.Name`
|
|
1400
|
-
* `historyRequest` | `Characteristics.eve.HistoryRequest`
|
|
1401
|
-
* `setTime` | `Characteristics.eve.SetTime`
|
|
1402
|
-
* `historyStatus` | `Characteristics.eve.HistoryStatus`
|
|
1403
|
-
* `historyEntries` | `Characteristics.eve.HistoryEntries`
|
|
1404
|
-
*
|
|
1405
|
-
* This delegate creates the history from the associated
|
|
1406
|
-
* `Characteristics.hap.On` characteristic.
|
|
1407
|
-
* @extends ServiceDelegate.History
|
|
1408
|
-
* @memberof ServiceDelegate.History
|
|
1409
|
-
*/
|
|
1410
|
-
class On extends ServiceDelegate.History {
|
|
1411
|
-
/** Create a new instance of a Raspberry Pi _History_ service delegate.
|
|
1412
|
-
* @param {!AccessoryDelegate} accessoryDelegate - The delegate of the
|
|
1413
|
-
* corresponding HomeKit accessory.
|
|
1414
|
-
* @param {!object} params - The parameters for the
|
|
1415
|
-
* _History_ HomeKit service.
|
|
1416
|
-
* @param {!CharacteristicDelegate} onDelegate - A reference to the
|
|
1417
|
-
* delegate of the associated `Characteristics.hap.On`
|
|
1418
|
-
* characteristic.
|
|
1419
|
-
*/
|
|
1420
|
-
constructor (accessoryDelegate, params, onDelegate) {
|
|
1421
|
-
super(accessoryDelegate, params)
|
|
1422
|
-
if (!(onDelegate instanceof homebridgeLib.CharacteristicDelegate)) {
|
|
1423
|
-
throw new TypeError('onDelegate: not a CharacteristicDelegate')
|
|
1424
|
-
}
|
|
1425
|
-
this._entry = {
|
|
1426
|
-
time: 0,
|
|
1427
|
-
on: onDelegate.value ? 1 : 0
|
|
1428
|
-
}
|
|
1429
|
-
onDelegate.on('didSet', (value) => {
|
|
1430
|
-
this._entry.on = value ? 1 : 0
|
|
1431
|
-
this._addEntry()
|
|
1432
|
-
})
|
|
1433
|
-
}
|
|
1434
|
-
|
|
1435
|
-
get _fingerPrint () { return '01 0e01' }
|
|
1436
|
-
|
|
1437
|
-
_entryStream (entry) {
|
|
1438
|
-
return util.format(
|
|
1439
|
-
'|0b %s %s 01 %s',
|
|
1440
|
-
numToHex(swap32(this._h.currentEntry), 8),
|
|
1441
|
-
numToHex(swap32(entry.time - this._h.initialTime), 8),
|
|
1442
|
-
numToHex(entry.on, 2)
|
|
1443
|
-
)
|
|
1444
|
-
}
|
|
1445
|
-
}
|
|
1446
|
-
|
|
1447
|
-
module.exports = ServiceDelegate
|