Home Assistant: add plugin source, support temp for heating switch devices (BC) (#31915)
This commit is contained in:
parent
28d36a51f0
commit
a5956a6804
4 changed files with 173 additions and 92 deletions
|
|
@ -1,79 +0,0 @@
|
|||
package charger
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/evcc-io/evcc/api"
|
||||
"github.com/evcc-io/evcc/util"
|
||||
"github.com/evcc-io/evcc/util/homeassistant"
|
||||
)
|
||||
|
||||
type HomeAssistantSwitch struct {
|
||||
conn *homeassistant.Connection
|
||||
enable string
|
||||
power string
|
||||
*switchSocket
|
||||
}
|
||||
|
||||
func init() {
|
||||
registry.Add("homeassistant-switch", NewHomeAssistantSwitchFromConfig)
|
||||
}
|
||||
|
||||
func NewHomeAssistantSwitchFromConfig(other map[string]any) (api.Charger, error) {
|
||||
var cc struct {
|
||||
embed `mapstructure:",squash"`
|
||||
homeassistant.Config `mapstructure:",squash"`
|
||||
Enable string
|
||||
Power string
|
||||
StandbyPower float64
|
||||
}
|
||||
|
||||
if err := util.DecodeOther(other, &cc); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return NewHomeAssistantSwitch(cc.embed, cc.URI, cc.Home_, cc.Insecure, cc.Enable, cc.Power, cc.StandbyPower)
|
||||
}
|
||||
|
||||
func NewHomeAssistantSwitch(embed embed, uri, home string, insecure bool, enable, power string, standbypower float64) (api.Charger, error) {
|
||||
if enable == "" {
|
||||
return nil, errors.New("missing enable switch entity")
|
||||
}
|
||||
|
||||
// standbypower < 0 ensures that currentPower is never used by the switch socket if not present
|
||||
if power == "" && standbypower >= 0 {
|
||||
return nil, errors.New("missing either power entity or negative standbypower")
|
||||
}
|
||||
|
||||
log := util.NewLogger("ha-switch")
|
||||
|
||||
conn, err := homeassistant.NewConnection(log, uri, home, insecure)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
c := &HomeAssistantSwitch{
|
||||
enable: enable,
|
||||
power: power,
|
||||
conn: conn,
|
||||
}
|
||||
|
||||
c.switchSocket = NewSwitchSocket(&embed, c.Enabled, c.currentPower, standbypower)
|
||||
|
||||
return c, nil
|
||||
}
|
||||
|
||||
// Enabled implements the api.Charger interface
|
||||
func (c *HomeAssistantSwitch) Enabled() (bool, error) {
|
||||
return c.conn.GetBoolState(c.enable)
|
||||
}
|
||||
|
||||
// Enable implements the api.Charger interface
|
||||
func (c *HomeAssistantSwitch) Enable(enable bool) error {
|
||||
return c.conn.CallSwitchService(c.enable, enable)
|
||||
}
|
||||
|
||||
// currentPower implements the api.Meter interface (optional)
|
||||
func (c *HomeAssistantSwitch) currentPower() (float64, error) {
|
||||
return c.conn.GetFloatState(c.power)
|
||||
}
|
||||
|
|
@ -2,9 +2,11 @@ package charger
|
|||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
|
||||
"github.com/evcc-io/evcc/api"
|
||||
"github.com/evcc-io/evcc/api/implement"
|
||||
"github.com/evcc-io/evcc/charger/measurement"
|
||||
"github.com/evcc-io/evcc/core/loadpoint"
|
||||
"github.com/evcc-io/evcc/plugin"
|
||||
"github.com/evcc-io/evcc/util"
|
||||
|
|
@ -23,13 +25,14 @@ type SwitchSocket struct {
|
|||
|
||||
func NewSwitchSocketFromConfig(ctx context.Context, other map[string]any) (api.Charger, error) {
|
||||
var cc struct {
|
||||
embed `mapstructure:",squash"`
|
||||
Enabled plugin.Config
|
||||
Enable plugin.Config
|
||||
Power plugin.Config
|
||||
Energy *plugin.Config
|
||||
Soc *plugin.Config
|
||||
StandbyPower float64
|
||||
embed `mapstructure:",squash"`
|
||||
Enabled plugin.Config
|
||||
Enable plugin.Config
|
||||
Power *plugin.Config
|
||||
Energy *plugin.Config
|
||||
Soc *plugin.Config
|
||||
measurement.Temperature `mapstructure:",squash"` // optional, for heating devices
|
||||
StandbyPower float64
|
||||
}
|
||||
|
||||
if err := util.DecodeOther(other, &cc); err != nil {
|
||||
|
|
@ -51,6 +54,11 @@ func NewSwitchSocketFromConfig(ctx context.Context, other map[string]any) (api.C
|
|||
return nil, err
|
||||
}
|
||||
|
||||
// standbypower < 0 ensures that power is never used by the switch socket if not present
|
||||
if power == nil && cc.StandbyPower >= 0 {
|
||||
return nil, errors.New("missing either power or negative standbypower")
|
||||
}
|
||||
|
||||
c := &SwitchSocket{
|
||||
Caps: implement.New(),
|
||||
enabled: enabled,
|
||||
|
|
@ -68,7 +76,17 @@ func NewSwitchSocketFromConfig(ctx context.Context, other map[string]any) (api.C
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// for heating devices, the soc slot holds temperature in °C — fall back to temp getter
|
||||
temp, limitTemp, err := cc.Temperature.Configure(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if soc == nil && temp != nil {
|
||||
soc = temp
|
||||
}
|
||||
implement.May(c, implement.Battery(soc))
|
||||
implement.May(c, implement.SocLimiter(limitTemp))
|
||||
|
||||
return c, nil
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue