SGReady: add dimming via relay (BC) (#24704)

This commit is contained in:
andig 2025-11-04 17:17:18 +01:00 • committed by GitHub
parent fe909654b0
commit e4802610f9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
32 changed files with 245 additions and 150 deletions

View file

@ -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 "";
}

View file

@ -28,6 +28,10 @@
@change="handleTemplateChange"
/>
<p v-if="showDeprecatedWarning" class="text-danger">
{{ $t("config.general.typeDeprecated", { type: values.type }) }}
</p>
<YamlEntry
v-if="showYamlInput"
v-model="values.yaml"
@ -172,6 +176,8 @@ export default defineComponent({
preserveOnTemplateChange: Array as PropType<string[]>,
// 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) {

View file

@ -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");

View file

@ -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

View file

@ -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

View file

@ -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;

View file

@ -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)
}

134
charger/sgready-relay.go Normal file
View file

@ -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)
}

View file

@ -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
}

View file

@ -58,8 +58,8 @@
"heating": "Индивидуален нагревател"
},
"heatpump": "Индивидуална термо помпа",
"sgready": "Индивидуална термо помпа (sg-ready, и др.)",
"sgready-boost": "Индивидуална термо помпа (sg-ready, boost)",
"sgready": "Индивидуална термо помпа (sg-ready чрез plugins)",
"sgready-relay": "Индивидуална термо помпа (sg-ready чрез relays)",
"switchsocket": "Индивидуален превключвател"
}
},

View file

@ -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"
}
},

View file

@ -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"
}
},

View file

@ -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": {

View file

@ -58,8 +58,8 @@
"heating": "Θερμαντήρας που καθορίζεται από τον χρήστη"
},
"heatpump": "Αντλία θερμότητας που καθορίζεται από τον χρήστη",
"sgready": "Αντλία θερμότητας που καθορίζεται από τον χρήστη (SG-ready, all)",
"sgready-boost": "Αντλία θερμότητας που καθορίζεται από τον χρήστη (SG-ready, boost)",
"sgready": "Αντλία θερμότητας που καθορίζεται από τον χρήστη (sg-ready μέσω plugins)",
"sgready-relay": "Αντλία θερμότητας που καθορίζεται από τον χρήστη (sg-ready μέσω ρελέ)",
"switchsocket": "Διακόπτης πρίζας που καθορίζεται από τον χρήστη"
}
},

View file

@ -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": {

View file

@ -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"
}
},

View file

@ -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"
}
},

View file

@ -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"
}
},

View file

@ -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"
}
},

View file

@ -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"
}
},

View file

@ -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"
}
},

View file

@ -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ė"
}
},

View file

@ -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"
}
},

View file

@ -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"
}
},

View file

@ -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"
}
},

View file

@ -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"
}
},

View file

@ -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"
}
},

View file

@ -58,8 +58,8 @@
"heating": "பயனர் வரையறுக்கப்பட்ட ஈட்டர்"
},
"heatpump": "பயனர் வரையறுக்கப்பட்ட வெப்ப பம்ப்",
"sgready": "பயனர் வரையறுக்கப்பட்ட வெப்ப பம்ப் (எச்.சி-தயார், அனைத்தும்)",
"sgready-boost": "பயனர் வரையறுக்கப்பட்ட வெப்ப பம்ப் (எச்.சி-தயார், பூச்ட்)",
"sgready": "பயனர் வரையறுக்கப்பட்ட வெப்ப பம்ப் (sg-ready via plugins)",
"sgready-relay": "பயனர் வரையறுக்கப்பட்ட வெப்ப பம்ப் (sg-ready via relays)",
"switchsocket": "பயனர் வரையறுக்கப்பட்ட சுவிட்ச் சாக்கெட்"
}
},

View file

@ -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"
}
},

View file

@ -58,8 +58,8 @@
"heating": "Користувацький обігрівач"
},
"heatpump": "Користувацький тепловий насос",
"sgready": "Користувацький тепловий насос (готовий до роботи з підтримкою теплового насоса, усі)",
"sgready-boost": "Тепловий насос, що визначається користувачем (підтримка теплового насоса, підвищення потужності)",
"sgready": "Користувацький тепловий насос (sg-ready через плагіни)",
"sgready-relay": "Користувацький тепловий насос (sg-ready через реле)",
"switchsocket": "Користувацький перемикач-розетка"
}
},

View file

@ -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)

View file

@ -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");