From e4802610f949ddb7bb6e7b7828d8561520cec803 Mon Sep 17 00:00:00 2001 From: andig Date: Tue, 4 Nov 2025 17:17:18 +0100 Subject: [PATCH] SGReady: add dimming via relay (BC) (#24704) --- assets/js/components/Config/ChargerModal.vue | 15 +- .../Config/DeviceModal/DeviceModalBase.vue | 9 ++ assets/js/components/Config/DeviceTags.vue | 1 + .../Config/defaultYaml/sgreadyBoost.yaml | 15 -- .../Config/defaultYaml/sgreadyRelay.yaml | 26 ++++ assets/js/types/evcc.ts | 3 +- charger/sgready-boost.go | 79 ----------- charger/sgready-relay.go | 134 ++++++++++++++++++ charger/sgready.go | 9 +- i18n/bg.json | 4 +- i18n/cs.json | 4 +- i18n/da.json | 4 +- i18n/de.json | 6 +- i18n/el.json | 4 +- i18n/en.json | 7 +- i18n/es.json | 4 +- i18n/fi.json | 4 +- i18n/fr.json | 4 +- i18n/hr.json | 4 +- i18n/hu.json | 4 +- i18n/lb.json | 4 +- i18n/lt.json | 4 +- i18n/nl.json | 4 +- i18n/pl.json | 4 +- i18n/pt.json | 4 +- i18n/sl.json | 4 +- i18n/sv.json | 4 +- i18n/ta.json | 4 +- i18n/tr.json | 4 +- i18n/uk.json | 4 +- server/http_config_helper.go | 7 +- tests/config-loadpoint.spec.ts | 8 +- 32 files changed, 245 insertions(+), 150 deletions(-) delete mode 100644 assets/js/components/Config/defaultYaml/sgreadyBoost.yaml create mode 100644 assets/js/components/Config/defaultYaml/sgreadyRelay.yaml delete mode 100644 charger/sgready-boost.go create mode 100644 charger/sgready-relay.go diff --git a/assets/js/components/Config/ChargerModal.vue b/assets/js/components/Config/ChargerModal.vue index 12d3896f3..ced532338 100644 --- a/assets/js/components/Config/ChargerModal.vue +++ b/assets/js/components/Config/ChargerModal.vue @@ -8,6 +8,7 @@ :modal-title="modalTitle" :provide-template-options="provideTemplateOptions" :initial-values="initialValues" + :is-type-deprecated="isTypeDeprecated" :is-yaml-input-type="isYamlInput" :transform-api-data="transformApiData" :filter-template-params="filterTemplateParams" @@ -54,7 +55,7 @@ import heatpumpYaml from "./defaultYaml/heatpump.yaml?raw"; import switchsocketHeaterYaml from "./defaultYaml/switchsocketHeater.yaml?raw"; import switchsocketChargerYaml from "./defaultYaml/switchsocketCharger.yaml?raw"; import sgreadyYaml from "./defaultYaml/sgready.yaml?raw"; -import sgreadyBoostYaml from "./defaultYaml/sgreadyBoost.yaml?raw"; +import sgreadyRelayYaml from "./defaultYaml/sgreadyRelay.yaml?raw"; import { LOADPOINT_TYPE, type LoadpointType } from "@/types/evcc"; const initialValues = { @@ -122,7 +123,7 @@ export default defineComponent({ ...products.filter((p) => p.group === "heatinggeneric"), ...[ ConfigType.Custom, - ConfigType.SgReadyBoost, + ConfigType.SgReadyRelay, ConfigType.SgReady, ConfigType.Heatpump, ConfigType.SwitchSocket, @@ -186,9 +187,13 @@ export default defineComponent({ ConfigType.Heatpump, ConfigType.SwitchSocket, ConfigType.SgReady, - ConfigType.SgReadyBoost, + ConfigType.SgReadyRelay, + ConfigType.SgReadyBoost, // deprecated ].includes(type); }, + isTypeDeprecated(type: ConfigType): boolean { + return type === ConfigType.SgReadyBoost; + }, handleTemplateChange(e: Event, values: DeviceValues) { const value = (e.target as HTMLSelectElement).value as ConfigType; if (this.isYamlInput(value)) { @@ -225,8 +230,8 @@ export default defineComponent({ return this.isHeating ? switchsocketHeaterYaml : switchsocketChargerYaml; case ConfigType.SgReady: return sgreadyYaml; - case ConfigType.SgReadyBoost: - return sgreadyBoostYaml; + case ConfigType.SgReadyRelay: + return sgreadyRelayYaml; default: // template return ""; } diff --git a/assets/js/components/Config/DeviceModal/DeviceModalBase.vue b/assets/js/components/Config/DeviceModal/DeviceModalBase.vue index 5c2d36a7a..f2050945e 100644 --- a/assets/js/components/Config/DeviceModal/DeviceModalBase.vue +++ b/assets/js/components/Config/DeviceModal/DeviceModalBase.vue @@ -28,6 +28,10 @@ @change="handleTemplateChange" /> +

+ {{ $t("config.general.typeDeprecated", { type: values.type }) }} +

+ , // Optional: determine if YAML input should be shown isYamlInputType: Function as PropType<(type: ConfigType) => boolean>, + // Optional: determine if a config type is deprecated + isTypeDeprecated: Function as PropType<(type: ConfigType) => boolean>, // Optional: provide template options from parent (to avoid circular dependency) provideTemplateOptions: Function as PropType<(products: Product[]) => TemplateGroup[]>, // Optional: handle template change (receives event and values, allows setting values.yaml) @@ -298,6 +304,9 @@ export default defineComponent({ showTemplateSelector() { return this.computedTemplateOptions.length > 0; }, + showDeprecatedWarning() { + return this.isTypeDeprecated && this.isTypeDeprecated(this.values.type); + }, }, watch: { isModalVisible(visible) { diff --git a/assets/js/components/Config/DeviceTags.vue b/assets/js/components/Config/DeviceTags.vue index 36fa3354a..0d6313469 100644 --- a/assets/js/components/Config/DeviceTags.vue +++ b/assets/js/components/Config/DeviceTags.vue @@ -92,6 +92,7 @@ export default { case "singlePhase": case "enabled": case "configured": + case "dimmed": return value ? this.$t("config.deviceValue.yes") : this.$t("config.deviceValue.no"); diff --git a/assets/js/components/Config/defaultYaml/sgreadyBoost.yaml b/assets/js/components/Config/defaultYaml/sgreadyBoost.yaml deleted file mode 100644 index 764ee5c1d..000000000 --- a/assets/js/components/Config/defaultYaml/sgreadyBoost.yaml +++ /dev/null @@ -1,15 +0,0 @@ -## required attributes [type: sgready-boost] - -charger: # configuration of a switch controlling the sg-ready port - type: template - template: shelly # example shelly - host: 192.168.0.101 # - -## optional attributes (read-only) - -#temp: # current temperature (°C) -# source: const -# value: 42 -#limittemp: # temperature limit (°C) configured in device -# source: const -# value: 84 diff --git a/assets/js/components/Config/defaultYaml/sgreadyRelay.yaml b/assets/js/components/Config/defaultYaml/sgreadyRelay.yaml new file mode 100644 index 000000000..3e6f8ed84 --- /dev/null +++ b/assets/js/components/Config/defaultYaml/sgreadyRelay.yaml @@ -0,0 +1,26 @@ +## required attributes [type: sgready-relay] + +boost: # relay that switches the boost contact of the heat pump + type: template + template: shelly # example shelly one + host: 192.168.0.101 # + +## optional attributes + +#dim: # relay that switches the dim contact of the heat pump +# type: template +# template: shelly # example shelly two +# host: 192.168.0.102 # + +#power: # meter reading in W +# source: const +# value: 1234 +#energy: # meter reading in kWh +# source: const +# value: 42.5 +#temp: # current temperature (°C) +# source: const +# value: 42 +#limittemp: # temperature limit (°C) configured in device +# source: const +# value: 84 diff --git a/assets/js/types/evcc.ts b/assets/js/types/evcc.ts index 7745aa7de..1988ae80a 100644 --- a/assets/js/types/evcc.ts +++ b/assets/js/types/evcc.ts @@ -112,7 +112,8 @@ export enum ConfigType { Heatpump = "heatpump", SwitchSocket = "switchsocket", SgReady = "sgready", - SgReadyBoost = "sgready-boost", + SgReadyRelay = "sgready-relay", + SgReadyBoost = "sgready-boost", // deprecated } export type ConfigVehicle = Entity; diff --git a/charger/sgready-boost.go b/charger/sgready-boost.go deleted file mode 100644 index 67eccb8cf..000000000 --- a/charger/sgready-boost.go +++ /dev/null @@ -1,79 +0,0 @@ -package charger - -import ( - "context" - "fmt" - - "github.com/evcc-io/evcc/api" - "github.com/evcc-io/evcc/charger/measurement" - "github.com/evcc-io/evcc/util" - "github.com/evcc-io/evcc/util/config" -) - -func init() { - registry.AddCtx("sgready-boost", NewSgReadyBoostFromConfig) -} - -// NewSgReadyBoostFromConfig creates an SG Ready charger with boost relay from generic config -func NewSgReadyBoostFromConfig(ctx context.Context, other map[string]any) (api.Charger, error) { - cc := struct { - embed `mapstructure:",squash"` - Charger config.Typed - measurement.Temperature `mapstructure:",squash"` - }{ - embed: embed{ - Icon_: "heatpump", - Features_: []api.Feature{api.Heating, api.IntegratedDevice}, - }, - } - - if err := util.DecodeOther(other, &cc); err != nil { - return nil, err - } - - charger, err := NewFromConfig(ctx, cc.Charger.Type, cc.Charger.Other) - if err != nil { - return nil, err - } - - tempG, limitTempG, err := cc.Temperature.Configure(ctx) - if err != nil { - return nil, err - } - - res, err := NewSgReadyBoost(ctx, &cc.embed, charger) - if err != nil { - return nil, err - } - - return decorateSgReady(res, nil, nil, tempG, limitTempG), nil -} - -// NewSgReadyBoost creates SG Ready charger with boost relay -func NewSgReadyBoost(ctx context.Context, embed *embed, charger api.Charger) (*SgReady, error) { - modeS := func(mode int64) error { - switch mode { - case Dim: - return api.ErrNotAvailable - case Normal: - return charger.Enable(false) - case Boost: - return charger.Enable(true) - default: - return fmt.Errorf("invalid sgready mode: %d", mode) - } - } - - modeG := func() (int64, error) { - enabled, err := charger.Enabled() - if err != nil { - return 0, err - } - if enabled { - return Boost, nil - } - return Normal, nil - } - - return NewSgReady(ctx, embed, modeS, modeG, nil) -} diff --git a/charger/sgready-relay.go b/charger/sgready-relay.go new file mode 100644 index 000000000..78ae8cdee --- /dev/null +++ b/charger/sgready-relay.go @@ -0,0 +1,134 @@ +package charger + +import ( + "context" + "fmt" + + "github.com/evcc-io/evcc/api" + "github.com/evcc-io/evcc/charger/measurement" + "github.com/evcc-io/evcc/util" + "github.com/evcc-io/evcc/util/config" +) + +func init() { + registry.AddCtx("sgready-relay", NewSgReadyRelayFromConfig) + + // TODO deprecated + registry.AddCtx("sgready-boost", func(ctx context.Context, other map[string]any) (api.Charger, error) { + if charger, ok := other["charger"]; ok { + other["boost"] = charger + delete(other, "charger") + } + return NewSgReadyRelayFromConfig(ctx, other) + }) +} + +// NewSgReadyRelayFromConfig creates an SG Ready charger with boost/dim relays from generic config +func NewSgReadyRelayFromConfig(ctx context.Context, other map[string]interface{}) (api.Charger, error) { + cc := struct { + embed `mapstructure:",squash"` + Boost config.Typed + Dim *config.Typed + measurement.Temperature `mapstructure:",squash"` + measurement.Energy `mapstructure:",squash"` + }{ + embed: embed{ + Icon_: "heatpump", + Features_: []api.Feature{api.Heating, api.IntegratedDevice}, + }, + } + + if err := util.DecodeOther(other, &cc); err != nil { + return nil, err + } + + boost, err := NewFromConfig(ctx, cc.Boost.Type, cc.Boost.Other) + if err != nil { + return nil, err + } + + var dim api.Charger + if cc.Dim != nil { + dim, err = NewFromConfig(ctx, cc.Dim.Type, cc.Dim.Other) + if err != nil { + return nil, err + } + } + + tempG, limitTempG, err := cc.Temperature.Configure(ctx) + if err != nil { + return nil, err + } + + res, err := NewSgReadyRelay(ctx, &cc.embed, boost, dim) + if err != nil { + return nil, err + } + + powerG, energyG, err := cc.Energy.Configure(ctx) + if err != nil { + return nil, err + } + + return decorateSgReady(res, powerG, energyG, tempG, limitTempG), nil +} + +// NewSgReadyRelay creates SG Ready charger with boost relay +func NewSgReadyRelay(ctx context.Context, embed *embed, boost, dim api.Charger) (*SgReady, error) { + modeS := func(mode int64) error { + switch mode { + case Dim: + if dim == nil { + return api.ErrNotAvailable + } + if err := boost.Enable(false); err != nil { + return err + } + return dim.Enable(true) + + case Normal: + if dim != nil { + if err := dim.Enable(false); err != nil { + return err + } + } + return boost.Enable(false) + + case Boost: + if dim != nil { + if err := dim.Enable(false); err != nil { + return err + } + } + return boost.Enable(true) + + default: + return fmt.Errorf("invalid sgready mode: %d", mode) + } + } + + modeG := func() (int64, error) { + if dim != nil { + dimmed, err := dim.Enabled() + if err != nil { + return 0, err + } + if dimmed { + return Dim, nil + } + } + + boosted, err := boost.Enabled() + if err != nil { + return 0, err + } + + if boosted { + return Boost, nil + } + + return Normal, nil + } + + return NewSgReady(ctx, embed, modeS, modeG, nil) +} diff --git a/charger/sgready.go b/charger/sgready.go index c57c4f550..fa05e6474 100644 --- a/charger/sgready.go +++ b/charger/sgready.go @@ -19,7 +19,6 @@ package charger import ( "context" - "errors" "github.com/evcc-io/evcc/api" "github.com/evcc-io/evcc/charger/measurement" @@ -134,11 +133,11 @@ func (wb *SgReady) Status() (api.ChargeStatus, error) { return api.StatusNone, err } - if mode == Dim { - return api.StatusNone, errors.New("dim mode") + status := map[int64]api.ChargeStatus{ + Dim: api.StatusB, + Normal: api.StatusB, + Boost: api.StatusC, } - - status := map[int64]api.ChargeStatus{Boost: api.StatusC, Normal: api.StatusB} return status[mode], nil } diff --git a/i18n/bg.json b/i18n/bg.json index d73587261..22d2ea8b1 100644 --- a/i18n/bg.json +++ b/i18n/bg.json @@ -58,8 +58,8 @@ "heating": "Индивидуален нагревател" }, "heatpump": "Индивидуална термо помпа", - "sgready": "Индивидуална термо помпа (sg-ready, и др.)", - "sgready-boost": "Индивидуална термо помпа (sg-ready, boost)", + "sgready": "Индивидуална термо помпа (sg-ready чрез plugins)", + "sgready-relay": "Индивидуална термо помпа (sg-ready чрез relays)", "switchsocket": "Индивидуален превключвател" } }, diff --git a/i18n/cs.json b/i18n/cs.json index 608b383dc..435b4df9f 100644 --- a/i18n/cs.json +++ b/i18n/cs.json @@ -58,8 +58,8 @@ "heating": "Vlastní konfigurace kotle (topení)" }, "heatpump": "Vlastní konfigurace tepelného čerpadla", - "sgready": "Vlastní konfigurace tepelného čerpadla (SG Ready, All)", - "sgready-boost": "Vlastní konfigurace tepelného čerpadla (SGReady, Boost)", + "sgready": "Vlastní konfigurace tepelného čerpadla (sg-ready přes plugins)", + "sgready-relay": "Vlastní konfigurace tepelného čerpadla (sg-ready přes relé)", "switchsocket": "Vlastní konfigurace chytré zásuvky" } }, diff --git a/i18n/da.json b/i18n/da.json index 3d766d960..c2c96c16d 100644 --- a/i18n/da.json +++ b/i18n/da.json @@ -58,8 +58,8 @@ "heating": "Brugerdefineret varmelegeme" }, "heatpump": "Brugerdefineret varmepumpe", - "sgready": "Brugerdefineret varmepumpe (sg-klar, alle)", - "sgready-boost": "Brugerdefineret varmepumpe (sg-klar, boost)", + "sgready": "Brugerdefineret varmepumpe (sg-ready via plugins)", + "sgready-relay": "Brugerdefineret varmepumpe (sg-ready via relæer)", "switchsocket": "Brugerdefineret stikkontakt" } }, diff --git a/i18n/de.json b/i18n/de.json index da4523ef9..ae0585bf4 100644 --- a/i18n/de.json +++ b/i18n/de.json @@ -58,8 +58,8 @@ "heating": "Benutzerdefinierte Heizung" }, "heatpump": "Benutzerdefinierte Wärmepumpe", - "sgready": "Benutzerdefinierte Wärmepumpe (sg-ready, komplett)", - "sgready-boost": "Benutzerdefinierte Wärmepumpe (sg-ready, boost)", + "sgready": "Benutzerdefinierte Wärmepumpe (SG-Ready über Plugins)", + "sgready-relay": "Benutzerdefinierte Wärmepumpe (SG-Ready über Relais)", "switchsocket": "Benutzerdefinierte schaltbare Steckdose" } }, @@ -94,6 +94,7 @@ "currency": "Währung", "current": "Strom", "currentRange": "Strom", + "dimmed": "Gedimmt", "enabled": "Ladebereit", "energy": "Energie", "feedinPrice": "Einspeisevergütung", @@ -185,6 +186,7 @@ "telemetry": "Telemetrie", "templateLoading": "Lade …", "title": "Titel", + "typeDeprecated": "Der Typ '{type}' ist veraltet und wird in einer zukünftigen Version entfernt. Bitte Changelog prüfen und Gerät neu anlegen.", "validateSave": "Überprüfen & speichern" }, "grid": { diff --git a/i18n/el.json b/i18n/el.json index a9c67ae74..103bdc664 100644 --- a/i18n/el.json +++ b/i18n/el.json @@ -58,8 +58,8 @@ "heating": "Θερμαντήρας που καθορίζεται από τον χρήστη" }, "heatpump": "Αντλία θερμότητας που καθορίζεται από τον χρήστη", - "sgready": "Αντλία θερμότητας που καθορίζεται από τον χρήστη (SG-ready, all)", - "sgready-boost": "Αντλία θερμότητας που καθορίζεται από τον χρήστη (SG-ready, boost)", + "sgready": "Αντλία θερμότητας που καθορίζεται από τον χρήστη (sg-ready μέσω plugins)", + "sgready-relay": "Αντλία θερμότητας που καθορίζεται από τον χρήστη (sg-ready μέσω ρελέ)", "switchsocket": "Διακόπτης πρίζας που καθορίζεται από τον χρήστη" } }, diff --git a/i18n/en.json b/i18n/en.json index a921a18d3..d88a29319 100644 --- a/i18n/en.json +++ b/i18n/en.json @@ -58,8 +58,9 @@ "heating": "User-defined heater" }, "heatpump": "User-defined heat pump", - "sgready": "User-defined heat pump (sg-ready, all)", - "sgready-boost": "User-defined heat pump (sg-ready, boost)", + "sgready": "User-defined heat pump (sg-ready via plugins)", + "sgready-boost": "User-defined heat pump (sg-ready-boost, deprecated)", + "sgready-relay": "User-defined heat pump (sg-ready via relays)", "switchsocket": "User-defined switch socket" } }, @@ -94,6 +95,7 @@ "currency": "Currency", "current": "Current", "currentRange": "Current", + "dimmed": "Dimmed", "enabled": "Enabled", "energy": "Energy", "feedinPrice": "Feed-in price", @@ -185,6 +187,7 @@ "telemetry": "Telemetry", "templateLoading": "Loading...", "title": "Title", + "typeDeprecated": "The type '{type}' is outdated and will be removed in a future version. Please check the changelog and recreate this device.", "validateSave": "Validate & save" }, "grid": { diff --git a/i18n/es.json b/i18n/es.json index e9f5b5d9b..3e24f13e6 100644 --- a/i18n/es.json +++ b/i18n/es.json @@ -48,8 +48,8 @@ "heating": "Calefactor definido por el usuario" }, "heatpump": "Bomba de calor definida por el usuario", - "sgready": "Bomba de calor definida por el usuario (sg-ready, todas)", - "sgready-boost": "Bomba de calor definida por el usuario (sg-ready, boost)", + "sgready": "Bomba de calor definida por el usuario (sg-ready via plugins)", + "sgready-relay": "Bomba de calor definida por el usuario (sg-ready via relays)", "switchsocket": "Enchufe conmutable definido por el usuario" } }, diff --git a/i18n/fi.json b/i18n/fi.json index d7045f1bb..7bcefa5ee 100644 --- a/i18n/fi.json +++ b/i18n/fi.json @@ -58,8 +58,8 @@ "heating": "Itse määritelty lämmitin" }, "heatpump": "Itse määritelty lämpöpumppu", - "sgready": "Itse määritelty lämpöpumppu (älyverkkovalmius, kaikki)", - "sgready-boost": "Itse määritelty lämpöpumppu (älyverkkovalmius, tehostus)", + "sgready": "Itse määritelty lämpöpumppu (sg-ready pluginien kautta)", + "sgready-relay": "Itse määritelty lämpöpumppu (sg-ready releiden kautta)", "switchsocket": "Itse määritelty relepistorasia" } }, diff --git a/i18n/fr.json b/i18n/fr.json index ed1f570e1..0ad9ec010 100644 --- a/i18n/fr.json +++ b/i18n/fr.json @@ -58,8 +58,8 @@ "heating": "Chauffage personnalisé" }, "heatpump": "Pompe à chaleur personnalisée", - "sgready": "Pompe à chaleur personnalisée (sg-ready, tout)", - "sgready-boost": "Pompe à chaleur personnalisée (sg-ready, boost)", + "sgready": "Pompe à chaleur personnalisée (sg-ready via plugins)", + "sgready-relay": "Pompe à chaleur personnalisée (sg-ready via relays)", "switchsocket": "Prise de commutation personnalisée" } }, diff --git a/i18n/hr.json b/i18n/hr.json index fff1a29ba..a5ed93feb 100644 --- a/i18n/hr.json +++ b/i18n/hr.json @@ -58,8 +58,8 @@ "heating": "Korisnički definirani grijač" }, "heatpump": "Korisnički definirana dizalica topline", - "sgready": "Korisnički definirana dizalica topline (sg-ready, svi)", - "sgready-boost": "Korisnički definirana dizalica topline (sg-ready, boost)", + "sgready": "Korisnički definirana dizalica topline (sg-ready putem dodataka)", + "sgready-relay": "Korisnički definirana dizalica topline (sg-ready putem releja)", "switchsocket": "Korisnički definirana upravljiva utičnica" } }, diff --git a/i18n/hu.json b/i18n/hu.json index 5f251695b..af632c0d0 100644 --- a/i18n/hu.json +++ b/i18n/hu.json @@ -58,8 +58,8 @@ "heating": "Felhasználó által meghatározott fűtőberendezés" }, "heatpump": "Felhasználó által meghatározott hőszivattyú", - "sgready": "Felhasználó által meghatározott hőszivattyú (sg-ready, all)", - "sgready-boost": "Felhasználó által meghatározott hőszivattyú (sg-ready, boost)", + "sgready": "Felhasználó által meghatározott hőszivattyú (sg-ready pluginokon keresztül)", + "sgready-relay": "Felhasználó által meghatározott hőszivattyú (sg-ready reléken keresztül)", "switchsocket": "Felhasználó által meghatározott dugalj" } }, diff --git a/i18n/lb.json b/i18n/lb.json index d1bf31a0f..d2840429a 100644 --- a/i18n/lb.json +++ b/i18n/lb.json @@ -58,8 +58,8 @@ "heating": "Benotzerdefinéirt Heizung" }, "heatpump": "Benotzerdefinéirt Wärmepompel", - "sgready": "Benotzerdefinéirt Wärmepompel (sg-ready, komplett)", - "sgready-boost": "Benotzerdefinéirt Wärmepompel (sg-ready, boost)", + "sgready": "Benotzerdefinéiert Wärmepompel (sg-ready iwwer Plugins)", + "sgready-relay": "Benotzerdefinéiert Wärmepompel (sg-ready iwwer Relais)", "switchsocket": "Benotzerdefinéirt schaltbar Steckdous" } }, diff --git a/i18n/lt.json b/i18n/lt.json index 725eb7fc1..108abfa45 100644 --- a/i18n/lt.json +++ b/i18n/lt.json @@ -58,8 +58,8 @@ "heating": "Vartotojo nustatytas šildytuvas" }, "heatpump": "Vartotojo nustatytas šilumos siurblys", - "sgready": "Vartotojo nustatytas šilumos siurblys (SG-Ready, visi)", - "sgready-boost": "Vartotojo nustatytas šilumos siurblys (SG-Ready, boost)", + "sgready": "Vartotojo nustatytas šilumos siurblys (sg-ready per įskiepius)", + "sgready-relay": "Vartotojo nustatytas šilumos siurblys (sg-ready per relės)", "switchsocket": "Vartotojo apibrėžta išmanioji rozetė" } }, diff --git a/i18n/nl.json b/i18n/nl.json index 6e3b1676a..9ce53d976 100644 --- a/i18n/nl.json +++ b/i18n/nl.json @@ -58,8 +58,8 @@ "heating": "Gebruikersgedefinieerde verwarmer" }, "heatpump": "Gebruikersgedefinieerde warmtepomp", - "sgready": "Gebruikersgedefinieerde warmtepomp (sg-ready, alle)", - "sgready-boost": "Gebruikersgedefinieerde warmtepomp (sg-ready, boost)", + "sgready": "Gebruikersgedefinieerde warmtepomp (sg-ready via plugins)", + "sgready-relay": "Gebruikersgedefinieerde warmtepomp (sg-ready via relais)", "switchsocket": "Gebruikersgedefinieerd schakelbaar stopcontact" } }, diff --git a/i18n/pl.json b/i18n/pl.json index 6c809edbd..6ba8e281e 100644 --- a/i18n/pl.json +++ b/i18n/pl.json @@ -58,8 +58,8 @@ "heating": "Podgrzewacz zdefiniowany przez użytkownika" }, "heatpump": "Pompa ciepła zdefiniowana przez użytkownika", - "sgready": "Pompa ciepła zdefiniowana przez użytkownika (sg-ready, all)", - "sgready-boost": "Pompa ciepła zdefiniowana przez użytkownika (sg-ready, boost)", + "sgready": "Pompa ciepła zdefiniowana przez użytkownika (sg-ready przez wtyczki)", + "sgready-relay": "Pompa ciepła zdefiniowana przez użytkownika (sg-ready przez przekaźniki)", "switchsocket": "Gniazdo przełączalne zdefiniowane przez użytkownika" } }, diff --git a/i18n/pt.json b/i18n/pt.json index 6f235249f..d1b8d75df 100644 --- a/i18n/pt.json +++ b/i18n/pt.json @@ -58,8 +58,8 @@ "heating": "Aquecimento personalizado" }, "heatpump": "Bomba de calor personalizada", - "sgready": "Bomba de calor personalizada (sg-ready, tout)", - "sgready-boost": "Bomba de calor personalizada (sg-ready, boost)", + "sgready": "Bomba de calor personalizada (sg-ready via plugins)", + "sgready-relay": "Bomba de calor personalizada (sg-ready via relés)", "switchsocket": "Tomada de interrutor definida pelo utilizador" } }, diff --git a/i18n/sl.json b/i18n/sl.json index de10252c5..17bc08a5f 100644 --- a/i18n/sl.json +++ b/i18n/sl.json @@ -58,8 +58,8 @@ "heating": "Uporabniško določen grelec" }, "heatpump": "Uporabniško določena toplotna črpalka", - "sgready": "Uporabniško določena toplotna črpalka (sg-ready, all)", - "sgready-boost": "Uporabniško določena toplotna črpalka (sg-ready, boost)", + "sgready": "Uporabniško določena toplotna črpalka (sg-ready preko vtičnikov)", + "sgready-relay": "Uporabniško določena toplotna črpalka (sg-ready preko relejev)", "switchsocket": "Uporabniško definirana vtičnica stikala" } }, diff --git a/i18n/sv.json b/i18n/sv.json index c7be7b2b5..d08e7bef2 100644 --- a/i18n/sv.json +++ b/i18n/sv.json @@ -58,8 +58,8 @@ "heating": "Egendefinierad värmare" }, "heatpump": "Egendefinierad värmepump", - "sgready": "Egendefinierad värmepump (sg-ready, alla)", - "sgready-boost": "Egendefinierad värmepump (sg-ready, boost)", + "sgready": "Egendefinierad värmepump (sg-ready via plugins)", + "sgready-relay": "Egendefinierad värmepump (sg-ready via reläer)", "switchsocket": "Egendefinierad strömbrytare" } }, diff --git a/i18n/ta.json b/i18n/ta.json index 8a8950f80..14749473b 100644 --- a/i18n/ta.json +++ b/i18n/ta.json @@ -58,8 +58,8 @@ "heating": "பயனர் வரையறுக்கப்பட்ட ஈட்டர்" }, "heatpump": "பயனர் வரையறுக்கப்பட்ட வெப்ப பம்ப்", - "sgready": "பயனர் வரையறுக்கப்பட்ட வெப்ப பம்ப் (எச்.சி-தயார், அனைத்தும்)", - "sgready-boost": "பயனர் வரையறுக்கப்பட்ட வெப்ப பம்ப் (எச்.சி-தயார், பூச்ட்)", + "sgready": "பயனர் வரையறுக்கப்பட்ட வெப்ப பம்ப் (sg-ready via plugins)", + "sgready-relay": "பயனர் வரையறுக்கப்பட்ட வெப்ப பம்ப் (sg-ready via relays)", "switchsocket": "பயனர் வரையறுக்கப்பட்ட சுவிட்ச் சாக்கெட்" } }, diff --git a/i18n/tr.json b/i18n/tr.json index 8d1573eb9..58b389832 100644 --- a/i18n/tr.json +++ b/i18n/tr.json @@ -58,8 +58,8 @@ "heating": "Kullanıcı tanımlı ısıtıcı" }, "heatpump": "Kullanıcı tanımlı ısı pompası", - "sgready": "Kullanıcı tanımlı ısı pompası (sg-ready, tamamı)", - "sgready-boost": "Kullanıcı tanımlı ısı pompası (sg-ready, takviye)", + "sgready": "Kullanıcı tanımlı ısı pompası (sg-ready eklentiler üzerinden)", + "sgready-relay": "Kullanıcı tanımlı ısı pompası (sg-ready röleler üzerinden)", "switchsocket": "Kullanıcı tanımlı şalterli priz" } }, diff --git a/i18n/uk.json b/i18n/uk.json index c4e5a577e..8cd20cee8 100644 --- a/i18n/uk.json +++ b/i18n/uk.json @@ -58,8 +58,8 @@ "heating": "Користувацький обігрівач" }, "heatpump": "Користувацький тепловий насос", - "sgready": "Користувацький тепловий насос (готовий до роботи з підтримкою теплового насоса, усі)", - "sgready-boost": "Тепловий насос, що визначається користувачем (підтримка теплового насоса, підвищення потужності)", + "sgready": "Користувацький тепловий насос (sg-ready через плагіни)", + "sgready-relay": "Користувацький тепловий насос (sg-ready через реле)", "switchsocket": "Користувацький перемикач-розетка" } }, diff --git a/server/http_config_helper.go b/server/http_config_helper.go index 7ea912ff0..1963730f1 100644 --- a/server/http_config_helper.go +++ b/server/http_config_helper.go @@ -27,7 +27,7 @@ const ( ) var ( - customTypes = []string{"custom", "template", "heatpump", "switchsocket", "sgready", "sgready-boost"} + customTypes = []string{"custom", "template", "heatpump", "switchsocket", "sgready", "sgready-relay"} ) type configReq struct { @@ -328,6 +328,11 @@ func testInstance(instance any) map[string]testResult { makeResult(key, val, err) } + if dev, ok := instance.(api.Dimmer); ok { + val, err := dev.Dimmed() + makeResult("dimmed", val, err) + } + if dev, ok := instance.(api.Identifier); ok { val, err := dev.Identify() makeResult("identifier", val, err) diff --git a/tests/config-loadpoint.spec.ts b/tests/config-loadpoint.spec.ts index db20e2614..1ba858fcb 100644 --- a/tests/config-loadpoint.spec.ts +++ b/tests/config-loadpoint.spec.ts @@ -572,8 +572,12 @@ test.describe("heating loadpoint", async () => { await expectModalVisible(modal); await modal.getByLabel("Manufacturer").selectOption("User-defined heater"); await modal.getByLabel("Manufacturer").selectOption("User-defined heat pump"); - await modal.getByLabel("Manufacturer").selectOption("User-defined heat pump (sg-ready, all)"); - await modal.getByLabel("Manufacturer").selectOption("User-defined heat pump (sg-ready, boost)"); + await modal + .getByLabel("Manufacturer") + .selectOption("User-defined heat pump (sg-ready via plugins)"); + await modal + .getByLabel("Manufacturer") + .selectOption("User-defined heat pump (sg-ready via relays)"); await modal.getByLabel("Manufacturer").selectOption("User-defined switch socket"); await modal.getByLabel("Manufacturer").selectOption("User-defined heat pump");