diff --git a/assets/js/components/Config/DeviceModal/DeviceModalBase.vue b/assets/js/components/Config/DeviceModal/DeviceModalBase.vue index 8acdc089d..d2fc59597 100644 --- a/assets/js/components/Config/DeviceModal/DeviceModalBase.vue +++ b/assets/js/components/Config/DeviceModal/DeviceModalBase.vue @@ -367,6 +367,11 @@ export default defineComponent({ delete data["icon"]; } + // Remove modbus field if current template doesn't have modbus parameter + if (!this.modbus) { + delete data["modbus"]; + } + // Allow parent to transform API data if (this.transformApiData) { data = this.transformApiData(data, this.values); diff --git a/charger/config/config.go b/charger/config/config.go index 80751b11f..8000c1d27 100644 --- a/charger/config/config.go +++ b/charger/config/config.go @@ -6,6 +6,7 @@ import ( "strings" "github.com/evcc-io/evcc/api" + "github.com/evcc-io/evcc/util" reg "github.com/evcc-io/evcc/util/registry" ) @@ -20,7 +21,7 @@ func NewFromConfig(ctx context.Context, typ string, other map[string]any) (api.C v, err := factory(ctx, other) if err != nil { - return nil, fmt.Errorf("cannot create charger type '%s': %w", typ, err) + return nil, fmt.Errorf("cannot create charger type '%s': %w", util.TypeWithTemplateName(typ, other), err) } return v, nil diff --git a/meter/config/config.go b/meter/config/config.go index e8e593e5d..d51614235 100644 --- a/meter/config/config.go +++ b/meter/config/config.go @@ -6,6 +6,7 @@ import ( "strings" "github.com/evcc-io/evcc/api" + "github.com/evcc-io/evcc/util" reg "github.com/evcc-io/evcc/util/registry" ) @@ -20,7 +21,7 @@ func NewFromConfig(ctx context.Context, typ string, other map[string]any) (api.M v, err := factory(ctx, other) if err != nil { - return nil, fmt.Errorf("cannot create meter type '%s': %w", typ, err) + return nil, fmt.Errorf("cannot create meter type '%s': %w", util.TypeWithTemplateName(typ, other), err) } return v, nil diff --git a/plugin/auth/config.go b/plugin/auth/config.go index f51fccd99..38f8abf86 100644 --- a/plugin/auth/config.go +++ b/plugin/auth/config.go @@ -5,6 +5,7 @@ import ( "fmt" "strings" + "github.com/evcc-io/evcc/util" "golang.org/x/oauth2" ) @@ -17,7 +18,7 @@ func NewFromConfig(ctx context.Context, typ string, other map[string]any) (oauth v, err := factory(ctx, other) if err != nil { - err = fmt.Errorf("cannot create auth type '%s': %w", typ, err) + err = fmt.Errorf("cannot create auth type '%s': %w", util.TypeWithTemplateName(typ, other), err) } return v, err diff --git a/push/config.go b/push/config.go index 5d149e53c..050036dfe 100644 --- a/push/config.go +++ b/push/config.go @@ -5,6 +5,7 @@ import ( "fmt" "strings" + "github.com/evcc-io/evcc/util" reg "github.com/evcc-io/evcc/util/registry" ) @@ -24,7 +25,7 @@ func NewFromConfig(ctx context.Context, typ string, other map[string]any) (Messe v, err := factory(ctx, other) if err != nil { - err = fmt.Errorf("cannot create messenger type '%s': %w", typ, err) + err = fmt.Errorf("cannot create messenger type '%s': %w", util.TypeWithTemplateName(typ, other), err) } return v, err diff --git a/tariff/config.go b/tariff/config.go index 96c1f6b9e..8e3392530 100644 --- a/tariff/config.go +++ b/tariff/config.go @@ -6,6 +6,7 @@ import ( "strings" "github.com/evcc-io/evcc/api" + "github.com/evcc-io/evcc/util" reg "github.com/evcc-io/evcc/util/registry" ) @@ -25,7 +26,7 @@ func NewFromConfig(ctx context.Context, typ string, other map[string]any) (api.T v, err := factory(ctx, other) if err != nil { - return nil, fmt.Errorf("cannot create tariff type '%s': %w", typ, err) + return nil, fmt.Errorf("cannot create tariff type '%s': %w", util.TypeWithTemplateName(typ, other), err) } // check slot length diff --git a/tariff/proxy_cache.go b/tariff/proxy_cache.go index c1e0367d0..bc6e2251d 100644 --- a/tariff/proxy_cache.go +++ b/tariff/proxy_cache.go @@ -33,10 +33,8 @@ var _ api.Tariff = (*cachingProxy)(nil) // NewCachedFromConfig creates a proxy that controls tariff instantiation and caching func NewCachedFromConfig(ctx context.Context, typ string, other map[string]any) (api.Tariff, error) { tariffType := typ - if typ == "template" { - if template, ok := other["template"].(string); ok { - tariffType = template - } + if template := util.TemplateName(typ, other); template != "" { + tariffType = template } p := &cachingProxy{ diff --git a/tests/config-fatals.spec.ts b/tests/config-fatals.spec.ts index cf04872a4..7830a296f 100644 --- a/tests/config-fatals.spec.ts +++ b/tests/config-fatals.spec.ts @@ -83,7 +83,7 @@ test.describe("fatal config handling", async () => { // verify loadpoint still visible with error await expect(page.getByTestId("fatal-error")).toBeVisible(); await expect(page.getByTestId("fatal-error")).toContainText( - /meter: .+? cannot create meter .+?: cannot create meter type 'template': cannot create meter type 'shelly'/ + /meter: .+? cannot create meter .+?: cannot create meter type 'template:shelly-1pm': cannot create meter type 'shelly'/ ); await expect(page.getByTestId("fatal-error")).toContainText( /loadpoint: .+? missing charge meter instance/ diff --git a/util/template.go b/util/template.go new file mode 100644 index 000000000..eca9d853b --- /dev/null +++ b/util/template.go @@ -0,0 +1,17 @@ +package util + +func TypeWithTemplateName(typ string, other map[string]any) string { + if template := TemplateName(typ, other); template != "" { + typ += ":" + template + } + return typ +} + +func TemplateName(typ string, other map[string]any) string { + if typ == "template" && other != nil { + if template, ok := other["template"].(string); ok && template != "" { + return template + } + } + return "" +}