Repository: evcc-io/evcc
Pull request #7634 (2023-04-24 07:50:43)

fix: wattpilot with reconnect mutex and loglevel configuration
* reconnect is locked by a mutex now
* logging is reported via logrus and done via json and on stderr

bring more light into #7601 with logging 


Patch:
diff --git a/charger/wattpilot.go b/charger/fronius-wattpilot.go
similarity index 98%
rename from charger/wattpilot.go
rename to charger/fronius-wattpilot.go
index a276a1e8..97642bc5 100644
--- a/charger/wattpilot.go
+++ b/charger/fronius-wattpilot.go
@@ -36,15 +36,17 @@ 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),
 	}
 
-	if _, err := c.api.Connect(); err != nil {
+	if err := c.api.Connect(); err != nil {
 		return nil, err
 	}
 
diff --git a/go.mod b/go.mod
index 51cb7863..256291f8 100644
--- a/go.mod
+++ b/go.mod
@@ -62,7 +62,7 @@ require (
 	github.com/libp2p/zeroconf/v2 v2.2.0
 	github.com/lorenzodonini/ocpp-go v0.16.1-0.20230416102136-782920b66533
 	github.com/lunixbochs/struc v0.0.0-20200707160740-784aaebc1d40
-	github.com/mabunixda/wattpilot v1.3.1
+	github.com/mabunixda/wattpilot v1.4.1
 	github.com/manifoldco/promptui v0.9.0
 	github.com/mergermarket/go-pkcs7 v0.0.0-20170926155232-153b18ea13c9
 	github.com/mitchellh/go-homedir v1.1.0
@@ -102,6 +102,7 @@ require (
 	google.golang.org/protobuf v1.30.0
 	gopkg.in/yaml.v3 v3.0.1
 	gorm.io/gorm v1.25.0
+	nhooyr.io/websocket v1.8.7
 )
 
 require (
@@ -196,7 +197,6 @@ require (
 	modernc.org/mathutil v1.5.0 // indirect
 	modernc.org/memory v1.5.0 // indirect
 	modernc.org/sqlite v1.21.1 // indirect
-	nhooyr.io/websocket v1.8.7 // indirect
 )
 
 replace github.com/foogod/go-powerwall => github.com/andig/go-powerwall v0.2.1-0.20230102102528-4d59ac6910c6
diff --git a/go.sum b/go.sum
index 9b56feab..7f5805ec 100644
--- a/go.sum
+++ b/go.sum
@@ -750,8 +750,8 @@ github.com/lorenzodonini/ocpp-go v0.16.1-0.20230416102136-782920b66533/go.mod h1
 github.com/lunixbochs/struc v0.0.0-20200707160740-784aaebc1d40 h1:EnfXoSqDfSNJv0VBNqY/88RNnhSGYkrHaO0mmFGbVsc=
 github.com/lunixbochs/struc v0.0.0-20200707160740-784aaebc1d40/go.mod h1:vy1vK6wD6j7xX6O6hXe621WabdtNkou2h7uRtTfRMyg=
 github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ=
-github.com/mabunixda/wattpilot v1.3.1 h1:SlPjgxtBzVGfqXRGy+88BvqTpqhVcVQY0nr2b7UI7k8=
-github.com/mabunixda/wattpilot v1.3.1/go.mod h1:h+EsQdE8PtdgoICydM7/2ki/Das1b/TAQWMXJTnKZLk=
+github.com/mabunixda/wattpilot v1.4.1 h1:lQcJ0+w8T+6J7BW2l7RxUeUA393koHSmgM9PK1RVtCg=
+github.com/mabunixda/wattpilot v1.4.1/go.mod h1:1nie1EpKFupf9Eem0azKS2U66OjV/uAIAZDDeovcs+s=
 github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
 github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
 github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
diff --git a/provider/socket.go b/provider/socket.go
index 46c5fbf7..6e57bcc5 100644
--- a/provider/socket.go
+++ b/provider/socket.go
@@ -122,10 +122,12 @@ func (p *Socket) listen() {
 
 			p.log.TRACE.Printf("recv: %s", b)
 
-			p.mux.Lock()
-			p.val = b
-			p.wait.Update()
-			p.mux.Unlock()
+			if v, err := p.pipeline.Process(b); err == nil {
+				p.mux.Lock()
+				p.val = v
+				p.wait.Update()
+				p.mux.Unlock()
+			}
 		}
 	}
 }
@@ -146,13 +148,11 @@ var _ StringProvider = (*Socket)(nil)
 // StringGetter sends string request
 func (p *Socket) StringGetter() func() (string, error) {
 	return func() (string, error) {
-		b, err := p.hasValue()
+		v, err := p.hasValue()
 		if err != nil {
 			return "", err
 		}
 
-		v, err := p.pipeline.Process(b)
-
 		return string(v), err
 	}
 }
diff --git a/templates/definition/charger/wattpilot.yaml b/templates/definition/charger/fronius-wattpilot.yaml
similarity index 76%
rename from templates/definition/charger/wattpilot.yaml
rename to templates/definition/charger/fronius-wattpilot.yaml
index 3215b9e3..bb3cdc1d 100644
--- a/templates/definition/charger/wattpilot.yaml
+++ b/templates/definition/charger/fronius-wattpilot.yaml
@@ -10,15 +10,12 @@ requirements:
       Benötigt mindestens Firmware 36.3 oder neuer.
     en: |
       Requires firmware 36.3 or later.
-  uri: https://docs.evcc.io/docs/devices/chargers#
+  uri: https://docs.evcc.io/docs/devices/chargers/#fronius-wattpilot
 params:
   - name: host
   - name: password
+    mask: true
 render: |
   type: wattpilot
-  {{ if .host }}
   uri: {{ .host }}
-  {{ end }}
-  {{ if ne .password "" }}
   password: {{ .password }}
-  {{ end }}


Test patch:
diff --git a/provider/socket_test.go b/provider/socket_test.go
new file mode 100644
index 00000000..1ddae010
--- /dev/null
+++ b/provider/socket_test.go
@@ -0,0 +1,53 @@
+package provider
+
+import (
+	"context"
+	"fmt"
+	"net/http"
+	"net/http/httptest"
+	"testing"
+	"time"
+
+	"github.com/stretchr/testify/require"
+	"nhooyr.io/websocket"
+)
+
+func TestSocketProvider(t *testing.T) {
+	ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
+	defer cancel()
+
+	srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+		c, err := websocket.Accept(w, r, nil)
+		require.NoError(t, err)
+		defer c.Close(websocket.StatusNormalClosure, "")
+
+		uuids := []string{"foo", "bar"}
+		for i := 0; ; i++ {
+			json := fmt.Sprintf(`{"data":{"uuid":"%s","tuples":[[1682319567986,%d]]}}`, uuids[i%2], i%2)
+
+			if err := c.Write(ctx, websocket.MessageText, []byte(json)); err != nil {
+				require.NoError(t, err)
+			}
+
+			select {
+			case <-time.Tick(time.Millisecond):
+			case <-ctx.Done():
+				return
+			}
+		}
+	}))
+
+	defer srv.Close()
+
+	addr := "ws://" + srv.Listener.Addr().String()
+	p, err := NewSocketProviderFromConfig(map[string]any{
+		"uri": addr,
+		"jq":  `.data | select(.uuid=="bar") .tuples[0][1]`,
+	})
+	require.NoError(t, err)
+
+	g := p.IntGetter()
+	i, err := g()
+	require.NoError(t, err)
+	require.Equal(t, int64(1), i)
+}