From 291bc930b41ac2d8788f311b0236fb6ca40fbc42 Mon Sep 17 00:00:00 2001 From: andig Date: Sun, 21 Jun 2026 11:32:08 +0200 Subject: [PATCH] Smart-hello: add SocLimiter support (#31080) --- vehicle/smart/hello/api.go | 30 ++++++++++++++++++++++++++++++ vehicle/smart/hello/provider.go | 14 +++++++++++++- vehicle/smart/hello/types.go | 4 ++++ 3 files changed, 47 insertions(+), 1 deletion(-) diff --git a/vehicle/smart/hello/api.go b/vehicle/smart/hello/api.go index ad8dcb122..92c610ad1 100644 --- a/vehicle/smart/hello/api.go +++ b/vehicle/smart/hello/api.go @@ -199,3 +199,33 @@ func (v *API) Status(vin string) (VehicleStatus, error) { return res.Data.VehicleStatus, err } + +func (v *API) SocStatus(vin string) (VehicleSocStatus, error) { + if err := v.UpdateSession(vin); err != nil { + return VehicleSocStatus{}, fmt.Errorf("update session failed: %w", err) + } + + var res struct { + Code Int + Message string + Error Error + Data VehicleSocStatus + } + + params := url.Values{ + "setting": {"charging"}, + } + + path := "/remote-control/vehicle/status/soc/" + vin + req, err := v.request(http.MethodGet, path, params, nil) + if err != nil { + return VehicleSocStatus{}, err + } + + err = v.DoJSON(req, &res) + if err := responseError(err, res.Code, res.Message, res.Error); err != nil { + return VehicleSocStatus{}, err + } + + return res.Data, err +} diff --git a/vehicle/smart/hello/provider.go b/vehicle/smart/hello/provider.go index e1d83e9d1..ed9ca503f 100644 --- a/vehicle/smart/hello/provider.go +++ b/vehicle/smart/hello/provider.go @@ -10,7 +10,8 @@ import ( // https://github.com/TA2k/ioBroker.smart-eq type Provider struct { - statusG func() (VehicleStatus, error) + statusG func() (VehicleStatus, error) + socStatusG func() (VehicleSocStatus, error) } func NewProvider(log *util.Logger, api *API, vin string, cache time.Duration) *Provider { @@ -18,6 +19,9 @@ func NewProvider(log *util.Logger, api *API, vin string, cache time.Duration) *P statusG: util.Cached(func() (VehicleStatus, error) { return api.Status(vin) }, cache), + socStatusG: util.Cached(func() (VehicleSocStatus, error) { + return api.SocStatus(vin) + }, cache), } return v @@ -76,3 +80,11 @@ func (v *Provider) Climater() (bool, error) { res, err := v.statusG() return bool(res.AdditionalVehicleStatus.ClimateStatus.PreClimateActive || res.AdditionalVehicleStatus.ClimateStatus.Defrost), err } + +var _ api.SocLimiter = (*Provider)(nil) + +// GetLimitSoc implements the api.SocLimiter interface +func (v *Provider) GetLimitSoc() (int64, error) { + res, err := v.socStatusG() + return int64(res.Soc) / 10, err +} diff --git a/vehicle/smart/hello/types.go b/vehicle/smart/hello/types.go index de61ecf7c..e03807b9c 100644 --- a/vehicle/smart/hello/types.go +++ b/vehicle/smart/hello/types.go @@ -56,6 +56,10 @@ type Vehicle struct { ProprietaryPlatform Int `json:"proprietaryPlatform"` // 0: legacy tsp backend (supported), 1: newer platform (status endpoint returns 8063) } +type VehicleSocStatus struct { + Soc Int `json:"soc"` // charging target soc in tenths of a percent, e.g. 800 = 80% +} + type VehicleStatus struct { BasicVehicleStatus struct { UsageMode Int `json:"usageMode"` // "0",