Skip to content

Commit

Permalink
Update History.js
Browse files Browse the repository at this point in the history
- Bug fix: RangeError: The value of "value" is out of range. It must be >= -32768 and <= 32767. Received 41948 when history entry contains illegal value.
Now invalid value is simply not reported to Eve and default has been changes to unsigned int16 (from signed int16).  See ebaauw/homebridge-p1#70.
- Add `averagePowerDelegate` parameter for Homebridge P1 support for capacity tariff in Flanders, see ebaauw/homebridge-p1#69.
- Refactor consumption history (again...)
  • Loading branch information
ebaauw committed Feb 11, 2023
1 parent 4a1ddf0 commit 3ce0ee5
Showing 1 changed file with 58 additions and 27 deletions.
85 changes: 58 additions & 27 deletions lib/ServiceDelegate/History.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ class HistoryValue {
* @params {Buffer} buffer - The buffer to write to.
* @params {integer} offset - The offset within the buffer.
*/
writeEntry (entry, buffer, offset) { buffer.writeUInt16LE(entry[this.id], offset) }
writeEntry (entry, buffer, offset) { buffer.writeInt16LE(entry[this.id], offset) }
}

class TemperatureValue extends HistoryValue {
Expand Down Expand Up @@ -133,69 +133,97 @@ class ContactValue extends HistoryValue {
}
}

// Device delivers consumption in kWh.
class ConsumptionValue extends HistoryValue {
get tag () { return 0x07 }
get id () { return 'p' }

constructor (parent, delegate) {
super(parent, delegate)
this._consumption = delegate.value
this._consumption = delegate.value // kWh
this._time = History.now()
}

prepareEntry (entry) {
const delta = this._delegate.value - this._consumption // kWh
const period = entry.time - this._time // s
const power = period === 0 ? 0 : 1000 * 3600 * delta / period // W
let delta = this._delegate.value - this._consumption // kWh
delta *= 1000 // Wh
entry[this.id] = Math.round(delta * 10) // 0.1 Wh
if (this._parent.computedPowerDelegate != null) {
// Optionally compute (average) power.
delta *= 3600 // Ws
const period = entry.time - this._time // s
const power = period === 0 ? 0 : delta / period // W
this._parent.computedPowerDelegate.value = Math.round(power) // W
}
entry[this.id] = Math.round(power * 10) // 0.1 W * 10 min
this._consumption = this._delegate.value
this._consumption -= this._delegate.value
this._time = entry.time
}
}

// Device delivers power in W.
class PowerValue extends HistoryValue {
get tag () { return 0x07 }
get id () { return 'p' }

constructor (parent, delegate) {
super(parent, delegate)
this._runningConsumption = 0 // 10-min-interval running value
this._totalConsumption = parent.computedConsumptionDelegate.value * 100
this._power = delegate.value // current power
this._time = History.now() // start time of current power
this._runningConsumption = 0 // Ws
this._totalConsumption = parent.computedConsumptionDelegate.value // kWh
this._totalConsumption *= 3600 * 1000 // Ws
this._power = delegate.value // W
this._time = History.now()
delegate.on('didSet', (value) => {
const now = History.now()
const delta = this._power * (now - this._time) // Ws
this._runningConsumption += Math.round(delta / 60.0) // 0.1W * 10 min
this._totalConsumption += delta / 36000.0 // 0.01 kWh
this._power = value
this._runningConsumption += delta // Ws
this._totalConsumption += delta // Ws
this._power = value // W
this._time = now
})
parent.addCharacteristicDelegate({
key: 'resetTotal',
Characteristic: parent.Characteristics.eve.ResetTotal
}).on('didSet', (value) => {
this._runningConsumption = 0
this._totalConsumption = 0
parent.computedConsumptionDelegate.value = this._totalConsumption
this._runningConsumption = 0 // Ws
this._totalConsumption = 0 // Ws
const totalConsumption = this._totalConsumption * 3600 * 1000 * 100 // 0.01 kWh
parent.computedConsumptionDelegate.value = Math.round(totalConsumption) / 100.0 // kWh
})
}

prepareEntry (entry) {
const delta = this._power * (entry.time - this._time) // Ws
this._runningConsumption += delta / 60.0 // 0.1 W * 10 min
this._totalConsumption += delta / 36000.0 // 0.01 kWh
this._parent.computedConsumptionDelegate.value = Math.round(this._totalConsumption) / 100.0 // kWh
entry[this.id] = Math.round(this._runningConsumption) // 0.1 W * 10 min
this._runningConsumption += delta // Ws
this._totalConsumption += delta // Ws
const consumption = this.this._runningConsumption * 3600 // Wh
entry[this.id] = Math.round(consumption * 10) // 0.1 Wh
const totalConsumption = this._totalConsumption * 3600 * 1000 * 100 // 0.01 kWh
this._parent.computedConsumptionDelegate.value = Math.round(totalConsumption) / 100.0 // kWh
this._power = this._delegate.value
this._time = entry.time
this._runningConsumption = 0
}
}

// Device delivers running avarage of power in W.
class AveragePowerValue extends HistoryValue {
get tag () { return 0x07 }
get id () { return 'p' }

constructor (parent, delegate) {
super(parent, delegate)
this._time = History.now()
}

prepareEntry (entry) {
const delta = entry.time - this._time // s
let consumption = this._delegate.value * delta // Ws
consumption *= 3600 // Wh
entry[this.id] = Math.round(consumption * 10) // 0.1 Wh
this._time = entry.time
}
}

class SwitchOnValue extends HistoryValue {
get tag () { return 0x0E }
get length () { return 1 }
Expand Down Expand Up @@ -285,6 +313,7 @@ const historyValueTypes = {
airPressure: AirPressureValue,
contact: ContactValue,
power: PowerValue,
averagePower: AveragePowerValue,
switchOn: SwitchOnValue,
consumption: ConsumptionValue,
valvePosition: ValvePositionValue,
Expand Down Expand Up @@ -597,12 +626,14 @@ class History extends ServiceDelegate {
let bitmap = 0
let offset = 1
for (const i in this._valueTypes) {
const valueType = this._valueTypes[i]
if (entry[valueType.id] != null) {
bitmap |= 0x01 << i
valueType.writeEntry(entry, buffer, offset)
offset += valueType.length
}
try {
const valueType = this._valueTypes[i]
if (entry[valueType.id] != null) {
bitmap |= 0x01 << i
valueType.writeEntry(entry, buffer, offset)
offset += valueType.length
}
} catch (error) { this.warn(error) }
}
buffer.writeUInt8(bitmap, 0)
return buffer.slice(0, offset)
Expand Down

0 comments on commit 3ce0ee5

Please sign in to comment.