diff --git a/charger/charger.go b/charger/charger.go index 0b7b8570df..8a04d934c8 100644 --- a/charger/charger.go +++ b/charger/charger.go @@ -1,6 +1,7 @@ package charger import ( + "context" "errors" "fmt" @@ -20,13 +21,13 @@ type Charger struct { } func init() { - registry.Add(api.Custom, NewConfigurableFromConfig) + registry.AddCtx(api.Custom, NewConfigurableFromConfig) } //go:generate go run ../cmd/tools/decorate.go -f decorateCustom -b *Charger -r api.Charger -t "api.ChargerEx,MaxCurrentMillis,func(float64) error" -t "api.Identifier,Identify,func() (string, error)" -t "api.PhaseSwitcher,Phases1p3p,func(int) error" -t "api.Resurrector,WakeUp,func() error" -t "api.Battery,Soc,func() (float64, error)" -t "api.Meter,CurrentPower,func() (float64, error)" -t "api.MeterEnergy,TotalEnergy,func() (float64, error)" -t "api.PhaseCurrents,Currents,func() (float64, float64, float64, error)" -t "api.PhaseVoltages,Voltages,func() (float64, float64, float64, error)" // NewConfigurableFromConfig creates a new configurable charger -func NewConfigurableFromConfig(other map[string]interface{}) (api.Charger, error) { +func NewConfigurableFromConfig(ctx context.Context, other map[string]interface{}) (api.Charger, error) { var cc struct { embed `mapstructure:",squash"` Status, Enable, Enabled, MaxCurrent provider.Config @@ -47,22 +48,22 @@ func NewConfigurableFromConfig(other map[string]interface{}) (api.Charger, error return nil, err } - status, err := provider.NewStringGetterFromConfig(cc.Status) + status, err := provider.NewStringGetterFromConfig(ctx, cc.Status) if err != nil { return nil, fmt.Errorf("status: %w", err) } - enabled, err := provider.NewBoolGetterFromConfig(cc.Enabled) + enabled, err := provider.NewBoolGetterFromConfig(ctx, cc.Enabled) if err != nil { return nil, fmt.Errorf("enabled: %w", err) } - enable, err := provider.NewBoolSetterFromConfig("enable", cc.Enable) + enable, err := provider.NewBoolSetterFromConfig(ctx, "enable", cc.Enable) if err != nil { return nil, fmt.Errorf("enable: %w", err) } - maxcurrent, err := provider.NewIntSetterFromConfig("maxcurrent", cc.MaxCurrent) + maxcurrent, err := provider.NewIntSetterFromConfig(ctx, "maxcurrent", cc.MaxCurrent) if err != nil { return nil, fmt.Errorf("maxcurrent: %w", err) } @@ -76,7 +77,7 @@ func NewConfigurableFromConfig(other map[string]interface{}) (api.Charger, error var maxcurrentmillis func(float64) error if cc.MaxCurrentMillis != nil { - maxcurrentmillis, err = provider.NewFloatSetterFromConfig("maxcurrentmillis", *cc.MaxCurrentMillis) + maxcurrentmillis, err = provider.NewFloatSetterFromConfig(ctx, "maxcurrentmillis", *cc.MaxCurrentMillis) if err != nil { return nil, fmt.Errorf("maxcurrentmillis: %w", err) } @@ -89,7 +90,7 @@ func NewConfigurableFromConfig(other map[string]interface{}) (api.Charger, error return nil, errors.New("1p3p does no longer handle disable/enable. Use tos: true to confirm you understand the consequences") } - phases1p3pS, err := provider.NewIntSetterFromConfig("phases", *cc.Phases1p3p) + phases1p3pS, err := provider.NewIntSetterFromConfig(ctx, "phases", *cc.Phases1p3p) if err != nil { return nil, fmt.Errorf("phases: %w", err) } @@ -102,7 +103,7 @@ func NewConfigurableFromConfig(other map[string]interface{}) (api.Charger, error // decorate identifier var identify func() (string, error) if cc.Identify != nil { - identify, err = provider.NewStringGetterFromConfig(*cc.Identify) + identify, err = provider.NewStringGetterFromConfig(ctx, *cc.Identify) if err != nil { return nil, fmt.Errorf("identify: %w", err) } @@ -111,7 +112,7 @@ func NewConfigurableFromConfig(other map[string]interface{}) (api.Charger, error // decorate wakeup var wakeup func() error if cc.Wakeup != nil { - wakeupS, err := provider.NewBoolSetterFromConfig("wakeup", *cc.Wakeup) + wakeupS, err := provider.NewBoolSetterFromConfig(ctx, "wakeup", *cc.Wakeup) if err != nil { return nil, fmt.Errorf("wakeup: %w", err) } @@ -124,19 +125,19 @@ func NewConfigurableFromConfig(other map[string]interface{}) (api.Charger, error // decorate soc var soc func() (float64, error) if cc.Soc != nil { - soc, err = provider.NewFloatGetterFromConfig(*cc.Soc) + soc, err = provider.NewFloatGetterFromConfig(ctx, *cc.Soc) if err != nil { return nil, fmt.Errorf("soc: %w", err) } } // decorate measurements - powerG, energyG, err := meter.BuildMeasurements(cc.Power, cc.Energy) + powerG, energyG, err := meter.BuildMeasurements(ctx, cc.Power, cc.Energy) if err != nil { return nil, err } - currentsG, voltagesG, _, err := meter.BuildPhaseMeasurements(cc.Currents, cc.Voltages, nil) + currentsG, voltagesG, _, err := meter.BuildPhaseMeasurements(ctx, cc.Currents, cc.Voltages, nil) if err != nil { return nil, err } diff --git a/charger/config.go b/charger/config.go index 2dcc7e6870..6449c3d780 100644 --- a/charger/config.go +++ b/charger/config.go @@ -17,13 +17,13 @@ func Types() []string { } // NewFromConfig creates charger from configuration -func NewFromConfig(typ string, other map[string]interface{}) (api.Charger, error) { +func NewFromConfig(ctx context.Context, typ string, other map[string]interface{}) (api.Charger, error) { factory, err := registry.Get(strings.ToLower(typ)) if err != nil { return nil, err } - v, err := factory(context.TODO(), other) + v, err := factory(ctx, other) if err != nil { err = fmt.Errorf("cannot create charger type '%s': %w", typ, err) } diff --git a/charger/openwb.go b/charger/openwb.go index baed6950d2..8856fc5280 100644 --- a/charger/openwb.go +++ b/charger/openwb.go @@ -91,7 +91,7 @@ func NewOpenWB(log *util.Logger, mqttconf mqtt.Config, id int, topic string, p1p if err != nil { return nil, err } - statusG := provider.NewOpenWBStatusProvider(pluggedG, chargingG).StringGetter + statusG := provider.NewCombinedProvider(pluggedG, chargingG).StringGetter // setters currentTopic := openwb.SlaveChargeCurrentTopic diff --git a/charger/switchsocket.go b/charger/switchsocket.go index cdb45812f3..a2824a96fe 100644 --- a/charger/switchsocket.go +++ b/charger/switchsocket.go @@ -1,6 +1,8 @@ package charger import ( + "context" + "github.com/evcc-io/evcc/api" "github.com/evcc-io/evcc/core/loadpoint" "github.com/evcc-io/evcc/provider" @@ -8,7 +10,7 @@ import ( ) func init() { - registry.Add("switchsocket", NewSwitchSocketFromConfig) + registry.AddCtx("switchsocket", NewSwitchSocketFromConfig) } type SwitchSocket struct { @@ -17,7 +19,7 @@ type SwitchSocket struct { *switchSocket } -func NewSwitchSocketFromConfig(other map[string]interface{}) (api.Charger, error) { +func NewSwitchSocketFromConfig(ctx context.Context, other map[string]interface{}) (api.Charger, error) { var cc struct { embed `mapstructure:",squash"` Enabled provider.Config @@ -30,17 +32,17 @@ func NewSwitchSocketFromConfig(other map[string]interface{}) (api.Charger, error return nil, err } - enabled, err := provider.NewBoolGetterFromConfig(cc.Enabled) + enabled, err := provider.NewBoolGetterFromConfig(ctx, cc.Enabled) if err != nil { return nil, err } - enable, err := provider.NewBoolSetterFromConfig("enable", cc.Enable) + enable, err := provider.NewBoolSetterFromConfig(ctx, "enable", cc.Enable) if err != nil { return nil, err } - power, err := provider.NewFloatGetterFromConfig(cc.Power) + power, err := provider.NewFloatGetterFromConfig(ctx, cc.Power) if err != nil { return nil, err } diff --git a/charger/template.go b/charger/template.go index ddbfca36b8..e476d8a7ca 100644 --- a/charger/template.go +++ b/charger/template.go @@ -1,19 +1,21 @@ package charger import ( + "context" + "github.com/evcc-io/evcc/api" "github.com/evcc-io/evcc/util/templates" ) func init() { - registry.Add("template", NewChargerFromTemplateConfig) + registry.AddCtx("template", NewChargerFromTemplateConfig) } -func NewChargerFromTemplateConfig(other map[string]interface{}) (api.Charger, error) { +func NewChargerFromTemplateConfig(ctx context.Context, other map[string]interface{}) (api.Charger, error) { instance, err := templates.RenderInstance(templates.Charger, other) if err != nil { return nil, err } - return NewFromConfig(instance.Type, instance.Other) + return NewFromConfig(ctx, instance.Type, instance.Other) } diff --git a/charger/template_test.go b/charger/template_test.go index d77de33156..1d679b3950 100644 --- a/charger/template_test.go +++ b/charger/template_test.go @@ -1,6 +1,7 @@ package charger import ( + "context" "testing" "github.com/evcc-io/evcc/util/templates" @@ -35,7 +36,7 @@ var acceptable = []string{ func TestTemplates(t *testing.T) { templates.TestClass(t, templates.Charger, func(t *testing.T, values map[string]any) { t.Helper() - if _, err := NewFromConfig("template", values); err != nil && !test.Acceptable(err, acceptable) { + if _, err := NewFromConfig(context.TODO(), "template", values); err != nil && !test.Acceptable(err, acceptable) { t.Log(values) t.Error(err) } diff --git a/cmd/configure/devicetest.go b/cmd/configure/devicetest.go index 5d800dd124..c6052472d6 100644 --- a/cmd/configure/devicetest.go +++ b/cmd/configure/devicetest.go @@ -1,6 +1,7 @@ package configure import ( + "context" "errors" "time" @@ -68,13 +69,14 @@ func (d *DeviceTest) configure() (interface{}, error) { var v interface{} + ctx := context.TODO() switch DeviceCategories[d.DeviceCategory].class { case templates.Meter: - v, err = meter.NewFromConfig(instance.Type, instance.Other) + v, err = meter.NewFromConfig(ctx, instance.Type, instance.Other) case templates.Charger: - v, err = charger.NewFromConfig(instance.Type, instance.Other) + v, err = charger.NewFromConfig(ctx, instance.Type, instance.Other) case templates.Vehicle: - v, err = vehicle.NewFromConfig(instance.Type, instance.Other) + v, err = vehicle.NewFromConfig(ctx, instance.Type, instance.Other) } return v, err diff --git a/cmd/setup.go b/cmd/setup.go index 3dc2180a85..7642c905d4 100644 --- a/cmd/setup.go +++ b/cmd/setup.go @@ -2,6 +2,7 @@ package cmd import ( "cmp" + "context" "errors" "fmt" "net/http" @@ -219,7 +220,9 @@ func configureMeters(static []config.Named, names ...string) error { } eg.Go(func() error { - instance, err := meter.NewFromConfig(cc.Type, cc.Other) + ctx := util.WithLogger(context.TODO(), util.NewLogger(cc.Name)) + + instance, err := meter.NewFromConfig(ctx, cc.Type, cc.Other) if err != nil { return &DeviceError{cc.Name, fmt.Errorf("cannot create meter '%s': %w", cc.Name, err)} } @@ -246,9 +249,9 @@ func configureMeters(static []config.Named, names ...string) error { return nil } - // TODO add fake devices + ctx := util.WithLogger(context.TODO(), util.NewLogger(cc.Name)) - instance, err := meter.NewFromConfig(cc.Type, cc.Other) + instance, err := meter.NewFromConfig(ctx, cc.Type, cc.Other) if err != nil { return &DeviceError{cc.Name, fmt.Errorf("cannot create meter '%s': %w", cc.Name, err)} } @@ -281,7 +284,9 @@ func configureChargers(static []config.Named, names ...string) error { } eg.Go(func() error { - instance, err := charger.NewFromConfig(cc.Type, cc.Other) + ctx := util.WithLogger(context.TODO(), util.NewLogger(cc.Name)) + + instance, err := charger.NewFromConfig(ctx, cc.Type, cc.Other) if err != nil { return &DeviceError{cc.Name, fmt.Errorf("cannot create charger '%s': %w", cc.Name, err)} } @@ -308,9 +313,9 @@ func configureChargers(static []config.Named, names ...string) error { return nil } - // TODO add fake devices + ctx := util.WithLogger(context.TODO(), util.NewLogger(cc.Name)) - instance, err := charger.NewFromConfig(cc.Type, cc.Other) + instance, err := charger.NewFromConfig(ctx, cc.Type, cc.Other) if err != nil { return fmt.Errorf("cannot create charger '%s': %w", cc.Name, err) } @@ -327,7 +332,9 @@ func configureChargers(static []config.Named, names ...string) error { } func vehicleInstance(cc config.Named) (api.Vehicle, error) { - instance, err := vehicle.NewFromConfig(cc.Type, cc.Other) + ctx := util.WithLogger(context.TODO(), util.NewLogger(cc.Name)) + + instance, err := vehicle.NewFromConfig(ctx, cc.Type, cc.Other) if err != nil { var ce *util.ConfigError if errors.As(err, &ce) { @@ -656,7 +663,7 @@ func configureHEMS(conf config.Typed, site *core.Site, httpd *server.HTTPd) erro // } // } - hems, err := hems.NewFromConfig(conf.Type, conf.Other, site, httpd) + hems, err := hems.NewFromConfig(context.TODO(), conf.Type, conf.Other, site, httpd) if err != nil { return fmt.Errorf("failed configuring hems: %w", err) } @@ -761,7 +768,9 @@ func configureMessengers(conf globalconfig.Messaging, vehicles push.Vehicles, va } func tariffInstance(name string, conf config.Typed) (api.Tariff, error) { - instance, err := tariff.NewFromConfig(conf.Type, conf.Other) + ctx := util.WithLogger(context.TODO(), util.NewLogger(name)) + + instance, err := tariff.NewFromConfig(ctx, conf.Type, conf.Other) if err != nil { var ce *util.ConfigError if errors.As(err, &ce) { diff --git a/cmd/tariff.go b/cmd/tariff.go index 461762890e..0b80cee40b 100644 --- a/cmd/tariff.go +++ b/cmd/tariff.go @@ -1,6 +1,7 @@ package cmd import ( + "context" "fmt" "os" "text/tabwriter" @@ -52,7 +53,7 @@ func runTariff(cmd *cobra.Command, args []string) { fmt.Println(key + ":") } - tf, err := tariff.NewFromConfig(cc.Type, cc.Other) + tf, err := tariff.NewFromConfig(context.TODO(), cc.Type, cc.Other) if err != nil { fatal(err) } diff --git a/hems/config.go b/hems/config.go index fb5be71ac4..c0843cffd1 100644 --- a/hems/config.go +++ b/hems/config.go @@ -1,6 +1,7 @@ package hems import ( + "context" "errors" "strings" @@ -17,14 +18,14 @@ type HEMS interface { } // NewFromConfig creates new HEMS from config -func NewFromConfig(typ string, other map[string]interface{}, site site.API, httpd *server.HTTPd) (HEMS, error) { +func NewFromConfig(ctx context.Context, typ string, other map[string]interface{}, site site.API, httpd *server.HTTPd) (HEMS, error) { switch strings.ToLower(typ) { case "sma", "shm", "semp": return semp.New(other, site, httpd) case "eebus": return eebus.New(other, site) case "relay": - return relay.New(other, site) + return relay.New(ctx, other, site) default: return nil, errors.New("unknown hems: " + typ) } diff --git a/hems/relay/relay.go b/hems/relay/relay.go index 741b3bc77c..2d8e408d41 100644 --- a/hems/relay/relay.go +++ b/hems/relay/relay.go @@ -1,6 +1,7 @@ package relay import ( + "context" "errors" "time" @@ -20,7 +21,7 @@ type Relay struct { } // New creates an Relay HEMS from generic config -func New(other map[string]interface{}, site site.API) (*Relay, error) { +func New(ctx context.Context, other map[string]interface{}, site site.API) (*Relay, error) { var cc struct { MaxPower float64 Limit provider.Config @@ -49,7 +50,7 @@ func New(other map[string]interface{}, site site.API) (*Relay, error) { site.SetCircuit(lpc) // limit getter - limitG, err := provider.NewBoolGetterFromConfig(cc.Limit) + limitG, err := provider.NewBoolGetterFromConfig(ctx, cc.Limit) if err != nil { return nil, err } diff --git a/meter/config.go b/meter/config.go index 3a1228994b..8719c88eef 100644 --- a/meter/config.go +++ b/meter/config.go @@ -17,13 +17,13 @@ func Types() []string { } // NewFromConfig creates meter from configuration -func NewFromConfig(typ string, other map[string]interface{}) (api.Meter, error) { +func NewFromConfig(ctx context.Context, typ string, other map[string]interface{}) (api.Meter, error) { factory, err := registry.Get(strings.ToLower(typ)) if err != nil { return nil, err } - v, err := factory(context.TODO(), other) + v, err := factory(ctx, other) if err != nil { err = fmt.Errorf("cannot create meter type '%s': %w", typ, err) } diff --git a/meter/helper.go b/meter/helper.go index 7d57d474ed..9f8592152c 100644 --- a/meter/helper.go +++ b/meter/helper.go @@ -1,6 +1,7 @@ package meter import ( + "context" "errors" "fmt" @@ -8,11 +9,11 @@ import ( ) // BuildMeasurements returns typical meter measurement getters from config -func BuildMeasurements(power, energy *provider.Config) (func() (float64, error), func() (float64, error), error) { +func BuildMeasurements(ctx context.Context, power, energy *provider.Config) (func() (float64, error), func() (float64, error), error) { var powerG func() (float64, error) if power != nil { var err error - powerG, err = provider.NewFloatGetterFromConfig(*power) + powerG, err = provider.NewFloatGetterFromConfig(ctx, *power) if err != nil { return nil, nil, fmt.Errorf("power: %w", err) } @@ -21,7 +22,7 @@ func BuildMeasurements(power, energy *provider.Config) (func() (float64, error), var energyG func() (float64, error) if energy != nil { var err error - energyG, err = provider.NewFloatGetterFromConfig(*energy) + energyG, err = provider.NewFloatGetterFromConfig(ctx, *energy) if err != nil { return nil, nil, fmt.Errorf("energy: %w", err) } @@ -31,23 +32,23 @@ func BuildMeasurements(power, energy *provider.Config) (func() (float64, error), } // BuildPhaseMeasurements returns typical meter measurement getters from config -func BuildPhaseMeasurements(currents, voltages, powers []provider.Config) ( +func BuildPhaseMeasurements(ctx context.Context, currents, voltages, powers []provider.Config) ( func() (float64, float64, float64, error), func() (float64, float64, float64, error), func() (float64, float64, float64, error), error, ) { - currentsG, err := buildPhaseProviders(currents) + currentsG, err := buildPhaseProviders(ctx, currents) if err != nil { return nil, nil, nil, fmt.Errorf("currents: %w", err) } - voltagesG, err := buildPhaseProviders(voltages) + voltagesG, err := buildPhaseProviders(ctx, voltages) if err != nil { return nil, nil, nil, fmt.Errorf("voltages: %w", err) } - powersG, err := buildPhaseProviders(powers) + powersG, err := buildPhaseProviders(ctx, powers) if err != nil { return nil, nil, nil, fmt.Errorf("powers: %w", err) } @@ -56,7 +57,7 @@ func BuildPhaseMeasurements(currents, voltages, powers []provider.Config) ( } // buildPhaseProviders returns phases getter for given config -func buildPhaseProviders(providers []provider.Config) (func() (float64, float64, float64, error), error) { +func buildPhaseProviders(ctx context.Context, providers []provider.Config) (func() (float64, float64, float64, error), error) { if len(providers) == 0 { return nil, nil } @@ -67,7 +68,7 @@ func buildPhaseProviders(providers []provider.Config) (func() (float64, float64, var phases [3]func() (float64, error) for idx, prov := range providers { - c, err := provider.NewFloatGetterFromConfig(prov) + c, err := provider.NewFloatGetterFromConfig(ctx, prov) if err != nil { return nil, fmt.Errorf("[%d] %w", idx, err) } diff --git a/meter/meter.go b/meter/meter.go index cb8352d86c..7380cc9fe3 100644 --- a/meter/meter.go +++ b/meter/meter.go @@ -1,6 +1,7 @@ package meter import ( + "context" "fmt" "github.com/evcc-io/evcc/api" @@ -9,13 +10,13 @@ import ( ) func init() { - registry.Add(api.Custom, NewConfigurableFromConfig) + registry.AddCtx(api.Custom, NewConfigurableFromConfig) } //go:generate go run ../cmd/tools/decorate.go -f decorateMeter -b api.Meter -t "api.MeterEnergy,TotalEnergy,func() (float64, error)" -t "api.PhaseCurrents,Currents,func() (float64, float64, float64, error)" -t "api.PhaseVoltages,Voltages,func() (float64, float64, float64, error)" -t "api.PhasePowers,Powers,func() (float64, float64, float64, error)" -t "api.Battery,Soc,func() (float64, error)" -t "api.BatteryCapacity,Capacity,func() float64" -t "api.BatteryController,SetBatteryMode,func(api.BatteryMode) error" // NewConfigurableFromConfig creates api.Meter from config -func NewConfigurableFromConfig(other map[string]interface{}) (api.Meter, error) { +func NewConfigurableFromConfig(ctx context.Context, other map[string]interface{}) (api.Meter, error) { cc := struct { Power provider.Config Energy *provider.Config // optional @@ -40,12 +41,12 @@ func NewConfigurableFromConfig(other map[string]interface{}) (api.Meter, error) return nil, err } - powerG, energyG, err := BuildMeasurements(&cc.Power, cc.Energy) + powerG, energyG, err := BuildMeasurements(ctx, &cc.Power, cc.Energy) if err != nil { return nil, err } - currentsG, voltagesG, powersG, err := BuildPhaseMeasurements(cc.Currents, cc.Voltages, cc.Powers) + currentsG, voltagesG, powersG, err := BuildPhaseMeasurements(ctx, cc.Currents, cc.Voltages, cc.Powers) if err != nil { return nil, err } @@ -55,7 +56,7 @@ func NewConfigurableFromConfig(other map[string]interface{}) (api.Meter, error) // decorate soc var socG func() (float64, error) if cc.Soc != nil { - socG, err = provider.NewFloatGetterFromConfig(*cc.Soc) + socG, err = provider.NewFloatGetterFromConfig(ctx, *cc.Soc) if err != nil { return nil, fmt.Errorf("battery soc: %w", err) } @@ -65,7 +66,7 @@ func NewConfigurableFromConfig(other map[string]interface{}) (api.Meter, error) switch { case cc.Soc != nil && cc.LimitSoc != nil: - limitSocS, err := provider.NewFloatSetterFromConfig("limitSoc", *cc.LimitSoc) + limitSocS, err := provider.NewFloatSetterFromConfig(ctx, "limitSoc", *cc.LimitSoc) if err != nil { return nil, fmt.Errorf("battery limit soc: %w", err) } @@ -73,7 +74,7 @@ func NewConfigurableFromConfig(other map[string]interface{}) (api.Meter, error) batModeS = cc.battery.LimitController(socG, limitSocS) case cc.BatteryMode != nil: - modeS, err := provider.NewIntSetterFromConfig("batteryMode", *cc.BatteryMode) + modeS, err := provider.NewIntSetterFromConfig(ctx, "batteryMode", *cc.BatteryMode) if err != nil { return nil, fmt.Errorf("battery mode: %w", err) } diff --git a/meter/meter_average.go b/meter/meter_average.go index e5b5ae7ca7..36cbfca137 100644 --- a/meter/meter_average.go +++ b/meter/meter_average.go @@ -1,16 +1,18 @@ package meter import ( + "context" + "github.com/evcc-io/evcc/api" "github.com/evcc-io/evcc/util" ) func init() { - registry.Add("movingaverage", NewMovingAverageFromConfig) + registry.AddCtx("movingaverage", NewMovingAverageFromConfig) } // NewMovingAverageFromConfig creates api.Meter from config -func NewMovingAverageFromConfig(other map[string]interface{}) (api.Meter, error) { +func NewMovingAverageFromConfig(ctx context.Context, other map[string]interface{}) (api.Meter, error) { cc := struct { Decay float64 Meter struct { @@ -26,7 +28,7 @@ func NewMovingAverageFromConfig(other map[string]interface{}) (api.Meter, error) return nil, err } - m, err := NewFromConfig(cc.Meter.Type, cc.Meter.Other) + m, err := NewFromConfig(ctx, cc.Meter.Type, cc.Meter.Other) if err != nil { return nil, err } diff --git a/meter/template.go b/meter/template.go index 2de6e570db..9a0d0f66c5 100644 --- a/meter/template.go +++ b/meter/template.go @@ -1,19 +1,21 @@ package meter import ( + "context" + "github.com/evcc-io/evcc/api" "github.com/evcc-io/evcc/util/templates" ) func init() { - registry.Add("template", NewMeterFromTemplateConfig) + registry.AddCtx("template", NewMeterFromTemplateConfig) } -func NewMeterFromTemplateConfig(other map[string]interface{}) (api.Meter, error) { +func NewMeterFromTemplateConfig(ctx context.Context, other map[string]interface{}) (api.Meter, error) { instance, err := templates.RenderInstance(templates.Meter, other) if err != nil { return nil, err } - return NewFromConfig(instance.Type, instance.Other) + return NewFromConfig(ctx, instance.Type, instance.Other) } diff --git a/meter/template_test.go b/meter/template_test.go index eaf8d134bb..c2bed10ee6 100644 --- a/meter/template_test.go +++ b/meter/template_test.go @@ -1,6 +1,7 @@ package meter import ( + "context" "testing" "github.com/evcc-io/evcc/util/templates" @@ -35,7 +36,7 @@ func TestTemplates(t *testing.T) { templates.TestClass(t, templates.Meter, func(t *testing.T, values map[string]any) { t.Helper() - if _, err := NewFromConfig("template", values); err != nil && !test.Acceptable(err, acceptable) { + if _, err := NewFromConfig(context.TODO(), "template", values); err != nil && !test.Acceptable(err, acceptable) { t.Log(values) t.Error(err) } diff --git a/provider/calc.go b/provider/calc.go index abf8e8f460..3d8d3c6132 100644 --- a/provider/calc.go +++ b/provider/calc.go @@ -1,6 +1,7 @@ package provider import ( + "context" "errors" "fmt" @@ -13,11 +14,11 @@ type calcProvider struct { } func init() { - registry.Add("calc", NewCalcFromConfig) + registry.AddCtx("calc", NewCalcFromConfig) } // NewCalcFromConfig creates calc provider -func NewCalcFromConfig(other map[string]interface{}) (Provider, error) { +func NewCalcFromConfig(ctx context.Context, other map[string]interface{}) (Provider, error) { var cc struct { Add []Config Mul []Config @@ -38,7 +39,7 @@ func NewCalcFromConfig(other map[string]interface{}) (Provider, error) { } for idx, cc := range cc.Add { - f, err := NewFloatGetterFromConfig(cc) + f, err := NewFloatGetterFromConfig(ctx, cc) if err != nil { return nil, fmt.Errorf("add[%d]: %w", idx, err) } @@ -46,7 +47,7 @@ func NewCalcFromConfig(other map[string]interface{}) (Provider, error) { } for idx, cc := range cc.Mul { - f, err := NewFloatGetterFromConfig(cc) + f, err := NewFloatGetterFromConfig(ctx, cc) if err != nil { return nil, fmt.Errorf("mul[%d]: %w", idx, err) } @@ -54,7 +55,7 @@ func NewCalcFromConfig(other map[string]interface{}) (Provider, error) { } for idx, cc := range cc.Div { - f, err := NewFloatGetterFromConfig(cc) + f, err := NewFloatGetterFromConfig(ctx, cc) if err != nil { return nil, fmt.Errorf("div[%d]: %w", idx, err) } @@ -62,7 +63,7 @@ func NewCalcFromConfig(other map[string]interface{}) (Provider, error) { } if cc.Sign != nil { - f, err := NewFloatGetterFromConfig(*cc.Sign) + f, err := NewFloatGetterFromConfig(ctx, *cc.Sign) if err != nil { return nil, fmt.Errorf("sign: %w", err) } diff --git a/provider/combined.go b/provider/combined.go index 52abbc8389..05e9c982bd 100644 --- a/provider/combined.go +++ b/provider/combined.go @@ -1,29 +1,73 @@ package provider -type combinedProvider struct { - status func() (string, error) -} +import ( + "context" + + "github.com/evcc-io/evcc/api" + "github.com/evcc-io/evcc/util" +) func init() { - registry.Add("combined", NewCombinedFromConfig) - registry.Add("openwb", NewCombinedFromConfig) + registry.AddCtx("combined", NewCombinedFromConfig) + registry.AddCtx("openwb", NewCombinedFromConfig) +} + +// combinedProvider implements status conversion from openWB to api.Status +type combinedProvider struct { + plugged, charging func() (bool, error) } // NewCombinedFromConfig creates combined provider -func NewCombinedFromConfig(other map[string]interface{}) (Provider, error) { - status, err := NewOpenWBStatusProviderFromConfig(other) +func NewCombinedFromConfig(ctx context.Context, other map[string]interface{}) (Provider, error) { + var cc struct { + Plugged, Charging Config + } + + if err := util.DecodeOther(other, &cc); err != nil { + return nil, err + } + + plugged, err := NewBoolGetterFromConfig(ctx, cc.Plugged) + + var charging func() (bool, error) + if err == nil { + charging, err = NewBoolGetterFromConfig(ctx, cc.Charging) + } + if err != nil { return nil, err } - o := &combinedProvider{status: status} + o := NewCombinedProvider(plugged, charging) + return o, nil } -var _ StringProvider = (*combinedProvider)(nil) +// NewCombinedProvider creates provider for OpenWB status converted from MQTT topics +func NewCombinedProvider(plugged, charging func() (bool, error)) *combinedProvider { + return &combinedProvider{ + plugged: plugged, + charging: charging, + } +} + +// StringGetter returns string from OpenWB charging/ plugged status +func (o *combinedProvider) StringGetter() (string, error) { + charging, err := o.charging() + if err != nil { + return "", err + } + if charging { + return string(api.StatusC), nil + } + + plugged, err := o.plugged() + if err != nil { + return "", err + } + if plugged { + return string(api.StatusB), nil + } -func (o *combinedProvider) StringGetter() (func() (string, error), error) { - return func() (string, error) { - return o.status() - }, nil + return string(api.StatusA), nil } diff --git a/provider/config.go b/provider/config.go index da3e95c963..7e7d025f05 100644 --- a/provider/config.go +++ b/provider/config.go @@ -44,7 +44,7 @@ type Config struct { Other map[string]any `mapstructure:",remain" yaml:",inline"` } -func provider[T any](typ string, config Config) (T, error) { +func provider[T any](typ string, ctx context.Context, config Config) (T, error) { var zero T factory, err := registry.Get(config.Source) @@ -52,7 +52,7 @@ func provider[T any](typ string, config Config) (T, error) { return zero, err } - provider, err := factory(context.TODO(), config.Other) + provider, err := factory(ctx, config.Other) if err != nil { return zero, err } @@ -66,8 +66,8 @@ func provider[T any](typ string, config Config) (T, error) { } // NewIntGetterFromConfig creates a IntGetter from config -func NewIntGetterFromConfig(config Config) (func() (int64, error), error) { - prov, err := provider[IntProvider]("int", config) +func NewIntGetterFromConfig(ctx context.Context, config Config) (func() (int64, error), error) { + prov, err := provider[IntProvider]("int", ctx, config) if err != nil { return nil, err } @@ -76,8 +76,8 @@ func NewIntGetterFromConfig(config Config) (func() (int64, error), error) { } // NewFloatGetterFromConfig creates a FloatGetter from config -func NewFloatGetterFromConfig(config Config) (func() (float64, error), error) { - prov, err := provider[FloatProvider]("float", config) +func NewFloatGetterFromConfig(ctx context.Context, config Config) (func() (float64, error), error) { + prov, err := provider[FloatProvider]("float", ctx, config) if err != nil { return nil, err } @@ -86,8 +86,8 @@ func NewFloatGetterFromConfig(config Config) (func() (float64, error), error) { } // NewStringGetterFromConfig creates a StringGetter from config -func NewStringGetterFromConfig(config Config) (func() (string, error), error) { - prov, err := provider[StringProvider]("string", config) +func NewStringGetterFromConfig(ctx context.Context, config Config) (func() (string, error), error) { + prov, err := provider[StringProvider]("string", ctx, config) if err != nil { return nil, err } @@ -96,8 +96,8 @@ func NewStringGetterFromConfig(config Config) (func() (string, error), error) { } // NewBoolGetterFromConfig creates a BoolGetter from config -func NewBoolGetterFromConfig(config Config) (func() (bool, error), error) { - prov, err := provider[BoolProvider]("bool", config) +func NewBoolGetterFromConfig(ctx context.Context, config Config) (func() (bool, error), error) { + prov, err := provider[BoolProvider]("bool", ctx, config) if err != nil { return nil, err } @@ -106,8 +106,8 @@ func NewBoolGetterFromConfig(config Config) (func() (bool, error), error) { } // NewIntSetterFromConfig creates a IntSetter from config -func NewIntSetterFromConfig(param string, config Config) (func(int64) error, error) { - prov, err := provider[SetIntProvider]("int", config) +func NewIntSetterFromConfig(ctx context.Context, param string, config Config) (func(int64) error, error) { + prov, err := provider[SetIntProvider]("int", ctx, config) if err != nil { return nil, err } @@ -116,8 +116,8 @@ func NewIntSetterFromConfig(param string, config Config) (func(int64) error, err } // NewFloatSetterFromConfig creates a FloatSetter from config -func NewFloatSetterFromConfig(param string, config Config) (func(float642 float64) error, error) { - prov, err := provider[SetFloatProvider]("float", config) +func NewFloatSetterFromConfig(ctx context.Context, param string, config Config) (func(float642 float64) error, error) { + prov, err := provider[SetFloatProvider]("float", ctx, config) if err != nil { return nil, err } @@ -126,8 +126,8 @@ func NewFloatSetterFromConfig(param string, config Config) (func(float642 float6 } // NewStringSetterFromConfig creates a StringSetter from config -func NewStringSetterFromConfig(param string, config Config) (func(string) error, error) { - prov, err := provider[SetStringProvider]("string", config) +func NewStringSetterFromConfig(ctx context.Context, param string, config Config) (func(string) error, error) { + prov, err := provider[SetStringProvider]("string", ctx, config) if err != nil { return nil, err } @@ -136,8 +136,8 @@ func NewStringSetterFromConfig(param string, config Config) (func(string) error, } // NewBoolSetterFromConfig creates a BoolSetter from config -func NewBoolSetterFromConfig(param string, config Config) (func(bool) error, error) { - prov, err := provider[SetBoolProvider]("bool", config) +func NewBoolSetterFromConfig(ctx context.Context, param string, config Config) (func(bool) error, error) { + prov, err := provider[SetBoolProvider]("bool", ctx, config) if err != nil { return nil, err } diff --git a/provider/const.go b/provider/const.go index b8e916e287..2c58bb2ac9 100644 --- a/provider/const.go +++ b/provider/const.go @@ -1,6 +1,7 @@ package provider import ( + "context" "strconv" "github.com/evcc-io/evcc/provider/pipeline" @@ -8,16 +9,17 @@ import ( ) type constProvider struct { + ctx context.Context str string set Config } func init() { - registry.Add("const", NewConstFromConfig) + registry.AddCtx("const", NewConstFromConfig) } // NewConstFromConfig creates const provider -func NewConstFromConfig(other map[string]interface{}) (Provider, error) { +func NewConstFromConfig(ctx context.Context, other map[string]interface{}) (Provider, error) { var cc struct { Value string pipeline.Settings `mapstructure:",squash"` @@ -39,6 +41,7 @@ func NewConstFromConfig(other map[string]interface{}) (Provider, error) { } o := &constProvider{ + ctx: ctx, str: string(b), set: cc.Set, } @@ -96,7 +99,7 @@ func (o *constProvider) BoolGetter() (func() (bool, error), error) { var _ SetIntProvider = (*constProvider)(nil) func (o *constProvider) IntSetter(param string) (func(int64) error, error) { - set, err := NewIntSetterFromConfig(param, o.set) + set, err := NewIntSetterFromConfig(o.ctx, param, o.set) if err != nil { return nil, err } @@ -114,7 +117,7 @@ func (o *constProvider) IntSetter(param string) (func(int64) error, error) { var _ SetFloatProvider = (*constProvider)(nil) func (o *constProvider) FloatSetter(param string) (func(float64) error, error) { - set, err := NewFloatSetterFromConfig(param, o.set) + set, err := NewFloatSetterFromConfig(o.ctx, param, o.set) if err != nil { return nil, err } @@ -132,7 +135,7 @@ func (o *constProvider) FloatSetter(param string) (func(float64) error, error) { var _ SetBoolProvider = (*constProvider)(nil) func (o *constProvider) BoolSetter(param string) (func(bool) error, error) { - set, err := NewBoolSetterFromConfig(param, o.set) + set, err := NewBoolSetterFromConfig(o.ctx, param, o.set) if err != nil { return nil, err } diff --git a/provider/convert.go b/provider/convert.go index 1042b79359..d26932043b 100644 --- a/provider/convert.go +++ b/provider/convert.go @@ -1,23 +1,27 @@ package provider import ( + "context" "fmt" "github.com/evcc-io/evcc/util" ) type convertProvider struct { + ctx context.Context Convert string Set Config } func init() { - registry.Add("convert", NewConvertFromConfig) + registry.AddCtx("convert", NewConvertFromConfig) } // NewConvertFromConfig creates type conversion provider -func NewConvertFromConfig(other map[string]interface{}) (Provider, error) { - var cc convertProvider +func NewConvertFromConfig(ctx context.Context, other map[string]interface{}) (Provider, error) { + cc := convertProvider{ + ctx: ctx, + } if err := util.DecodeOther(other, &cc); err != nil { return nil, err @@ -33,7 +37,7 @@ func (o *convertProvider) FloatSetter(param string) (func(float64) error, error) return nil, fmt.Errorf("convert: invalid conversion: %s", o.Convert) } - set, err := NewIntSetterFromConfig(param, o.Set) + set, err := NewIntSetterFromConfig(o.ctx, param, o.Set) return func(val float64) error { return set(int64(val)) @@ -47,7 +51,7 @@ func (o *convertProvider) IntSetter(param string) (func(int64) error, error) { return nil, fmt.Errorf("convert: invalid conversion: %s", o.Convert) } - set, err := NewFloatSetterFromConfig(param, o.Set) + set, err := NewFloatSetterFromConfig(o.ctx, param, o.Set) return func(val int64) error { return set(float64(val)) diff --git a/provider/go.go b/provider/go.go index 7cf096e14d..ff76ac2b1b 100644 --- a/provider/go.go +++ b/provider/go.go @@ -1,6 +1,7 @@ package provider import ( + "context" "errors" "fmt" "reflect" @@ -19,11 +20,11 @@ type Go struct { } func init() { - registry.Add("go", NewGoProviderFromConfig) + registry.AddCtx("go", NewGoProviderFromConfig) } // NewGoProviderFromConfig creates a Go provider -func NewGoProviderFromConfig(other map[string]interface{}) (Provider, error) { +func NewGoProviderFromConfig(ctx context.Context, other map[string]interface{}) (Provider, error) { var cc struct { VM string Script string @@ -40,12 +41,12 @@ func NewGoProviderFromConfig(other map[string]interface{}) (Provider, error) { return nil, err } - in, err := configureInputs(cc.In) + in, err := configureInputs(ctx, cc.In) if err != nil { return nil, err } - out, err := configureOutputs(cc.Out) + out, err := configureOutputs(ctx, cc.Out) if err != nil { return nil, err } diff --git a/provider/helper.go b/provider/helper.go index 94d2e8aed2..41df2d41e2 100644 --- a/provider/helper.go +++ b/provider/helper.go @@ -1,6 +1,7 @@ package provider import ( + "context" "fmt" "github.com/evcc-io/evcc/api" @@ -31,3 +32,13 @@ func knownErrors(b []byte) error { return nil } } + +func contextLogger(ctx context.Context, log *util.Logger) *util.Logger { + if ctx != nil { + if l, ok := ctx.Value(util.CtxLogger).(*util.Logger); ok { + log = l + } + } + + return log +} diff --git a/provider/http.go b/provider/http.go index b47c0b02dc..9b3ddde81c 100644 --- a/provider/http.go +++ b/provider/http.go @@ -1,6 +1,7 @@ package provider import ( + "context" "fmt" "io" "math" @@ -32,7 +33,7 @@ type HTTP struct { } func init() { - registry.Add("http", NewHTTPProviderFromConfig) + registry.AddCtx("http", NewHTTPProviderFromConfig) } // Auth is the authorization config @@ -41,7 +42,7 @@ type Auth struct { } // NewHTTPProviderFromConfig creates a HTTP provider -func NewHTTPProviderFromConfig(other map[string]interface{}) (Provider, error) { +func NewHTTPProviderFromConfig(ctx context.Context, other map[string]interface{}) (Provider, error) { cc := struct { URI, Method string Headers map[string]string @@ -63,7 +64,7 @@ func NewHTTPProviderFromConfig(other map[string]interface{}) (Provider, error) { return nil, err } - log := util.NewLogger("http") + log := contextLogger(ctx, util.NewLogger("http")) http := NewHTTP( log, strings.ToUpper(cc.Method), diff --git a/provider/javascript.go b/provider/javascript.go index 67f0338d15..c36fc5946a 100644 --- a/provider/javascript.go +++ b/provider/javascript.go @@ -1,6 +1,8 @@ package provider import ( + "context" + "github.com/evcc-io/evcc/provider/javascript" "github.com/evcc-io/evcc/util" "github.com/robertkrimen/otto" @@ -16,11 +18,11 @@ type Javascript struct { } func init() { - registry.Add("js", NewJavascriptProviderFromConfig) + registry.AddCtx("js", NewJavascriptProviderFromConfig) } // NewJavascriptProviderFromConfig creates a Javascript provider -func NewJavascriptProviderFromConfig(other map[string]interface{}) (Provider, error) { +func NewJavascriptProviderFromConfig(ctx context.Context, other map[string]interface{}) (Provider, error) { var cc struct { VM string Script string @@ -37,12 +39,12 @@ func NewJavascriptProviderFromConfig(other map[string]interface{}) (Provider, er return nil, err } - in, err := configureInputs(cc.In) + in, err := configureInputs(ctx, cc.In) if err != nil { return nil, err } - out, err := configureOutputs(cc.Out) + out, err := configureOutputs(ctx, cc.Out) if err != nil { return nil, err } diff --git a/provider/map.go b/provider/map.go index 2e7140c9ec..ddc156ca03 100644 --- a/provider/map.go +++ b/provider/map.go @@ -1,22 +1,24 @@ package provider import ( + "context" "fmt" "github.com/evcc-io/evcc/util" ) type mapProvider struct { + ctx context.Context values map[int64]int64 set Config } func init() { - registry.Add("map", NewMapFromConfig) + registry.AddCtx("map", NewMapFromConfig) } // NewMapFromConfig creates type conversion provider -func NewMapFromConfig(other map[string]interface{}) (Provider, error) { +func NewMapFromConfig(ctx context.Context, other map[string]interface{}) (Provider, error) { var cc struct { Values map[int64]int64 Set Config @@ -31,6 +33,7 @@ func NewMapFromConfig(other map[string]interface{}) (Provider, error) { } o := &mapProvider{ + ctx: ctx, set: cc.Set, values: cc.Values, } @@ -41,7 +44,7 @@ func NewMapFromConfig(other map[string]interface{}) (Provider, error) { var _ SetIntProvider = (*mapProvider)(nil) func (o *mapProvider) IntSetter(param string) (func(int64) error, error) { - set, err := NewIntSetterFromConfig(param, o.set) + set, err := NewIntSetterFromConfig(o.ctx, param, o.set) return func(val int64) error { m, ok := o.values[val] diff --git a/provider/modbus.go b/provider/modbus.go index 51ac94b319..0dd97eeab9 100644 --- a/provider/modbus.go +++ b/provider/modbus.go @@ -2,6 +2,7 @@ package provider import ( "bytes" + "context" "fmt" "math" "strings" @@ -21,11 +22,11 @@ type Modbus struct { } func init() { - registry.Add("modbus", NewModbusFromConfig) + registry.AddCtx("modbus", NewModbusFromConfig) } // NewModbusFromConfig creates Modbus plugin -func NewModbusFromConfig(other map[string]interface{}) (Provider, error) { +func NewModbusFromConfig(ctx context.Context, other map[string]interface{}) (Provider, error) { cc := struct { modbus.Settings `mapstructure:",squash"` Register modbus.Register @@ -58,7 +59,7 @@ func NewModbusFromConfig(other map[string]interface{}) (Provider, error) { // set non-default connect delay conn.ConnectDelay(cc.ConnectDelay) - log := util.NewLogger("modbus") + log := contextLogger(ctx, util.NewLogger("modbus")) conn.Logger(log.TRACE) if err := cc.Register.Error(); err != nil { diff --git a/provider/mqtt.go b/provider/mqtt.go index df46465336..6f253da365 100644 --- a/provider/mqtt.go +++ b/provider/mqtt.go @@ -1,6 +1,7 @@ package provider import ( + "context" "time" "github.com/evcc-io/evcc/provider/mqtt" @@ -21,11 +22,11 @@ type Mqtt struct { } func init() { - registry.Add("mqtt", NewMqttFromConfig) + registry.AddCtx("mqtt", NewMqttFromConfig) } // NewMqttFromConfig creates Mqtt provider -func NewMqttFromConfig(other map[string]interface{}) (Provider, error) { +func NewMqttFromConfig(ctx context.Context, other map[string]interface{}) (Provider, error) { cc := struct { mqtt.Config `mapstructure:",squash"` Topic, Payload string // Payload only applies to setters @@ -41,7 +42,7 @@ func NewMqttFromConfig(other map[string]interface{}) (Provider, error) { return nil, err } - log := util.NewLogger("mqtt") + log := contextLogger(ctx, util.NewLogger("mqtt")) client, err := mqtt.RegisteredClientOrDefault(log, cc.Config) if err != nil { diff --git a/provider/openwb.go b/provider/openwb.go deleted file mode 100644 index 12b03e4b6d..0000000000 --- a/provider/openwb.go +++ /dev/null @@ -1,65 +0,0 @@ -package provider - -import ( - "github.com/evcc-io/evcc/api" - "github.com/evcc-io/evcc/util" -) - -// OpenWBStatus implements status conversion from openWB to api.Status -type OpenWBStatus struct { - plugged, charging func() (bool, error) -} - -// NewOpenWBStatusProviderFromConfig creates OpenWBStatus from given configuration -func NewOpenWBStatusProviderFromConfig(other map[string]interface{}) (func() (string, error), error) { - var cc struct { - Plugged, Charging Config - } - if err := util.DecodeOther(other, &cc); err != nil { - return nil, err - } - - plugged, err := NewBoolGetterFromConfig(cc.Plugged) - - var charging func() (bool, error) - if err == nil { - charging, err = NewBoolGetterFromConfig(cc.Charging) - } - - if err != nil { - return nil, err - } - - o := NewOpenWBStatusProvider(plugged, charging) - - return o.StringGetter, nil -} - -// NewOpenWBStatusProvider creates provider for OpenWB status converted from MQTT topics -func NewOpenWBStatusProvider(plugged, charging func() (bool, error)) *OpenWBStatus { - return &OpenWBStatus{ - plugged: plugged, - charging: charging, - } -} - -// StringGetter returns string from OpenWB charging/ plugged status -func (o *OpenWBStatus) StringGetter() (string, error) { - charging, err := o.charging() - if err != nil { - return "", err - } - if charging { - return string(api.StatusC), nil - } - - plugged, err := o.plugged() - if err != nil { - return "", err - } - if plugged { - return string(api.StatusB), nil - } - - return string(api.StatusA), nil -} diff --git a/provider/random.go b/provider/random.go index e749b582b9..769823fa93 100644 --- a/provider/random.go +++ b/provider/random.go @@ -1,6 +1,7 @@ package provider import ( + "context" "math" "math/rand/v2" @@ -8,15 +9,16 @@ import ( ) type randomProvider struct { + ctx context.Context set Config } func init() { - registry.Add("random", NewRandomFromConfig) + registry.AddCtx("random", NewRandomFromConfig) } // NewRandomFromConfig creates random provider -func NewRandomFromConfig(other map[string]interface{}) (Provider, error) { +func NewRandomFromConfig(ctx context.Context, other map[string]interface{}) (Provider, error) { var cc struct { Set Config } @@ -26,6 +28,7 @@ func NewRandomFromConfig(other map[string]interface{}) (Provider, error) { } o := &randomProvider{ + ctx: ctx, set: cc.Set, } @@ -35,7 +38,7 @@ func NewRandomFromConfig(other map[string]interface{}) (Provider, error) { var _ SetIntProvider = (*randomProvider)(nil) func (o *randomProvider) IntSetter(param string) (func(int64) error, error) { - set, err := NewIntSetterFromConfig(param, o.set) + set, err := NewIntSetterFromConfig(o.ctx, param, o.set) if err != nil { return nil, err } diff --git a/provider/sequence.go b/provider/sequence.go index 4e358d3e24..131b371c43 100644 --- a/provider/sequence.go +++ b/provider/sequence.go @@ -1,19 +1,22 @@ package provider import ( + "context" + "github.com/evcc-io/evcc/util" ) type sequenceProvider struct { + ctx context.Context set []Config } func init() { - registry.Add("sequence", NewSequenceFromConfig) + registry.AddCtx("sequence", NewSequenceFromConfig) } // NewSequenceFromConfig creates sequence provider -func NewSequenceFromConfig(other map[string]interface{}) (Provider, error) { +func NewSequenceFromConfig(ctx context.Context, other map[string]interface{}) (Provider, error) { var cc struct { Set []Config } @@ -23,6 +26,7 @@ func NewSequenceFromConfig(other map[string]interface{}) (Provider, error) { } o := &sequenceProvider{ + ctx: ctx, set: cc.Set, } @@ -34,7 +38,7 @@ var _ SetIntProvider = (*sequenceProvider)(nil) func (o *sequenceProvider) IntSetter(param string) (func(int64) error, error) { set := make([]func(int64) error, 0, len(o.set)) for _, cc := range o.set { - s, err := NewIntSetterFromConfig(param, cc) + s, err := NewIntSetterFromConfig(o.ctx, param, cc) if err != nil { return nil, err } @@ -56,7 +60,7 @@ var _ SetFloatProvider = (*sequenceProvider)(nil) func (o *sequenceProvider) FloatSetter(param string) (func(float64) error, error) { set := make([]func(float64) error, 0, len(o.set)) for _, cc := range o.set { - s, err := NewFloatSetterFromConfig(param, cc) + s, err := NewFloatSetterFromConfig(o.ctx, param, cc) if err != nil { return nil, err } @@ -78,7 +82,7 @@ var _ SetBoolProvider = (*sequenceProvider)(nil) func (o *sequenceProvider) BoolSetter(param string) (func(bool) error, error) { set := make([]func(bool) error, 0, len(o.set)) for _, cc := range o.set { - s, err := NewBoolSetterFromConfig(param, cc) + s, err := NewBoolSetterFromConfig(o.ctx, param, cc) if err != nil { return nil, err } diff --git a/provider/switch.go b/provider/switch.go index 3b7f5fc710..e420850cb8 100644 --- a/provider/switch.go +++ b/provider/switch.go @@ -1,6 +1,7 @@ package provider import ( + "context" "fmt" "strconv" @@ -13,16 +14,17 @@ type Case struct { } type switchProvider struct { + ctx context.Context cases []Case dflt *Config } func init() { - registry.Add("switch", NewSwitchFromConfig) + registry.AddCtx("switch", NewSwitchFromConfig) } // NewSwitchFromConfig creates switch provider -func NewSwitchFromConfig(other map[string]interface{}) (Provider, error) { +func NewSwitchFromConfig(ctx context.Context, other map[string]interface{}) (Provider, error) { var cc struct { Switch []Case Default *Config @@ -41,6 +43,7 @@ func NewSwitchFromConfig(other map[string]interface{}) (Provider, error) { } o := &switchProvider{ + ctx: ctx, cases: cc.Switch, dflt: cc.Default, } @@ -53,7 +56,7 @@ var _ SetIntProvider = (*switchProvider)(nil) func (o *switchProvider) IntSetter(param string) (func(int64) error, error) { set := make([]func(int64) error, 0, len(o.cases)) for _, cc := range o.cases { - s, err := NewIntSetterFromConfig(param, cc.Set) + s, err := NewIntSetterFromConfig(o.ctx, param, cc.Set) if err != nil { return nil, err } @@ -63,7 +66,7 @@ func (o *switchProvider) IntSetter(param string) (func(int64) error, error) { var dflt func(int64) error if o.dflt != nil { var err error - if dflt, err = NewIntSetterFromConfig(param, *o.dflt); err != nil { + if dflt, err = NewIntSetterFromConfig(o.ctx, param, *o.dflt); err != nil { return nil, err } } diff --git a/provider/transformation.go b/provider/transformation.go index da03d6a24b..8fd705e4e7 100644 --- a/provider/transformation.go +++ b/provider/transformation.go @@ -1,6 +1,7 @@ package provider import ( + "context" "fmt" "strings" ) @@ -20,7 +21,7 @@ type outputTransformation struct { function func(any) error } -func configureInputs(inConfig []transformationConfig) ([]inputTransformation, error) { +func configureInputs(ctx context.Context, inConfig []transformationConfig) ([]inputTransformation, error) { var in []inputTransformation for _, cc := range inConfig { @@ -28,28 +29,28 @@ func configureInputs(inConfig []transformationConfig) ([]inputTransformation, er switch strings.ToLower(cc.Type) { case "bool": - ff, err := NewBoolGetterFromConfig(cc.Config) + ff, err := NewBoolGetterFromConfig(ctx, cc.Config) if err != nil { return nil, fmt.Errorf("%s: %w", cc.Name, err) } f = func() (any, error) { return ff() } case "int": - ff, err := NewIntGetterFromConfig(cc.Config) + ff, err := NewIntGetterFromConfig(ctx, cc.Config) if err != nil { return nil, fmt.Errorf("%s: %w", cc.Name, err) } f = func() (any, error) { return ff() } case "float": - ff, err := NewFloatGetterFromConfig(cc.Config) + ff, err := NewFloatGetterFromConfig(ctx, cc.Config) if err != nil { return nil, fmt.Errorf("%s: %w", cc.Name, err) } f = func() (any, error) { return ff() } case "string": - ff, err := NewStringGetterFromConfig(cc.Config) + ff, err := NewStringGetterFromConfig(ctx, cc.Config) if err != nil { return nil, fmt.Errorf("%s: %w", cc.Name, err) } @@ -67,7 +68,7 @@ func configureInputs(inConfig []transformationConfig) ([]inputTransformation, er return in, nil } -func configureOutputs(outConfig []transformationConfig) ([]outputTransformation, error) { +func configureOutputs(ctx context.Context, outConfig []transformationConfig) ([]outputTransformation, error) { var out []outputTransformation for _, cc := range outConfig { @@ -75,7 +76,7 @@ func configureOutputs(outConfig []transformationConfig) ([]outputTransformation, switch strings.ToLower(cc.Type) { case "bool": - ff, err := NewBoolSetterFromConfig(cc.Name, cc.Config) + ff, err := NewBoolSetterFromConfig(ctx, cc.Name, cc.Config) if err != nil { return nil, fmt.Errorf("%s: %w", cc.Name, err) } @@ -85,7 +86,7 @@ func configureOutputs(outConfig []transformationConfig) ([]outputTransformation, } case "int": - ff, err := NewIntSetterFromConfig(cc.Name, cc.Config) + ff, err := NewIntSetterFromConfig(ctx, cc.Name, cc.Config) if err != nil { return nil, fmt.Errorf("%s: %w", cc.Name, err) } @@ -95,7 +96,7 @@ func configureOutputs(outConfig []transformationConfig) ([]outputTransformation, } case "float": - ff, err := NewFloatSetterFromConfig(cc.Name, cc.Config) + ff, err := NewFloatSetterFromConfig(ctx, cc.Name, cc.Config) if err != nil { return nil, fmt.Errorf("%s: %w", cc.Name, err) } @@ -105,7 +106,7 @@ func configureOutputs(outConfig []transformationConfig) ([]outputTransformation, } case "string": - ff, err := NewStringSetterFromConfig(cc.Name, cc.Config) + ff, err := NewStringSetterFromConfig(ctx, cc.Name, cc.Config) if err != nil { return nil, fmt.Errorf("%s: %w", cc.Name, err) } diff --git a/provider/watchdog.go b/provider/watchdog.go index 27f1757cdf..d7171a6c7c 100644 --- a/provider/watchdog.go +++ b/provider/watchdog.go @@ -11,6 +11,7 @@ import ( type watchdogProvider struct { mu sync.Mutex + ctx context.Context log *util.Logger reset *string set Config @@ -19,11 +20,11 @@ type watchdogProvider struct { } func init() { - registry.Add("watchdog", NewWatchDogFromConfig) + registry.AddCtx("watchdog", NewWatchDogFromConfig) } // NewWatchDogFromConfig creates watchDog provider -func NewWatchDogFromConfig(other map[string]interface{}) (Provider, error) { +func NewWatchDogFromConfig(ctx context.Context, other map[string]interface{}) (Provider, error) { var cc struct { Reset *string Set Config @@ -35,7 +36,8 @@ func NewWatchDogFromConfig(other map[string]interface{}) (Provider, error) { } o := &watchdogProvider{ - log: util.NewLogger("watchdog"), + ctx: ctx, + log: contextLogger(ctx, util.NewLogger("watchdog")), reset: cc.Reset, set: cc.Set, timeout: cc.Timeout, @@ -90,7 +92,7 @@ func setter[T comparable](o *watchdogProvider, set func(T) error, reset *T) func var _ SetIntProvider = (*watchdogProvider)(nil) func (o *watchdogProvider) IntSetter(param string) (func(int64) error, error) { - set, err := NewIntSetterFromConfig(param, o.set) + set, err := NewIntSetterFromConfig(o.ctx, param, o.set) if err != nil { return nil, err } @@ -110,7 +112,7 @@ func (o *watchdogProvider) IntSetter(param string) (func(int64) error, error) { var _ SetFloatProvider = (*watchdogProvider)(nil) func (o *watchdogProvider) FloatSetter(param string) (func(float64) error, error) { - set, err := NewFloatSetterFromConfig(param, o.set) + set, err := NewFloatSetterFromConfig(o.ctx, param, o.set) if err != nil { return nil, err } @@ -130,7 +132,7 @@ func (o *watchdogProvider) FloatSetter(param string) (func(float64) error, error var _ SetBoolProvider = (*watchdogProvider)(nil) func (o *watchdogProvider) BoolSetter(param string) (func(bool) error, error) { - set, err := NewBoolSetterFromConfig(param, o.set) + set, err := NewBoolSetterFromConfig(o.ctx, param, o.set) if err != nil { return nil, err } diff --git a/server/http_config_device_handler.go b/server/http_config_device_handler.go index ff9403f92d..91871d4b49 100644 --- a/server/http_config_device_handler.go +++ b/server/http_config_device_handler.go @@ -1,6 +1,7 @@ package server import ( + "context" "encoding/json" "errors" "net/http" @@ -190,8 +191,8 @@ func deviceStatusHandler(w http.ResponseWriter, r *http.Request) { jsonResult(w, testInstance(instance)) } -func newDevice[T any](class templates.Class, req map[string]any, newFromConf func(string, map[string]any) (T, error), h config.Handler[T]) (*config.Config, error) { - instance, err := newFromConf(typeTemplate, req) +func newDevice[T any](class templates.Class, req map[string]any, newFromConf newFromConfFunc[T], h config.Handler[T]) (*config.Config, error) { + instance, err := newFromConf(context.TODO(), typeTemplate, req) if err != nil { return nil, err } @@ -234,7 +235,7 @@ func newDeviceHandler(w http.ResponseWriter, r *http.Request) { conf, err = newDevice(class, req, vehicle.NewFromConfig, config.Vehicles()) case templates.Circuit: - conf, err = newDevice(class, req, func(_ string, other map[string]interface{}) (api.Circuit, error) { + conf, err = newDevice(class, req, func(_ context.Context, _ string, other map[string]interface{}) (api.Circuit, error) { return circuit.NewFromConfig(util.NewLogger("circuit"), other) }, config.Circuits()) } @@ -257,7 +258,7 @@ func newDeviceHandler(w http.ResponseWriter, r *http.Request) { jsonResult(w, res) } -func updateDevice[T any](id int, class templates.Class, conf map[string]any, newFromConf func(string, map[string]any) (T, error), h config.Handler[T]) error { +func updateDevice[T any](id int, class templates.Class, conf map[string]any, newFromConf newFromConfFunc[T], h config.Handler[T]) error { dev, instance, merged, err := deviceInstanceFromMergedConfig(id, class, conf, newFromConf, h) if err != nil { return err @@ -305,7 +306,7 @@ func updateDeviceHandler(w http.ResponseWriter, r *http.Request) { err = updateDevice(id, class, req, vehicle.NewFromConfig, config.Vehicles()) case templates.Circuit: - err = updateDevice(id, class, req, func(_ string, other map[string]interface{}) (api.Circuit, error) { + err = updateDevice(id, class, req, func(_ context.Context, _ string, other map[string]interface{}) (api.Circuit, error) { return circuit.NewFromConfig(util.NewLogger("circuit"), other) }, config.Circuits()) } @@ -392,9 +393,9 @@ func deleteDeviceHandler(w http.ResponseWriter, r *http.Request) { jsonResult(w, res) } -func testConfig[T any](id int, class templates.Class, conf map[string]any, newFromConf func(string, map[string]any) (T, error), h config.Handler[T]) (T, error) { +func testConfig[T any](id int, class templates.Class, conf map[string]any, newFromConf newFromConfFunc[T], h config.Handler[T]) (T, error) { if id == 0 { - return newFromConf(typeTemplate, conf) + return newFromConf(context.TODO(), typeTemplate, conf) } _, instance, _, err := deviceInstanceFromMergedConfig(id, class, conf, newFromConf, h) diff --git a/server/http_config_helper.go b/server/http_config_helper.go index 5fb19e73b8..1d16f2f28d 100644 --- a/server/http_config_helper.go +++ b/server/http_config_helper.go @@ -1,6 +1,7 @@ package server import ( + "context" "errors" "slices" "sync" @@ -18,6 +19,8 @@ const ( masked = "***" ) +type newFromConfFunc[T any] func(context.Context, string, map[string]any) (T, error) + var ( dirty bool mu sync.Mutex @@ -86,7 +89,7 @@ func mergeMasked(class templates.Class, conf, old map[string]any) (map[string]an return res, nil } -func deviceInstanceFromMergedConfig[T any](id int, class templates.Class, conf map[string]any, newFromConf func(string, map[string]any) (T, error), h config.Handler[T]) (config.Device[T], T, map[string]any, error) { +func deviceInstanceFromMergedConfig[T any](id int, class templates.Class, conf map[string]any, newFromConf newFromConfFunc[T], h config.Handler[T]) (config.Device[T], T, map[string]any, error) { var zero T dev, err := h.ByName(config.NameForID(id)) @@ -99,7 +102,7 @@ func deviceInstanceFromMergedConfig[T any](id int, class templates.Class, conf m return nil, zero, nil, err } - instance, err := newFromConf(typeTemplate, merged) + instance, err := newFromConf(context.TODO(), typeTemplate, merged) return dev, instance, merged, err } diff --git a/tariff/config.go b/tariff/config.go index a1cc7a945d..8cb18110a4 100644 --- a/tariff/config.go +++ b/tariff/config.go @@ -17,13 +17,13 @@ func Types() []string { } // NewFromConfig creates tariff from configuration -func NewFromConfig(typ string, other map[string]interface{}) (api.Tariff, error) { +func NewFromConfig(ctx context.Context, typ string, other map[string]interface{}) (api.Tariff, error) { factory, err := registry.Get(strings.ToLower(typ)) if err != nil { return nil, err } - v, err := factory(context.TODO(), other) + v, err := factory(ctx, other) if err != nil { err = fmt.Errorf("cannot create tariff type '%s': %w", typ, err) } diff --git a/tariff/tariff.go b/tariff/tariff.go index 1a1d77c18f..f29bc0abef 100644 --- a/tariff/tariff.go +++ b/tariff/tariff.go @@ -1,6 +1,7 @@ package tariff import ( + "context" "encoding/json" "fmt" "slices" @@ -24,10 +25,10 @@ type Tariff struct { var _ api.Tariff = (*Tariff)(nil) func init() { - registry.Add(api.Custom, NewConfigurableFromConfig) + registry.AddCtx(api.Custom, NewConfigurableFromConfig) } -func NewConfigurableFromConfig(other map[string]interface{}) (api.Tariff, error) { +func NewConfigurableFromConfig(ctx context.Context, other map[string]interface{}) (api.Tariff, error) { var cc struct { embed `mapstructure:",squash"` Price *provider.Config @@ -49,14 +50,14 @@ func NewConfigurableFromConfig(other map[string]interface{}) (api.Tariff, error) ) if cc.Price != nil { - priceG, err = provider.NewFloatGetterFromConfig(*cc.Price) + priceG, err = provider.NewFloatGetterFromConfig(ctx, *cc.Price) if err != nil { return nil, fmt.Errorf("price: %w", err) } } if cc.Forecast != nil { - forecastG, err = provider.NewStringGetterFromConfig(*cc.Forecast) + forecastG, err = provider.NewStringGetterFromConfig(ctx, *cc.Forecast) if err != nil { return nil, fmt.Errorf("forecast: %w", err) } diff --git a/tariff/template.go b/tariff/template.go index ec1512e1a3..bf9a44548f 100644 --- a/tariff/template.go +++ b/tariff/template.go @@ -1,19 +1,21 @@ package tariff import ( + "context" + "github.com/evcc-io/evcc/api" "github.com/evcc-io/evcc/util/templates" ) func init() { - registry.Add("template", NewTariffFromTemplateConfig) + registry.AddCtx("template", NewTariffFromTemplateConfig) } -func NewTariffFromTemplateConfig(other map[string]interface{}) (api.Tariff, error) { +func NewTariffFromTemplateConfig(ctx context.Context, other map[string]interface{}) (api.Tariff, error) { instance, err := templates.RenderInstance(templates.Tariff, other) if err != nil { return nil, err } - return NewFromConfig(instance.Type, instance.Other) + return NewFromConfig(ctx, instance.Type, instance.Other) } diff --git a/tariff/template_test.go b/tariff/template_test.go index 427d880452..53f8684b9f 100644 --- a/tariff/template_test.go +++ b/tariff/template_test.go @@ -1,6 +1,7 @@ package tariff import ( + "context" "testing" "github.com/evcc-io/evcc/util/templates" @@ -20,7 +21,7 @@ func TestTemplates(t *testing.T) { templates.TestClass(t, templates.Tariff, func(t *testing.T, values map[string]any) { t.Helper() - if _, err := NewFromConfig("template", values); err != nil && !test.Acceptable(err, acceptable) { + if _, err := NewFromConfig(context.TODO(), "template", values); err != nil && !test.Acceptable(err, acceptable) { t.Log(values) t.Error(err) } diff --git a/util/log_context.go b/util/log_context.go new file mode 100644 index 0000000000..6cdd4c7426 --- /dev/null +++ b/util/log_context.go @@ -0,0 +1,11 @@ +package util + +import ( + "context" +) + +var CtxLogger = struct{}{} + +func WithLogger(ctx context.Context, log *Logger) context.Context { + return context.WithValue(ctx, CtxLogger, log) +} diff --git a/vehicle/config.go b/vehicle/config.go index 2590013d0e..8af1df1745 100644 --- a/vehicle/config.go +++ b/vehicle/config.go @@ -24,7 +24,7 @@ func Types() []string { } // NewFromConfig creates vehicle from configuration -func NewFromConfig(typ string, other map[string]interface{}) (api.Vehicle, error) { +func NewFromConfig(ctx context.Context, typ string, other map[string]interface{}) (api.Vehicle, error) { var cc struct { Cloud bool Other map[string]interface{} `mapstructure:",remain"` @@ -44,7 +44,7 @@ func NewFromConfig(typ string, other map[string]interface{}) (api.Vehicle, error return nil, err } - v, err := factory(context.TODO(), cc.Other) + v, err := factory(ctx, cc.Other) if err != nil { err = fmt.Errorf("cannot create vehicle type '%s': %w", typ, err) } diff --git a/vehicle/template.go b/vehicle/template.go index e6399af0a9..69141f6df6 100644 --- a/vehicle/template.go +++ b/vehicle/template.go @@ -1,19 +1,21 @@ package vehicle import ( + "context" + "github.com/evcc-io/evcc/api" "github.com/evcc-io/evcc/util/templates" ) func init() { - registry.Add("template", NewVehicleFromTemplateConfig) + registry.AddCtx("template", NewVehicleFromTemplateConfig) } -func NewVehicleFromTemplateConfig(other map[string]interface{}) (api.Vehicle, error) { +func NewVehicleFromTemplateConfig(ctx context.Context, other map[string]interface{}) (api.Vehicle, error) { instance, err := templates.RenderInstance(templates.Vehicle, other) if err != nil { return nil, err } - return NewFromConfig(instance.Type, instance.Other) + return NewFromConfig(ctx, instance.Type, instance.Other) } diff --git a/vehicle/template_test.go b/vehicle/template_test.go index a9780a1c73..f542b0cc7c 100644 --- a/vehicle/template_test.go +++ b/vehicle/template_test.go @@ -1,6 +1,7 @@ package vehicle import ( + "context" "testing" "github.com/evcc-io/evcc/util/templates" @@ -22,16 +23,16 @@ var acceptable = []string{ "missing credentials", // Tesla "missing credentials id", // Tronity "missing access and/or refresh token, use `evcc token` to create", // Tesla - "login failed: code not found", //Polestar + "login failed: code not found", // Polestar "empty instance type- check for missing usage", // Merces - "invalid vehicle type: tesla", //Tesla + "invalid vehicle type: tesla", // Tesla } func TestTemplates(t *testing.T) { templates.TestClass(t, templates.Vehicle, func(t *testing.T, values map[string]any) { t.Helper() - if _, err := NewFromConfig("template", values); err != nil && !test.Acceptable(err, acceptable) { + if _, err := NewFromConfig(context.TODO(), "template", values); err != nil && !test.Acceptable(err, acceptable) { t.Log(values) t.Error(err) } diff --git a/vehicle/vehicle.go b/vehicle/vehicle.go index 4f7a2d858c..eaaa68a764 100644 --- a/vehicle/vehicle.go +++ b/vehicle/vehicle.go @@ -1,6 +1,7 @@ package vehicle import ( + "context" "fmt" "time" @@ -18,11 +19,11 @@ type Vehicle struct { } func init() { - registry.Add(api.Custom, NewConfigurableFromConfig) + registry.AddCtx(api.Custom, NewConfigurableFromConfig) } // NewConfigurableFromConfig creates a new Vehicle -func NewConfigurableFromConfig(other map[string]interface{}) (api.Vehicle, error) { +func NewConfigurableFromConfig(ctx context.Context, other map[string]interface{}) (api.Vehicle, error) { var cc struct { embed `mapstructure:",squash"` Soc provider.Config @@ -42,7 +43,7 @@ func NewConfigurableFromConfig(other map[string]interface{}) (api.Vehicle, error return nil, err } - socG, err := provider.NewFloatGetterFromConfig(cc.Soc) + socG, err := provider.NewFloatGetterFromConfig(ctx, cc.Soc) if err != nil { return nil, fmt.Errorf("soc: %w", err) } @@ -55,7 +56,7 @@ func NewConfigurableFromConfig(other map[string]interface{}) (api.Vehicle, error // decorate range var limitSoc func() (int64, error) if cc.LimitSoc != nil { - limitSoc, err = provider.NewIntGetterFromConfig(*cc.LimitSoc) + limitSoc, err = provider.NewIntGetterFromConfig(ctx, *cc.LimitSoc) if err != nil { return nil, fmt.Errorf("limitSoc: %w", err) } @@ -64,7 +65,7 @@ func NewConfigurableFromConfig(other map[string]interface{}) (api.Vehicle, error // decorate status var status func() (api.ChargeStatus, error) if cc.Status != nil { - get, err := provider.NewStringGetterFromConfig(*cc.Status) + get, err := provider.NewStringGetterFromConfig(ctx, *cc.Status) if err != nil { return nil, fmt.Errorf("status: %w", err) } @@ -80,7 +81,7 @@ func NewConfigurableFromConfig(other map[string]interface{}) (api.Vehicle, error // decorate range var rng func() (int64, error) if cc.Range != nil { - rng, err = provider.NewIntGetterFromConfig(*cc.Range) + rng, err = provider.NewIntGetterFromConfig(ctx, *cc.Range) if err != nil { return nil, fmt.Errorf("range: %w", err) } @@ -89,7 +90,7 @@ func NewConfigurableFromConfig(other map[string]interface{}) (api.Vehicle, error // decorate odometer var odo func() (float64, error) if cc.Odometer != nil { - odo, err = provider.NewFloatGetterFromConfig(*cc.Odometer) + odo, err = provider.NewFloatGetterFromConfig(ctx, *cc.Odometer) if err != nil { return nil, fmt.Errorf("odometer: %w", err) } @@ -98,7 +99,7 @@ func NewConfigurableFromConfig(other map[string]interface{}) (api.Vehicle, error // decorate climater var climater func() (bool, error) if cc.Climater != nil { - climater, err = provider.NewBoolGetterFromConfig(*cc.Climater) + climater, err = provider.NewBoolGetterFromConfig(ctx, *cc.Climater) if err != nil { return nil, fmt.Errorf("climater: %w", err) } @@ -107,7 +108,7 @@ func NewConfigurableFromConfig(other map[string]interface{}) (api.Vehicle, error // decorate maxCurrent var maxCurrent func(int64) error if cc.MaxCurrent != nil { - maxCurrent, err = provider.NewIntSetterFromConfig("maxcurrent", *cc.MaxCurrent) + maxCurrent, err = provider.NewIntSetterFromConfig(ctx, "maxcurrent", *cc.MaxCurrent) if err != nil { return nil, fmt.Errorf("maxCurrent: %w", err) } @@ -116,7 +117,7 @@ func NewConfigurableFromConfig(other map[string]interface{}) (api.Vehicle, error // decorate getMaxCurrent var getMaxCurrent func() (float64, error) if cc.GetMaxCurrent != nil { - getMaxCurrent, err = provider.NewFloatGetterFromConfig(*cc.GetMaxCurrent) + getMaxCurrent, err = provider.NewFloatGetterFromConfig(ctx, *cc.GetMaxCurrent) if err != nil { return nil, fmt.Errorf("getMaxCurrent: %w", err) } @@ -125,7 +126,7 @@ func NewConfigurableFromConfig(other map[string]interface{}) (api.Vehicle, error // decorate finishtime var finishTime func() (time.Time, error) if cc.FinishTime != nil { - stringG, err := provider.NewStringGetterFromConfig(*cc.FinishTime) + stringG, err := provider.NewStringGetterFromConfig(ctx, *cc.FinishTime) if err != nil { return nil, fmt.Errorf("finishTime: %w", err) } @@ -141,7 +142,7 @@ func NewConfigurableFromConfig(other map[string]interface{}) (api.Vehicle, error // decorate wakeup var wakeup func() error if cc.Wakeup != nil { - set, err := provider.NewBoolSetterFromConfig("wakeup", *cc.Wakeup) + set, err := provider.NewBoolSetterFromConfig(ctx, "wakeup", *cc.Wakeup) if err != nil { return nil, fmt.Errorf("wakeup: %w", err) } @@ -153,7 +154,7 @@ func NewConfigurableFromConfig(other map[string]interface{}) (api.Vehicle, error // decorate chargeEnable var chargeEnable func(bool) error if cc.ChargeEnable != nil { - chargeEnable, err = provider.NewBoolSetterFromConfig("chargeenable", *cc.ChargeEnable) + chargeEnable, err = provider.NewBoolSetterFromConfig(ctx, "chargeenable", *cc.ChargeEnable) if err != nil { return nil, fmt.Errorf("chargeEnable: %w", err) }