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.
@@ -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