Add Home Assistant Switch as switchsockets charger (#21358)
This commit is contained in:
parent
104538556d
commit
89c45015c9
3 changed files with 175 additions and 0 deletions
106
charger/homeassistant-switch.go
Normal file
106
charger/homeassistant-switch.go
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
package charger
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/evcc-io/evcc/api"
|
||||
"github.com/evcc-io/evcc/util"
|
||||
"github.com/evcc-io/evcc/util/request"
|
||||
"github.com/evcc-io/evcc/util/transport"
|
||||
)
|
||||
|
||||
type HomeAssistantSwitch struct {
|
||||
baseURL string
|
||||
switchEntity string
|
||||
powerEntity string
|
||||
*request.Helper
|
||||
*switchSocket
|
||||
}
|
||||
|
||||
func init() {
|
||||
registry.Add("homeassistant-switch", NewHomeAssistantSwitchFromConfig)
|
||||
}
|
||||
|
||||
func NewHomeAssistantSwitchFromConfig(other map[string]interface{}) (api.Charger, error) {
|
||||
var cc struct {
|
||||
embed `mapstructure:",squash"`
|
||||
BaseURL string
|
||||
Token string
|
||||
SwitchEntity string
|
||||
PowerEntity string
|
||||
StandbyPower float64
|
||||
}
|
||||
|
||||
if err := util.DecodeOther(other, &cc); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return NewHomeAssistantSwitch(cc.embed, cc.BaseURL, cc.Token, cc.SwitchEntity, cc.PowerEntity, cc.StandbyPower)
|
||||
}
|
||||
|
||||
//go:generate go tool decorate -f decorateHomeAssistantSwitch -b *HomeAssistantSwitch -r api.Charger -t "api.Meter,CurrentPower,func() (float64, error)"
|
||||
|
||||
func NewHomeAssistantSwitch(embed embed, baseURL, token, switchEntity, powerEntity string, standbypower float64) (api.Charger, error) {
|
||||
c := &HomeAssistantSwitch{
|
||||
baseURL: baseURL,
|
||||
switchEntity: switchEntity,
|
||||
powerEntity: powerEntity,
|
||||
Helper: request.NewHelper(util.NewLogger("ha-switch")),
|
||||
}
|
||||
|
||||
c.switchSocket = NewSwitchSocket(&embed, c.Enabled, c.CurrentPower, standbypower)
|
||||
c.Helper.Client.Transport = &transport.Decorator{
|
||||
Decorator: transport.DecorateHeaders(map[string]string{
|
||||
"Authorization": "Bearer " + token,
|
||||
"Content-Type": "application/json",
|
||||
}),
|
||||
Base: c.Helper.Client.Transport,
|
||||
}
|
||||
|
||||
var currentPower func() (float64, error)
|
||||
if powerEntity != "" {
|
||||
currentPower = c.currentPower
|
||||
}
|
||||
|
||||
return decorateHomeAssistantSwitch(c, currentPower), nil
|
||||
}
|
||||
|
||||
// Enabled implements the api.Charger interface
|
||||
func (c *HomeAssistantSwitch) Enabled() (bool, error) {
|
||||
var res struct {
|
||||
State string `json:"state"`
|
||||
}
|
||||
|
||||
uri := fmt.Sprintf("%s/api/states/%s", c.baseURL, c.switchEntity)
|
||||
err := c.Helper.GetJSON(uri, &res)
|
||||
|
||||
return res.State == "on", err
|
||||
}
|
||||
|
||||
// Enable implements the api.Charger interface
|
||||
func (c *HomeAssistantSwitch) Enable(enable bool) error {
|
||||
service := "turn_off"
|
||||
if enable {
|
||||
service = "turn_on"
|
||||
}
|
||||
|
||||
data := map[string]any{"entity_id": c.switchEntity}
|
||||
|
||||
uri := fmt.Sprintf("%s/api/services/switch/%s", c.baseURL, service)
|
||||
req, _ := request.New(http.MethodPost, uri, request.MarshalJSON(data), request.JSONEncoding)
|
||||
|
||||
return c.Helper.DoJSON(req, nil)
|
||||
}
|
||||
|
||||
// currentPower implements the api.Meter interface (optional)
|
||||
func (c *HomeAssistantSwitch) currentPower() (float64, error) {
|
||||
var res struct {
|
||||
State float64 `json:"state,string"`
|
||||
}
|
||||
|
||||
uri := fmt.Sprintf("%s/api/states/%s", c.baseURL, c.powerEntity)
|
||||
err := c.Helper.GetJSON(uri, &res)
|
||||
|
||||
return res.State, err
|
||||
}
|
||||
35
charger/homeassistant-switch_decorators.go
Normal file
35
charger/homeassistant-switch_decorators.go
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
package charger
|
||||
|
||||
// Code generated by github.com/evcc-io/evcc/cmd/tools/decorate.go. DO NOT EDIT.
|
||||
|
||||
import (
|
||||
"github.com/evcc-io/evcc/api"
|
||||
)
|
||||
|
||||
func decorateHomeAssistantSwitch(base *HomeAssistantSwitch, meter func() (float64, error)) api.Charger {
|
||||
switch {
|
||||
case meter == nil:
|
||||
return base
|
||||
|
||||
case meter != nil:
|
||||
return &struct {
|
||||
*HomeAssistantSwitch
|
||||
api.Meter
|
||||
}{
|
||||
HomeAssistantSwitch: base,
|
||||
Meter: &decorateHomeAssistantSwitchMeterImpl{
|
||||
meter: meter,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type decorateHomeAssistantSwitchMeterImpl struct {
|
||||
meter func() (float64, error)
|
||||
}
|
||||
|
||||
func (impl *decorateHomeAssistantSwitchMeterImpl) CurrentPower() (float64, error) {
|
||||
return impl.meter()
|
||||
}
|
||||
34
templates/definition/charger/homeassistant-switch.yaml
Normal file
34
templates/definition/charger/homeassistant-switch.yaml
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
template: homeassistant-switch
|
||||
products:
|
||||
- brand: Home Assistant Switch
|
||||
group: switchsockets
|
||||
params:
|
||||
- name: baseurl
|
||||
description:
|
||||
de: Basis-URL der Home Assistant Instanz (z.B. http://homeassistant.local:8123)
|
||||
en: Base URL of the Home Assistant instance (e.g. http://homeassistant.local:8123)
|
||||
required: true
|
||||
default: http://homeassistant.local:8123
|
||||
- name: token
|
||||
mask: true
|
||||
required: true
|
||||
description:
|
||||
de: Long-Lived Access Token aus Home Assistant Profil
|
||||
en: Long-Lived Access Token from Home Assistant profile
|
||||
- name: switchentity
|
||||
required: true
|
||||
description:
|
||||
de: Entity ID des schaltbaren Geräts (z.B. switch.smartsocket)
|
||||
en: Entity ID of the switch device (e.g. switch.smartsocket)
|
||||
- name: powerentity
|
||||
description:
|
||||
de: Entity ID für Leistungsmessung (optional, z.B. sensor.smartsocket_power)
|
||||
en: Entity ID for power measurement (optional, e.g. sensor.smartsocket_power)
|
||||
- preset: switchsocket
|
||||
render: |
|
||||
type: homeassistant-switch
|
||||
baseurl: {{ .baseurl }}
|
||||
token: {{ .token }}
|
||||
switchentity: {{ .switchentity }}
|
||||
powerentity: {{ .powerentity }}
|
||||
{{ include "switchsocket" . }}
|
||||
Loading…
Add table
Add a link
Reference in a new issue