diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..dbd7d47 --- /dev/null +++ b/Makefile @@ -0,0 +1,46 @@ +#Copyright (c) 2015, Hendrik van Wyk +#All rights reserved. +# +#Redistribution and use in source and binary forms, with or without +#modification, are permitted provided that the following conditions are met: +# +#* Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# +#* Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +#* Neither the name of invertergui nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +#THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +#AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +#IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +#DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +#FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +#DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +#SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +#CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +#OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +#OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +.PHONY: test install gofmt + +install: + go install ./... + +all: install gofmt test + +gofmt: + gofmt -l -s -w . + +test: + go test -v ./... + +test-race: + go test -v -race ./... + +vet: + go vet ./... diff --git a/README.md b/README.md index 1adc850..9521d63 100644 --- a/README.md +++ b/README.md @@ -1 +1,4 @@ # invertergui + +A primitive HTTP based monitor for a Victron Multiplus inverter. Uses https://github.com/ncthompson/inverter_monitor as +a data source. \ No newline at end of file diff --git a/cmd/invertergui/main.go b/cmd/invertergui/main.go new file mode 100644 index 0000000..b01441e --- /dev/null +++ b/cmd/invertergui/main.go @@ -0,0 +1,50 @@ +/* +Copyright (c) 2015, Hendrik van Wyk +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +* Neither the name of invertergui nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +package main + +import ( + "flag" + "github.com/hpdvanwyk/invertergui/datasource" + "github.com/hpdvanwyk/invertergui/webgui" + "log" + "net/http" + "time" +) + +func main() { + url := flag.String("url", "http://localhost:9005", "The url of the multiplus JSON interface.") + flag.Parse() + + source := datasource.NewJSONSource(*url) + gui := webgui.NewWebGui(source, 10*time.Second) + http.Handle("/", gui) + log.Fatal(http.ListenAndServe(":8080", nil)) +} diff --git a/datasource/decode_test.go b/datasource/decode_test.go new file mode 100644 index 0000000..1471e16 --- /dev/null +++ b/datasource/decode_test.go @@ -0,0 +1,69 @@ +/* +Copyright (c) 2015, Hendrik van Wyk +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +* Neither the name of invertergui nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +package datasource + +import ( + "net/http" + "net/http/httptest" + "reflect" + "testing" +) + +var sampleJSON string = `{"outCurrent": 1.19, +"leds": [0, 0, 0, 0, 1, 0, 0, 1], +"batVoltage": 26.63, +"inCurrent": 1.39, +"outVoltage": 235.3, +"inVoltage": 235.3, +"inFreq": 51.3, +"batCurrent": 0.0, +"outFreq": 735.3}` + +func returnJson(resp http.ResponseWriter, req *http.Request) { + resp.Write([]byte(sampleJSON)) +} + +func TestFetchStatus(t *testing.T) { + //setup test server + testServer := httptest.NewServer(http.HandlerFunc(returnJson)) + + var status MultiplusStatus + source := NewJSONSource(testServer.URL) + err := source.GetData(&status) + if err != nil { + t.Errorf("Unmarshal gave: %v", err) + } + expected := MultiplusStatus{1.19, 1.39, 235.3, 235.3, 26.63, 0, 51.3, 735.3, []int{0, 0, 0, 0, 1, 0, 0, 1}} + if !reflect.DeepEqual(status, expected) { + t.Errorf("JSON string did not decode as expected.") + } + testServer.Close() +} diff --git a/datasource/jsondecode.go b/datasource/jsondecode.go new file mode 100644 index 0000000..0505a7c --- /dev/null +++ b/datasource/jsondecode.go @@ -0,0 +1,77 @@ +/* +Copyright (c) 2015, Hendrik van Wyk +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +* Neither the name of invertergui nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +package datasource + +import ( + "encoding/json" + "net/http" +) + +type DataSource interface { + GetData(*MultiplusStatus) error +} + +type MultiplusStatus struct { + OutCurrent float64 `json:"outCurrent"` + InCurrent float64 `json:"inCurrent"` + OutVoltage float64 `json:"outVoltage"` + InVoltage float64 `json:"inVoltage"` + BatVoltage float64 `json:"batVoltage"` + BatCurrent float64 `json:"batCurrent"` + InFreq float64 `json:"inFreq"` + OutFreq float64 `json:"outFreq"` + Leds []int `json:"leds"` +} + +type source struct { + url string +} + +func NewJSONSource(url string) DataSource { + return &source{url: url} +} + +func (s *source) GetData(status *MultiplusStatus) error { + resp, err := http.Get(s.url) + if err != nil { + return err + } + dec := json.NewDecoder(resp.Body) + err = dec.Decode(status) + if err != nil { + return err + } + err = resp.Body.Close() + if err != nil { + return err + } + return nil +} diff --git a/webgui/htmltemplate.go b/webgui/htmltemplate.go new file mode 100644 index 0000000..946b0a4 --- /dev/null +++ b/webgui/htmltemplate.go @@ -0,0 +1,70 @@ +/* +Copyright (c) 2015, Hendrik van Wyk +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +* Neither the name of invertergui nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +package webgui + +var htmlTemplate string = ` +
+ + + + +Error encountered: {{.Error}}
{{end}} +Input - Output Power: {{.InMinOut}} VA
+