homebridge-lib 6.3.8 → 6.3.9

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.
@@ -76,13 +76,14 @@ class HistoryValue {
76
76
  * @params {Buffer} buffer - The buffer to write to.
77
77
  * @params {integer} offset - The offset within the buffer.
78
78
  */
79
- writeEntry (entry, buffer, offset) { buffer.writeInt16LE(entry[this.id], offset) }
79
+ writeEntry (entry, buffer, offset) { buffer.writeUInt16LE(entry[this.id], offset) }
80
80
  }
81
81
 
82
82
  class TemperatureValue extends HistoryValue {
83
83
  get tag () { return 0x01 }
84
84
  get id () { return 't' }
85
85
  prepareEntry (entry) { entry[this.id] = this._delegate.value * 100 }
86
+ writeEntry (entry, buffer, offset) { buffer.writeInt16LE(entry[this.id], offset) }
86
87
  }
87
88
 
88
89
  class HumidityValue extends HistoryValue {
@@ -106,7 +107,7 @@ class ContactValue extends HistoryValue {
106
107
  get tag () { return 0x06 }
107
108
  get length () { return 1 }
108
109
  get id () { return 'c' }
109
- prepareEntry (entry) { entry[this.id] = this._delegate.value ? 1 : 0 }
110
+ prepareEntry (entry) { entry[this.id] = this._delegate.value }
110
111
  writeEntry (entry, buffer, offset) { buffer.writeInt8(entry[this.id], offset) }
111
112
 
112
113
  constructor (parent, delegate) {
@@ -114,14 +115,10 @@ class ContactValue extends HistoryValue {
114
115
  delegate.on('didSet', (value) => {
115
116
  const now = History.now()
116
117
  const entry = { time: now }
117
- entry[this.id] = this._delegate.value ? 1 : 0
118
+ entry[this.id] = this._delegate.value
118
119
  parent.addEntry(entry)
119
- if (parent.lastContactDelegate != null) {
120
- parent.lastContactDelegate = parent.lastActivationValue(now)
121
- }
122
- if (parent.timesOpenedDelegate != null) {
123
- parent.timesOpenedDelegate.value += value
124
- }
120
+ parent.lastContactDelegate = parent.lastActivationValue(now)
121
+ parent.timesOpenedDelegate.value += value
125
122
  })
126
123
  parent.addCharacteristicDelegate({
127
124
  key: 'resetTotal',
@@ -132,67 +129,94 @@ class ContactValue extends HistoryValue {
132
129
  }
133
130
  }
134
131
 
132
+ // Eve history entries for _Total Consumption_ actually contain the (average) power,
133
+ // in 0.1 W, since the previous entry. Eve computes the displayed consumption in Wh.
134
+
135
+ // Device delivers consumption in kWh. We compute average power.
135
136
  class ConsumptionValue extends HistoryValue {
136
137
  get tag () { return 0x07 }
137
138
  get id () { return 'p' }
138
139
 
139
140
  constructor (parent, delegate) {
140
141
  super(parent, delegate)
141
- this._consumption = delegate.value
142
- this._time = History.now()
142
+ parent.addCharacteristicDelegate({
143
+ key: 'consumption',
144
+ unit: ' kWh',
145
+ value: delegate.value,
146
+ silent: true
147
+ })
148
+ parent.addCharacteristicDelegate({
149
+ key: 'time',
150
+ value: History.now(),
151
+ silent: true
152
+ })
143
153
  }
144
154
 
145
155
  prepareEntry (entry) {
146
- const delta = this._delegate.value - this._consumption // kWh
147
- const period = entry.time - this._time // s
148
- const power = period === 0 ? 0 : 1000 * 3600 * delta / period // W
156
+ const consumption = (this._delegate.value - this._parent.values.consumption) * 1000 * 3600 // Ws
157
+ const period = entry.time - this._parent.values.time // s
158
+ const power = consumption / period // W
159
+ entry[this.id] = Math.round(power * 10) // 0.1 W
149
160
  if (this._parent.computedPowerDelegate != null) {
150
- this._parent.computedPowerDelegate.value = Math.round(power) // W
161
+ this._parent.computedPowerDelegate.value = Math.round(power * 10) / 10 // W
151
162
  }
152
- entry[this.id] = Math.round(power * 10) // 0.1 W * 10 min
153
- this._consumption = this._delegate.value
154
- this._time = entry.time
163
+ this._parent.values.consumption = this._delegate.value
164
+ this._parent.values.time = entry.time
155
165
  }
156
166
  }
157
167
 
168
+ // Device delivers power in W. We compute total consumption and average power.
158
169
  class PowerValue extends HistoryValue {
159
170
  get tag () { return 0x07 }
160
171
  get id () { return 'p' }
161
172
 
162
173
  constructor (parent, delegate) {
163
174
  super(parent, delegate)
164
- this._runningConsumption = 0 // 10-min-interval running value
165
- this._totalConsumption = parent.computedConsumptionDelegate.value * 100
166
- this._power = delegate.value // current power
167
- this._time = History.now() // start time of current power
175
+ this._consumption = 0 // Ws
176
+ this._period = 0 // s
177
+ this._totalConsumption = parent.computedConsumptionDelegate.value * 1000 * 3600 // Ws
178
+ this._power = delegate.value // W
179
+ this._time = History.now()
168
180
  delegate.on('didSet', (value) => {
169
- const now = History.now()
170
- const delta = this._power * (now - this._time) // Ws
171
- this._runningConsumption += Math.round(delta / 60.0) // 0.1W * 10 min
172
- this._totalConsumption += delta / 36000.0 // 0.01 kWh
173
- this._power = value
174
- this._time = now
181
+ this.updateRunningTotals()
182
+ this._power = value // W
175
183
  })
176
184
  parent.addCharacteristicDelegate({
177
185
  key: 'resetTotal',
178
186
  Characteristic: parent.Characteristics.eve.ResetTotal
179
187
  }).on('didSet', (value) => {
180
- this._runningConsumption = 0
181
- this._totalConsumption = 0
182
- parent.computedConsumptionDelegate.value = this._totalConsumption
188
+ this._totalConsumption = 0 // Ws
189
+ parent.computedConsumptionDelegate.value = 0 // kWh
183
190
  })
184
191
  }
185
192
 
186
193
  prepareEntry (entry) {
187
- const delta = this._power * (entry.time - this._time) // Ws
188
- this._runningConsumption += delta / 60.0 // 0.1 W * 10 min
189
- this._totalConsumption += delta / 36000.0 // 0.01 kWh
190
- this._parent.computedConsumptionDelegate.value = Math.round(this._totalConsumption) / 100.0 // kWh
191
- entry[this.id] = Math.round(this._runningConsumption) // 0.1 W * 10 min
192
- this._power = this._delegate.value
193
- this._time = entry.time
194
- this._runningConsumption = 0
194
+ this.updateRunningTotals(entry.time)
195
+
196
+ const power = this._period === 0 ? 0 : this._consumption / this._period // W
197
+ entry[this.id] = Math.round(power * 10) // 0.1 W
198
+ const totalConsumption = this._totalConsumption / (1000 * 3600) // kWh
199
+ this._parent.computedConsumptionDelegate.value = Math.round(totalConsumption * 100) / 100 // kWh
200
+
201
+ this._consumption = 0
202
+ this._period = 0
195
203
  }
204
+
205
+ updateRunningTotals (now = History.now()) {
206
+ const period = now - this._time // s
207
+ const delta = this._power * period // Ws
208
+ this._consumption += delta // Ws
209
+ this._period += period // s
210
+ this._totalConsumption += delta // Ws
211
+ this._time = now
212
+ }
213
+ }
214
+
215
+ // Device delivers (running) avarage power in W.
216
+ class AveragePowerValue extends HistoryValue {
217
+ get tag () { return 0x07 }
218
+ get id () { return 'p' }
219
+ prepareEntry (entry) { entry[this.id] = this._delegate.value * 10 }
196
220
  }
197
221
 
198
222
  class SwitchOnValue extends HistoryValue {
@@ -225,6 +249,7 @@ class TargetTemperatureValue extends HistoryValue {
225
249
  get tag () { return 0x11 }
226
250
  get id () { return 's' }
227
251
  prepareEntry (entry) { entry[this.id] = this._delegate.value * 100 }
252
+ writeEntry (entry, buffer, offset) { buffer.writeInt16LE(entry[this.id], offset) }
228
253
  }
229
254
 
230
255
  class MotionValue extends HistoryValue {
@@ -273,7 +298,6 @@ class VocDensityValue extends HistoryValue {
273
298
  class LightLevelValue extends HistoryValue {
274
299
  get tag () { return 0x30 }
275
300
  get id () { return 'l' }
276
- // writeEntry (entry, buffer, offset) { buffer.writeUInt16LE(entry[this.id], offset) }
277
301
  }
278
302
 
279
303
  // Types of delegates for characteristics for history data points.
@@ -284,6 +308,7 @@ const historyValueTypes = {
284
308
  airPressure: AirPressureValue,
285
309
  contact: ContactValue,
286
310
  power: PowerValue,
311
+ averagePower: AveragePowerValue,
287
312
  switchOn: SwitchOnValue,
288
313
  consumption: ConsumptionValue,
289
314
  valvePosition: ValvePositionValue,
@@ -596,12 +621,14 @@ class History extends ServiceDelegate {
596
621
  let bitmap = 0
597
622
  let offset = 1
598
623
  for (const i in this._valueTypes) {
599
- const valueType = this._valueTypes[i]
600
- if (entry[valueType.id] != null) {
601
- bitmap |= 0x01 << i
602
- valueType.writeEntry(entry, buffer, offset)
603
- offset += valueType.length
604
- }
624
+ try {
625
+ const valueType = this._valueTypes[i]
626
+ if (entry[valueType.id] != null) {
627
+ bitmap |= 0x01 << i
628
+ valueType.writeEntry(entry, buffer, offset)
629
+ offset += valueType.length
630
+ }
631
+ } catch (error) { this.warn(error) }
605
632
  }
606
633
  buffer.writeUInt8(bitmap, 0)
607
634
  return buffer.slice(0, offset)
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "description": "Library for homebridge plugins",
4
4
  "author": "Erik Baauw",
5
5
  "license": "Apache-2.0",
6
- "version": "6.3.8",
6
+ "version": "6.3.9",
7
7
  "keywords": [
8
8
  "homekit",
9
9
  "homebridge"
@@ -22,11 +22,11 @@
22
22
  },
23
23
  "engines": {
24
24
  "homebridge": "^1.6.0",
25
- "node": "^18.14.0"
25
+ "node": "^18.14.1"
26
26
  },
27
27
  "dependencies": {
28
28
  "@homebridge/plugin-ui-utils": "~0.0.19",
29
- "hb-lib-tools": "^1.0.2"
29
+ "hb-lib-tools": "^1.0.3"
30
30
  },
31
31
  "scripts": {
32
32
  "prepare": "standard && rm -rf out && jsdoc -c jsdoc.json",