homebridge-lib 6.2.2 → 6.3.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/lib/ServiceDelegate/History.js +679 -0
- package/package.json +1 -1
- package/lib/ServiceDelegate/History/Consumption.js +0 -130
- package/lib/ServiceDelegate/History/Light.js +0 -74
- package/lib/ServiceDelegate/History/On.js +0 -98
- package/lib/ServiceDelegate/History/Power.js +0 -147
- package/lib/ServiceDelegate/History/Sensor.js +0 -215
- package/lib/ServiceDelegate/History/Thermo.js +0 -88
- package/lib/ServiceDelegate/History/index.js +0 -310
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
// homebridge-lib/lib/ServiceDelegate/History/Thermo.js
|
|
2
|
-
//
|
|
3
|
-
// Library for Homebridge plugins.
|
|
4
|
-
// Copyright © 2017-2023 Erik Baauw. All rights reserved.
|
|
5
|
-
|
|
6
|
-
'use strict'
|
|
7
|
-
|
|
8
|
-
const homebridgeLib = require('../../../index')
|
|
9
|
-
|
|
10
|
-
const { History } = homebridgeLib.ServiceDelegate
|
|
11
|
-
|
|
12
|
-
/** Class for an Eve Thermo _History_ service delegate.
|
|
13
|
-
*
|
|
14
|
-
* This delegate sets up a `Services.eve.History` HomeKit service
|
|
15
|
-
* with keys for the following HomeKit characteristics:
|
|
16
|
-
*
|
|
17
|
-
* key | Characteristic
|
|
18
|
-
* ---------------- | ----------------------------------
|
|
19
|
-
* `name` | `Characteristics.hap.Name`
|
|
20
|
-
* `historyRequest` | `Characteristics.eve.HistoryRequest`
|
|
21
|
-
* `setTime` | `Characteristics.eve.SetTime`
|
|
22
|
-
* `historyStatus` | `Characteristics.eve.HistoryStatus`
|
|
23
|
-
* `historyEntries` | `Characteristics.eve.HistoryEntries`
|
|
24
|
-
*
|
|
25
|
-
* This delegate creates the history from the associated
|
|
26
|
-
* `Characteristics.hap.CurrentTemperature`,
|
|
27
|
-
* `Characteristics.hap.TargetTemperature`, and
|
|
28
|
-
* `Characteristics.eve.ValvePosition` characteristics.
|
|
29
|
-
* @extends ServiceDelegate.History
|
|
30
|
-
* @memberof ServiceDelegate.History
|
|
31
|
-
*/
|
|
32
|
-
class Thermo extends History {
|
|
33
|
-
/** Create a new instance of an Eve Thermo _History_ service delegate.
|
|
34
|
-
* @param {!AccessoryDelegate} accessoryDelegate - The delegate of the
|
|
35
|
-
* corresponding HomeKit accessory.
|
|
36
|
-
* @param {!object} params - The parameters for the
|
|
37
|
-
* _History_ HomeKit service.
|
|
38
|
-
* @param {!CharacteristicDelegate} params.temperatureDelegate - A reference
|
|
39
|
-
* to the delegate of the associated `Characteristics.hap.CurrentTemperature`
|
|
40
|
-
* characteristic.
|
|
41
|
-
* @param {!CharacteristicDelegate} params.targetTemperatureDelegate - A
|
|
42
|
-
* reference to the delegate of the associated
|
|
43
|
-
* `Characteristics.hap.TargetTemperature` characteristic.
|
|
44
|
-
* @param {!CharacteristicDelegate} params.valvePositionDelegate - A
|
|
45
|
-
* reference to the delegate of the associated
|
|
46
|
-
* `Characteristics.eve.ValvePosition` characteristic.
|
|
47
|
-
*/
|
|
48
|
-
constructor (accessoryDelegate, params) {
|
|
49
|
-
super(accessoryDelegate, params)
|
|
50
|
-
if (!(params.temperatureDelegate instanceof homebridgeLib.CharacteristicDelegate)) {
|
|
51
|
-
throw new TypeError('params.temperatureDelegate: not a CharacteristicDelegate')
|
|
52
|
-
}
|
|
53
|
-
if (!(params.targetTemperatureDelegate instanceof homebridgeLib.CharacteristicDelegate)) {
|
|
54
|
-
throw new TypeError('params.targetTemperatureDelegate: not a CharacteristicDelegate')
|
|
55
|
-
}
|
|
56
|
-
if (!(params.valvePositionDelegate instanceof homebridgeLib.CharacteristicDelegate)) {
|
|
57
|
-
throw new TypeError('params.valvePositionDelegate: not a CharacteristicDelegate')
|
|
58
|
-
}
|
|
59
|
-
this.entry = {
|
|
60
|
-
t: params.temperatureDelegate.value * 100,
|
|
61
|
-
s: params.targetTemperatureDelegate.value * 100,
|
|
62
|
-
v: params.valvePositionDelegate.value
|
|
63
|
-
}
|
|
64
|
-
params.temperatureDelegate.on('didSet', (value) => {
|
|
65
|
-
this.entry.t = value * 100
|
|
66
|
-
})
|
|
67
|
-
params.targetTemperatureDelegate.on('didSet', (value) => {
|
|
68
|
-
this.entry.s = value * 100
|
|
69
|
-
})
|
|
70
|
-
params.valvePositionDelegate.on('didSet', (value) => {
|
|
71
|
-
this.entry.v = value
|
|
72
|
-
})
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
get fingerPrint () { return '03 0102 1102 1001' }
|
|
76
|
-
|
|
77
|
-
entryToBuffer (entry) {
|
|
78
|
-
const buffer = Buffer.alloc(6)
|
|
79
|
-
let o = 1
|
|
80
|
-
buffer.writeUInt16LE(entry.t, o); o += 2
|
|
81
|
-
buffer.writeUInt16LE(entry.s, o); o += 2
|
|
82
|
-
buffer.writeUInt8(entry.v, o); o += 1
|
|
83
|
-
buffer.writeUInt8(0x07, 0)
|
|
84
|
-
return buffer.slice(0, o)
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
module.exports = Thermo
|
|
@@ -1,310 +0,0 @@
|
|
|
1
|
-
// homebridge-lib/lib/ServiceDelegate/History/index.js
|
|
2
|
-
//
|
|
3
|
-
// Library for Homebridge plugins.
|
|
4
|
-
// Copyright © 2017-2023 Erik Baauw. All rights reserved.
|
|
5
|
-
//
|
|
6
|
-
// The logic for handling Eve history was inspired by 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 { ServiceDelegate } = homebridgeLib
|
|
15
|
-
|
|
16
|
-
/** Eve history keeps time as # seconds since epoch of 2001/01/01.
|
|
17
|
-
* @type {integer}
|
|
18
|
-
*/
|
|
19
|
-
const epoch = Math.round(new Date('2001-01-01T00:00:00Z').valueOf() / 1000)
|
|
20
|
-
|
|
21
|
-
const defaultMemorySize = 6 * 24 * 7 * 4 // 4 weeks of 1 entry per 10 minutes
|
|
22
|
-
|
|
23
|
-
/** Convert date (in # seconds since NodeJS epoch) to string.
|
|
24
|
-
* @param {integer} d - # seconds since NodeJS epoch.
|
|
25
|
-
* @returns {string} Human readable date string.
|
|
26
|
-
*/
|
|
27
|
-
function dateToString (d) {
|
|
28
|
-
return new Date(1000 * d).toString().slice(0, 24)
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
/** Abstract superclass for an Eve _History_ service delegate.
|
|
32
|
-
*
|
|
33
|
-
* This delegate sets up a `Services.eve.History` HomeKit service
|
|
34
|
-
* with keys for the following HomeKit characteristics:
|
|
35
|
-
*
|
|
36
|
-
* key | Characteristic
|
|
37
|
-
* ---------------- | ----------------------------------
|
|
38
|
-
* `name` | `Characteristics.hap.Name`
|
|
39
|
-
* `historyRequest` | `Characteristics.eve.HistoryRequest`
|
|
40
|
-
* `setTime` | `Characteristics.eve.SetTime`
|
|
41
|
-
* `historyStatus` | `Characteristics.eve.HistoryStatus`
|
|
42
|
-
* `historyEntries` | `Characteristics.eve.HistoryEntries`
|
|
43
|
-
* @abstract
|
|
44
|
-
* @extends ServiceDelegate
|
|
45
|
-
* @memberof ServiceDelegate
|
|
46
|
-
*/
|
|
47
|
-
class History extends ServiceDelegate {
|
|
48
|
-
static get Consumption () { return require('./Consumption') }
|
|
49
|
-
static get Light () { return require('./Light') }
|
|
50
|
-
static get On () { return require('./On') }
|
|
51
|
-
static get Power () { return require('./Power') }
|
|
52
|
-
static get Sensor () { return require('./Sensor') }
|
|
53
|
-
static get Thermo () { return require('./Thermo') }
|
|
54
|
-
|
|
55
|
-
/** Create a new instance of an Eve _History_ service delegate.
|
|
56
|
-
* @param {!AccessoryDelegate} accessoryDelegate - The delegate of the
|
|
57
|
-
* corresponding HomeKit accessory.
|
|
58
|
-
* @param {!object} params - The parameters for the
|
|
59
|
-
* _History_ HomeKit service.
|
|
60
|
-
* @param {integer} [params.memorySize=4032] - The memory size, in number of
|
|
61
|
-
* history entries. The default is 4 weeks of 1 entry per 10 minutes.
|
|
62
|
-
* @param {?boolean} params.config - Expose config.
|
|
63
|
-
*/
|
|
64
|
-
constructor (accessoryDelegate, params = {}) {
|
|
65
|
-
params.name = accessoryDelegate.name + ' History'
|
|
66
|
-
params.Service = accessoryDelegate.Services.eve.History
|
|
67
|
-
params.hidden = true
|
|
68
|
-
super(accessoryDelegate, params)
|
|
69
|
-
const memorySize = params.memorySize == null ? defaultMemorySize : params.memorySize
|
|
70
|
-
this._transfer = false
|
|
71
|
-
|
|
72
|
-
this.addCharacteristicDelegate({
|
|
73
|
-
key: 'history',
|
|
74
|
-
silent: true
|
|
75
|
-
})
|
|
76
|
-
this._h = this.values.history
|
|
77
|
-
if (this._h == null) {
|
|
78
|
-
this.values.history = {
|
|
79
|
-
memorySize,
|
|
80
|
-
firstEntry: 1,
|
|
81
|
-
lastEntry: 1,
|
|
82
|
-
entryOffset: 0,
|
|
83
|
-
entries: [null, null],
|
|
84
|
-
initialTime: History.now()
|
|
85
|
-
}
|
|
86
|
-
this._h = this.values.history
|
|
87
|
-
} else if (this._h.memorySize !== memorySize) {
|
|
88
|
-
this.values.history = {
|
|
89
|
-
memorySize,
|
|
90
|
-
firstEntry: this._h.lastEntry,
|
|
91
|
-
lastEntry: this._h.lastEntry,
|
|
92
|
-
entryOffset: this._h.lastEntry - 1,
|
|
93
|
-
entries: [null, null],
|
|
94
|
-
initialTime: this._h.initialTime
|
|
95
|
-
}
|
|
96
|
-
this._h = this.values.history
|
|
97
|
-
} else {
|
|
98
|
-
this.debug(
|
|
99
|
-
'restored %d history entries (%d to %d)', this._h.entries.length,
|
|
100
|
-
this._h.firstEntry, this._h.lastEntry
|
|
101
|
-
)
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
this.addCharacteristicDelegate({
|
|
105
|
-
key: 'historyRequest',
|
|
106
|
-
Characteristic: this.Characteristics.eve.HistoryRequest,
|
|
107
|
-
value: params.historyRequest,
|
|
108
|
-
setter: this._onSetHistoryRequest.bind(this),
|
|
109
|
-
silent: true
|
|
110
|
-
})
|
|
111
|
-
|
|
112
|
-
this.addCharacteristicDelegate({
|
|
113
|
-
key: 'setTime',
|
|
114
|
-
Characteristic: this.Characteristics.eve.SetTime,
|
|
115
|
-
value: params.setTime,
|
|
116
|
-
silent: true
|
|
117
|
-
}).on('didSet', (value) => {
|
|
118
|
-
const buffer = Buffer.from(value, 'base64')
|
|
119
|
-
this.vdebug('SetTime changed to %j', buffer.toString('hex'))
|
|
120
|
-
const date = dateToString(buffer.readUInt32LE() + epoch)
|
|
121
|
-
this.debug('SetTime changed to %s', date)
|
|
122
|
-
})
|
|
123
|
-
|
|
124
|
-
this.addCharacteristicDelegate({
|
|
125
|
-
key: 'historyStatus',
|
|
126
|
-
Characteristic: this.Characteristics.eve.HistoryStatus,
|
|
127
|
-
value: params.historyStatus,
|
|
128
|
-
silent: true
|
|
129
|
-
})
|
|
130
|
-
|
|
131
|
-
this.addCharacteristicDelegate({
|
|
132
|
-
key: 'historyEntries',
|
|
133
|
-
Characteristic: this.Characteristics.eve.HistoryEntries,
|
|
134
|
-
value: params.historyEntries,
|
|
135
|
-
getter: this._onGetEntries.bind(this),
|
|
136
|
-
silent: true
|
|
137
|
-
})
|
|
138
|
-
|
|
139
|
-
if (params.config) {
|
|
140
|
-
this.addCharacteristicDelegate({
|
|
141
|
-
key: 'configCommand',
|
|
142
|
-
Characteristic: this.Characteristics.eve.ConfigCommand,
|
|
143
|
-
setter: this._onSetConfig.bind(this)
|
|
144
|
-
// silent: true
|
|
145
|
-
})
|
|
146
|
-
|
|
147
|
-
this.addCharacteristicDelegate({
|
|
148
|
-
key: 'configData',
|
|
149
|
-
Characteristic: this.Characteristics.eve.ConfigData,
|
|
150
|
-
getter: this._onGetConfig.bind(this)
|
|
151
|
-
// silent: true
|
|
152
|
-
})
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
accessoryDelegate.propertyDelegate('name')
|
|
156
|
-
.on('didSet', (value) => {
|
|
157
|
-
this.values.configuredName = value + ' History'
|
|
158
|
-
})
|
|
159
|
-
|
|
160
|
-
this._accessoryDelegate.heartbeatEnabled = true
|
|
161
|
-
this._accessoryDelegate
|
|
162
|
-
.once('heartbeat', (beat) => {
|
|
163
|
-
this._historyBeat = (beat % 600) + 5
|
|
164
|
-
})
|
|
165
|
-
.on('heartbeat', (beat) => {
|
|
166
|
-
if (beat % 600 === this._historyBeat) {
|
|
167
|
-
this.addEntry(
|
|
168
|
-
Object.assign({ time: History.now() }, this.entry)
|
|
169
|
-
)
|
|
170
|
-
}
|
|
171
|
-
})
|
|
172
|
-
.on('shutdown', () => {
|
|
173
|
-
this.debug(
|
|
174
|
-
'saved %d history entries (%d to %d)', this._h.entries.length,
|
|
175
|
-
this._h.firstEntry, this._h.lastEntry
|
|
176
|
-
)
|
|
177
|
-
})
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
/** Return current time as # seconds since NodeJS epoch.
|
|
181
|
-
* @returns {integer} # seconds since NodeJS epoch.
|
|
182
|
-
*/
|
|
183
|
-
static now () { return Math.round(new Date().valueOf() / 1000) }
|
|
184
|
-
|
|
185
|
-
/** Convert date intp `Characteristics.eve.LastActivation` characteristic value.
|
|
186
|
-
* @param {integer} date - # seconds since NodeJS epoch.
|
|
187
|
-
* @returns {integer} Value for last activation.
|
|
188
|
-
*/
|
|
189
|
-
lastActivationValue (date = History.now()) { return date - this._h.initialTime }
|
|
190
|
-
|
|
191
|
-
/** Return the history fingerprint.
|
|
192
|
-
* @abstract
|
|
193
|
-
* @returns {string} fingerprint - Hex string with the fingerprint.
|
|
194
|
-
*/
|
|
195
|
-
get fingerPrint () { return '00' }
|
|
196
|
-
|
|
197
|
-
/** Convert a history entry to a buffer.
|
|
198
|
-
* @abstract
|
|
199
|
-
* @param {object} entry - The entry.
|
|
200
|
-
* @returns {Buffer} A Buffer with the values from the entry.
|
|
201
|
-
*/
|
|
202
|
-
entryToBuffer (entry) {
|
|
203
|
-
return Buffer.alloc(0)
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
/** Add an entry to the history.
|
|
207
|
-
* @param {object} entry - The entry.
|
|
208
|
-
*/
|
|
209
|
-
addEntry (entry) {
|
|
210
|
-
if (this._h.memorySize > 0) {
|
|
211
|
-
if (this._h.lastEntry - this._h.entryOffset >= this._h.memorySize) {
|
|
212
|
-
this._h.firstEntry++
|
|
213
|
-
}
|
|
214
|
-
this._h.lastEntry++
|
|
215
|
-
const index = (this._h.lastEntry - this._h.entryOffset) % this._h.memorySize
|
|
216
|
-
this.debug(
|
|
217
|
-
'History Entries: set entry %d (index %d) to %j',
|
|
218
|
-
this._h.lastEntry, index, entry
|
|
219
|
-
)
|
|
220
|
-
this._h.entries[index] = entry
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
this.debug('set History Status to %d .. %d', this._h.firstEntry, this._h.lastEntry)
|
|
224
|
-
const buffer = Buffer.alloc(1024)
|
|
225
|
-
let offset = 0
|
|
226
|
-
buffer.writeUInt32LE(entry.time - this._h.initialTime, offset); offset += 4
|
|
227
|
-
buffer.writeUInt32LE(0, offset); offset += 4
|
|
228
|
-
buffer.writeUInt32LE(this._h.initialTime - epoch, offset); offset += 4
|
|
229
|
-
buffer.write(this.fingerPrint.replace(/[^0-9A-F]/ig, ''), offset, 'hex')
|
|
230
|
-
offset += 1 + 2 * parseInt(this.fingerPrint.slice(0, 2))
|
|
231
|
-
buffer.writeUInt16LE(this._h.lastEntry - this._h.firstEntry + 1, offset); offset += 2
|
|
232
|
-
buffer.writeUInt16LE(this._h.memorySize, offset); offset += 2
|
|
233
|
-
buffer.writeUInt32LE(this._h.firstEntry, offset); offset += 4
|
|
234
|
-
buffer.writeUInt32LE(0, offset); offset += 4
|
|
235
|
-
buffer.writeUInt8(1, offset); offset += 1
|
|
236
|
-
buffer.writeUInt8(1, offset); offset += 1
|
|
237
|
-
const value = buffer.slice(0, offset)
|
|
238
|
-
this.values.historyStatus = value.toString('base64')
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
async _onSetHistoryRequest (value) {
|
|
242
|
-
const buffer = Buffer.from(value, 'base64')
|
|
243
|
-
this.vdebug('History Request changed to %j', buffer.toString('hex'))
|
|
244
|
-
const entry = buffer.readUInt32LE(2)
|
|
245
|
-
this.debug(
|
|
246
|
-
'History Request changed to %d (%d to %d)', entry,
|
|
247
|
-
this._h.firstEntry, this._h.lastEntry
|
|
248
|
-
)
|
|
249
|
-
this._currentEntry = Math.max(this._h.firstEntry, entry)
|
|
250
|
-
this._transfer = true
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
async _onGetEntries () {
|
|
254
|
-
if (this._currentEntry > this._h.lastEntry || !this._transfer) {
|
|
255
|
-
this.debug('History Entries: no entry')
|
|
256
|
-
this.vdebug('History Entries: send data: 00')
|
|
257
|
-
this._transfer = false
|
|
258
|
-
return Buffer.from('00', 'hex').toString('base64')
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
const buffer = Buffer.alloc(1024)
|
|
262
|
-
let offset = 0
|
|
263
|
-
for (let i = 0; i < 11; i++) {
|
|
264
|
-
const index = this._h.memorySize === 0
|
|
265
|
-
? 1
|
|
266
|
-
: (this._currentEntry - this._h.entryOffset) % this._h.memorySize
|
|
267
|
-
if (this._currentEntry === this._h.firstEntry) {
|
|
268
|
-
this.debug(
|
|
269
|
-
'History Entries (%d/11): entry %d (index: %d): %j (%s)',
|
|
270
|
-
i, this._currentEntry, index, { initialTime: this._h.initialTime - epoch },
|
|
271
|
-
dateToString(this._h.initialTime)
|
|
272
|
-
)
|
|
273
|
-
buffer.writeUInt8(21, offset); offset += 1
|
|
274
|
-
buffer.writeUInt32LE(this._currentEntry, offset); offset += 4
|
|
275
|
-
buffer.write('0100000081', offset, 'hex'); offset += 5
|
|
276
|
-
buffer.writeUInt32LE(this._h.initialTime - epoch, offset); offset += 4
|
|
277
|
-
buffer.write('00000000000000', offset, 'hex'); offset += 7
|
|
278
|
-
} else {
|
|
279
|
-
const entry = this._h.entries[index]
|
|
280
|
-
this.debug(
|
|
281
|
-
'History Entries (%d/11): entry %d (index: %d): %j (%s)',
|
|
282
|
-
i, this._currentEntry, index, entry, dateToString(entry.time)
|
|
283
|
-
)
|
|
284
|
-
const b = this.entryToBuffer(entry)
|
|
285
|
-
buffer.writeUInt8(b.length + 9, offset); offset += 1
|
|
286
|
-
buffer.writeUInt32LE(this._currentEntry, offset); offset += 4
|
|
287
|
-
buffer.writeUInt32LE(entry.time - this._h.initialTime, offset); offset += 4
|
|
288
|
-
b.copy(buffer, offset); offset += b.length
|
|
289
|
-
}
|
|
290
|
-
this._currentEntry++
|
|
291
|
-
if (this._currentEntry > this._h.lastEntry) {
|
|
292
|
-
break
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
|
-
const value = buffer.slice(0, offset)
|
|
296
|
-
this.vdebug('History Entries: send data: %s', value.toString('hex'))
|
|
297
|
-
return value.toString('base64')
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
async _onSetConfig (value) {
|
|
301
|
-
const buffer = Buffer.from(value, 'base64')
|
|
302
|
-
this.vdebug('Config Request changed to %j', buffer.toString('hex'))
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
async _onGetConfig () {
|
|
306
|
-
return Buffer.from('D200', 'hex').toString('base64')
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
module.exports = History
|