diff --git a/.golangci.yml b/.golangci.yml index 58250661c..38095ae27 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -1,10 +1,55 @@ run: go: "1.21" + issues: exclude: - .regActualCurrent. is unused - "`routeLogger` is unused" + linters-settings: staticcheck: checks: - "-SA1019" + +linters: + disable-all: true + enable: + - dogsled + - durationcheck + - exportloopref + - gci + - gofmt + - gofumpt + - goimports + - goprintffuncname + - govet + - importas + - ineffassign + - makezero + - misspell + - nolintlint + - rowserrcheck + - sqlclosecheck + - staticcheck + - tparallel + - typecheck + - unconvert + - unused + - wastedassign + - whitespace + + # fixme + # - bodyclose + # - exhaustive + # - gocritic + # - godot + # - gomoddirectives + # - nakedret + # - nilerr + # - noctx + # - prealloc + # - predeclared + # - revive + # - stylecheck + # - unparam + # - dupl diff --git a/charger/alphatec.go b/charger/alphatec.go index 5c1fd67ba..56fa6dee2 100644 --- a/charger/alphatec.go +++ b/charger/alphatec.go @@ -93,7 +93,7 @@ func NewAlphatec(uri, device, comset string, baudrate int, proto modbus.Protocol func (wb *Alphatec) setCurrent(current uint16) error { b := make([]byte, 2) - binary.BigEndian.PutUint16(b, uint16(current)) + binary.BigEndian.PutUint16(b, current) _, err := wb.conn.WriteMultipleRegisters(alphatecRegAmpsConfig, 1, b) diff --git a/charger/easee.go b/charger/easee.go index 597efaedd..a3d0e0378 100644 --- a/charger/easee.go +++ b/charger/easee.go @@ -356,7 +356,7 @@ func (c *Easee) ProductUpdate(i json.RawMessage) { } // OpMode changed FROM >1 ("car connected") TO 1/disconnected - stop ticker if channel exists - // channel may not exist regulary if the car was connected but charging never started + // channel may not exist regularly if the car was connected but charging never started if c.opMode != easee.ModeDisconnected && opMode == easee.ModeDisconnected && c.stopTicker != nil { close(c.stopTicker) c.stopTicker = nil diff --git a/charger/easee/signalr.go b/charger/easee/signalr.go index a326190f8..3197d0611 100644 --- a/charger/easee/signalr.go +++ b/charger/easee/signalr.go @@ -73,7 +73,7 @@ const ( LOCAL_PRE_AUTHORIZE_ENABLED ObservationID = 15 // Preauthorize with whitelist enabled. Readback on setting [event] [Boolean] LOCAL_AUTHORIZE_OFFLINE_ENABLED ObservationID = 16 // Allow offline charging for whitelisted RFID token. Readback on setting [event] [Boolean] ALLOW_OFFLINE_TX_FOR_UNKNOWN_ID ObservationID = 17 // Allow offline charging for all RFID tokens. Readback on setting [event] [Boolean] - ERRATIC_EVMAX_TOGGLES ObservationID = 18 // 0 == erratic checking disabled, otherwise the number of toggles between states Charging and Charging Complate that will trigger an error [Integer] + ERRATIC_EVMAX_TOGGLES ObservationID = 18 // 0 == erratic checking disabled, otherwise the number of toggles between states Charging and Charging Complete that will trigger an error [Integer] BACKPLATE_TYPE ObservationID = 19 // Readback on backplate type [Integer] SITE_STRUCTURE ObservationID = 20 // Site Structure [boot] [String] DETECTED_POWER_GRID_TYPE ObservationID = 21 // Detected power grid type according to PowerGridType table [boot] [Integer] @@ -94,7 +94,7 @@ const ( FORCED_THREE_PHASE_ON_ITWITH_GND_FAULT ObservationID = 39 // Default disabled. Must be set manually if grid type is indeed three phase IT [Boolean] LED_STRIP_BRIGHTNESS ObservationID = 40 // LED strip brightness, 0-100% [Integer] LOCAL_AUTHORIZATION_REQUIRED ObservationID = 41 // Local RFID authorization is required for charging [user options] [event] [Boolean] - AUTHORIZATION_REQUIRED ObservationID = 42 // Authorization is requried for charging [Boolean] + AUTHORIZATION_REQUIRED ObservationID = 42 // Authorization is required for charging [Boolean] REMOTE_START_REQUIRED ObservationID = 43 // Remote start required flag [event] [Boolean] SMART_BUTTON_ENABLED ObservationID = 44 // Smart button is enabled [Boolean] OFFLINE_CHARGING_MODE ObservationID = 45 // Charger behavior when offline [Integer] diff --git a/charger/fronius-wattpilot.go b/charger/fronius-wattpilot.go index 99c4dde34..6dc87aae9 100644 --- a/charger/fronius-wattpilot.go +++ b/charger/fronius-wattpilot.go @@ -36,12 +36,10 @@ func NewWattpilotFromConfig(other map[string]interface{}) (api.Charger, error) { } return NewWattpilot(cc.URI, cc.Password, cc.Cache) - } // NewWattpilot creates Wattpilot charger func NewWattpilot(uri, password string, cache time.Duration) (api.Charger, error) { - c := &Wattpilot{ api: wattpilot.New(uri, password), } diff --git a/charger/go-e/api.go b/charger/go-e/api.go index ea012ab75..53a6aa6cf 100644 --- a/charger/go-e/api.go +++ b/charger/go-e/api.go @@ -66,7 +66,7 @@ func (c *LocalAPI) upgradeV2() { err := c.response("api/status?filter=alw", &res) if err == nil { - c.uri = c.uri + "/api" + c.uri += "/api" } else { c.v2 = false } diff --git a/charger/huawei-ac.go b/charger/huawei-ac.go index 8e0d5d1a2..c5054e280 100644 --- a/charger/huawei-ac.go +++ b/charger/huawei-ac.go @@ -108,7 +108,7 @@ func (wb *HuaweiACCharger) Status() (api.ChargeStatus, error) { return api.StatusNone, err } - //ToDo: Real status + // ToDo: Real status switch u := binary.BigEndian.Uint16(b); u { case 0: return api.StatusA, nil diff --git a/charger/mcc.go b/charger/mcc.go index eaed1a4a5..4dc7cca05 100644 --- a/charger/mcc.go +++ b/charger/mcc.go @@ -119,7 +119,7 @@ func (mcc *MobileConnect) fetchToken(request *http.Request) error { } // login as the home user with the given password -func (mcc *MobileConnect) login(password string) error { +func (mcc *MobileConnect) login() error { uri := fmt.Sprintf("%s/%s", mcc.uri, mccAPILogin) data := url.Values{ @@ -170,7 +170,7 @@ func (mcc *MobileConnect) request(method, uri string) (*http.Request, error) { // do we need to login? if mcc.token == "" { - if err := mcc.login(mcc.password); err != nil { + if err := mcc.login(); err != nil { return nil, err } } diff --git a/charger/mcc_test.go b/charger/mcc_test.go index 1ef3fc06d..9720f6a7c 100644 --- a/charger/mcc_test.go +++ b/charger/mcc_test.go @@ -31,7 +31,7 @@ type apiResponse struct { // NewTestClient returns *http.Client with Transport replaced to avoid making real calls func NewTestClient(fn roundTripFunc) *http.Client { return &http.Client{ - Transport: roundTripFunc(fn), + Transport: fn, } } @@ -50,13 +50,13 @@ func NewTestMobileConnect(t *testing.T, responses []apiResponse) *MobileConnect // response string for the currently invoked call var responseString string for _, s := range responses { - if strings.Contains("/"+string(s.apiCall), req.URL.Path) { + if strings.Contains("/"+s.apiCall, req.URL.Path) { responseString = s.apiResponse } } return &http.Response{ - StatusCode: 200, + StatusCode: http.StatusOK, // Send response to be tested Body: io.NopCloser(bytes.NewBufferString(responseString)), // Must be set to non-nil value or it panics @@ -83,7 +83,7 @@ func TestMobileConnectLogin(t *testing.T) { t.Run(tc.name, func(t *testing.T) { mcc := NewTestMobileConnect(t, tc.responses) - if err := mcc.login(tc.password); (err != nil) != tc.wantErr { + if err := mcc.login(); (err != nil) != tc.wantErr { t.Errorf("MobileConnect.login() error = %v, wantErr %v", err, tc.wantErr) } }) @@ -263,13 +263,15 @@ func TestMobileConnectCurrentPower(t *testing.T) { "no data response", []apiResponse{ {mccAPIEnergy, "\"\"\n"}, - }, 0, false, + }, + 0, false, }, { "home plug - error response", []apiResponse{ {mccAPIEnergy, "\"{\\n \\\"L1\\\": {\\n \\\"Ampere\\\": 0,\\n \\\"Power\\\": 0,\\n \\\"Volts\\\": 246.60000000000002\\n },\\n \\\"L2\\\": {\\n \\\"Ampere\\\": 0,\\n \\\"Power\\\": 0,\\n \\\"Volts\\\": 16.800000000000001\\n },\\n \\\"L3\\\": {\\n \\\"Ampere\\\": 0,\\n \\\"Power\\\": 0,\\n \\\"Volts\\\": 16.300000000000001\\n }\\n}\\n\""}, - }, 0, false, + }, + 0, false, }, } for _, tc := range tests { @@ -300,19 +302,22 @@ func TestMobileConnectChargedEnergy(t *testing.T) { "valid response", []apiResponse{ {mccAPICurrentSession, "\"{\\n \\\"account\\\": \\\"PRIVATE\\\",\\n \\\"chargingRate\\\": 0,\\n \\\"chargingType\\\": \\\"AC\\\",\\n \\\"clockSrc\\\": \\\"NTP\\\",\\n \\\"costs\\\": 0,\\n \\\"currency\\\": \\\"\\\",\\n \\\"departTime\\\": \\\"\\\",\\n \\\"duration\\\": 30789,\\n \\\"endOfChargeTime\\\": \\\"\\\",\\n \\\"endSoc\\\": 0,\\n \\\"endTime\\\": \\\"\\\",\\n \\\"energySumKwh\\\": 18.832000000000001,\\n \\\"evChargingRatekW\\\": 0,\\n \\\"evTargetSoc\\\": -1,\\n \\\"evVasAvailability\\\": false,\\n \\\"pcid\\\": \\\"\\\",\\n \\\"powerRange\\\": 0,\\n \\\"selfEnergy\\\": 0,\\n \\\"sessionId\\\": 13,\\n \\\"soc\\\": -1,\\n \\\"solarEnergyShare\\\": 0,\\n \\\"startSoc\\\": 0,\\n \\\"startTime\\\": \\\"2020-04-15T10:07:22+02:00\\\",\\n \\\"totalRange\\\": 0,\\n \\\"vehicleBrand\\\": \\\"\\\",\\n \\\"vehicleModel\\\": \\\"\\\",\\n \\\"whitelist\\\": false\\n}\\n\""}, - }, 18.832000000000001, false, + }, + 18.832000000000001, false, }, { "no data response", []apiResponse{ {mccAPICurrentSession, "\"\"\n"}, - }, 0, false, + }, + 0, false, }, { "error response", []apiResponse{ {mccAPICurrentSession, "invalidjson"}, - }, 0, true, + }, + 0, true, }, } for _, tc := range tests { @@ -342,19 +347,22 @@ func TestMobileConnectChargingTime(t *testing.T) { "valid response", []apiResponse{ {mccAPICurrentSession, "\"{\\n \\\"account\\\": \\\"PRIVATE\\\",\\n \\\"chargingRate\\\": 0,\\n \\\"chargingType\\\": \\\"AC\\\",\\n \\\"clockSrc\\\": \\\"NTP\\\",\\n \\\"costs\\\": 0,\\n \\\"currency\\\": \\\"\\\",\\n \\\"departTime\\\": \\\"\\\",\\n \\\"duration\\\": 30789,\\n \\\"endOfChargeTime\\\": \\\"\\\",\\n \\\"endSoc\\\": 0,\\n \\\"endTime\\\": \\\"\\\",\\n \\\"energySumKwh\\\": 18.832000000000001,\\n \\\"evChargingRatekW\\\": 0,\\n \\\"evTargetSoc\\\": -1,\\n \\\"evVasAvailability\\\": false,\\n \\\"pcid\\\": \\\"\\\",\\n \\\"powerRange\\\": 0,\\n \\\"selfEnergy\\\": 0,\\n \\\"sessionId\\\": 13,\\n \\\"soc\\\": -1,\\n \\\"solarEnergyShare\\\": 0,\\n \\\"startSoc\\\": 0,\\n \\\"startTime\\\": \\\"2020-04-15T10:07:22+02:00\\\",\\n \\\"totalRange\\\": 0,\\n \\\"vehicleBrand\\\": \\\"\\\",\\n \\\"vehicleModel\\\": \\\"\\\",\\n \\\"whitelist\\\": false\\n}\\n\""}, - }, 30789 * time.Second, false, + }, + 30789 * time.Second, false, }, { "no data response", []apiResponse{ {mccAPICurrentSession, "\"\"\n"}, - }, 0, false, + }, + 0, false, }, { "error response", []apiResponse{ {mccAPICurrentSession, "invalidjson"}, - }, 0, true, + }, + 0, true, }, } for _, tc := range tests { @@ -399,13 +407,15 @@ func TestMobileConnectCurrents(t *testing.T) { "no data response", []apiResponse{ {mccAPIEnergy, "\"\"\n"}, - }, 0, 0, 0, false, + }, + 0, 0, 0, false, }, { "home plug - error response", []apiResponse{ {mccAPIEnergy, "\"{\\n \\\"L1\\\": {\\n \\\"Ampere\\\": 0,\\n \\\"Power\\\": 0,\\n \\\"Volts\\\": 246.60000000000002\\n },\\n \\\"L2\\\": {\\n \\\"Ampere\\\": 0,\\n \\\"Power\\\": 0,\\n \\\"Volts\\\": 16.800000000000001\\n },\\n \\\"L3\\\": {\\n \\\"Ampere\\\": 0,\\n \\\"Power\\\": 0,\\n \\\"Volts\\\": 16.300000000000001\\n }\\n}\\n\""}, - }, 0, 0, 0, false, + }, + 0, 0, 0, false, }, } for _, tc := range tests { diff --git a/charger/ocpp_test.go b/charger/ocpp_test.go index 8cd7c4467..6a22e9980 100644 --- a/charger/ocpp_test.go +++ b/charger/ocpp_test.go @@ -109,16 +109,16 @@ func (suite *ocppTestSuite) TestConnect() { // status _, err = c1.Status() - suite.NoError(err) + suite.Require().NoError(err) // power f, err := c1.currentPower() - suite.NoError(err) + suite.Require().NoError(err) suite.Equal(1e3, f) // energy f, err = c1.totalEnergy() - suite.NoError(err) + suite.Require().NoError(err) suite.Equal(1.2, f) } @@ -148,7 +148,7 @@ func (suite *ocppTestSuite) TestConnect() { res, err := cp1.StopTransaction(0, types.NewDateTime(suite.clock.Now()), expectedTxn) suite.Require().NoError(err) - suite.Equal(res.IdTagInfo.Status, types.AuthorizationStatusAccepted) + suite.Equal(types.AuthorizationStatusAccepted, res.IdTagInfo.Status) } // 2nd charge point - remote @@ -166,7 +166,7 @@ func (suite *ocppTestSuite) TestConnect() { // status _, err = c2.Status() - suite.NoError(err) + suite.Require().NoError(err) } // error on unconfigured 2nd charge point diff --git a/charger/pantabox.go b/charger/pantabox.go index 95dade7d8..4b94c969e 100644 --- a/charger/pantabox.go +++ b/charger/pantabox.go @@ -2,6 +2,7 @@ package charger import ( "fmt" + "strconv" "strings" "github.com/evcc-io/evcc/api" @@ -69,7 +70,7 @@ func (wb *Pantabox) Enabled() (bool, error) { // Enable implements the api.Charger interface func (wb *Pantabox) Enable(enable bool) error { - resp, err := wb.Post(wb.uri+"/charger/enable", request.PlainContent, strings.NewReader(fmt.Sprintf("%t", enable))) + resp, err := wb.Post(wb.uri+"/charger/enable", request.PlainContent, strings.NewReader(strconv.FormatBool(enable))) if err == nil { defer resp.Body.Close() @@ -83,7 +84,7 @@ func (wb *Pantabox) Enable(enable bool) error { // MaxCurrent implements the api.Charger interface func (wb *Pantabox) MaxCurrent(current int64) error { - resp, err := wb.Post(wb.uri+"/charger/current", request.PlainContent, strings.NewReader(fmt.Sprintf("%d", current))) + resp, err := wb.Post(wb.uri+"/charger/current", request.PlainContent, strings.NewReader(strconv.FormatInt(current, 10))) if err == nil { defer resp.Body.Close() diff --git a/charger/smaevcharger/types.go b/charger/smaevcharger/types.go index 235aa3f28..a9f3394cc 100644 --- a/charger/smaevcharger/types.go +++ b/charger/smaevcharger/types.go @@ -54,7 +54,7 @@ type SendParameter struct { Values []Value `json:"values"` } -// part of Paramter Send structure +// part of Parameter Send structure type Value struct { Timestamp string `json:"timestamp"` ChannelId string `json:"channelId"` diff --git a/charger/template_test.go b/charger/template_test.go index d33ff9efc..d77de3315 100644 --- a/charger/template_test.go +++ b/charger/template_test.go @@ -34,6 +34,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) { t.Log(values) t.Error(err) diff --git a/charger/twc3.go b/charger/twc3.go index 3577bfbb5..e383950ae 100644 --- a/charger/twc3.go +++ b/charger/twc3.go @@ -55,7 +55,7 @@ type Vitals struct { SessionEnergyWh float64 `json:"session_energy_wh"` // 22864.699 ConfigStatus int `json:"config_status"` // 5 EvseState int `json:"evse_state"` // 1 - CurrentAlerts []any `json:"current_alerts"` //[] + CurrentAlerts []any `json:"current_alerts"` // [] } // NewTwc3FromConfig creates a new vehicle diff --git a/cmd/configure/flow.go b/cmd/configure/flow.go index e1e7d75e4..9ae3b487d 100644 --- a/cmd/configure/flow.go +++ b/cmd/configure/flow.go @@ -163,7 +163,6 @@ func (c *CmdConfigure) configureLinkedTemplate(templateItem templates.Template, if c.askConfigFailureNextStep() { continue } - } else { c.configuration.AddDevice(deviceItem, category) c.processDeviceCapabilities(templateItem.Capabilities) diff --git a/cmd/configure/helper.go b/cmd/configure/helper.go index d3a33ef85..a269b412e 100644 --- a/cmd/configure/helper.go +++ b/cmd/configure/helper.go @@ -76,10 +76,8 @@ func (c *CmdConfigure) processDeviceValues(values map[string]interface{}, templa c.addedDeviceIndex-- return device, c.errDeviceNotValid } - } else { - if deviceCategory == DeviceCategoryCharger && testResult == DeviceTestResultValid { - device.ChargerHasMeter = true - } + } else if deviceCategory == DeviceCategoryCharger && testResult == DeviceTestResultValid { + device.ChargerHasMeter = true } templateItem.Params = append(templateItem.Params, templates.Param{Name: "name", Value: device.Name}) @@ -330,7 +328,7 @@ func (c *CmdConfigure) fetchElements(deviceCategory DeviceCategory) []templates. } } - sort.Slice(items[:], func(i, j int) bool { + sort.Slice(items, func(i, j int) bool { // sort generic templates to the bottom if items[i].Group != "" && items[j].Group == "" { return false @@ -376,7 +374,7 @@ func (c *CmdConfigure) processConfig(templateItem *templates.Template, deviceCat fmt.Println(c.localizedString("Config_Title")) fmt.Println() - c.processModbusConfig(templateItem, deviceCategory) + c.processModbusConfig(templateItem) return c.processParams(templateItem, deviceCategory) } @@ -485,7 +483,7 @@ func (c *CmdConfigure) processInputConfig(param templates.Param) string { // processModbusConfig adds default values from the modbus Param to the template // and handles user input for interface type selection -func (c *CmdConfigure) processModbusConfig(templateItem *templates.Template, deviceCategory DeviceCategory) { +func (c *CmdConfigure) processModbusConfig(templateItem *templates.Template) { var choices []string var choiceTypes []string diff --git a/cmd/configure/main.go b/cmd/configure/main.go index 31d095a1f..283584b9b 100644 --- a/cmd/configure/main.go +++ b/cmd/configure/main.go @@ -209,10 +209,8 @@ func (c *CmdConfigure) flowNewConfigFile() { // in case of permission error, we can't write to the file anyway if os.IsPermission(err) { fmt.Println(c.localizedString("File_Permissions", localizeMap{"FileName": filename})) - } else { - if c.askYesNo(c.localizedString("File_Exists", localizeMap{"FileName": filename})) { - break - } + } else if c.askYesNo(c.localizedString("File_Exists", localizeMap{"FileName": filename})) { + break } filename = c.askValue(question{ @@ -302,7 +300,6 @@ func (c *CmdConfigure) configureLoadpoints() { fmt.Println(c.localizedString("Loadpoint_Setup")) for { - loadpointTitle := c.askValue(question{ label: c.localizedString("Loadpoint_Title"), defaultValue: c.localizedString("Loadpoint_DefaultTitle"), diff --git a/cmd/detect/tasks/modbus.go b/cmd/detect/tasks/modbus.go index 68880de9f..ab4d45383 100644 --- a/cmd/detect/tasks/modbus.go +++ b/cmd/detect/tasks/modbus.go @@ -74,7 +74,7 @@ type ModbusHandler struct { Timeout time.Duration } -func (h *ModbusHandler) testRegister(log *util.Logger, conn gridx.Client) bool { +func (h *ModbusHandler) testRegister(_ *util.Logger, conn gridx.Client) bool { var bytes []byte var err error diff --git a/cmd/detect/tasks/tcp.go b/cmd/detect/tasks/tcp.go index 76d4fab56..c22152b99 100644 --- a/cmd/detect/tasks/tcp.go +++ b/cmd/detect/tasks/tcp.go @@ -35,7 +35,7 @@ type TcpHandler struct { dialer net.Dialer } -func (h *TcpHandler) Test(log *util.Logger, in ResultDetails) (res []ResultDetails) { +func (h *TcpHandler) Test(_ *util.Logger, in ResultDetails) (res []ResultDetails) { for _, port := range h.Ports { addr := net.JoinHostPort(in.IP, strconv.Itoa(port)) conn, err := h.dialer.Dial("tcp", addr) diff --git a/cmd/helper.go b/cmd/helper.go index 95f0f0758..e88ed51d0 100644 --- a/cmd/helper.go +++ b/cmd/helper.go @@ -57,7 +57,8 @@ func redact(src string) string { "token", "access", "refresh", "accesstoken", "refreshtoken", // tokens, including template variations "ain", "secret", "serial", "deviceid", "machineid", "idtag", // devices "app", "chats", "recipients", // push messaging - "vin"} // vehicles + "vin", // vehicles + } return regexp. MustCompile(fmt.Sprintf(`(?i)\b(%s)\b.*?:.*`, strings.Join(secrets, "|"))). ReplaceAllString(src, "$1: *****") diff --git a/cmd/root.go b/cmd/root.go index addb44c99..cb1cafeff 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -24,12 +24,11 @@ import ( "github.com/evcc-io/evcc/util/telemetry" "github.com/fatih/structs" "github.com/jeremywohl/flatten" - "golang.org/x/exp/maps" - _ "github.com/joho/godotenv/autoload" "github.com/prometheus/client_golang/prometheus/promhttp" "github.com/spf13/cobra" "github.com/spf13/viper" + "golang.org/x/exp/maps" ) const rebootDelay = 5 * time.Minute // delayed reboot on error diff --git a/cmd/setup.go b/cmd/setup.go index d76b2ed44..133c8084d 100644 --- a/cmd/setup.go +++ b/cmd/setup.go @@ -645,19 +645,14 @@ func configureSite(conf map[string]interface{}, loadpoints []*core.Loadpoint, ta } func configureLoadpoints(conf globalConfig) (loadpoints []*core.Loadpoint, err error) { - lpInterfaces, ok := viper.AllSettings()["loadpoints"].([]interface{}) - if !ok || len(lpInterfaces) == 0 { + if len(conf.Loadpoints) == 0 { return nil, errors.New("missing loadpoints") } - for id, lpcI := range lpInterfaces { - var lpc map[string]interface{} - if err := util.DecodeOther(lpcI, &lpc); err != nil { - return nil, fmt.Errorf("failed decoding loadpoint configuration: %w", err) - } - + for id, lpc := range conf.Loadpoints { log := util.NewLoggerWithLoadpoint("lp-"+strconv.Itoa(id+1), id+1) settings := &core.Settings{Key: "lp" + strconv.Itoa(id+1) + "."} + lp, err := core.NewLoadpointFromConfig(log, settings, lpc) if err != nil { return nil, fmt.Errorf("failed configuring loadpoint: %w", err) diff --git a/cmd/token_tronity.go b/cmd/token_tronity.go index f2e9956d5..affadb2a0 100644 --- a/cmd/token_tronity.go +++ b/cmd/token_tronity.go @@ -33,7 +33,6 @@ func tokenExchangeHandler(oc *oauth2.Config, state string, resC chan *oauth2.Tok token, err := oc.Exchange(ctx, code, oauth2.SetAuthURLParam("grant_type", "code"), // app ) - if err != nil { w.WriteHeader(http.StatusBadRequest) fmt.Fprintln(w, err) diff --git a/cmd/tools/decorate.go b/cmd/tools/decorate.go index 9b208d644..cff45133d 100644 --- a/cmd/tools/decorate.go +++ b/cmd/tools/decorate.go @@ -49,9 +49,7 @@ func generate(out io.Writer, packageName, functionName, baseType string, dynamic return dict, nil }, // contains checks if slice contains string - "contains": func(combo []string, typ string) bool { - return slices.Contains(combo, typ) - }, + "contains": slices.Contains[[]string, string], // ordered returns a slice of typeStructs ordered by dynamicType "ordered": func() []typeStruct { ordered := make([]typeStruct, 0) diff --git a/core/coordinator/api.go b/core/coordinator/api.go index 408480383..6bb196327 100644 --- a/core/coordinator/api.go +++ b/core/coordinator/api.go @@ -13,7 +13,7 @@ type API interface { // Owner returns the loadpoint that currently owns the vehicle Owner(api.Vehicle) loadpoint.API - // Aquire acquires the vehicle for the loadpoint and releases it at any other loadpoint + // Acquire acquires the vehicle for the loadpoint and releases it at any other loadpoint Acquire(api.Vehicle) // Release releases a vehicle from a loadpoint diff --git a/core/energy_metrics.go b/core/energy_metrics.go index 06d7e4013..68934ed43 100644 --- a/core/energy_metrics.go +++ b/core/energy_metrics.go @@ -3,7 +3,7 @@ package core // EnergyMetrics calculates stats about the charged energy and gives you details about price or co2s type EnergyMetrics struct { totalKWh float64 // Total amount of energy used (kWh) - solarKWh float64 // Self-produced energy energy (kWh) + solarKWh float64 // Self-produced energy (kWh) price *float64 // Total cost (Currency) co2 *float64 // Amount of emitted CO2 (gCO2eq) currentGreenShare float64 // Current share of solar energy of site (0-1) diff --git a/core/energy_metrics_test.go b/core/energy_metrics_test.go index 1395215ce..65ac760b7 100644 --- a/core/energy_metrics_test.go +++ b/core/energy_metrics_test.go @@ -28,72 +28,83 @@ func TestEnergyMetrics(t *testing.T) { totalWh, solarPercentage float64 price, pricePerKWh, co2PerKWh *float64 }{ - {"initial state", + { + "initial state", []tcStep{}, 0, 0, nil, nil, nil, }, - {"energy value", + { + "energy value", []tcStep{ {0.1, 0, nil, nil}, {0.2, 0, nil, nil}, }, 200, 0, nil, nil, nil, }, - {"ignore lower energy value", + { + "ignore lower energy value", []tcStep{ {0.2, 0, nil, nil}, {0.1, 0, nil, nil}, }, 200, 0, nil, nil, nil, }, - {"half solar", + { + "half solar", []tcStep{ {0.1, 1, nil, nil}, {0.2, 0, nil, nil}, }, 200, 50, nil, nil, nil, }, - {"only solar", + { + "only solar", []tcStep{ {0.1, 1, nil, nil}, {0.2, 1, nil, nil}, }, 200, 100, nil, nil, nil, }, - {"static price", + { + "static price", []tcStep{ {1, 0, f(0.5), nil}, }, 1000, 0, f(0.5), f(0.5), nil, }, - {"dynamic price", + { + "dynamic price", []tcStep{ {1, 0, f(1), nil}, {2, 0, f(0), nil}, }, 2000, 0, f(1), f(0.5), nil, }, - {"dynamic price", + { + "dynamic price", []tcStep{ {2, 0, f(1), nil}, {4, 0, f(0), nil}, }, 4000, 0, f(2), f(0.5), nil, }, - {"static co2", + { + "static co2", []tcStep{ {1, 0, nil, f(500)}, }, 1000, 0, nil, nil, f(500), }, - {"dynamic co2", + { + "dynamic co2", []tcStep{ {1, 0, nil, f(1000)}, {2, 0, nil, f(0)}, }, 2000, 0, nil, nil, f(500), }, - {"grid only, half, full solar, half, grid only", + { + "grid only, half, full solar, half, grid only", []tcStep{ {1, 0, f(2), f(200)}, {2, 0.5, f(1), f(50)}, @@ -106,8 +117,6 @@ func TestEnergyMetrics(t *testing.T) { } for _, tc := range tc { - //t.Logf("%+v", tc) - s := NewEnergyMetrics() for _, tc := range tc.steps { diff --git a/core/health.go b/core/health.go index 0440974ef..9aa030872 100644 --- a/core/health.go +++ b/core/health.go @@ -13,7 +13,7 @@ type Health struct { } // NewHealth creates new health checker -func NewHealth(timeout time.Duration) (health *Health) { +func NewHealth(timeout time.Duration) *Health { return &Health{timeout: timeout} } diff --git a/core/loadpoint.go b/core/loadpoint.go index 90045e6d3..e27aea841 100644 --- a/core/loadpoint.go +++ b/core/loadpoint.go @@ -9,6 +9,9 @@ import ( "sync" "time" + evbus "github.com/asaskevich/EventBus" + "github.com/avast/retry-go/v4" + "github.com/benbjohnson/clock" "github.com/evcc-io/evcc/api" "github.com/evcc-io/evcc/core/coordinator" "github.com/evcc-io/evcc/core/keys" @@ -23,10 +26,6 @@ import ( "github.com/evcc-io/evcc/util" "github.com/evcc-io/evcc/util/config" "github.com/evcc-io/evcc/util/telemetry" - - evbus "github.com/asaskevich/EventBus" - "github.com/avast/retry-go/v4" - "github.com/benbjohnson/clock" ) const ( diff --git a/core/loadpoint_phases_test.go b/core/loadpoint_phases_test.go index e6427da53..52fa6cdd6 100644 --- a/core/loadpoint_phases_test.go +++ b/core/loadpoint_phases_test.go @@ -123,6 +123,8 @@ func TestMaxActivePhases(t *testing.T) { } func testScale(t *testing.T, lp *Loadpoint, sitePower float64, direction string, tc testCase) { + t.Helper() + act := lp.activePhases() max := lp.maxActivePhases() diff --git a/core/loadpoint_session_test.go b/core/loadpoint_session_test.go index a5e7f9b35..2b2a4840f 100644 --- a/core/loadpoint_session_test.go +++ b/core/loadpoint_session_test.go @@ -11,15 +11,16 @@ import ( "github.com/evcc-io/evcc/util" "github.com/golang/mock/gomock" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestSession(t *testing.T) { var err error serverdb.Instance, err = serverdb.New("sqlite", ":memory:") - assert.NoError(t, err) + require.NoError(t, err) db, err := session.NewStore("foo", serverdb.Instance) - assert.NoError(t, err) + require.NoError(t, err) clock := clock.NewMock() @@ -68,7 +69,7 @@ func TestSession(t *testing.T) { assert.Equal(t, clock.Now(), lp.session.Finished) s, err := db.Sessions() - assert.NoError(t, err) + require.NoError(t, err) assert.Len(t, s, 1) t.Logf("session: %+v", s) @@ -82,7 +83,7 @@ func TestSession(t *testing.T) { assert.Equal(t, clock.Now(), lp.session.Finished) s, err = db.Sessions() - assert.NoError(t, err) + require.NoError(t, err) assert.Len(t, s, 1) t.Logf("session: %+v", s) } @@ -90,32 +91,32 @@ func TestSession(t *testing.T) { func TestCloseSessionsOnStartup_emptyDb(t *testing.T) { var err error serverdb.Instance, err = serverdb.New("sqlite", ":memory:") - assert.NoError(t, err) + require.NoError(t, err) db, err := session.NewStore("foo", serverdb.Instance) - assert.NoError(t, err) + require.NoError(t, err) // assert empty DB is no problem err = db.ClosePendingSessionsInHistory(1000) - assert.NoError(t, err) + require.NoError(t, err) } func TestCloseSessionsOnStartup(t *testing.T) { var err error serverdb.Instance, err = serverdb.New("sqlite", ":memory:") - assert.NoError(t, err) + require.NoError(t, err) db1, err := session.NewStore("foo", serverdb.Instance) - assert.NoError(t, err) + require.NoError(t, err) db2, err := session.NewStore("bar", serverdb.Instance) - assert.NoError(t, err) + require.NoError(t, err) clock := clock.NewMock() // test data, creates 6 sessions for each loadpoint, 3rd and 6th are "unfinished" - var sessions1 []*session.Session = createMockSessions(db1, clock) - var sessions2 []*session.Session = createMockSessions(db2, clock) + sessions1 := createMockSessions(db1, clock) + sessions2 := createMockSessions(db2, clock) // write interleaved for two loadpoints for index, session := range sessions1 { @@ -124,12 +125,12 @@ func TestCloseSessionsOnStartup(t *testing.T) { } err = db1.ClosePendingSessionsInHistory(1000) - assert.NoError(t, err) + require.NoError(t, err) // check fixed sessions for db1 var db1Sessions session.Sessions err = serverdb.Instance.Where("Loadpoint = ?", "foo").Order("ID").Find(&db1Sessions).Error - assert.NoError(t, err) + require.NoError(t, err) assert.Len(t, db1Sessions, 6) // check fixed history @@ -146,7 +147,7 @@ func TestCloseSessionsOnStartup(t *testing.T) { // ensure no side effects on loadpoint 2 data, i.e. data left unfixed var db2Sessions session.Sessions err = serverdb.Instance.Where("Loadpoint = ?", "bar").Order("ID").Find(&db2Sessions).Error - assert.NoError(t, err) + require.NoError(t, err) assert.Len(t, db2Sessions, 6) for i, s := range db2Sessions { @@ -163,8 +164,7 @@ func TestCloseSessionsOnStartup(t *testing.T) { func createMockSessions(db *session.DB, clock *clock.Mock) []*session.Session { var sessions []*session.Session for i := 1; i <= 6; i++ { - - var meter1Start float64 = float64(i * 10) + meter1Start := float64(i * 10) session := db.New(meter1Start) session.Created = clock.Now().Add(1 * time.Minute) @@ -175,7 +175,7 @@ func createMockSessions(db *session.DB, clock *clock.Mock) []*session.Session { } session.Finished = clock.Now().Add(2 * time.Minute) - meterStop := float64(meter1Start + 10) + meterStop := meter1Start + 10 session.MeterStop = &meterStop session.ChargedEnergy = 10 sessions = append(sessions, session) diff --git a/core/loadpoint_sync_test.go b/core/loadpoint_sync_test.go index 3d5df2196..26096c87b 100644 --- a/core/loadpoint_sync_test.go +++ b/core/loadpoint_sync_test.go @@ -8,6 +8,7 @@ import ( "github.com/evcc-io/evcc/util" "github.com/golang/mock/gomock" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestSyncCharger(t *testing.T) { @@ -42,7 +43,7 @@ func TestSyncCharger(t *testing.T) { enabled: tc.expected, } - assert.NoError(t, lp.syncCharger()) + require.NoError(t, lp.syncCharger()) assert.Equal(t, tc.corrected, lp.enabled) } } diff --git a/core/loadpoint_test.go b/core/loadpoint_test.go index 5305d6a15..9411da117 100644 --- a/core/loadpoint_test.go +++ b/core/loadpoint_test.go @@ -33,6 +33,8 @@ func (n *Null) ChargingTime() (time.Duration, error) { } func createChannels(t *testing.T) (chan util.Param, chan push.Event, chan *Loadpoint) { + t.Helper() + uiChan := make(chan util.Param) pushChan := make(chan push.Event) lpChan := make(chan *Loadpoint) @@ -67,6 +69,8 @@ func attachChannels(lp *Loadpoint, uiChan chan util.Param, pushChan chan push.Ev } func attachListeners(t *testing.T, lp *Loadpoint) { + t.Helper() + Voltage = 230 // V if charger, ok := lp.charger.(*api.MockCharger); ok && charger != nil { @@ -421,7 +425,7 @@ func TestDisableAndEnableAtTargetSoc(t *testing.T) { attachListeners(t, lp) lp.enabled = true - lp.chargeCurrent = float64(minA) + lp.chargeCurrent = minA lp.status = api.StatusC t.Log("charging below soc target") @@ -487,7 +491,7 @@ func TestSetModeAndSocAtDisconnect(t *testing.T) { attachListeners(t, lp) lp.enabled = true - lp.chargeCurrent = float64(minA) + lp.chargeCurrent = minA lp.mode = api.ModeNow t.Log("charging at min") @@ -512,6 +516,8 @@ func TestSetModeAndSocAtDisconnect(t *testing.T) { // cacheExpecter can be used to verify asynchronously written values from cache func cacheExpecter(t *testing.T, lp *Loadpoint) (*util.Cache, func(key string, val interface{})) { + t.Helper() + // attach cache for verifying values paramC := make(chan util.Param) lp.uiChan = paramC @@ -554,7 +560,7 @@ func TestChargedEnergyAtDisconnect(t *testing.T) { attachListeners(t, lp) lp.enabled = true - lp.chargeCurrent = float64(maxA) + lp.chargeCurrent = maxA lp.mode = api.ModeNow // attach cache for verifying values diff --git a/core/planner/planner_test.go b/core/planner/planner_test.go index f2de73551..61ceb906a 100644 --- a/core/planner/planner_test.go +++ b/core/planner/planner_test.go @@ -10,6 +10,7 @@ import ( "github.com/evcc-io/evcc/util" "github.com/golang/mock/gomock" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func rates(prices []float64, start time.Time, slotDuration time.Duration) api.Rates { @@ -43,13 +44,13 @@ func TestPlan(t *testing.T) { } rates, err := trf.Rates() - assert.NoError(t, err) + require.NoError(t, err) slices.SortStableFunc(rates, sortByCost) { plan := p.plan(rates, time.Hour, clock.Now()) - assert.Equal(t, 0, len(plan)) + assert.Empty(t, plan) } tc := []struct { @@ -81,7 +82,7 @@ func TestPlan(t *testing.T) { }, { "plan (30)30-0-60-0-0-0", - time.Duration(90 * time.Minute), + 90 * time.Minute, clock.Now(), clock.Now().Add(6 * time.Hour), clock.Now().Add(30 * time.Minute), @@ -105,7 +106,7 @@ func TestPlan(t *testing.T) { }, { "plan (30)30-0-60-0-0-0", - time.Duration(90 * time.Minute), + 90 * time.Minute, clock.Now().Add(30 * time.Minute), clock.Now().Add(6 * time.Hour), clock.Now().Add(30 * time.Minute), @@ -133,12 +134,12 @@ func TestNilTariff(t *testing.T) { } plan, err := p.Plan(time.Hour, clock.Now().Add(30*time.Minute)) - assert.NoError(t, err) - assert.True(t, !SlotAt(clock.Now(), plan).IsEmpty(), "should start past start time") + require.NoError(t, err) + assert.False(t, SlotAt(clock.Now(), plan).IsEmpty(), "should start past start time") plan, err = p.Plan(time.Hour, clock.Now().Add(-30*time.Minute)) - assert.NoError(t, err) - assert.False(t, !SlotAt(clock.Now(), plan).IsEmpty(), "should not start past target time") + require.NoError(t, err) + assert.True(t, SlotAt(clock.Now(), plan).IsEmpty(), "should not start past target time") } func TestFlatTariffTargetInThePast(t *testing.T) { @@ -155,12 +156,12 @@ func TestFlatTariffTargetInThePast(t *testing.T) { } plan, err := p.Plan(time.Hour, clock.Now().Add(30*time.Minute)) - assert.NoError(t, err) - assert.True(t, !SlotAt(clock.Now(), plan).IsEmpty(), "should start past start time") + require.NoError(t, err) + assert.False(t, SlotAt(clock.Now(), plan).IsEmpty(), "should start past start time") plan, err = p.Plan(time.Hour, clock.Now().Add(-30*time.Minute)) - assert.NoError(t, err) - assert.False(t, !SlotAt(clock.Now(), plan).IsEmpty(), "should not start past target time") + require.NoError(t, err) + assert.True(t, SlotAt(clock.Now(), plan).IsEmpty(), "should not start past target time") } func TestFlatTariffLongSlots(t *testing.T) { @@ -181,13 +182,13 @@ func TestFlatTariffLongSlots(t *testing.T) { // expect 00:00-01:00 UTC plan, err := p.Plan(time.Hour, clock.Now().Add(2*time.Hour)) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, api.Rate{Start: clock.Now(), End: clock.Now().Add(time.Hour)}, SlotAt(clock.Now(), plan)) assert.Equal(t, api.Rate{}, SlotAt(clock.Now().Add(time.Hour), plan)) // expect 00:00-01:00 UTC plan, err = p.Plan(time.Hour, clock.Now().Add(time.Hour)) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, api.Rate{Start: clock.Now(), End: clock.Now().Add(time.Hour)}, SlotAt(clock.Now(), plan)) } @@ -205,11 +206,11 @@ func TestTargetAfterKnownPrices(t *testing.T) { } plan, err := p.Plan(40*time.Minute, clock.Now().Add(2*time.Hour)) // charge efficiency does not allow to test with 1h - assert.NoError(t, err) + require.NoError(t, err) assert.False(t, !SlotAt(clock.Now(), plan).IsEmpty(), "should not start if car can be charged completely after known prices ") plan, err = p.Plan(2*time.Hour, clock.Now().Add(2*time.Hour)) - assert.NoError(t, err) + require.NoError(t, err) assert.True(t, !SlotAt(clock.Now(), plan).IsEmpty(), "should start if car can not be charged completely after known prices ") } @@ -227,10 +228,10 @@ func TestChargeAfterTargetTime(t *testing.T) { } plan, err := p.Plan(time.Hour, clock.Now()) - assert.NoError(t, err) - assert.False(t, !SlotAt(clock.Now(), plan).IsEmpty(), "should not start past target time") + require.NoError(t, err) + assert.True(t, SlotAt(clock.Now(), plan).IsEmpty(), "should not start past target time") plan, err = p.Plan(time.Hour, clock.Now().Add(-time.Hour)) - assert.NoError(t, err) - assert.False(t, !SlotAt(clock.Now(), plan).IsEmpty(), "should not start past target time") + require.NoError(t, err) + assert.True(t, SlotAt(clock.Now(), plan).IsEmpty(), "should not start past target time") } diff --git a/core/site_battery_test.go b/core/site_battery_test.go index 5e4623a85..859b78983 100644 --- a/core/site_battery_test.go +++ b/core/site_battery_test.go @@ -8,6 +8,7 @@ import ( "github.com/evcc-io/evcc/util" "github.com/golang/mock/gomock" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestDetermineBatteryMode(t *testing.T) { @@ -49,7 +50,6 @@ func TestDetermineBatteryMode(t *testing.T) { } func TestUpdateBatteryMode(t *testing.T) { - expBatMode := api.BatteryHold ctrl := gomock.NewController(t) @@ -70,6 +70,6 @@ func TestUpdateBatteryMode(t *testing.T) { } err := s.updateBatteryMode(expBatMode) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, expBatMode, s.GetBatteryMode()) } diff --git a/core/site_test.go b/core/site_test.go index 59f2422a3..539025d02 100644 --- a/core/site_test.go +++ b/core/site_test.go @@ -37,51 +37,81 @@ func TestGreenShare(t *testing.T) { grid, pv, battery, home, lp float64 greenShareTotal, greenShareHome, greenShareLoadpoints float64 }{ - {"half grid, half pv, green home", + { + "half grid, half pv, green home", 1000, 1000, 0, 1000, 1000, - 0.5, 1, 0}, - {"half grid, half pv, no home", + 0.5, 1, 0, + }, + { + "half grid, half pv, no home", 1000, 1000, 0, 0, 2000, - 0.5, 1, 0.5}, - {"half grid, half pv, no lp", + 0.5, 1, 0.5, + }, + { + "half grid, half pv, no lp", 2500, 2500, 0, 5000, 0, - 0.5, 0.5, 0}, - {"full pv", + 0.5, 0.5, 0, + }, + { + "full pv", 0, 5000, 0, 1000, 4000, - 1, 1, 1}, - {"full grid", + 1, 1, 1, + }, + { + "full grid", 5000, 0, 0, 1000, 4000, - 0, 0, 0}, - {"half grid, half battery, green home", + 0, 0, 0, + }, + { + "half grid, half battery, green home", 1000, 0, 1000, 1000, 1000, - 0.5, 1, 0}, - {"half grid, half battery, no home", + 0.5, 1, 0, + }, + { + "half grid, half battery, no home", 1000, 0, 1000, 0, 2000, - 0.5, 1, 0.5}, - {"half grid, half battery, no lp", + 0.5, 1, 0.5, + }, + { + "half grid, half battery, no lp", 1000, 0, 1000, 2000, 0, - 0.5, 0.5, 0}, - {"full pv, pv export", + 0.5, 0.5, 0, + }, + { + "full pv, pv export", -5000, 10000, 0, 1000, 4000, - 1, 1, 1}, - {"full pv, pv export, no lp", + 1, 1, 1, + }, + { + "full pv, pv export, no lp", -5000, 10000, 0, 5000, 0, - 1, 1, 1}, - {"full pv, pv export, battery charge", + 1, 1, 1, + }, + { + "full pv, pv export, battery charge", -2500, 10000, -2500, 1000, 4000, - 1, 1, 1}, - {"full grid, battery charge", + 1, 1, 1, + }, + { + "full grid, battery charge", 3000, 0, -1000, 1000, 1000, - 0, 0, 0}, - {"full grid, battery charge, no lp", + 0, 0, 0, + }, + { + "full grid, battery charge, no lp", 2000, 0, -1000, 1000, 0, - 0, 0, 0}, - {"half grid, half pv, battery charge, no lp", + 0, 0, 0, + }, + { + "half grid, half pv, battery charge, no lp", 1000, 1000, -1000, 1000, 0, - 1, 1, 0}, - {"half grid, half pv, battery charge, home, lp", + 1, 1, 0, + }, + { + "half grid, half pv, battery charge, home, lp", 1000, 1000, -1000, 500, 500, - 1, 1, 1}, + 1, 1, 1, + }, } for _, tc := range tc { diff --git a/core/soc/estimator.go b/core/soc/estimator.go index 0558ce238..61cd702a1 100644 --- a/core/soc/estimator.go +++ b/core/soc/estimator.go @@ -50,7 +50,7 @@ func (s *Estimator) Reset() { s.prevSoc = 0 s.prevChargedEnergy = 0 s.initialSoc = 0 - s.capacity = float64(s.vehicle.Capacity()) * 1e3 // cache to simplify debugging + s.capacity = s.vehicle.Capacity() * 1e3 // cache to simplify debugging s.virtualCapacity = s.capacity / ChargeEfficiency // initial capacity taking efficiency into account s.energyPerSocStep = s.virtualCapacity / 100 s.minChargePower = 1000 // default 1 kW diff --git a/core/timer_test.go b/core/timer_test.go index 253e295e4..32a227b65 100644 --- a/core/timer_test.go +++ b/core/timer_test.go @@ -17,14 +17,14 @@ func TestTimer(t *testing.T) { // start at.Start() clck.Add(10 * time.Second) - require.Equal(t, at.Expired(), false) + require.False(t, at.Expired()) // wait another 20 sec to expire the timer - this will reset the timer as well clck.Add(wakeupTimeout + 10*time.Second) - require.Equal(t, at.Expired(), true) + require.True(t, at.Expired()) // start at.Start() clck.Add(time.Minute) - require.Equal(t, at.Expired(), true) + require.True(t, at.Expired()) } diff --git a/hems/ocpp/ocpp.go b/hems/ocpp/ocpp.go index eed2651ab..dc9ce5bf8 100644 --- a/hems/ocpp/ocpp.go +++ b/hems/ocpp/ocpp.go @@ -11,7 +11,6 @@ import ( "github.com/evcc-io/evcc/hems/ocpp/profile" "github.com/evcc-io/evcc/util" "github.com/evcc-io/evcc/util/machine" - ocpp16 "github.com/lorenzodonini/ocpp-go/ocpp1.6" ocppcore "github.com/lorenzodonini/ocpp-go/ocpp1.6/core" "github.com/lorenzodonini/ocpp-go/ws" diff --git a/meter/bosch/api.go b/meter/bosch/api.go index 73ece5fd5..19cd8c4f1 100644 --- a/meter/bosch/api.go +++ b/meter/bosch/api.go @@ -84,7 +84,6 @@ func (c *API) updateValues() error { req, err := request.New(http.MethodPost, uri, strings.NewReader(data), map[string]string{ "Content-Type": "text/plain", }) - if err != nil { return err } diff --git a/meter/homematic/types_test.go b/meter/homematic/types_test.go index ac60e93c6..e7b797c92 100644 --- a/meter/homematic/types_test.go +++ b/meter/homematic/types_test.go @@ -6,17 +6,17 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) // Test MethodResponse response func TestUnmarshalMethodResponse(t *testing.T) { - { // BidCos-RF (Port 2001) getParamset measure-channel response test var res MethodResponse xmlstr := `IEC_ENERGY_COUNTER689.586500IEC_POWER166.390000` - assert.NoError(t, xml.Unmarshal([]byte(strings.Replace(string(xmlstr), "iso-8859-1", "UTF-8", 1)), &res)) + require.NoError(t, xml.Unmarshal([]byte(strings.Replace(xmlstr, "iso-8859-1", "UTF-8", 1)), &res)) assert.Equal(t, "IEC_ENERGY_COUNTER", res.Member[0].Name) assert.Equal(t, float64(689.586500), res.Member[0].Value.CCUFloat) @@ -27,7 +27,7 @@ func TestUnmarshalMethodResponse(t *testing.T) { var res MethodResponse xmlstr := `VOLTAGE230.6POWER_STATUS0ENERGY_COUNTER10888.7CURRENT_STATUS0FREQUENCY49.97ENERGY_COUNTER_OVERFLOW0POWER0.05VOLTAGE_STATUS0CURRENT0.0FREQUENCY_STATUS0` - assert.NoError(t, xml.Unmarshal([]byte(strings.Replace(string(xmlstr), "ISO-8859-1", "UTF-8", 1)), &res)) + require.NoError(t, xml.Unmarshal([]byte(strings.Replace(xmlstr, "ISO-8859-1", "UTF-8", 1)), &res)) assert.Equal(t, "ENERGY_COUNTER", res.Member[2].Name) assert.Equal(t, float64(10888.7), res.Member[2].Value.CCUFloat) @@ -40,10 +40,10 @@ func TestUnmarshalMethodResponse(t *testing.T) { var res MethodResponse xmlstr := `SECTION_STATUS0PROCESS0STATE1SECTION2` - assert.NoError(t, xml.Unmarshal([]byte(strings.Replace(string(xmlstr), "ISO-8859-1", "UTF-8", 1)), &res)) + require.NoError(t, xml.Unmarshal([]byte(strings.Replace(xmlstr, "ISO-8859-1", "UTF-8", 1)), &res)) assert.Equal(t, "STATE", res.Member[2].Name) - assert.Equal(t, true, res.Member[2].Value.CCUBool) + assert.True(t, res.Member[2].Value.CCUBool) } { @@ -51,12 +51,11 @@ func TestUnmarshalMethodResponse(t *testing.T) { var res MethodResponse xmlstr := `faultCode-2faultStringInvalid device` - assert.NoError(t, xml.Unmarshal([]byte(strings.Replace(string(xmlstr), "ISO-8859-1", "UTF-8", 1)), &res)) + require.NoError(t, xml.Unmarshal([]byte(strings.Replace(xmlstr, "ISO-8859-1", "UTF-8", 1)), &res)) assert.Equal(t, "faultCode", res.Fault[0].Name) assert.Equal(t, int64(-2), res.Fault[0].Value.CCUInt) assert.Equal(t, "faultString", res.Fault[1].Name) assert.Equal(t, "Invalid device", res.Fault[1].Value.CCUString) } - } diff --git a/meter/homewizard/types_test.go b/meter/homewizard/types_test.go index f9e548e66..9fa79816f 100644 --- a/meter/homewizard/types_test.go +++ b/meter/homewizard/types_test.go @@ -5,6 +5,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) // Test ApiResponse @@ -13,7 +14,7 @@ func TestUnmarshalApiResponse(t *testing.T) { var res ApiResponse jsonstr := `{"product_type": "HWE-SKT","product_name": "P1 Meter","serial": "3c39e7aabbcc","firmware_version": "2.11","api_version": "v1"}` - assert.NoError(t, json.Unmarshal([]byte(jsonstr), &res)) + require.NoError(t, json.Unmarshal([]byte(jsonstr), &res)) assert.Equal(t, "HWE-SKT", res.ProductType) assert.Equal(t, "v1", res.ApiVersion) @@ -26,9 +27,9 @@ func TestUnmarshalStateResponse(t *testing.T) { var res StateResponse jsonstr := `{"power_on": true,"switch_lock": false,"brightness": 255}` - assert.NoError(t, json.Unmarshal([]byte(jsonstr), &res)) + require.NoError(t, json.Unmarshal([]byte(jsonstr), &res)) - assert.Equal(t, true, res.PowerOn) + assert.True(t, res.PowerOn) } } @@ -38,7 +39,7 @@ func TestUnmarshalDataResponse(t *testing.T) { var res DataResponse jsonstr := `{"wifi_ssid": "My Wi-Fi","wifi_strength": 100,"total_power_import_t1_kwh": 30.511,"total_power_export_t1_kwh": 85.951,"active_power_w": 543,"active_power_l1_w": 676}` - assert.NoError(t, json.Unmarshal([]byte(jsonstr), &res)) + require.NoError(t, json.Unmarshal([]byte(jsonstr), &res)) assert.Equal(t, float64(30.511), res.TotalPowerImportT1kWh+res.TotalPowerImportT2kWh+res.TotalPowerImportT3kWh+res.TotalPowerImportT4kWh) assert.Equal(t, float64(543), res.ActivePowerW) diff --git a/meter/powerwall.go b/meter/powerwall.go index 2ec991432..9eb52076a 100644 --- a/meter/powerwall.go +++ b/meter/powerwall.go @@ -155,7 +155,7 @@ func NewPowerWall(uri, usage, user, password string, cache time.Duration, refres } batteryCapacity = func() float64 { - return float64(res.NominalFullPackEnergy) / 1e3 + return res.NominalFullPackEnergy / 1e3 } } @@ -212,7 +212,7 @@ func (m *PowerWall) batterySoc() (float64, error) { return 0, err } - return float64(res.Percentage), err + return res.Percentage, err } // decorate soc diff --git a/meter/rct.go b/meter/rct.go index ce3174408..e9f947f5d 100644 --- a/meter/rct.go +++ b/meter/rct.go @@ -9,7 +9,6 @@ import ( "github.com/cenkalti/backoff/v4" "github.com/evcc-io/evcc/api" "github.com/evcc-io/evcc/util" - "github.com/mlnoga/rct" ) diff --git a/meter/shelly/switch.go b/meter/shelly/switch.go index 6627ba0fd..20a4ebbeb 100644 --- a/meter/shelly/switch.go +++ b/meter/shelly/switch.go @@ -145,7 +145,7 @@ func (sh *Switch) TotalEnergy() (float64, error) { func gen1Energy(devicetype string, energy float64) float64 { // Gen 1 Shelly EM devices are providing Watt hours, Gen 1 Shelly PM devices are providing Watt minutes if !strings.Contains(devicetype, "EM") { - energy = energy / 60 + energy /= 60 } return energy } diff --git a/meter/shelly/types_test.go b/meter/shelly/types_test.go index 007347e14..d6ab28753 100644 --- a/meter/shelly/types_test.go +++ b/meter/shelly/types_test.go @@ -5,6 +5,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) // Test Gen1StatusResponse response @@ -14,7 +15,7 @@ func TestUnmarshalGen1StatusResponse(t *testing.T) { var res Gen1StatusResponse jsonstr := `{"wifi_sta":{"connected":true,"ssid":"XXXX-WLAN","ip":"192.168.178.XXX","rssi":-54},"cloud":{"enabled":false,"connected":false},"mqtt":{"connected":false},"time":"17:59","unixtime":1676134770,"serial":2437,"has_update":true,"mac":"84CCA8XXXXXXX","cfg_changed_cnt":1,"actions_stats":{"skipped":0},"relays":[{"ison":false,"has_timer":false,"timer_started":0,"timer_duration":0,"timer_remaining":0,"overpower":false,"source":"http"}],"meters":[{"power":4711.12,"overpower":0.00,"is_valid":true,"timestamp":1676138370,"counters":[0.000, 0.000, 0.000],"total":6472513}],"inputs":[{"input":0,"event":"","event_cnt":0}],"temperature":16.79,"overtemperature":false,"tmp":{"tC":16.79,"tF":62.22, "is_valid":true},"temperature_status":"Normal","ext_sensors":{},"ext_temperature":{},"ext_humidity":{},"update":{"status":"pending","has_update":true,"new_version":"20221108-153925/v1.12.1-1PM-fix-g2821131","old_version":"20220209-094317/v1.11.8-g8c7bb8d"},"ram_total":50456,"ram_free":37056,"fs_size":233681,"fs_free":149094,"uptime":17284290}` - assert.NoError(t, json.Unmarshal([]byte(jsonstr), &res)) + require.NoError(t, json.Unmarshal([]byte(jsonstr), &res)) assert.Equal(t, 107875.21666666666, gen1Energy("SHSW-PM", res.Meters[0].Total)) assert.Equal(t, 4711.12, res.Meters[0].Power) @@ -25,7 +26,7 @@ func TestUnmarshalGen1StatusResponse(t *testing.T) { var res Gen1StatusResponse jsonstr := `{"wifi_sta":{"connected":true,"ssid":"XXXX-WLAN","ip":"192.168.178.XXX","rssi":-57},"cloud":{"enabled":false,"connected":false},"mqtt":{"connected":false},"time":"19:25","unixtime":1676139913,"serial":959,"has_update":true,"mac":"E8DB8XXXXXX","cfg_changed_cnt":1,"actions_stats":{"skipped":0},"relays":[{"ison":false,"has_timer":false,"timer_started":0,"timer_duration":0,"timer_remaining":0,"source":"timer"}],"meters":[{"power":81.5,"is_valid":true}],"inputs":[{"input":0,"event":"","event_cnt":0}],"ext_sensors":{},"ext_temperature":{},"ext_humidity":{},"update":{"status":"pending","has_update":true,"new_version":"20221027-091427/v1.12.1-ga9117d3","old_version":"20211109-124958/v1.11.7-g682a0db"},"ram_total":50880,"ram_free":38796,"fs_size":233681,"fs_free":151102,"uptime":20319391}` - assert.NoError(t, json.Unmarshal([]byte(jsonstr), &res)) + require.NoError(t, json.Unmarshal([]byte(jsonstr), &res)) assert.Equal(t, 0.0, gen1Energy("SHSW-1", res.Meters[0].Total)) assert.Equal(t, 81.5, res.Meters[0].Power) @@ -36,7 +37,7 @@ func TestUnmarshalGen1StatusResponse(t *testing.T) { var res Gen1StatusResponse jsonstr := `{"wifi_sta":{"connected":true,"ssid":"XXXX","ip":"192.168.178.XXX","rssi":-55},"cloud":{"enabled":false,"connected":false},"mqtt":{"connected":false},"time":"11:16","unixtime":1676110566,"serial":21580,"has_update":false,"mac":"C45BXXXXX","cfg_changed_cnt":0,"actions_stats":{"skipped":0},"relays":[{"ison":false,"has_timer":false,"timer_started":0,"timer_duration":0,"timer_remaining":0,"overpower":false,"is_valid":true,"source":"input"}],"emeters":[{"power":-620.34,"reactive":714.48,"pf":-0.66,"voltage":235.68,"is_valid":true,"total":401472.9,"total_returned":653673.7},{"power":0.00,"reactive":0.00,"pf":0.00,"voltage":235.68,"is_valid":true,"total":173411.3,"total_returned":294.2}],"update":{"status":"idle","has_update":false,"new_version":"20221027-105518/v1.12.1-ga9117d3","old_version":"20221027-105518/v1.12.1-ga9117d3"},"ram_total":51072,"ram_free":35660,"fs_size":233681,"fs_free":156373,"uptime":2226140}` - assert.NoError(t, json.Unmarshal([]byte(jsonstr), &res)) + require.NoError(t, json.Unmarshal([]byte(jsonstr), &res)) assert.Equal(t, 401472.9, gen1Energy("SHEM", res.EMeters[0].Total)) assert.Equal(t, -620.34, res.EMeters[0].Power) @@ -49,7 +50,7 @@ func TestUnmarshalGen2StatusResponse(t *testing.T) { var res Gen2StatusResponse jsonstr := `{"ble":{},"cloud":{"connected":true},"eth":{"ip":null},"input:0":{"id":0,"state":false},"input:1":{"id":1,"state":false},"mqtt":{"connected":false},"switch:0":{"id":0, "source":"HTTP", "output":false, "apower":47.11, "voltage":232.0, "current":0.000, "pf":0.00, "aenergy":{"total":5.125,"by_minute":[0.000,0.000,0.000],"minute_ts":1675718520},"temperature":{"tC":25.3, "tF":77.5}},"sys":{"mac":"30C6F78BB4D8","restart_required":false,"time":"22:22","unixtime":1675718522,"uptime":45070,"ram_size":234204,"ram_free":137716,"fs_size":524288,"fs_free":172032,"cfg_rev":13,"kvs_rev":1,"schedule_rev":0,"webhook_rev":0,"available_updates":{"beta":{"version":"0.13.0-beta3"}}},"wifi":{"sta_ip":"192.168.178.64","status":"got ip","ssid":"***","rssi":-62},"ws":{"connected":false}}` - assert.NoError(t, json.Unmarshal([]byte(jsonstr), &res)) + require.NoError(t, json.Unmarshal([]byte(jsonstr), &res)) assert.Equal(t, 5.125, res.Switch0.Aenergy.Total) assert.Equal(t, 47.11, res.Switch0.Apower) diff --git a/meter/tapo/connection.go b/meter/tapo/connection.go index d4a0a43c9..d932ae2a4 100644 --- a/meter/tapo/connection.go +++ b/meter/tapo/connection.go @@ -100,7 +100,7 @@ func (c *Connection) ChargedEnergy() (float64, error) { } if int64(resp.TodayEnergy) > c.lasttodayenergy { - c.energy = c.energy + (int64(resp.TodayEnergy) - c.lasttodayenergy) + c.energy += (int64(resp.TodayEnergy) - c.lasttodayenergy) } c.lasttodayenergy = int64(resp.TodayEnergy) diff --git a/meter/tasmota/connection.go b/meter/tasmota/connection.go index b23215e3b..438e5626c 100644 --- a/meter/tasmota/connection.go +++ b/meter/tasmota/connection.go @@ -114,7 +114,6 @@ func (c *Connection) RelayExists() error { // Enable implements the api.Charger interface func (c *Connection) Enable(enable bool) error { for _, channel := range c.channels { - cmd := fmt.Sprintf("Power%d off", channel) if enable { cmd = fmt.Sprintf("Power%d on", channel) @@ -191,7 +190,6 @@ func (c *Connection) Enabled() (bool, error) { enabled = strings.ToUpper(res.StatusSTS.Power8) == "ON" default: enabled = strings.ToUpper(res.StatusSTS.Power) == "ON" || strings.ToUpper(res.StatusSTS.Power1) == "ON" - } } return enabled, nil diff --git a/meter/template_test.go b/meter/template_test.go index 7ace1b8ad..0cc4a2aad 100644 --- a/meter/template_test.go +++ b/meter/template_test.go @@ -31,6 +31,8 @@ var acceptable = []string{ 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) { t.Log(values) t.Error(err) diff --git a/meter/tplink/connection.go b/meter/tplink/connection.go index be24bf447..4cd553759 100644 --- a/meter/tplink/connection.go +++ b/meter/tplink/connection.go @@ -37,7 +37,7 @@ func (d *Connection) ExecCmd(cmd string, res interface{}) error { buf := bytes.NewBuffer([]byte{0, 0, 0, 0}) var key byte = 171 // initialization vector for i := 0; i < len(cmd); i++ { - key = key ^ cmd[i] + key ^= cmd[i] _ = buf.WriteByte(key) } diff --git a/packaging/toml.go b/packaging/toml.go index 0b1e19c93..555f54d44 100644 --- a/packaging/toml.go +++ b/packaging/toml.go @@ -67,7 +67,7 @@ func process(filepath string) error { fmt.Fprintln(out, sc.Text()) } - if err := os.WriteFile(filepath, []byte(out.String()), 0644); err != nil { + if err := os.WriteFile(filepath, []byte(out.String()), 0o644); err != nil { return fmt.Errorf("%s: %v", filepath, err) } diff --git a/provider/cache_test.go b/provider/cache_test.go index 059ae722a..b1c484733 100644 --- a/provider/cache_test.go +++ b/provider/cache_test.go @@ -36,7 +36,8 @@ func TestCachedGetter(t *testing.T) { expect := func(s struct { f float64 e error - }) { + }, + ) { f, e := c.Get() if f != s.f || e != s.e { t.Errorf("unexpected cache value: %f, %v\n", f, e) diff --git a/provider/mqtt/registry.go b/provider/mqtt/registry.go index 40163c65c..a24ff4452 100644 --- a/provider/mqtt/registry.go +++ b/provider/mqtt/registry.go @@ -37,7 +37,6 @@ func RegisteredClient(log *util.Logger, broker, user, password, clientID string, mu.Lock() defer mu.Unlock() client, err := registry.Get(key) - if err != nil { if clientID == "" { clientID = ClientID() diff --git a/provider/mqtt_handler.go b/provider/mqtt_handler.go index e9f673dc3..459734851 100644 --- a/provider/mqtt_handler.go +++ b/provider/mqtt_handler.go @@ -60,7 +60,7 @@ func (h *msgHandler) stringGetter() (string, error) { return "", err } - return string(v), nil + return v, nil } func (h *msgHandler) boolGetter() (bool, error) { diff --git a/provider/pipeline/pipeline_test.go b/provider/pipeline/pipeline_test.go index ba27c68c1..56557f47f 100644 --- a/provider/pipeline/pipeline_test.go +++ b/provider/pipeline/pipeline_test.go @@ -31,7 +31,6 @@ func TestRegexDefault(t *testing.T) { func TestJq(t *testing.T) { for _, uuid := range []string{"a8232ee0-a4ab-11ec-8d36-211f6b082dc8", "08232ee0-a4ab-11ec-8d36-211f6b082dc8"} { - p, err := new(Pipeline).WithJq(fmt.Sprintf(`.data[] | select(.uuid=="%s") | .tuples[0][1]`, uuid)) require.NoError(t, err) diff --git a/server/db/settings/settings_test.go b/server/db/settings/settings_test.go index 770e5b7c5..99657920a 100644 --- a/server/db/settings/settings_test.go +++ b/server/db/settings/settings_test.go @@ -5,13 +5,14 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestString(t *testing.T) { v := "foo" SetString("string", v) res, err := String("string") - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, v, res) } @@ -19,7 +20,7 @@ func TestInt(t *testing.T) { v := int64(math.MaxInt64) SetInt("int64", v) res, err := Int("int64") - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, v, res) } @@ -27,6 +28,6 @@ func TestFloat(t *testing.T) { v := 3.141 SetFloat("float64", v) res, err := Float("float64") - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, v, res) } diff --git a/server/influxdb_test.go b/server/influxdb_test.go index ef03ac949..435483f93 100644 --- a/server/influxdb_test.go +++ b/server/influxdb_test.go @@ -26,7 +26,7 @@ func (w *influxWriter) WritePoint(p *write.Point) { } func (w *influxWriter) finish() { - assert.Equal(w.t, len(w.p), w.idx, "not enough points") + assert.Len(w.t, w.p, w.idx, "not enough points") } func TestInfluxTypes(t *testing.T) { diff --git a/server/modbus/proxy_test.go b/server/modbus/proxy_test.go index 588584e66..5bd72f7c1 100644 --- a/server/modbus/proxy_test.go +++ b/server/modbus/proxy_test.go @@ -12,23 +12,24 @@ import ( "github.com/evcc-io/evcc/util" "github.com/evcc-io/evcc/util/modbus" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestConcurrentRead(t *testing.T) { l, err := net.Listen("tcp", "localhost:0") - assert.NoError(t, err) + require.NoError(t, err) defer l.Close() srv, _ := mbserver.New(&echoHandler{ id: 0, RequestHandler: new(mbserver.DummyHandler), }) - assert.NoError(t, srv.Start(l)) + require.NoError(t, srv.Start(l)) defer func() { _ = srv.Stop() }() // client conn, err := modbus.NewConnection(l.Addr().String(), "", "", 0, modbus.Tcp, 1) - assert.NoError(t, err) + require.NoError(t, err) var wg sync.WaitGroup @@ -41,7 +42,7 @@ func TestConcurrentRead(t *testing.T) { qty := uint16(rand.Int31n(32) + 1) b, err := conn.ReadInputRegistersWithSlave(uint8(id), addr, qty) - assert.NoError(t, err) + require.NoError(t, err) if err == nil { for u := uint16(0); u < qty; u++ { @@ -62,56 +63,56 @@ func TestConcurrentRead(t *testing.T) { func TestReadCoils(t *testing.T) { // downstream server l, err := net.Listen("tcp", "localhost:0") - assert.NoError(t, err) + require.NoError(t, err) defer l.Close() srv, _ := mbserver.New(&echoHandler{ id: 0, RequestHandler: new(mbserver.DummyHandler), }) - assert.NoError(t, srv.Start(l)) + require.NoError(t, srv.Start(l)) defer func() { _ = srv.Stop() }() // proxy server pl, err := net.Listen("tcp", "localhost:0") - assert.NoError(t, err) + require.NoError(t, err) defer pl.Close() downstreamConn, err := modbus.NewConnection(l.Addr().String(), "", "", 0, modbus.Tcp, 1) - assert.NoError(t, err) + require.NoError(t, err) proxy, _ := mbserver.New(&handler{ log: util.NewLogger("foo"), conn: downstreamConn, }) - assert.NoError(t, proxy.Start(pl)) + require.NoError(t, proxy.Start(pl)) defer func() { _ = proxy.Stop() }() // test client { conn, err := modbus.NewConnection(pl.Addr().String(), "", "", 0, modbus.Tcp, 1) - assert.NoError(t, err) + require.NoError(t, err) { // read b, err := conn.ReadCoilsWithSlave(1, 1, 1) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, []byte{0x01}, b) b, err = conn.ReadCoilsWithSlave(1, 1, 2) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, []byte{0x03}, b) b, err = conn.ReadCoilsWithSlave(1, 1, 9) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, []byte{0xFF, 0x01}, b) } { // write b, err := conn.WriteSingleCoilWithSlave(1, 1, 0xFF00) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, []byte{0xFF, 0x00}, b) b, err = conn.WriteMultipleCoilsWithSlave(1, 1, 9, []byte{0xFF, 0x01}) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, []byte{0x00, 0x09}, b) } } diff --git a/server/mqtt.go b/server/mqtt.go index f2ae5ba5c..5963e9c08 100644 --- a/server/mqtt.go +++ b/server/mqtt.go @@ -167,7 +167,7 @@ func (m *MQTT) listenSiteSetters(topic string, site site.API) error { var err error if err == nil { - err = m.Handler.ListenSetter(m.root+"/site/prioritySoc", func(payload string) error { + err = m.Handler.ListenSetter(topic+"/site/prioritySoc", func(payload string) error { val, err := parseFloat(payload) if err == nil { err = site.SetPrioritySoc(val) @@ -177,7 +177,7 @@ func (m *MQTT) listenSiteSetters(topic string, site site.API) error { } if err == nil { - err = m.Handler.ListenSetter(m.root+"/site/bufferSoc", func(payload string) error { + err = m.Handler.ListenSetter(topic+"/site/bufferSoc", func(payload string) error { val, err := parseFloat(payload) if err == nil { err = site.SetBufferSoc(val) @@ -187,7 +187,7 @@ func (m *MQTT) listenSiteSetters(topic string, site site.API) error { } if err == nil { - err = m.Handler.ListenSetter(m.root+"/site/bufferStartSoc", func(payload string) error { + err = m.Handler.ListenSetter(topic+"/site/bufferStartSoc", func(payload string) error { val, err := parseFloat(payload) if err == nil { err = site.SetBufferStartSoc(val) @@ -197,7 +197,7 @@ func (m *MQTT) listenSiteSetters(topic string, site site.API) error { } if err == nil { - err = m.Handler.ListenSetter(m.root+"/site/residualPower", func(payload string) error { + err = m.Handler.ListenSetter(topic+"/site/residualPower", func(payload string) error { val, err := parseFloat(payload) if err == nil { err = site.SetResidualPower(val) @@ -207,7 +207,7 @@ func (m *MQTT) listenSiteSetters(topic string, site site.API) error { } if err == nil { - err = m.Handler.ListenSetter(m.root+"/site/smartCostLimit", func(payload string) error { + err = m.Handler.ListenSetter(topic+"/site/smartCostLimit", func(payload string) error { val, err := parseFloat(payload) if err == nil { err = site.SetSmartCostLimit(val) diff --git a/server/socket_test.go b/server/socket_test.go index dd40b9456..03288eb91 100644 --- a/server/socket_test.go +++ b/server/socket_test.go @@ -6,6 +6,7 @@ import ( "time" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestEncode(t *testing.T) { @@ -27,7 +28,7 @@ func TestEncode(t *testing.T) { for _, tc := range tc { out, err := encode(tc.in) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, tc.out, out) } } @@ -44,7 +45,7 @@ func TestEncodeSlice(t *testing.T) { for _, tc := range tc { out, err := encodeSlice(tc.in) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, tc.out, out) } } diff --git a/tariff/entsoe/areas.go b/tariff/entsoe/areas.go index 6243c9859..2e49ddbb0 100644 --- a/tariff/entsoe/areas.go +++ b/tariff/entsoe/areas.go @@ -113,7 +113,7 @@ var zones = map[string][]string{ "10YPT-REN------W": {"LFA|PT", "LFB|PT", "MBA|PT", "SCA|PT", "CTA|PT", "Portugal (PT)", "BZN|PT"}, "10YRO-TEL------P": {"BZN|RO", "Romania (RO)", "CTA|RO", "SCA|RO", "MBA|RO", "LFB|RO", "LFA|RO"}, "10YSE-1--------K": {"MBA|SE", "SCA|SE", "CTA|SE", "Sweden (SE)"}, - "10YSI-ELES-----O": {"Slovenia (SI)", "BZN|SI", "CTA|SI", "SCA|SI", "MBA|SI", "LFA|SI"}, + "10YSI-EELS-----O": {"Slovenia (SI)", "BZN|SI", "CTA|SI", "SCA|SI", "MBA|SI", "LFA|SI"}, "10YSK-SEPS-----K": {"LFA|SK", "LFB|SK", "MBA|SK", "SCA|SK", "CTA|SK", "BZN|SK", "Slovakia (SK)"}, "10YTR-TEIAS----W": {"Turkey (TR)", "BZN|TR", "CTA|TR", "SCA|TR", "MBA|TR", "LFB|TR", "LFA|TR"}, "10YUA-WEPS-----0": {"LFA|UA-BEI", "LFB|UA-BEI", "MBA|UA-BEI", "SCA|UA-BEI", "CTA|UA-BEI", "BZN|UA-BEI"}, diff --git a/tariff/fixed/day.go b/tariff/fixed/day.go index 63d214d60..f09e93368 100644 --- a/tariff/fixed/day.go +++ b/tariff/fixed/day.go @@ -88,7 +88,7 @@ func ParseDays(s string) ([]Day, error) { if err != nil { return nil, err } - res = append(res, Day(from%7)) + res = append(res, from%7) if len(fromto) == 2 { to, err := ParseDay(fromto[1]) diff --git a/tariff/fixed/day_test.go b/tariff/fixed/day_test.go index d98aa28cf..bcad9fcef 100644 --- a/tariff/fixed/day_test.go +++ b/tariff/fixed/day_test.go @@ -4,43 +4,44 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestParseDays(t *testing.T) { d, err := ParseDays(" sunday ") - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, []Day{Sunday}, d) d, err = ParseDays("sun") - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, []Day{Sunday}, d) d, err = ParseDays("so") - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, []Day{Sunday}, d) d, err = ParseDays("0 ") - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, []Day{Sunday}, d) d, err = ParseDays(" 7") - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, []Day{Sunday}, d) d, err = ParseDays(" 6-7 ") - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, []Day{Saturday, Sunday}, d) d, err = ParseDays("1- 7") - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, []Day{Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday}, d) _, err = ParseDays(" ") - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, []Day{Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday}, d) d, err = ParseDays("1, 3-7") - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, []Day{Monday, Wednesday, Thursday, Friday, Saturday, Sunday}, d) _, err = ParseDays("-") diff --git a/tariff/fixed/timerange_test.go b/tariff/fixed/timerange_test.go index a7a59892b..391f220ab 100644 --- a/tariff/fixed/timerange_test.go +++ b/tariff/fixed/timerange_test.go @@ -4,15 +4,16 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestParseTimeRange(t *testing.T) { d, err := ParseTimeRanges(" 7:00 - 12:30 ") - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, []TimeRange{{HourMin{7, 0}, HourMin{12, 30}}}, d, "hour:min range") d, err = ParseTimeRanges(" 8-10 ") - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, []TimeRange{{HourMin{8, 0}, HourMin{10, 0}}}, d, "hour range") _, err = ParseTimeRanges("-1-10") @@ -22,14 +23,14 @@ func TestParseTimeRange(t *testing.T) { assert.EqualError(t, err, "invalid time: 25", " after midnight") d, err = ParseTimeRanges("8-0") - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, []TimeRange{{HourMin{8, 0}, HourMin{0, 0}}}, d, "hour till midnight (0)") _, err = ParseTimeRanges("10-8") assert.EqualError(t, err, "invalid time range: 10-8, must be before ") d, err = ParseTimeRanges("8-10, 20-22:30") - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, []TimeRange{ {HourMin{8, 0}, HourMin{10, 0}}, {HourMin{20, 0}, HourMin{22, 30}}, diff --git a/tariff/fixed_test.go b/tariff/fixed_test.go index 15656af25..3dab95c29 100644 --- a/tariff/fixed_test.go +++ b/tariff/fixed_test.go @@ -9,6 +9,7 @@ import ( "github.com/evcc-io/evcc/tariff/fixed" "github.com/jinzhu/now" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestFixed(t *testing.T) { @@ -33,7 +34,7 @@ func TestFixed(t *testing.T) { } rates, err := tf.Rates() - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, expect, rates) } @@ -47,7 +48,7 @@ func TestFixedSplitZones(t *testing.T) { {0.1, "0-5:30,21-0"}, }, }) - assert.NoError(t, err) + require.NoError(t, err) tf := at.(*Fixed) tf.clock = clock.NewMock() @@ -99,6 +100,6 @@ func TestFixedSplitZones(t *testing.T) { } rates, err := tf.Rates() - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, expect, rates) } diff --git a/util/decoder_test.go b/util/decoder_test.go index b78eb42c5..7f34b769b 100644 --- a/util/decoder_test.go +++ b/util/decoder_test.go @@ -5,6 +5,7 @@ import ( "github.com/mitchellh/mapstructure" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestDecodeNil(t *testing.T) { @@ -23,12 +24,12 @@ func TestDecodeNil(t *testing.T) { } decoder, err := mapstructure.NewDecoder(decoderConfig) - assert.NoError(t, err) + require.NoError(t, err) err = decoder.Decode(map[string]any{ "user": nil, }) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, struct { User, Password string diff --git a/util/log.go b/util/log.go index 707767b53..185c1b398 100644 --- a/util/log.go +++ b/util/log.go @@ -54,7 +54,7 @@ func newLogger(area string, lp int) *Logger { padded := area for len(padded) < LogAreaPadding { - padded = padded + " " + padded += " " } level := LogLevelForArea(area) @@ -188,10 +188,7 @@ func captureLogger(l *Logger) { } func captureLogLevel(level string, lp int, l *log.Logger) { - re, err := regexp.Compile(`^\[[a-zA-Z0-9-]+\s*\] \w+ .{19} `) - if err != nil { - panic(err) - } + re := regexp.MustCompile(`^\[[a-zA-Z0-9-]+\s*\] \w+ .{19} `) ui := uiWriter{ lp: lp, diff --git a/util/machine/machine.go b/util/machine/machine.go index e8a8c2f77..e74c6901c 100644 --- a/util/machine/machine.go +++ b/util/machine/machine.go @@ -7,9 +7,8 @@ import ( "fmt" "strings" - "github.com/samber/lo" - "github.com/denisbrodbeck/machineid" + "github.com/samber/lo" ) var id string diff --git a/util/modbus/functions.go b/util/modbus/functions.go index 7a7330099..8c6797e13 100644 --- a/util/modbus/functions.go +++ b/util/modbus/functions.go @@ -53,7 +53,7 @@ func decodeBool16(mask uint64) func(b []byte) float64 { return func(b []byte) float64 { u := binary.BigEndian.Uint16(b) if mask > 0 { - u = u & uint16(mask) + u &= uint16(mask) } if u > 0 { return 1 diff --git a/util/modbus/modbus.go b/util/modbus/modbus.go index 2d140950c..bf316dd8a 100644 --- a/util/modbus/modbus.go +++ b/util/modbus/modbus.go @@ -390,7 +390,6 @@ func RegisterOperation(r Register) (rs485.Operation, error) { } switch strings.ToLower(r.Decode) { - // 8 bit (coil) case "bool8": op.Transform = decodeBool8 diff --git a/util/templates/documentation.go b/util/templates/documentation.go index 3754bb140..3419f790e 100644 --- a/util/templates/documentation.go +++ b/util/templates/documentation.go @@ -3,7 +3,7 @@ package templates import ( "bytes" _ "embed" - "fmt" + "strconv" "strings" "text/template" @@ -36,7 +36,7 @@ func (t *Template) RenderDocumentation(product Product, lang string) ([]byte, er case string: t.Params[index].Value = yamlQuote(v) case int: - t.Params[index].Value = fmt.Sprintf("%d", v) + t.Params[index].Value = strconv.Itoa(v) } } } diff --git a/util/templates/render_testing.go b/util/templates/render_testing.go index 351c3124d..8ade9e63e 100644 --- a/util/templates/render_testing.go +++ b/util/templates/render_testing.go @@ -11,6 +11,8 @@ import ( // test renders and instantiates plus yaml-parses the template per usage func test(t *testing.T, tmpl Template, values map[string]interface{}, cb func(values map[string]interface{})) { + t.Helper() + b, _, err := tmpl.RenderResult(TemplateRenderModeInstance, values) if err != nil { t.Log(string(b)) @@ -32,6 +34,8 @@ func test(t *testing.T, tmpl Template, values map[string]interface{}, cb func(va } func TestClass(t *testing.T, class Class, instantiate func(t *testing.T, values map[string]interface{})) { + t.Parallel() + for _, tmpl := range ByClass(class) { tmpl := tmpl diff --git a/util/templates/template.go b/util/templates/template.go index e4b8430e2..169984ab1 100644 --- a/util/templates/template.go +++ b/util/templates/template.go @@ -5,6 +5,7 @@ import ( _ "embed" "fmt" "slices" + "strconv" "strings" "text/template" @@ -230,7 +231,7 @@ func (t *Template) RenderProxyWithValues(values map[string]interface{}, lang str case string: t.Params[index].Value = yamlQuote(v) case int: - t.Params[index].Value = fmt.Sprintf("%d", v) + t.Params[index].Value = strconv.Itoa(v) } } } diff --git a/util/templates/utils.go b/util/templates/utils.go index 6360dc5bc..cb9f2cd72 100644 --- a/util/templates/utils.go +++ b/util/templates/utils.go @@ -57,9 +57,7 @@ func FuncMap(tmpl *template.Template) *template.Template { } return buf.String(), nil }, - "urlEncode": func(v string) string { - return url.QueryEscape(v) - }, + "urlEncode": url.QueryEscape, "toDuration": func(v string) time.Duration { d, err := time.ParseDuration(v) if err != nil { diff --git a/util/templates/utils_test.go b/util/templates/utils_test.go index 1a543aba8..814823720 100644 --- a/util/templates/utils_test.go +++ b/util/templates/utils_test.go @@ -5,6 +5,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "gopkg.in/yaml.v3" ) @@ -19,7 +20,7 @@ func TestYamlDecode(t *testing.T) { } err := yaml.Unmarshal([]byte(input), &res) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, value, res.Value) }) } diff --git a/util/test/ci.go b/util/test/ci.go index 2e280e83e..900b4ab55 100644 --- a/util/test/ci.go +++ b/util/test/ci.go @@ -6,6 +6,8 @@ import ( ) func SkipCI(t *testing.T) { + t.Helper() + if os.Getenv("CI") != "" { t.Skip("Skipping testing in CI environment") } diff --git a/vehicle/carwings.go b/vehicle/carwings.go index 40a228987..a088a66fc 100644 --- a/vehicle/carwings.go +++ b/vehicle/carwings.go @@ -11,7 +11,6 @@ import ( "github.com/evcc-io/evcc/provider" "github.com/evcc-io/evcc/util" "github.com/evcc-io/evcc/util/request" - "github.com/joeshaw/carwings" ) @@ -111,7 +110,7 @@ func (v *CarWings) status() (carwings.BatteryStatus, error) { // api result is stale if v.refreshKey != "" { if err := v.refreshResult(); err != nil { - return *new(carwings.BatteryStatus), err + return carwings.BatteryStatus{}, err } } @@ -120,7 +119,7 @@ func (v *CarWings) status() (carwings.BatteryStatus, error) { if err == nil { if elapsed := time.Since(bs.Timestamp); elapsed > carwingsStatusExpiry { if err = v.refreshRequest(); err != nil { - return *new(carwings.BatteryStatus), err + return carwings.BatteryStatus{}, err } err = api.ErrMustRetry diff --git a/vehicle/fiat/types.go b/vehicle/fiat/types.go index 51ad67f9b..c175fba05 100644 --- a/vehicle/fiat/types.go +++ b/vehicle/fiat/types.go @@ -94,7 +94,7 @@ func (ct *TimeMillis) UnmarshalJSON(data []byte) error { if err == nil { t := time.Unix(0, i*1e6) - (*ct).Time = t + ct.Time = t } return err diff --git a/vehicle/ford/identity.go b/vehicle/ford/identity.go index 92cd2a792..c09626082 100644 --- a/vehicle/ford/identity.go +++ b/vehicle/ford/identity.go @@ -103,7 +103,7 @@ func (v *Identity) login() (*oauth.Token, error) { var settings Settings - if err := json.Unmarshal([]byte(match[1]), &settings); err != nil { + if err := json.Unmarshal(match[1], &settings); err != nil { return nil, err } diff --git a/vehicle/ford/types.go b/vehicle/ford/types.go index 2ed72bf85..a1c28780d 100644 --- a/vehicle/ford/types.go +++ b/vehicle/ford/types.go @@ -64,7 +64,7 @@ func (ct *Timestamp) UnmarshalJSON(data []byte) error { t, err := time.Parse(TimeFormat, s) if err == nil { - (*ct).Time = t + ct.Time = t } return err diff --git a/vehicle/mb/identity.go b/vehicle/mb/identity.go index 38540246e..2cf12014a 100644 --- a/vehicle/mb/identity.go +++ b/vehicle/mb/identity.go @@ -86,7 +86,7 @@ func (v *Identity) Login(user, password string) error { req, err := request.New(http.MethodPost, uri, request.MarshalJSON(data), request.JSONEncoding) if err == nil { if err = v.DoJSON(req, &res); err != nil && len(res.Errors) > 0 { - err = fmt.Errorf("%s: %w", string(res.Errors[0].Key), err) + err = fmt.Errorf("%s: %w", res.Errors[0].Key, err) } } @@ -98,7 +98,7 @@ func (v *Identity) Login(user, password string) error { req, err = request.New(http.MethodPost, uri, request.MarshalJSON(data), request.JSONEncoding) if err == nil { if err = v.DoJSON(req, &res); err != nil && len(res.Errors) > 0 { - err = fmt.Errorf("%s: %w", string(res.Errors[0].Key), err) + err = fmt.Errorf("%s: %w", res.Errors[0].Key, err) } } } diff --git a/vehicle/nissan/types.go b/vehicle/nissan/types.go index d84790856..212b127a1 100644 --- a/vehicle/nissan/types.go +++ b/vehicle/nissan/types.go @@ -111,7 +111,7 @@ func (ct *Timestamp) UnmarshalJSON(data []byte) error { t, err := time.Parse(timeFormat, s) if err == nil { - (*ct).Time = t + ct.Time = t } return err diff --git a/vehicle/ovms.go b/vehicle/ovms.go index 9a4fc49f6..c4def163b 100644 --- a/vehicle/ovms.go +++ b/vehicle/ovms.go @@ -2,6 +2,7 @@ package vehicle import ( "fmt" + "net" "net/http" "net/http/cookiejar" "net/url" @@ -102,31 +103,31 @@ func (v *Ovms) loginToServer() (err error) { return err } +func (v *Ovms) uri(path string) string { + return fmt.Sprintf("https://%s/api/%s/%s", net.JoinHostPort(v.server, "6869"), path, v.vehicleId) +} + func (v *Ovms) connectRequest() (ovmsConnectResponse, error) { - uri := fmt.Sprintf("https://%s:6869/api/vehicle/%s", v.server, v.vehicleId) var res ovmsConnectResponse - err := v.GetJSON(uri, &res) + err := v.GetJSON(v.uri("vehicle"), &res) return res, err } func (v *Ovms) chargeRequest() (ovmsChargeResponse, error) { - uri := fmt.Sprintf("https://%s:6869/api/charge/%s", v.server, v.vehicleId) var res ovmsChargeResponse - err := v.GetJSON(uri, &res) + err := v.GetJSON(v.uri("charge"), &res) return res, err } func (v *Ovms) statusRequest() (ovmsStatusResponse, error) { - uri := fmt.Sprintf("https://%s:6869/api/status/%s", v.server, v.vehicleId) var res ovmsStatusResponse - err := v.GetJSON(uri, &res) + err := v.GetJSON(v.uri("status"), &res) return res, err } func (v *Ovms) locationRequest() (ovmsLocationResponse, error) { - uri := fmt.Sprintf("https://%s:6869/api/location/%s", v.server, v.vehicleId) var res ovmsLocationResponse - err := v.GetJSON(uri, &res) + err := v.GetJSON(v.uri("location"), &res) return res, err } diff --git a/vehicle/psa.go b/vehicle/psa.go index 47ac9f4e3..e0ddfd488 100644 --- a/vehicle/psa.go +++ b/vehicle/psa.go @@ -102,7 +102,6 @@ func newPSA(log *util.Logger, brand, realm, id, secret string, other map[string] return v.VIN }, ) - if err != nil { return nil, err } diff --git a/vehicle/renault/kamereon/api.go b/vehicle/renault/kamereon/api.go index 7411ec56e..6af6290bd 100644 --- a/vehicle/renault/kamereon/api.go +++ b/vehicle/renault/kamereon/api.go @@ -58,7 +58,6 @@ func (v *API) request_(uri string, body io.Reader) (Response, error) { func (v *API) request(uri string, body io.Reader) (Response, error) { res, err := v.request_(uri, body) - // repeat auth if error if err != nil { if err = v.login(); err == nil { diff --git a/vehicle/seat/cupra/provider.go b/vehicle/seat/cupra/provider.go index 346f6eec7..d5f1b2be5 100644 --- a/vehicle/seat/cupra/provider.go +++ b/vehicle/seat/cupra/provider.go @@ -32,7 +32,7 @@ var _ api.Battery = (*Provider)(nil) // Soc implements the api.Vehicle interface func (v *Provider) Soc() (float64, error) { res, err := v.statusG() - return float64(res.Engines.Primary.Level), err + return res.Engines.Primary.Level, err } var _ api.ChargeState = (*Provider)(nil) @@ -89,7 +89,7 @@ var _ api.VehicleOdometer = (*Provider)(nil) // Odometer implements the api.VehicleOdometer interface func (v *Provider) Odometer() (float64, error) { res, err := v.statusG() - return float64(res.Measurements.MileageKm), err + return res.Measurements.MileageKm, err } var _ api.VehicleClimater = (*Provider)(nil) diff --git a/vehicle/smart/types.go b/vehicle/smart/types.go index 2617d47c6..ee84f40ea 100644 --- a/vehicle/smart/types.go +++ b/vehicle/smart/types.go @@ -55,7 +55,7 @@ func (ct *TimeSecs) UnmarshalJSON(data []byte) error { if err == nil { t := time.Unix(i, 0) - (*ct).Time = t + ct.Time = t } return err diff --git a/vehicle/template_test.go b/vehicle/template_test.go index 5686112cd..c7f3a544d 100644 --- a/vehicle/template_test.go +++ b/vehicle/template_test.go @@ -26,6 +26,8 @@ var acceptable = []string{ 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) { t.Log(values) t.Error(err) diff --git a/vehicle/volvo/types.go b/vehicle/volvo/types.go index 1211585d7..dae2ddf5e 100644 --- a/vehicle/volvo/types.go +++ b/vehicle/volvo/types.go @@ -94,7 +94,7 @@ func (ct *Timestamp) UnmarshalJSON(data []byte) error { t, err := time.Parse(timeFormat, s) if err == nil { - (*ct).Time = t + ct.Time = t } return err diff --git a/vehicle/vw/id/types.go b/vehicle/vw/id/types.go index 5bb679083..a303eb83f 100644 --- a/vehicle/vw/id/types.go +++ b/vehicle/vw/id/types.go @@ -331,7 +331,7 @@ func (ct *Timestamp) UnmarshalJSON(data []byte) error { t, err := time.Parse(time.RFC3339, s) if err == nil { - (*ct).Time = t + ct.Time = t } return err diff --git a/vehicle/vw/types.go b/vehicle/vw/types.go index 7abc6ff9f..7888e0b9d 100644 --- a/vehicle/vw/types.go +++ b/vehicle/vw/types.go @@ -133,12 +133,12 @@ func (t *TimedTemperature) UnmarshalJSON(data []byte) error { err := json.Unmarshal(data, &temp) if err == nil { - (*t).Timestamp = temp.Timestamp + t.Timestamp = temp.Timestamp if val, err := strconv.Atoi(string(temp.Content)); err == nil { - (*t).Content = temp2Float(val) + t.Content = temp2Float(val) } else { - (*t).Content = math.NaN() + t.Content = math.NaN() } }