diff --git a/meter/homeassistant.go b/meter/homeassistant.go index cd2c5689c..3dcab2826 100644 --- a/meter/homeassistant.go +++ b/meter/homeassistant.go @@ -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) diff --git a/meter/homeassistant_decorators.go b/meter/homeassistant_decorators.go index dd826d7d5..b83974192 100644 --- a/meter/homeassistant_decorators.go +++ b/meter/homeassistant_decorators.go @@ -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) } diff --git a/templates/definition/meter/homeassistant.yaml b/templates/definition/meter/homeassistant.yaml index 8e1542815..6e21058de 100644 --- a/templates/definition/meter/homeassistant.yaml +++ b/templates/definition/meter/homeassistant.yaml @@ -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 }}