From 04c2f8c1ac6a53fbb04012f103ef7566ddef1fec Mon Sep 17 00:00:00 2001 From: andig Date: Sun, 26 Oct 2025 17:08:58 +0100 Subject: [PATCH] Vaillant: add support for multiple systems per account (#24718) --- charger/helper.go | 21 +++++++++++++++------ charger/vaillant.go | 9 +++++++-- templates/definition/charger/vaillant.yaml | 10 ++++++++++ 3 files changed, 32 insertions(+), 8 deletions(-) diff --git a/charger/helper.go b/charger/helper.go index 214ad8194..341c04c50 100644 --- a/charger/helper.go +++ b/charger/helper.go @@ -27,16 +27,25 @@ func ensureChargerEx[T any]( id string, list func() ([]T, error), extract func(T) (string, error), +) (T, error) { + return ensureEx("charger", id, list, extract) +} + +// ensureEx extracts element with name typ with matching id from list of elements +func ensureEx[T any]( + typ, id string, + list func() ([]T, error), + extract func(T) (string, error), ) (T, error) { var zero T - chargers, err := list() + elems, err := list() if err != nil { - return zero, fmt.Errorf("cannot get chargers: %w", err) + return zero, fmt.Errorf("cannot get %ss: %w", typ, err) } if id = strings.ToUpper(id); id != "" { - for _, charger := range chargers { + for _, charger := range elems { cc, err := extract(charger) if err != nil { return zero, err @@ -45,12 +54,12 @@ func ensureChargerEx[T any]( return charger, nil } } - } else if len(chargers) == 1 { + } else if len(elems) == 1 { // id empty and exactly one charger - return chargers[0], nil + return elems[0], nil } - return zero, fmt.Errorf("cannot find charger, got: %v", lo.Map(chargers, func(v T, _ int) string { + return zero, fmt.Errorf("cannot find %s, got: %v", typ, lo.Map(elems, func(v T, _ int) string { vin, _ := extract(v) return vin })) diff --git a/charger/vaillant.go b/charger/vaillant.go index 0790f5c6f..12f53a1bd 100644 --- a/charger/vaillant.go +++ b/charger/vaillant.go @@ -51,6 +51,7 @@ func NewVaillantFromConfig(ctx context.Context, other map[string]interface{}) (a embed `mapstructure:",squash"` User, Password string Realm string + System string HeatingZone int HeatingSetpoint float32 Cache time.Duration @@ -85,12 +86,16 @@ func NewVaillantFromConfig(ctx context.Context, other map[string]interface{}) (a return nil, err } - homes, err := conn.GetHomes() + home, err := ensureEx("home", cc.System, func() ([]sensonet.Home, error) { + return conn.GetHomes() + }, func(home sensonet.Home) (string, error) { + return home.SystemID, nil + }) if err != nil { return nil, err } - systemId := homes[0].SystemID + systemId := home.SystemID heating := cc.HeatingSetpoint > 0 wwCancel := func() {} diff --git a/templates/definition/charger/vaillant.yaml b/templates/definition/charger/vaillant.yaml index 0d792eec4..d114353cc 100644 --- a/templates/definition/charger/vaillant.yaml +++ b/templates/definition/charger/vaillant.yaml @@ -29,6 +29,13 @@ params: description: de: Boost Temperatur en: Boost temperature + - name: system + description: + de: Name der Anlage + en: Name of the system + help: + de: Notwendig falls mehrere Anlagen im Account vorhanden sind + en: Required if multiple systems are present in the account - name: phases deprecated: true render: | @@ -36,5 +43,8 @@ render: | user: {{ .user }} password: {{ .password }} realm: {{ if eq .realm "AT" -}} vaillant-austria-b2c {{- end }} + {{- if .system }} + system: {{ .system }} + {{- end }} heatingzone: {{ .zone }} heatingsetpoint: {{ .setpoint }}