diff --git a/assets/js/app.js b/assets/js/app.js index 0c2787a94..0e9deefc1 100644 --- a/assets/js/app.js +++ b/assets/js/app.js @@ -222,4 +222,5 @@ const router = new VueRouter({ const app = new Vue({ router, }).$mount("#app"); -store.init; \ No newline at end of file + +store.init(); diff --git a/core/api.go b/core/api.go index 0c02f5c90..b1c79240b 100644 --- a/core/api.go +++ b/core/api.go @@ -7,10 +7,10 @@ import ( "github.com/andig/evcc/core/wrapper" ) -// NilVal implements Stringer for nil values -type NilVal int +// nilVal implements Stringer for nil values +type nilVal int -func (n *NilVal) String() string { +func (n *nilVal) String() string { return "—" } @@ -160,7 +160,7 @@ func (lp *LoadPoint) publishSoC() { log.ERROR.Printf("%s vehicle error: %v", lp.Name, err) } - var n *NilVal + var n *nilVal lp.publish("socCharge", n) lp.publish("chargeEstimate", -1) } diff --git a/server/assets.go b/server/assets.go index 902d4e98b..1424dcdd4 100644 --- a/server/assets.go +++ b/server/assets.go @@ -3824,39 +3824,39 @@ AP//MWVC4HgxAAA= "/js/app.js": { name: "app.js", local: "../assets/js/app.js", - size: 5012, + size: 5016, modtime: 1566640112, compressed: ` -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 `, }, diff --git a/server/socket.go b/server/socket.go index 508684c75..120bc36a2 100644 --- a/server/socket.go +++ b/server/socket.go @@ -82,32 +82,33 @@ func NewSocketHub() *SocketHub { } } -func (h *SocketHub) encode(v core.Param) ([]byte, error) { +func encode(v interface{}) (string, error) { var s string - switch val := v.Val.(type) { + switch val := v.(type) { case time.Duration: // must be before stringer to convert to seconds instead of string - s = fmt.Sprintf("{\"%s\": %d}", v.Key, int64(val.Seconds())) + s = fmt.Sprintf("%d", int64(val.Seconds())) case fmt.Stringer, string: - s = fmt.Sprintf("{\"%s\": \"%s\"}", v.Key, val) + s = fmt.Sprintf("\"%s\"", val) case float64: - s = fmt.Sprintf("{\"%s\": %.3f}", v.Key, val) + s = fmt.Sprintf("%.3f", val) default: - s = fmt.Sprintf("{\"%s\": %v}", v.Key, val) + s = fmt.Sprintf("%v", val) } - return []byte(s), nil + return s, nil } func (h *SocketHub) broadcast(i core.Param) { if len(h.clients) > 0 { - message, err := h.encode(i) + val, err := encode(i.Val) if err != nil { log.FATAL.Fatal(err) } + message := fmt.Sprintf("{\"%s\": %s}", i.Key, val) for client := range h.clients { select { - case client.send <- message: + case client.send <- []byte(message): default: close(client.send) delete(h.clients, client) diff --git a/server/socket_test.go b/server/socket_test.go new file mode 100644 index 000000000..3d37bee76 --- /dev/null +++ b/server/socket_test.go @@ -0,0 +1,41 @@ +package server + +import ( + "reflect" + "testing" + "time" +) + +type nilVal int + +func (n *nilVal) String() string { + return "—" +} + +func TestEncode(t *testing.T) { + var nv nilVal + tc := []struct { + in, out interface{} + }{ + {int64(1), "1"}, + {float64(1.2345), "1.234"}, + {"1.2345", "\"1.2345\""}, + {&nv, "\"—\""}, + {time.Duration(time.Hour), "3600"}, + {"minpv", "\"minpv\""}, + } + + for _, tc := range tc { + t.Logf("%+v", tc) + out, err := encode(tc.in) + if err != nil { + t.Error(err) + } + + if out != tc.out { + t.Errorf("expected %v (string), got %v (%s)", + tc.out, out, reflect.TypeOf(out).Kind(), + ) + } + } +}