Home Assistant Meter: add battery soc (#24511)

This commit is contained in:
Sebastian Sucker 2025-10-17 18:45:16 +02:00 • committed by GitHub
parent 6cbb2a6d42
commit ae68505bd2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 171 additions and 11 deletions

View file

@ -1,6 +1,6 @@
package meter
//go:generate go tool decorate -f decorateHomeAssistant -b *HomeAssistant -r api.Meter -t "api.MeterEnergy,TotalEnergy,func() (float64, error)" -t "api.PhaseCurrents,Currents,func() (float64, float64, float64, error)" -t "api.PhaseVoltages,Voltages,func() (float64, float64, float64, error)"
//go:generate go tool decorate -f decorateHomeAssistant -b *HomeAssistant -r api.Meter -t "api.MeterEnergy,TotalEnergy,func() (float64, error)" -t "api.PhaseCurrents,Currents,func() (float64, float64, float64, error)" -t "api.PhaseVoltages,Voltages,func() (float64, float64, float64, error)" -t "api.Battery,Soc,func() (float64, error)"
import (
"errors"
@ -30,6 +30,7 @@ func NewHomeAssistantFromConfig(other map[string]interface{}) (api.Meter, error)
Energy string
Currents []string
Voltages []string
Soc string
}{}
if err := util.DecodeOther(other, &cc); err != nil {
@ -54,6 +55,7 @@ func NewHomeAssistantFromConfig(other map[string]interface{}) (api.Meter, error)
// decorators for optional interfaces
var energy func() (float64, error)
var currents, voltages func() (float64, float64, float64, error)
var soc func() (float64, error)
if cc.Energy != "" {
energy = func() (float64, error) { return conn.GetFloatState(cc.Energy) }
@ -76,7 +78,11 @@ func NewHomeAssistantFromConfig(other map[string]interface{}) (api.Meter, error)
voltages = func() (float64, float64, float64, error) { return conn.GetPhaseFloatStates(phases) }
}
return decorateHomeAssistant(m, energy, currents, voltages), nil
if cc.Soc != "" {
soc = func() (float64, error) { return conn.GetFloatState(cc.Soc) }
}
return decorateHomeAssistant(m, energy, currents, voltages, soc), nil
}
var _ api.Meter = (*HomeAssistant)(nil)

View file

@ -6,12 +6,12 @@ import (
"github.com/evcc-io/evcc/api"
)
func decorateHomeAssistant(base *HomeAssistant, meterEnergy func() (float64, error), phaseCurrents func() (float64, float64, float64, error), phaseVoltages func() (float64, float64, float64, error)) api.Meter {
func decorateHomeAssistant(base *HomeAssistant, meterEnergy func() (float64, error), phaseCurrents func() (float64, float64, float64, error), phaseVoltages func() (float64, float64, float64, error), battery func() (float64, error)) api.Meter {
switch {
case meterEnergy == nil && phaseCurrents == nil && phaseVoltages == nil:
case battery == nil && meterEnergy == nil && phaseCurrents == nil && phaseVoltages == nil:
return base
case meterEnergy != nil && phaseCurrents == nil && phaseVoltages == nil:
case battery == nil && meterEnergy != nil && phaseCurrents == nil && phaseVoltages == nil:
return &struct {
*HomeAssistant
api.MeterEnergy
@ -22,7 +22,7 @@ func decorateHomeAssistant(base *HomeAssistant, meterEnergy func() (float64, err
},
}
case meterEnergy == nil && phaseCurrents != nil && phaseVoltages == nil:
case battery == nil && meterEnergy == nil && phaseCurrents != nil && phaseVoltages == nil:
return &struct {
*HomeAssistant
api.PhaseCurrents
@ -33,7 +33,7 @@ func decorateHomeAssistant(base *HomeAssistant, meterEnergy func() (float64, err
},
}
case meterEnergy != nil && phaseCurrents != nil && phaseVoltages == nil:
case battery == nil && meterEnergy != nil && phaseCurrents != nil && phaseVoltages == nil:
return &struct {
*HomeAssistant
api.MeterEnergy
@ -48,7 +48,7 @@ func decorateHomeAssistant(base *HomeAssistant, meterEnergy func() (float64, err
},
}
case meterEnergy == nil && phaseCurrents == nil && phaseVoltages != nil:
case battery == nil && meterEnergy == nil && phaseCurrents == nil && phaseVoltages != nil:
return &struct {
*HomeAssistant
api.PhaseVoltages
@ -59,7 +59,7 @@ func decorateHomeAssistant(base *HomeAssistant, meterEnergy func() (float64, err
},
}
case meterEnergy != nil && phaseCurrents == nil && phaseVoltages != nil:
case battery == nil && meterEnergy != nil && phaseCurrents == nil && phaseVoltages != nil:
return &struct {
*HomeAssistant
api.MeterEnergy
@ -74,7 +74,7 @@ func decorateHomeAssistant(base *HomeAssistant, meterEnergy func() (float64, err
},
}
case meterEnergy == nil && phaseCurrents != nil && phaseVoltages != nil:
case battery == nil && meterEnergy == nil && phaseCurrents != nil && phaseVoltages != nil:
return &struct {
*HomeAssistant
api.PhaseCurrents
@ -89,7 +89,7 @@ func decorateHomeAssistant(base *HomeAssistant, meterEnergy func() (float64, err
},
}
case meterEnergy != nil && phaseCurrents != nil && phaseVoltages != nil:
case battery == nil && meterEnergy != nil && phaseCurrents != nil && phaseVoltages != nil:
return &struct {
*HomeAssistant
api.MeterEnergy
@ -107,11 +107,155 @@ func decorateHomeAssistant(base *HomeAssistant, meterEnergy func() (float64, err
phaseVoltages: phaseVoltages,
},
}
case battery != nil && meterEnergy == nil && phaseCurrents == nil && phaseVoltages == nil:
return &struct {
*HomeAssistant
api.Battery
}{
HomeAssistant: base,
Battery: &decorateHomeAssistantBatteryImpl{
battery: battery,
},
}
case battery != nil && meterEnergy != nil && phaseCurrents == nil && phaseVoltages == nil:
return &struct {
*HomeAssistant
api.Battery
api.MeterEnergy
}{
HomeAssistant: base,
Battery: &decorateHomeAssistantBatteryImpl{
battery: battery,
},
MeterEnergy: &decorateHomeAssistantMeterEnergyImpl{
meterEnergy: meterEnergy,
},
}
case battery != nil && meterEnergy == nil && phaseCurrents != nil && phaseVoltages == nil:
return &struct {
*HomeAssistant
api.Battery
api.PhaseCurrents
}{
HomeAssistant: base,
Battery: &decorateHomeAssistantBatteryImpl{
battery: battery,
},
PhaseCurrents: &decorateHomeAssistantPhaseCurrentsImpl{
phaseCurrents: phaseCurrents,
},
}
case battery != nil && meterEnergy != nil && phaseCurrents != nil && phaseVoltages == nil:
return &struct {
*HomeAssistant
api.Battery
api.MeterEnergy
api.PhaseCurrents
}{
HomeAssistant: base,
Battery: &decorateHomeAssistantBatteryImpl{
battery: battery,
},
MeterEnergy: &decorateHomeAssistantMeterEnergyImpl{
meterEnergy: meterEnergy,
},
PhaseCurrents: &decorateHomeAssistantPhaseCurrentsImpl{
phaseCurrents: phaseCurrents,
},
}
case battery != nil && meterEnergy == nil && phaseCurrents == nil && phaseVoltages != nil:
return &struct {
*HomeAssistant
api.Battery
api.PhaseVoltages
}{
HomeAssistant: base,
Battery: &decorateHomeAssistantBatteryImpl{
battery: battery,
},
PhaseVoltages: &decorateHomeAssistantPhaseVoltagesImpl{
phaseVoltages: phaseVoltages,
},
}
case battery != nil && meterEnergy != nil && phaseCurrents == nil && phaseVoltages != nil:
return &struct {
*HomeAssistant
api.Battery
api.MeterEnergy
api.PhaseVoltages
}{
HomeAssistant: base,
Battery: &decorateHomeAssistantBatteryImpl{
battery: battery,
},
MeterEnergy: &decorateHomeAssistantMeterEnergyImpl{
meterEnergy: meterEnergy,
},
PhaseVoltages: &decorateHomeAssistantPhaseVoltagesImpl{
phaseVoltages: phaseVoltages,
},
}
case battery != nil && meterEnergy == nil && phaseCurrents != nil && phaseVoltages != nil:
return &struct {
*HomeAssistant
api.Battery
api.PhaseCurrents
api.PhaseVoltages
}{
HomeAssistant: base,
Battery: &decorateHomeAssistantBatteryImpl{
battery: battery,
},
PhaseCurrents: &decorateHomeAssistantPhaseCurrentsImpl{
phaseCurrents: phaseCurrents,
},
PhaseVoltages: &decorateHomeAssistantPhaseVoltagesImpl{
phaseVoltages: phaseVoltages,
},
}
case battery != nil && meterEnergy != nil && phaseCurrents != nil && phaseVoltages != nil:
return &struct {
*HomeAssistant
api.Battery
api.MeterEnergy
api.PhaseCurrents
api.PhaseVoltages
}{
HomeAssistant: base,
Battery: &decorateHomeAssistantBatteryImpl{
battery: battery,
},
MeterEnergy: &decorateHomeAssistantMeterEnergyImpl{
meterEnergy: meterEnergy,
},
PhaseCurrents: &decorateHomeAssistantPhaseCurrentsImpl{
phaseCurrents: phaseCurrents,
},
PhaseVoltages: &decorateHomeAssistantPhaseVoltagesImpl{
phaseVoltages: phaseVoltages,
},
}
}
return nil
}
type decorateHomeAssistantBatteryImpl struct {
battery func() (float64, error)
}
func (impl *decorateHomeAssistantBatteryImpl) Soc() (float64, error) {
return impl.battery()
}
type decorateHomeAssistantMeterEnergyImpl struct {
meterEnergy func() (float64, error)
}

View file

@ -94,6 +94,15 @@ params:
help:
en: Entity ID for L3 voltage measurement in volts
de: Entitäts-ID für L3 Spannungsmessung in Volt
- name: soc
description:
de: Batterieladestand
en: Battery State of Charge
example: "sensor.battery_soc"
advanced: true
help:
en: Entity ID for battery state of charge in percent
de: Entitäts-ID für Batterieladestand in Prozent
render: |
type: homeassistant
uri: {{ .uri }}
@ -108,3 +117,4 @@ render: |
- {{ .voltageL1 }}
- {{ .voltageL2 }}
- {{ .voltageL3 }}
soc: {{ .soc }}