diff --git a/templates/definition/vehicle/homeassistant.yaml b/templates/definition/vehicle/homeassistant.yaml index 540429381..56bb7692e 100644 --- a/templates/definition/vehicle/homeassistant.yaml +++ b/templates/definition/vehicle/homeassistant.yaml @@ -84,6 +84,12 @@ params: en: Service to wake up vehicle example: "script.vehicle_wakeup" type: string + - name: setMaxCurrent + description: + de: Ladestromstärke setzen [A] + en: Set charging current [A] + example: "number.vehicle_charging_current" + type: string render: | type: homeassistant {{ include "vehicle-common" . }} @@ -101,3 +107,4 @@ render: | start_charging: {{ .start_charging }} stop_charging: {{ .stop_charging }} wakeup: {{ .wakeup }} + setMaxCurrent: {{ .setMaxCurrent }} diff --git a/vehicle/homeassistant.go b/vehicle/homeassistant.go index 8f896fe78..7084d72d1 100644 --- a/vehicle/homeassistant.go +++ b/vehicle/homeassistant.go @@ -44,9 +44,10 @@ func NewHomeAssistantVehicleFromConfig(other map[string]any) (api.Vehicle, error FinishTime string // optional } Services struct { - Start string `mapstructure:"start_charging"` // script.* optional - Stop string `mapstructure:"stop_charging"` // script.* optional - Wakeup string // script.* optional + Start string `mapstructure:"start_charging"` // script.* optional + Stop string `mapstructure:"stop_charging"` // script.* optional + Wakeup string // script.* optional + SetMaxCurrent string `mapstructure:"setMaxCurrent"` // number.* or input_number.* optional } } @@ -79,14 +80,16 @@ func NewHomeAssistantVehicleFromConfig(other map[string]any) (api.Vehicle, error // prepare optional feature functions with concise names var ( - limitSoc func() (int64, error) - status func() (api.ChargeStatus, error) - rng func() (int64, error) - odo func() (float64, error) - climater func() (bool, error) - finish func() (time.Time, error) - chargeEnable func(bool) error - wakeup func() error + limitSoc func() (int64, error) + status func() (api.ChargeStatus, error) + rng func() (int64, error) + odo func() (float64, error) + climater func() (bool, error) + finish func() (time.Time, error) + chargeEnable func(bool) error + wakeup func() error + maxCurrent func(int64) error + getMaxCurrent func() (float64, error) ) if cc.Sensors.LimitSoc != "" { @@ -118,6 +121,10 @@ func NewHomeAssistantVehicleFromConfig(other map[string]any) (api.Vehicle, error if cc.Services.Wakeup != "" { wakeup = func() error { return res.callScript(cc.Services.Wakeup) } } + if cc.Services.SetMaxCurrent != "" { + maxCurrent = func(current int64) error { return res.setMaxCurrent(cc.Services.SetMaxCurrent, current) } + getMaxCurrent = func() (float64, error) { return res.getFloatSensor(cc.Services.SetMaxCurrent) } + } // decorate all features return decorateVehicle( @@ -127,8 +134,8 @@ func NewHomeAssistantVehicleFromConfig(other map[string]any) (api.Vehicle, error rng, odo, climater, - nil, // maxCurrent setter not implemented - nil, // getMaxCurrent getter not implemented + maxCurrent, + getMaxCurrent, finish, wakeup, chargeEnable, @@ -166,6 +173,36 @@ func (v *HomeAssistant) callScript(script string) error { return err } +func (v *HomeAssistant) setMaxCurrent(entity string, current int64) error { + // Determine service domain from entity prefix + parts := strings.SplitN(entity, ".", 2) + if len(parts) != 2 { + return fmt.Errorf("invalid entity format: %s", entity) + } + + domain := parts[0] + var service string + + switch domain { + case "number": + service = "set_value" + case "input_number": + service = "set_value" + default: + return fmt.Errorf("unsupported entity domain: %s", domain) + } + + data := map[string]interface{}{ + "entity_id": entity, + "value": current, + } + + uri := fmt.Sprintf("%s/api/services/%s/%s", v.uri, domain, service) + req, _ := request.New(http.MethodPost, uri, request.MarshalJSON(data), request.JSONEncoding) + _, err := v.DoBody(req) + return err +} + // generic helpers for fetching and parsing sensor values func (v *HomeAssistant) getFloatSensor(entity string) (float64, error) { s, err := v.getState(entity)