chore: use Go 1.26 (#26786)

This commit is contained in:
andig 2026-02-12 15:56:06 +01:00 • committed by GitHub
parent 88ecd6f152
commit 0ee6d787e1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
33 changed files with 96 additions and 122 deletions

View file

@ -266,9 +266,18 @@ jobs:
env:
TZ: Europe/Berlin
- uses: actions/upload-artifact@v6
- name: Upload Playwright Report
uses: actions/upload-artifact@v6
if: ${{ !cancelled() }}
with:
name: playwright-report
path: playwright-report/
retention-days: 14
- name: Upload Playwright Raw Test Results
uses: actions/upload-artifact@v6
if: failure()
with:
name: playwright-test-results
path: test-results/
retention-days: 2

View file

@ -1,6 +1,6 @@
version: "2"
run:
go: "1.25"
# run:
# go: "1.26"
linters:
default: none
enable:

View file

@ -20,7 +20,7 @@ func wait(err error, rc chan error) error {
close(rc)
}
if oe := new(ocpp.Error); errors.As(err, &oe) && oe.Code == ocppj.GenericError {
if oe, ok := errors.AsType[*ocpp.Error](err); ok && oe.Code == ocppj.GenericError {
err = api.ErrTimeout
}
}

View file

@ -247,7 +247,7 @@ var _ api.MeterEnergy = (*Smaevcharger)(nil)
// TotalEnergy implements the api.MeterEnergy interface
func (wb *Smaevcharger) TotalEnergy() (float64, error) {
res, err := wb.getMeasurement("Measurement.Metering.GridMs.TotWhIn")
if se := new(smaevcharger.ErrUnknownMeasurement); errors.As(err, &se) {
if _, ok := errors.AsType[*smaevcharger.ErrUnknownMeasurement](err); ok {
res, err = wb.getMeasurement("Measurement.Metering.GridMs.TotWhIn.ChaSta")
}
return res / 1e3, err
@ -258,7 +258,7 @@ var _ api.Meter = (*Smaevcharger)(nil)
// CurrentPower implements the api.Meter interface
func (wb *Smaevcharger) CurrentPower() (float64, error) {
res, err := wb.getMeasurement("Measurement.Metering.GridMs.TotWIn")
if se := new(smaevcharger.ErrUnknownMeasurement); errors.As(err, &se) {
if _, ok := errors.AsType[*smaevcharger.ErrUnknownMeasurement](err); ok {
res, err = wb.getMeasurement("Measurement.Metering.GridMs.TotWIn.ChaSta")
}
return res, err
@ -269,7 +269,7 @@ var _ api.ChargeRater = (*Smaevcharger)(nil)
// ChargedEnergy implements the api.ChargeRater interface
func (wb *Smaevcharger) ChargedEnergy() (float64, error) {
res, err := wb.getMeasurement("Measurement.ChaSess.WhIn")
if se := new(smaevcharger.ErrUnknownMeasurement); errors.As(err, &se) {
if _, ok := errors.AsType[*smaevcharger.ErrUnknownMeasurement](err); ok {
res, err = wb.getMeasurement("Measurement.Metering.GridMs.TotWhIn.ChaSta")
}
return res / 1e3, err

View file

@ -55,42 +55,23 @@ type typeStruct struct {
Functions []funcStruct
}
var a struct {
api.Meter
api.MeterEnergy
api.PhaseCurrents
api.PhaseVoltages
api.PhasePowers
api.MaxACPowerGetter
var dependents = make(map[string][]string)
api.PhaseSwitcher
api.PhaseGetter
func init() {
reflectTypes := map[reflect.Type][]reflect.Type{
reflect.TypeFor[api.Meter](): {reflect.TypeFor[api.MeterEnergy](), reflect.TypeFor[api.PhaseCurrents](), reflect.TypeFor[api.PhaseVoltages](), reflect.TypeFor[api.MaxACPowerGetter]()},
reflect.TypeFor[api.PhaseCurrents](): {reflect.TypeFor[api.PhasePowers]()}, // phase powers are only used to determine currents sign
reflect.TypeFor[api.PhaseSwitcher](): {reflect.TypeFor[api.PhaseGetter]()},
reflect.TypeFor[api.Battery](): {reflect.TypeFor[api.BatteryCapacity](), reflect.TypeFor[api.SocLimiter](), reflect.TypeFor[api.BatteryController](), reflect.TypeFor[api.BatterySocLimiter](), reflect.TypeFor[api.BatteryPowerLimiter]()},
reflect.TypeFor[api.ChargeState](): {reflect.TypeFor[api.ChargeController](), reflect.TypeFor[api.CurrentController]()},
reflect.TypeFor[api.CurrentController](): {reflect.TypeFor[api.CurrentGetter]()},
}
api.Battery
api.BatteryCapacity
api.SocLimiter // vehicles only
api.BatteryController
api.BatterySocLimiter
api.BatteryPowerLimiter
// vehicle
api.ChargeState
api.ChargeController
api.CurrentController
api.CurrentGetter
}
func typ(i any) string {
return reflect.TypeOf(i).Elem().String()
}
var dependents = map[string][]string{
typ(&a.Meter): {typ(&a.MeterEnergy), typ(&a.PhaseCurrents), typ(&a.PhaseVoltages), typ(&a.MaxACPowerGetter)},
typ(&a.PhaseCurrents): {typ(&a.PhasePowers)}, // phase powers are only used to determine currents sign
typ(&a.PhaseSwitcher): {typ(&a.PhaseGetter)},
typ(&a.Battery): {typ(&a.BatteryCapacity), typ(&a.SocLimiter), typ(&a.BatteryController), typ(&a.BatterySocLimiter), typ(&a.BatteryPowerLimiter)},
typ(&a.ChargeState): {typ(&a.ChargeController), typ(&a.CurrentController)},
typ(&a.CurrentController): {typ(&a.CurrentGetter)},
for typ, types := range reflectTypes {
dependents[typ.String()] = lo.Map(types, func(typ reflect.Type, _ int) string {
return typ.String()
})
}
}
// hasIntersection returns if the slices intersect

View file

@ -82,7 +82,7 @@ func (e ClassError) MarshalJSON() ([]byte, error) {
Error: e.err.Error(),
}
if de := new(DeviceError); errors.As(e.err, &de) {
if de, ok := errors.AsType[*DeviceError](e.err); ok {
res.Device = de.Name
}

View file

@ -81,17 +81,14 @@ func wrapFatalError(err error) error {
return nil
}
var opErr *net.OpError
var pathErr *os.PathError
switch {
case errors.As(err, &opErr):
if opErr.Op == "listen" && strings.Contains(opErr.Error(), "address already in use") {
if err2, ok := errors.AsType[*net.OpError](err); ok {
if err2.Op == "listen" && strings.Contains(err2.Error(), "address already in use") {
err = fmt.Errorf("could not open port- check that evcc is not already running (%w)", err)
}
}
case errors.As(err, &pathErr):
if pathErr.Op == "remove" && strings.Contains(pathErr.Error(), "operation not permitted") {
if err2, ok := errors.AsType[*os.PathError](err); ok {
if err2.Op == "remove" && strings.Contains(err2.Error(), "operation not permitted") {
err = fmt.Errorf("could not remove file- check that evcc is not already running (%w)", err)
}
}

View file

@ -98,7 +98,7 @@ func nameValid(name string) error {
func loadConfigFile(conf *globalconfig.All, checkDB bool) error {
if err := viper.ReadInConfig(); err != nil {
if !errors.As(err, &vpr.ConfigFileNotFoundError{}) {
if _, ok := errors.AsType[vpr.ConfigFileNotFoundError](err); !ok {
return fmt.Errorf("failed reading config file: %w", err)
}
}
@ -390,7 +390,7 @@ func vehicleInstance(cc config.Named) (api.Vehicle, error) {
}
if err != nil {
if ce := new(util.ConfigError); errors.As(err, &ce) {
if _, ok := errors.AsType[*util.ConfigError](err); ok {
return nil, err
}
@ -856,7 +856,7 @@ func tariffInstance(name string, conf config.Typed) (api.Tariff, error) {
instance, err := tariff.NewFromConfig(ctx, conf.Type, props)
if err != nil {
if ce := new(util.ConfigError); errors.As(err, &ce) {
if _, ok := errors.AsType[*util.ConfigError](err); ok {
return nil, err
}

View file

@ -8,7 +8,6 @@ import (
"github.com/evcc-io/evcc/core/session"
"github.com/evcc-io/evcc/core/wrapper"
"github.com/jinzhu/now"
"github.com/samber/lo"
)
func (lp *Loadpoint) chargeMeterTotal() float64 {
@ -77,12 +76,12 @@ func (lp *Loadpoint) stopSession() {
s.MeterStop = &meterStop
}
s.SolarPercentage = lo.ToPtr(lp.energyMetrics.SolarPercentage())
s.SolarPercentage = new(lp.energyMetrics.SolarPercentage())
s.Price = lp.energyMetrics.Price()
s.PricePerKWh = lp.energyMetrics.PricePerKWh()
s.Co2PerKWh = lp.energyMetrics.Co2PerKWh()
s.ChargedEnergy = lp.energyMetrics.TotalWh() / 1e3
s.ChargeDuration = lo.ToPtr(lp.chargeDuration.Abs())
s.ChargeDuration = new(lp.chargeDuration.Abs())
lp.db.Persist(s)
}

View file

@ -6,7 +6,6 @@ import (
"time"
"github.com/benbjohnson/clock"
"github.com/samber/lo"
)
type meterEnergy struct {
@ -34,7 +33,7 @@ func (m *meterEnergy) AccumulatedEnergy() float64 {
func (m *meterEnergy) AddMeterTotal(v float64) {
defer func() {
m.updated = m.clock.Now()
m.meter = lo.ToPtr(v)
m.meter = new(v)
}()
if m.meter == nil {

View file

@ -614,10 +614,10 @@ func (site *Site) updateBatteryMeters() []types.Measurement {
if m, ok := meter.(api.Battery); ok {
batSoc, err := soc.Guard(m.Soc())
if err == nil {
mm[i].Soc = lo.ToPtr(batSoc)
mm[i].Soc = new(batSoc)
if m, ok := m.(api.BatteryCapacity); ok {
mm[i].Capacity = lo.ToPtr(m.Capacity())
mm[i].Capacity = new(m.Capacity())
}
site.log.DEBUG.Printf("battery %d soc: %.0f%%", i+1, batSoc)
@ -627,7 +627,7 @@ func (site *Site) updateBatteryMeters() []types.Measurement {
}
_, controllable := meter.(api.BatteryController)
mm[i].Controllable = lo.ToPtr(controllable)
mm[i].Controllable = new(controllable)
}
batterySocAcc := lo.SumBy(mm, func(m types.Measurement) float64 {

View file

@ -115,7 +115,7 @@ func (site *Site) publishTariffs(greenShareHome float64, greenShareLoadpoints fl
// calculate adjusted solar rates
if solar := tariff.Rates(site.GetTariff(api.TariffUsageSolar)); len(solar) > 0 {
fc.Solar = lo.ToPtr(site.solarDetails(solar))
fc.Solar = new(site.solarDetails(solar))
}
site.publish(keys.Forecast, util.NewSharder(keys.Forecast, fc))
@ -169,7 +169,7 @@ func (site *Site) solarDetails(solar api.Rates) solarDetails {
const minEnergy = 0.5 // kWh
if produced+fcst > minEnergy {
res.Scale = lo.ToPtr(scale)
res.Scale = new(scale)
}
}

7
go.mod
View file

@ -1,6 +1,6 @@
module github.com/evcc-io/evcc
go 1.25.3
go 1.26.0
require (
dario.cat/mergo v1.0.2
@ -146,6 +146,7 @@ require (
github.com/clipperhouse/uax29/v2 v2.3.0 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.7 // indirect
github.com/creack/goselect v0.1.2 // indirect
github.com/creack/pty v1.1.18 // indirect
github.com/cronokirby/saferith v0.33.0 // indirect
github.com/cstockton/go-conv v1.0.0 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
@ -174,6 +175,7 @@ require (
github.com/golanguzb70/lrucache v1.2.0 // indirect
github.com/google/go-querystring v1.2.0 // indirect
github.com/google/jsonschema-go v0.4.2 // indirect
github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 // indirect
github.com/google/renameio/v2 v2.0.0 // indirect
github.com/gorilla/websocket v1.5.3 // indirect
github.com/gosimple/unidecode v1.0.1 // indirect
@ -207,7 +209,7 @@ require (
github.com/olekukonko/cat v0.0.0-20250911104152-50322a0618f6 // indirect
github.com/olekukonko/errors v1.1.0 // indirect
github.com/olekukonko/ll v0.1.4-0.20260115111900-9e59c2286df0 // indirect
github.com/onsi/ginkgo/v2 v2.13.0 // indirect
github.com/onsi/ginkgo/v2 v2.23.4 // indirect
github.com/pascaldekloe/name v1.0.1 // indirect
github.com/pelletier/go-toml/v2 v2.2.4 // indirect
github.com/perimeterx/marshmallow v1.1.5 // indirect
@ -222,6 +224,7 @@ require (
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
github.com/rickb777/date v1.21.1 // indirect
github.com/rickb777/plural v1.4.2 // indirect
github.com/rogpeppe/go-internal v1.14.1 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/sagikazarmark/locafero v0.12.0 // indirect
github.com/shopspring/decimal v1.4.0 // indirect

20
go.sum
View file

@ -150,8 +150,9 @@ github.com/cpuguy83/go-md2man/v2 v2.0.7/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6N
github.com/creack/goselect v0.1.2 h1:2DNy14+JPjRBgPzAd1thbQp4BSIihxcBf0IXhQXDRa0=
github.com/creack/goselect v0.1.2/go.mod h1:a/NhLweNvqIYMuxcMOuWY516Cimucms3DglDzQP3hKY=
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
github.com/creack/pty v1.1.17 h1:QeVUsEDNrLBW4tMgZHvxy18sKtr6VI492kBhUfhDJNI=
github.com/creack/pty v1.1.17/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY=
github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
github.com/cronokirby/saferith v0.33.0 h1:TgoQlfsD4LIwx71+ChfRcIpjkw+RPOapDEVxa+LhwLo=
github.com/cronokirby/saferith v0.33.0/go.mod h1:QKJhjoqUtBsXCAVEjw38mFqoi7DebT7kthcD7UzbnoA=
github.com/cstockton/go-conv v1.0.0 h1:zj/q/0MpQ/97XfiC9glWiohO8lhgR4TTnHYZifLTv6I=
@ -267,7 +268,8 @@ github.com/go-playground/validator/v10 v10.30.1/go.mod h1:oSuBIQzuJxL//3MelwSLD5
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
github.com/go-telegram/bot v1.18.0 h1:yQzv437DY42SYTPBY48RinAvwbmf1ox5QICskIYWCD8=
github.com/go-telegram/bot v1.18.0/go.mod h1:i2TRs7fXWIeaceF3z7KzsMt/he0TwkVC680mvdTFYeM=
github.com/go-test/deep v1.1.1 h1:0r/53hagsehfO4bzD2Pgr/+RgHqhmf+k1Bpse2cTu1U=
@ -330,8 +332,8 @@ github.com/google/go-querystring v1.2.0/go.mod h1:8IFJqpSRITyJ8QhQ13bmbeMBDfmeEJ
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/jsonschema-go v0.4.2 h1:tmrUohrwoLZZS/P3x7ex0WAVknEkBZM46iALbcqoRA8=
github.com/google/jsonschema-go v0.4.2/go.mod h1:r5quNTdLOYEz95Ru18zA0ydNbBuYoo9tgaYcxEYhJVE=
github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e h1:ijClszYn+mADRFY17kjQEVQ1XRhq2/JR1M3sGqeJoxs=
github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA=
github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 h1:BHT72Gu3keYf3ZEu2J0b1vyeLSOYI8bm5wbJM/8yDe8=
github.com/google/pprof v0.0.0-20250403155104-27863c87afa6/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/renameio/v2 v2.0.0 h1:UifI23ZTGY8Tt29JbYFiuyIU3eX+RNFtUwefq9qAhxg=
github.com/google/renameio/v2 v2.0.0/go.mod h1:BtmJXm5YlszgC+TD4HOEEUFgkJP3nLxehU6hfe7jRt4=
@ -574,8 +576,8 @@ github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
github.com/onsi/ginkgo/v2 v2.13.0 h1:0jY9lJquiL8fcf3M4LAXN5aMlS/b2BV86HFFPCPMgE4=
github.com/onsi/ginkgo/v2 v2.13.0/go.mod h1:TE309ZR8s5FsKKpuB1YAQYBzCaAfUgatB/xlT/ETL/o=
github.com/onsi/ginkgo/v2 v2.23.4 h1:ktYTpKJAVZnDT4VjxSbiBenUjmlL/5QkBEocaWXiQus=
github.com/onsi/ginkgo/v2 v2.23.4/go.mod h1:Bt66ApGPBFzHyR+JO10Zbt0Gsp4uWxu5mIOTusL46e8=
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/onsi/gomega v1.38.0 h1:c/WX+w8SLAinvuKKQFh77WEucCnPk4j2OTUr7lt7BeY=
github.com/onsi/gomega v1.38.0/go.mod h1:OcXcwId0b9QsE7Y49u+BTrL4IdKOBOKnD6VQNTJEB6o=
@ -666,8 +668,8 @@ github.com/robertkrimen/otto v0.5.1 h1:avDI4ToRk8k1hppLdYFTuuzND41n37vPGJU7547dG
github.com/robertkrimen/otto v0.5.1/go.mod h1:bS433I4Q9p+E5pZLu7r17vP6FkE6/wLxBdmKjoqJXF8=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
@ -799,6 +801,8 @@ go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJr
go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs=
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs=
go.uber.org/automaxprocs v1.6.0/go.mod h1:ifeIMSnPZuznNm6jmdzmU3/bfk01Fe2fotchwEFJ8r8=
go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=

View file

@ -15,7 +15,6 @@ import (
"github.com/evcc-io/evcc/plugin"
"github.com/evcc-io/evcc/server/eebus"
"github.com/evcc-io/evcc/util"
"github.com/samber/lo"
)
type EEBus struct {
@ -297,7 +296,7 @@ func (c *EEBus) updateSession(id *uint, typ smartgrid.Type, limit float64) error
if limit > 0 && *id == 0 {
var power *float64
if p := c.root.GetChargePower(); p > 0 {
power = lo.ToPtr(p)
power = new(p)
}
sid, err := smartgrid.StartManage(typ, power, limit)

View file

@ -13,7 +13,6 @@ import (
"github.com/evcc-io/evcc/hems/smartgrid"
"github.com/evcc-io/evcc/plugin"
"github.com/evcc-io/evcc/util"
"github.com/samber/lo"
)
type Relay struct {
@ -129,7 +128,7 @@ func (c *Relay) updateSession(limit float64) error {
if limit > 0 && c.smartgridID == 0 {
var power *float64
if p := c.root.GetChargePower(); p > 0 {
power = lo.ToPtr(p)
power = new(p)
}
sid, err := smartgrid.StartManage(smartgrid.Dim, power, limit)

View file

@ -201,7 +201,7 @@ func (m *Com) request(f func(any) (*http.Request, error), payload map[string]str
}
// re-login if request returns 405-error
if se := new(request.StatusError); errors.As(err, &se) && se.StatusCode() != http.StatusMethodNotAllowed {
if se, ok := errors.AsType[*request.StatusError](err); ok && se.StatusCode() != http.StatusMethodNotAllowed {
return err
}

View file

@ -92,8 +92,7 @@ func (p *Script) exec(script string) (string, error) {
if err != nil {
// use STDOUT if available
var ee *exec.ExitError
if errors.As(err, &ee) {
if ee, ok := errors.AsType[*exec.ExitError](err); ok {
s = strings.TrimSpace(string(ee.Stderr))
}

View file

@ -8,7 +8,6 @@ import (
"github.com/evcc-io/evcc/util"
inf2 "github.com/influxdata/influxdb-client-go/v2"
"github.com/influxdata/influxdb-client-go/v2/api/write"
"github.com/samber/lo"
"github.com/stretchr/testify/suite"
)
@ -60,7 +59,7 @@ func (w *influxSuite) TestNil() {
}
func (w *influxSuite) TestPointer() {
w.WriteParam(util.Param{Key: "foo", Val: lo.ToPtr(1)})
w.WriteParam(util.Param{Key: "foo", Val: new(1)})
w.Equal([]*write.Point{inf2.NewPoint("foo", nil, map[string]any{"value": 1}, w.clock.Now())}, w.p)
}
@ -89,7 +88,7 @@ func (w *influxSuite) TestSlice() {
}
func (w *influxSuite) TestMeasurement() {
w.WriteParam(util.Param{Key: "battery", Val: types.Measurement{Power: 1, Soc: lo.ToPtr(10.0)}})
w.WriteParam(util.Param{Key: "battery", Val: types.Measurement{Power: 1, Soc: new(10.0)}})
w.Equal([]*write.Point{
inf2.NewPoint("batteryPower", nil, map[string]any{"value": 1.0}, w.clock.Now()),
inf2.NewPoint("batterySoc", nil, map[string]any{"value": 10.0}, w.clock.Now()),
@ -98,8 +97,8 @@ func (w *influxSuite) TestMeasurement() {
func (w *influxSuite) TestSliceOfStruct() {
w.WriteParam(util.Param{Key: "grid", Val: []types.Measurement{
{Power: 1, Soc: lo.ToPtr(10.0)},
{Power: 2, Soc: lo.ToPtr(20.0)},
{Power: 1, Soc: new(10.0)},
{Power: 2, Soc: new(20.0)},
}})
w.Equal([]*write.Point{
inf2.NewPoint("gridPower", map[string]string{"id": "1"}, map[string]any{"value": 1.0}, w.clock.Now()),
@ -115,7 +114,7 @@ func (w *influxSuite) TestBatteryState() {
Soc: 20.0,
Devices: []types.Measurement{{
Power: 1,
Soc: lo.ToPtr(10.0),
Soc: new(10.0),
}},
}})
w.Equal([]*write.Point{

View file

@ -44,7 +44,7 @@ func (h *handler) logResult(op string, b []byte, err error) {
func (h *handler) exceptionToUint16AndError(op string, b []byte, err error) ([]uint16, error) {
h.logResult(op, b, err)
if me := new(gridx.Error); errors.As(err, &me) {
if me, ok := errors.AsType[*gridx.Error](err); ok {
err = mbserver.MapExceptionCodeToError(me.ExceptionCode)
}
@ -74,7 +74,7 @@ func coilsToBytes(b []bool) []byte {
func (h *handler) bytesToBoolResult(op string, qty uint16, b []byte, err error) ([]bool, error) {
h.logResult(op, b, err)
if me := new(gridx.Error); errors.As(err, &me) {
if me, ok := errors.AsType[*gridx.Error](err); ok {
err = mbserver.MapExceptionCodeToError(me.ExceptionCode)
}

View file

@ -14,7 +14,6 @@ import (
"github.com/evcc-io/evcc/core/vehicle"
"github.com/evcc-io/evcc/plugin/mqtt"
"github.com/evcc-io/evcc/util"
"github.com/samber/lo"
)
// MQTT is the MQTT server. It uses the MQTT client for publishing.
@ -232,7 +231,7 @@ func (m *MQTT) listenSiteSetters(topic string, site site.API) error {
{"batteryGridChargeLimit", floatPtrSetter(site.SetBatteryGridChargeLimit)},
{"batteryMode", ptrSetter(api.BatteryModeString, func(m *api.BatteryMode) error {
if m == nil {
m = lo.ToPtr(api.BatteryUnknown)
m = new(api.BatteryUnknown)
}
return site.SetBatteryModeExternal(*m)
})},

View file

@ -8,7 +8,6 @@ import (
"time"
"github.com/evcc-io/evcc/core/types"
"github.com/samber/lo"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/suite"
)
@ -108,7 +107,7 @@ func (suite *mqttSuite) TestMeasurement() {
suite.Equal(topics, suite.topics, "topics")
suite.Equal([]string{"", "", "0", "1", "", "", "", "", "", ""}, suite.payloads, "payloads")
suite.publish("test", false, types.Measurement{Controllable: lo.ToPtr(false)})
suite.publish("test", false, types.Measurement{Controllable: new(false)})
suite.Equal(topics, suite.topics, "topics")
suite.Equal([]string{"", "", "0", "", "", "", "", "", "", "false"}, suite.payloads, "payloads")
@ -128,7 +127,7 @@ func (suite *mqttSuite) TestBatteryState() {
Soc: 20.0,
Devices: []types.Measurement{{
Power: 1,
Soc: lo.ToPtr(10.0),
Soc: new(10.0),
}},
})

View file

@ -30,7 +30,7 @@ func bo() backoff.BackOff {
// backoffPermanentError returns a permanent error in case of HTTP 400
func backoffPermanentError(err error) error {
if se := new(request.StatusError); errors.As(err, &se) {
if se, ok := errors.AsType[*request.StatusError](err); ok {
if code := se.StatusCode(); code >= 400 && code <= 599 {
return backoff.Permanent(se)
}

View file

@ -18,11 +18,11 @@ func ErrorAsJson(err error) any {
Error: err.Error(),
}
if ae := new(api.ErrLoginRequired); errors.As(err, &ae) {
if ae, ok := errors.AsType[*api.ErrLoginRequired](err); ok {
res.LoginRequired = ae.ProviderAuth
}
if ue := new(api.ErrUrl); errors.As(err, &ue) {
if ue, ok := errors.AsType[*api.ErrUrl](err); ok {
res.URI = ue.URL().String()
}

View file

@ -11,7 +11,6 @@ import (
"time"
"github.com/Masterminds/sprig/v3"
"github.com/samber/lo"
)
var re = regexp.MustCompile(`(?i)\${(\w+)(:([a-zA-Z0-9%.]+))?}`)
@ -72,10 +71,10 @@ func ReplaceFormatted(s string, kv map[string]any) (string, error) {
match, key, format := m[0], m[1], m[3]
// find key and replacement value
var val *any
var val any
for k, v := range kv {
if strings.EqualFold(k, key) {
val = &v
val = v
break
}
}
@ -83,11 +82,11 @@ func ReplaceFormatted(s string, kv map[string]any) (string, error) {
if val == nil {
wanted = append(wanted, key)
format = "%s"
val = lo.ToPtr(any("?"))
val = "?"
}
// update all literal matches
new := FormatValue(format, *val)
new := FormatValue(format, val)
s = strings.ReplaceAll(s, match, new)
}

View file

@ -3,7 +3,6 @@ package modbus
import (
"testing"
"github.com/samber/lo"
"github.com/stretchr/testify/require"
)
@ -31,7 +30,7 @@ func TestSettingsProtocol(t *testing.T) {
res Protocol
}{
{Settings{UDP: true}, Udp},
{Settings{RTU: lo.ToPtr(true)}, Rtu},
{Settings{RTU: new(true)}, Rtu},
{Settings{Device: "foo"}, Rtu},
{Settings{URI: "foo"}, Tcp},
{Settings{}, Tcp},

View file

@ -60,7 +60,7 @@ func testAuth(other map[string]any) error {
_, err := auth.NewFromConfig(context.TODO(), cc.Type, params)
// ConfigError indicates invalid parameters in mapstructure decode
if ce := new(util.ConfigError); errors.As(err, &ce) {
if _, ok := errors.AsType[*util.ConfigError](err); ok {
return err
}

View file

@ -12,6 +12,7 @@ import (
"github.com/cenkalti/backoff/v4"
mqtt "github.com/eclipse/paho.mqtt.golang"
"github.com/eclipse/paho.mqtt.golang/packets"
"github.com/evcc-io/evcc/api"
"github.com/evcc-io/evcc/util"
"golang.org/x/oauth2"
)
@ -77,7 +78,7 @@ func (v *MqttConnector) run(ctx context.Context, ts oauth2.TokenSource) {
token, err := ts.Token()
if err != nil {
if !tokenError(err) {
if _, ok := errors.AsType[*api.ErrLoginRequired](err); !ok {
v.log.ERROR.Println(err)
}

View file

@ -1,9 +1,6 @@
package cardata
import (
"errors"
"github.com/evcc-io/evcc/api"
"golang.org/x/oauth2"
)
@ -27,8 +24,3 @@ func TokenExtra(t *oauth2.Token, key string) string {
}
return ""
}
func tokenError(err error) bool {
ae := new(api.ErrLoginRequired)
return errors.As(err, &ae)
}

View file

@ -52,7 +52,7 @@ func (v *Provider) deepRefresh() error {
if err == nil && res.ResponseStatus != "pending" {
err = fmt.Errorf("invalid response status: %s", res.ResponseStatus)
} else {
if se := new(request.StatusError); errors.As(err, &se) && se.StatusCode() == http.StatusForbidden {
if se, ok := errors.AsType[*request.StatusError](err); ok && se.StatusCode() == http.StatusForbidden {
err = nil
}
}

View file

@ -50,8 +50,7 @@ func NewProvider(api *kamereon.API, accountID, vin string, wakeupMode string, ca
_, err = api.WakeUp(accountID, vin)
// Check if default wakeup is unsupported
var se *request.StatusError
if errors.As(err, &se) && se.HasStatus(http.StatusForbidden, http.StatusNotFound, http.StatusBadGateway) {
if se, ok := errors.AsType[*request.StatusError](err); ok && se.HasStatus(http.StatusForbidden, http.StatusNotFound, http.StatusBadGateway) {
_, err = api.WakeUpMy24(accountID, vin)
}
}
@ -138,8 +137,7 @@ func (v *Provider) GetLimitSoc() (int64, error) {
res, err := v.socLevelsG()
// Check if endpoint is unavailable
var se *request.StatusError
if errors.As(err, &se) && se.HasStatus(http.StatusForbidden, http.StatusNotFound, http.StatusBadGateway) {
if se, ok := errors.AsType[*request.StatusError](err); ok && se.HasStatus(http.StatusForbidden, http.StatusNotFound, http.StatusBadGateway) {
return 0, api.ErrNotAvailable
}
@ -180,8 +178,7 @@ func (v *Provider) Climater() (bool, error) {
res, err := v.hvacG()
// Zoe Ph2, Megane e-tech
var se *request.StatusError
if errors.As(err, &se) && se.HasStatus(http.StatusForbidden, http.StatusNotFound, http.StatusBadGateway) {
if se, ok := errors.AsType[*request.StatusError](err); ok && se.HasStatus(http.StatusForbidden, http.StatusNotFound, http.StatusBadGateway) {
return false, api.ErrNotAvailable
}

View file

@ -203,7 +203,7 @@ func (v *Tronity) post(uri string) error {
}
// ignore HTTP 405
if se := new(request.StatusError); errors.As(err, &se) && se.StatusCode() == http.StatusMethodNotAllowed {
if se, ok := errors.AsType[*request.StatusError](err); ok && se.StatusCode() == http.StatusMethodNotAllowed {
err = nil
}

View file

@ -100,7 +100,7 @@ func (v *API) Status(vin string) (StatusResponse, error) {
err = v.DoJSON(req, &res)
}
if se := new(request.StatusError); errors.As(err, &se) {
if _, ok := errors.AsType[*request.StatusError](err); ok {
var rr RolesRights
rr, err = v.RolesRights(vin)