From 47e73a4eff22ade6dad03d6e3926fba1f2fc8d88 Mon Sep 17 00:00:00 2001 From: Nicholas Thompson Date: Sun, 10 Mar 2019 21:36:34 +0200 Subject: [PATCH] Concept plugin layout --- Makefile | 14 +- cmd/guimock/main.go | 29 --- cmd/invertercli/invertercli.go | 90 --------- cmd/invertergui/main.go | 53 ++++-- mk2core/core.go | 57 ++++++ mk2driver/mockmk2.go | 2 - plugins/cli/cli.go | 47 +++++ {webgui => plugins/munin}/munin.go | 183 ++++++++++--------- plugins/munin/muninconfig.go | 82 +++++++++ {webgui => plugins/prometheus}/prometheus.go | 52 ++++-- {webgui => plugins/webui}/webgui.go | 39 +--- {webgui => plugins/webui}/webgui_test.go | 2 +- 12 files changed, 363 insertions(+), 287 deletions(-) delete mode 100644 cmd/guimock/main.go delete mode 100644 cmd/invertercli/invertercli.go create mode 100644 mk2core/core.go create mode 100644 plugins/cli/cli.go rename {webgui => plugins/munin}/munin.go (64%) create mode 100644 plugins/munin/muninconfig.go rename {webgui => plugins/prometheus}/prometheus.go (82%) rename {webgui => plugins/webui}/webgui.go (86%) rename {webgui => plugins/webui}/webgui_test.go (99%) diff --git a/Makefile b/Makefile index 85fc2bb..ed42a39 100644 --- a/Makefile +++ b/Makefile @@ -26,21 +26,13 @@ #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 test-race vet install gofmt docker statik lint clean guimock invertergui invertercli build +.PHONY: test test-race vet install gofmt docker statik lint clean invertergui -.DEFAULT_GOAL = build - -guimock: - go build ./cmd/guimock/ +.DEFAULT_GOAL = invertergui invertergui: go build ./cmd/invertergui/ -invertercli: - go build ./cmd/invertercli/ - -build: guimock invertergui invertercli - all: build gofmt test gofmt: @@ -62,4 +54,4 @@ lint: golangci-lint run clean: - rm ./guimock ./invertercli ./invertergui \ No newline at end of file + rm ./invertergui \ No newline at end of file diff --git a/cmd/guimock/main.go b/cmd/guimock/main.go deleted file mode 100644 index fe3b465..0000000 --- a/cmd/guimock/main.go +++ /dev/null @@ -1,29 +0,0 @@ -package main - -import ( - "flag" - "log" - "net/http" - - "github.com/diebietse/invertergui/frontend" - "github.com/diebietse/invertergui/mk2driver" - "github.com/diebietse/invertergui/webgui" - - "github.com/prometheus/client_golang/prometheus/promhttp" -) - -func main() { - addr := flag.String("addr", ":8080", "TCP address to listen on.") - flag.Parse() - - mk2 := mk2driver.NewMk2Mock() - gui := webgui.NewWebGui(mk2) - - http.Handle("/", frontend.NewStatic()) - http.Handle("/ws", http.HandlerFunc(gui.ServeHub)) - - http.Handle("/munin", http.HandlerFunc(gui.ServeMuninHTTP)) - http.Handle("/muninconfig", http.HandlerFunc(gui.ServeMuninConfigHTTP)) - http.Handle("/metrics", promhttp.Handler()) - log.Fatal(http.ListenAndServe(*addr, nil)) -} diff --git a/cmd/invertercli/invertercli.go b/cmd/invertercli/invertercli.go deleted file mode 100644 index 85f156a..0000000 --- a/cmd/invertercli/invertercli.go +++ /dev/null @@ -1,90 +0,0 @@ -package main - -import ( - "flag" - "fmt" - "io" - "log" - "net" - "os" - "os/signal" - "syscall" - - "github.com/diebietse/invertergui/mk2if" - "github.com/tarm/serial" - "github.com/diebietse/invertergui/mk2driver" - "github.com/mikepb/go-serial" -) - -// Basic CLI to serve as example lib usage -func main() { - //Info = log.New() - - tcp := flag.Bool("tcp", false, "Use TCP instead of TTY") - ip := flag.String("ip", "localhost:8139", "IP to connect when using tcp connection.") - dev := flag.String("dev", "/dev/ttyUSB0", "TTY device to use.") - flag.Parse() - - var p io.ReadWriteCloser - var err error - var tcpAddr *net.TCPAddr - - if *tcp { - tcpAddr, err = net.ResolveTCPAddr("tcp", *ip) - if err != nil { - panic(err) - } - p, err = net.DialTCP("tcp", nil, tcpAddr) - if err != nil { - panic(err) - } - } else { - serialConfig := &serial.Config{Name: *dev, Baud: 2400} - p, err = serial.OpenPort(serialConfig) - if err != nil { - panic(err) - } - } - defer p.Close() - mk2, err := mk2driver.NewMk2Connection(p) - if err != nil { - panic(err) - } - defer mk2.Close() - - c := mk2.C() - sigterm := make(chan os.Signal, 1) - signal.Notify(sigterm, syscall.SIGTERM, os.Interrupt) -mainloop: - for { - select { - case tmp := <-c: - if tmp.Valid { - PrintInfo(tmp) - } - case <-sigterm: - break mainloop - } - } - log.Printf("Closing connection") -} - -func PrintInfo(info *mk2driver.Mk2Info) { - out := fmt.Sprintf("Version: %v\n", info.Version) - out += fmt.Sprintf("Bat Volt: %.2fV Bat Cur: %.2fA \n", info.BatVoltage, info.BatCurrent) - out += fmt.Sprintf("In Volt: %.2fV In Cur: %.2fA In Freq %.2fHz\n", info.InVoltage, info.InCurrent, info.InFrequency) - out += fmt.Sprintf("Out Volt: %.2fV Out Cur: %.2fA Out Freq %.2fHz\n", info.OutVoltage, info.OutCurrent, info.OutFrequency) - out += fmt.Sprintf("In Power %.2fW Out Power %.2fW\n", info.InVoltage*info.InCurrent, info.OutVoltage*info.OutCurrent) - out += fmt.Sprintf("Charge State: %.2f%%\n", info.ChargeState*100) - out += "LEDs state:" - for k, v := range info.LEDs { - out += fmt.Sprintf(" %s %s", mk2driver.LedNames[k], mk2driver.StateNames[v]) - } - - out += "\nErrors:" - for _, v := range info.Errors { - out += " " + v.Error() - } - out += "\n" - log.Printf("System Info: \n%v", out) -} diff --git a/cmd/invertergui/main.go b/cmd/invertergui/main.go index 1ff6a22..20864b7 100644 --- a/cmd/invertergui/main.go +++ b/cmd/invertergui/main.go @@ -38,8 +38,12 @@ import ( "net/http" "github.com/diebietse/invertergui/frontend" + "github.com/diebietse/invertergui/mk2core" "github.com/diebietse/invertergui/mk2driver" - "github.com/diebietse/invertergui/webgui" + "github.com/diebietse/invertergui/plugins/cli" + "github.com/diebietse/invertergui/plugins/munin" + "github.com/diebietse/invertergui/plugins/prometheus" + "github.com/diebietse/invertergui/plugins/webui" "github.com/prometheus/client_golang/prometheus/promhttp" "github.com/tarm/serial" ) @@ -50,14 +54,44 @@ func main() { tcp := flag.Bool("tcp", false, "Use TCP instead of TTY") ip := flag.String("ip", "localhost:8139", "IP to connect when using tcp connection.") dev := flag.String("dev", "/dev/ttyUSB0", "TTY device to use.") + mock := flag.Bool("mock", false, "Creates a mock device for test puposes") + cliEnable := flag.Bool("cli", false, "Enable CLI output") flag.Parse() + var mk2 mk2driver.Mk2 + if *mock { + mk2 = mk2driver.NewMk2Mock() + } else { + mk2 = getMk2Device(*tcp, *ip, *dev) + } + + defer mk2.Close() + + core := mk2core.NewCore(mk2) + + if *cliEnable { + cli.NewCli(core.NewSubscription()) + } + + gui := webui.NewWebGui(core.NewSubscription()) + mu := munin.NewMunin(core.NewSubscription()) + prometheus.NewPrometheus(core.NewSubscription()) + + http.Handle("/", frontend.NewStatic()) + http.Handle("/ws", http.HandlerFunc(gui.ServeHub)) + http.Handle("/munin", http.HandlerFunc(mu.ServeMuninHTTP)) + http.Handle("/muninconfig", http.HandlerFunc(mu.ServeMuninConfigHTTP)) + http.Handle("/metrics", promhttp.Handler()) + log.Fatal(http.ListenAndServe(*addr, nil)) +} + +func getMk2Device(tcp bool, ip, dev string) mk2driver.Mk2 { var p io.ReadWriteCloser var err error var tcpAddr *net.TCPAddr - if *tcp { - tcpAddr, err = net.ResolveTCPAddr("tcp", *ip) + if tcp { + tcpAddr, err = net.ResolveTCPAddr("tcp", ip) if err != nil { panic(err) } @@ -66,25 +100,16 @@ func main() { panic(err) } } else { - serialConfig := &serial.Config{Name: *dev, Baud: 2400} + serialConfig := &serial.Config{Name: dev, Baud: 2400} p, err = serial.OpenPort(serialConfig) if err != nil { panic(err) } } - defer p.Close() mk2, err := mk2driver.NewMk2Connection(p) if err != nil { panic(err) } - defer mk2.Close() - gui := webgui.NewWebGui(mk2) - - http.Handle("/", frontend.NewStatic()) - http.Handle("/ws", http.HandlerFunc(gui.ServeHub)) - http.Handle("/munin", http.HandlerFunc(gui.ServeMuninHTTP)) - http.Handle("/muninconfig", http.HandlerFunc(gui.ServeMuninConfigHTTP)) - http.Handle("/metrics", promhttp.Handler()) - log.Fatal(http.ListenAndServe(*addr, nil)) + return mk2 } diff --git a/mk2core/core.go b/mk2core/core.go new file mode 100644 index 0000000..eeab19c --- /dev/null +++ b/mk2core/core.go @@ -0,0 +1,57 @@ +package mk2core + +import ( + "github.com/diebietse/invertergui/mk2driver" +) + +type Core struct { + mk2driver.Mk2 + plugins map[*subscription]bool + register chan *subscription +} + +func NewCore(m mk2driver.Mk2) *Core { + core := &Core{ + Mk2: m, + register: make(chan *subscription, 255), + plugins: map[*subscription]bool{}, + } + go core.run() + return core +} + +func (c *Core) NewSubscription() mk2driver.Mk2 { + sub := &subscription{ + send: make(chan *mk2driver.Mk2Info), + } + c.register <- sub + return sub +} + +func (c *Core) run() { + for { + select { + case r := <-c.register: + c.plugins[r] = true + case e := <-c.C(): + for plugin := range c.plugins { + select { + case plugin.send <- e: + default: + } + } + } + } +} + +type subscription struct { + send chan *mk2driver.Mk2Info +} + +func (s *subscription) C() chan *mk2driver.Mk2Info { + return s.send +} + +func (s *subscription) Close() { + close(s.send) +} diff --git a/mk2driver/mockmk2.go b/mk2driver/mockmk2.go index 38aa6c4..3432e8a 100644 --- a/mk2driver/mockmk2.go +++ b/mk2driver/mockmk2.go @@ -1,7 +1,6 @@ package mk2driver import ( - "fmt" "time" ) @@ -64,7 +63,6 @@ func (m *mock) genMockValues() { if mult < 0 { mult = 1.0 } - fmt.Printf("Sending\n") m.c <- input time.Sleep(1 * time.Second) } diff --git a/plugins/cli/cli.go b/plugins/cli/cli.go new file mode 100644 index 0000000..59af50d --- /dev/null +++ b/plugins/cli/cli.go @@ -0,0 +1,47 @@ +package cli + +import ( + "fmt" + "log" + + "github.com/diebietse/invertergui/mk2driver" +) + +type Cli struct { + mk2driver.Mk2 +} + +func NewCli(mk2 mk2driver.Mk2) { + newCli := &Cli{ + Mk2: mk2, + } + go newCli.run() +} + +func (c *Cli) run() { + for e := range c.C() { + if e.Valid { + printInfo(e) + } + } +} + +func printInfo(info *mk2driver.Mk2Info) { + out := fmt.Sprintf("Version: %v\n", info.Version) + out += fmt.Sprintf("Bat Volt: %.2fV Bat Cur: %.2fA \n", info.BatVoltage, info.BatCurrent) + out += fmt.Sprintf("In Volt: %.2fV In Cur: %.2fA In Freq %.2fHz\n", info.InVoltage, info.InCurrent, info.InFrequency) + out += fmt.Sprintf("Out Volt: %.2fV Out Cur: %.2fA Out Freq %.2fHz\n", info.OutVoltage, info.OutCurrent, info.OutFrequency) + out += fmt.Sprintf("In Power %.2fW Out Power %.2fW\n", info.InVoltage*info.InCurrent, info.OutVoltage*info.OutCurrent) + out += fmt.Sprintf("Charge State: %.2f%%\n", info.ChargeState*100) + out += "LEDs state:" + for k, v := range info.LEDs { + out += fmt.Sprintf(" %s %s", mk2driver.LedNames[k], mk2driver.StateNames[v]) + } + + out += "\nErrors:" + for _, v := range info.Errors { + out += " " + v.Error() + } + out += "\n" + log.Printf("System Info: \n%v", out) +} diff --git a/webgui/munin.go b/plugins/munin/munin.go similarity index 64% rename from webgui/munin.go rename to plugins/munin/munin.go index 542092d..d6bf4a6 100644 --- a/webgui/munin.go +++ b/plugins/munin/munin.go @@ -28,32 +28,49 @@ 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 +package munin import ( "bytes" "fmt" "net/http" + "time" "github.com/diebietse/invertergui/mk2driver" ) +type Munin struct { + mk2driver.Mk2 + muninResponse chan *muninData +} + type muninData struct { - status mk2driver.Mk2Info + status *mk2driver.Mk2Info timesUpdated int } -func (w *WebGui) ServeMuninHTTP(rw http.ResponseWriter, r *http.Request) { - muninDat := <-w.muninRespChan +func NewMunin(mk2 mk2driver.Mk2) *Munin { + m := &Munin{ + Mk2: mk2, + muninResponse: make(chan *muninData), + } + + go m.run() + + return m +} + +func (m *Munin) ServeMuninHTTP(rw http.ResponseWriter, r *http.Request) { + muninDat := <-m.muninResponse if muninDat.timesUpdated == 0 { rw.WriteHeader(500) _, _ = rw.Write([]byte("No data to return.\n")) return } - calcMuninAverages(&muninDat) + calcMuninAverages(muninDat) status := muninDat.status - tmpInput := buildTemplateInput(&status) + tmpInput := buildTemplateInput(status) outputBuf := &bytes.Buffer{} fmt.Fprintf(outputBuf, "multigraph in_batvolt\n") fmt.Fprintf(outputBuf, "volt.value %s\n", tmpInput.BatVoltage) @@ -82,98 +99,35 @@ func (w *WebGui) ServeMuninHTTP(rw http.ResponseWriter, r *http.Request) { } } -func (w *WebGui) ServeMuninConfigHTTP(rw http.ResponseWriter, r *http.Request) { - output := `multigraph in_batvolt -graph_title Battery Voltage -graph_vlabel Voltage (V) -graph_category inverter -graph_info Battery voltage - -volt.info Voltage of battery -volt.label Voltage of battery (V) - -multigraph in_batcharge -graph_title Battery Charge -graph_vlabel Charge (%) -graph_category inverter -graph_info Battery charge - -charge.info Estimated charge of battery -charge.label Battery charge (%) - -multigraph in_batcurrent -graph_title Battery Current -graph_vlabel Current (A) -graph_category inverter -graph_info Battery current - -current.info Battery current -current.label Battery current (A) - -multigraph in_batpower -graph_title Battery Power -graph_vlabel Power (W) -graph_category inverter -graph_info Battery power - -power.info Battery power -power.label Battery power (W) - -multigraph in_mainscurrent -graph_title Mains Current -graph_vlabel Current (A) -graph_category inverter -graph_info Mains current - -currentin.info Input current -currentin.label Input current (A) -currentout.info Output current -currentout.label Output current (A) - -multigraph in_mainsvoltage -graph_title Mains Voltage -graph_vlabel Voltage (V) -graph_category inverter -graph_info Mains voltage - -voltagein.info Input voltage -voltagein.label Input voltage (V) -voltageout.info Output voltage -voltageout.label Output voltage (V) - -multigraph in_mainspower -graph_title Mains Power -graph_vlabel Power (VA) -graph_category inverter -graph_info Mains power - -powerin.info Input power -powerin.label Input power (VA) -powerout.info Output power -powerout.label Output power (VA) - -multigraph in_mainsfreq -graph_title Mains frequency -graph_vlabel Frequency (Hz) -graph_category inverter -graph_info Mains frequency - -freqin.info In frequency -freqin.label In frequency (Hz) -freqout.info Out frequency -freqout.label Out frequency (Hz) -` - +func (m *Munin) ServeMuninConfigHTTP(rw http.ResponseWriter, r *http.Request) { + output := muninConfig _, err := rw.Write([]byte(output)) if err != nil { fmt.Printf("%v\n", err) } } +func (m *Munin) run() { + muninValues := &muninData{ + status: &mk2driver.Mk2Info{}, + } + for { + select { + case e := <-m.C(): + if e.Valid { + calcMuninValues(muninValues, e) + + } + case m.muninResponse <- muninValues: + zeroMuninValues(muninValues) + } + } +} + //Munin only samples once every 5 minutes so averages have to be calculated for some values. func calcMuninValues(muninDat *muninData, newStatus *mk2driver.Mk2Info) { muninDat.timesUpdated++ - muninVal := &muninDat.status + muninVal := muninDat.status muninVal.OutCurrent += newStatus.OutCurrent muninVal.InCurrent += newStatus.InCurrent muninVal.BatCurrent += newStatus.BatCurrent @@ -189,7 +143,7 @@ func calcMuninValues(muninDat *muninData, newStatus *mk2driver.Mk2Info) { } func calcMuninAverages(muninDat *muninData) { - muninVal := &muninDat.status + muninVal := muninDat.status muninVal.OutCurrent /= float64(muninDat.timesUpdated) muninVal.InCurrent /= float64(muninDat.timesUpdated) muninVal.BatCurrent /= float64(muninDat.timesUpdated) @@ -201,7 +155,7 @@ func calcMuninAverages(muninDat *muninData) { func zeroMuninValues(muninDat *muninData) { muninDat.timesUpdated = 0 - muninVal := &muninDat.status + muninVal := muninDat.status muninVal.OutCurrent = 0 muninVal.InCurrent = 0 muninVal.BatCurrent = 0 @@ -215,3 +169,50 @@ func zeroMuninValues(muninDat *muninData) { muninVal.ChargeState = 0 } + +type templateInput struct { + Date string `json:"date"` + + OutCurrent string `json:"output_current"` + OutVoltage string `json:"output_voltage"` + OutPower string `json:"output_power"` + + InCurrent string `json:"input_current"` + InVoltage string `json:"input_voltage"` + InPower string `json:"input_power"` + + InMinOut string + + BatVoltage string `json:"battery_voltage"` + BatCurrent string `json:"battery_current"` + BatPower string `json:"battery_power"` + BatCharge string `json:"battery_charge"` + + InFreq string `json:"input_frequency"` + OutFreq string `json:"output_frequency"` +} + +func buildTemplateInput(status *mk2driver.Mk2Info) *templateInput { + outPower := status.OutVoltage * status.OutCurrent + inPower := status.InCurrent * status.InVoltage + + newInput := &templateInput{ + Date: status.Timestamp.Format(time.RFC1123Z), + OutCurrent: fmt.Sprintf("%.2f", status.OutCurrent), + OutVoltage: fmt.Sprintf("%.2f", status.OutVoltage), + OutPower: fmt.Sprintf("%.2f", outPower), + InCurrent: fmt.Sprintf("%.2f", status.InCurrent), + InVoltage: fmt.Sprintf("%.2f", status.InVoltage), + InFreq: fmt.Sprintf("%.2f", status.InFrequency), + OutFreq: fmt.Sprintf("%.2f", status.OutFrequency), + InPower: fmt.Sprintf("%.2f", inPower), + + InMinOut: fmt.Sprintf("%.2f", inPower-outPower), + + BatCurrent: fmt.Sprintf("%.2f", status.BatCurrent), + BatVoltage: fmt.Sprintf("%.2f", status.BatVoltage), + BatPower: fmt.Sprintf("%.2f", status.BatVoltage*status.BatCurrent), + BatCharge: fmt.Sprintf("%.2f", status.ChargeState*100), + } + return newInput +} diff --git a/plugins/munin/muninconfig.go b/plugins/munin/muninconfig.go new file mode 100644 index 0000000..10d3320 --- /dev/null +++ b/plugins/munin/muninconfig.go @@ -0,0 +1,82 @@ +package munin + +const muninConfig = `multigraph in_batvolt +graph_title Battery Voltage +graph_vlabel Voltage (V) +graph_category inverter +graph_info Battery voltage + +volt.info Voltage of battery +volt.label Voltage of battery (V) + +multigraph in_batcharge +graph_title Battery Charge +graph_vlabel Charge (%) +graph_category inverter +graph_info Battery charge + +charge.info Estimated charge of battery +charge.label Battery charge (%) + +multigraph in_batcurrent +graph_title Battery Current +graph_vlabel Current (A) +graph_category inverter +graph_info Battery current + +current.info Battery current +current.label Battery current (A) + +multigraph in_batpower +graph_title Battery Power +graph_vlabel Power (W) +graph_category inverter +graph_info Battery power + +power.info Battery power +power.label Battery power (W) + +multigraph in_mainscurrent +graph_title Mains Current +graph_vlabel Current (A) +graph_category inverter +graph_info Mains current + +currentin.info Input current +currentin.label Input current (A) +currentout.info Output current +currentout.label Output current (A) + +multigraph in_mainsvoltage +graph_title Mains Voltage +graph_vlabel Voltage (V) +graph_category inverter +graph_info Mains voltage + +voltagein.info Input voltage +voltagein.label Input voltage (V) +voltageout.info Output voltage +voltageout.label Output voltage (V) + +multigraph in_mainspower +graph_title Mains Power +graph_vlabel Power (VA) +graph_category inverter +graph_info Mains power + +powerin.info Input power +powerin.label Input power (VA) +powerout.info Output power +powerout.label Output power (VA) + +multigraph in_mainsfreq +graph_title Mains frequency +graph_vlabel Frequency (Hz) +graph_category inverter +graph_info Mains frequency + +freqin.info In frequency +freqin.label In frequency (Hz) +freqout.info Out frequency +freqout.label Out frequency (Hz) +` diff --git a/webgui/prometheus.go b/plugins/prometheus/prometheus.go similarity index 82% rename from webgui/prometheus.go rename to plugins/prometheus/prometheus.go index 54c6992..49a91f2 100644 --- a/webgui/prometheus.go +++ b/plugins/prometheus/prometheus.go @@ -28,14 +28,15 @@ 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 +package prometheus import ( "github.com/diebietse/invertergui/mk2driver" "github.com/prometheus/client_golang/prometheus" ) -type prometheusUpdater struct { +type Prometheus struct { + mk2driver.Mk2 batteryVoltage prometheus.Gauge batteryCharge prometheus.Gauge batteryCurrent prometheus.Gauge @@ -50,8 +51,9 @@ type prometheusUpdater struct { mainsFreqOut prometheus.Gauge } -func newPrometheusUpdater() *prometheusUpdater { - tmp := &prometheusUpdater{ +func NewPrometheus(mk2 mk2driver.Mk2) { + tmp := &Prometheus{ + Mk2: mk2, batteryVoltage: prometheus.NewGauge(prometheus.GaugeOpts{ Name: "battery_voltage_v", Help: "Voltage of the battery.", @@ -101,7 +103,8 @@ func newPrometheusUpdater() *prometheusUpdater { Help: "Mains frequency at inverter output", }), } - prometheus.MustRegister(tmp.batteryVoltage, + prometheus.MustRegister( + tmp.batteryVoltage, tmp.batteryCharge, tmp.batteryCurrent, tmp.batteryPower, @@ -114,21 +117,30 @@ func newPrometheusUpdater() *prometheusUpdater { tmp.mainsFreqIn, tmp.mainsFreqOut, ) - return tmp + + go tmp.run() } -func (pu *prometheusUpdater) updatePrometheus(newStatus *mk2driver.Mk2Info) { - s := newStatus - pu.batteryVoltage.Set(s.BatVoltage) - pu.batteryCharge.Set(newStatus.ChargeState * 100) - pu.batteryCurrent.Set(s.BatCurrent) - pu.batteryPower.Set(s.BatVoltage * s.BatCurrent) - pu.mainsCurrentIn.Set(s.InCurrent) - pu.mainsCurrentOut.Set(s.OutCurrent) - pu.mainsVoltageIn.Set(s.InVoltage) - pu.mainsVoltageOut.Set(s.OutVoltage) - pu.mainsPowerIn.Set(s.InVoltage * s.InCurrent) - pu.mainsPowerOut.Set(s.OutVoltage * s.OutCurrent) - pu.mainsFreqIn.Set(s.InFrequency) - pu.mainsFreqOut.Set(s.OutFrequency) +func (p *Prometheus) run() { + for e := range p.C() { + if e.Valid { + p.updatePrometheus(e) + } + } +} + +func (p *Prometheus) updatePrometheus(newStatus *mk2driver.Mk2Info) { + s := newStatus + p.batteryVoltage.Set(s.BatVoltage) + p.batteryCharge.Set(newStatus.ChargeState * 100) + p.batteryCurrent.Set(s.BatCurrent) + p.batteryPower.Set(s.BatVoltage * s.BatCurrent) + p.mainsCurrentIn.Set(s.InCurrent) + p.mainsCurrentOut.Set(s.OutCurrent) + p.mainsVoltageIn.Set(s.InVoltage) + p.mainsVoltageOut.Set(s.OutVoltage) + p.mainsPowerIn.Set(s.InVoltage * s.InCurrent) + p.mainsPowerOut.Set(s.OutVoltage * s.OutCurrent) + p.mainsFreqIn.Set(s.InFrequency) + p.mainsFreqOut.Set(s.OutFrequency) } diff --git a/webgui/webgui.go b/plugins/webui/webgui.go similarity index 86% rename from webgui/webgui.go rename to plugins/webui/webgui.go index 1464ece..761aa8d 100644 --- a/webgui/webgui.go +++ b/plugins/webui/webgui.go @@ -28,7 +28,7 @@ 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 +package webui import ( "fmt" @@ -50,24 +50,19 @@ const ( ) type WebGui struct { + mk2driver.Mk2 stopChan chan struct{} - muninRespChan chan muninData - poller mk2driver.Mk2 - wg sync.WaitGroup - hub *websocket.Hub - - pu *prometheusUpdater + wg sync.WaitGroup + hub *websocket.Hub } func NewWebGui(source mk2driver.Mk2) *WebGui { - w := new(WebGui) - w.muninRespChan = make(chan muninData) - w.stopChan = make(chan struct{}) - w.poller = source - w.pu = newPrometheusUpdater() - w.hub = websocket.NewHub() - + w := &WebGui{ + stopChan: make(chan struct{}), + Mk2: source, + hub: websocket.NewHub(), + } w.wg.Add(1) go w.dataPoll() return w @@ -99,14 +94,6 @@ type templateInput struct { LedMap map[string]string `json:"led_map"` } -func (w *WebGui) ServeHTTP(rw http.ResponseWriter, r *http.Request) { - http.ServeFile(rw, r, "./frontend/index.html") -} - -func (w *WebGui) ServeJS(rw http.ResponseWriter, r *http.Request) { - http.ServeFile(rw, r, "./frontend/js/controller.js") -} - func (w *WebGui) ServeHub(rw http.ResponseWriter, r *http.Request) { w.hub.ServeHTTP(rw, r) } @@ -176,21 +163,15 @@ func (w *WebGui) Stop() { // dataPoll waits for data from the w.poller channel. It will send its currently stored status // to respChan if anything reads from it. func (w *WebGui) dataPoll() { - pollChan := w.poller.C() - var muninValues muninData for { select { - case s := <-pollChan: + case s := <-w.C(): if s.Valid { - calcMuninValues(&muninValues, s) - w.pu.updatePrometheus(s) err := w.hub.Broadcast(buildTemplateInput(s)) if err != nil { log.Printf("Could not send update to clients: %v", err) } } - case w.muninRespChan <- muninValues: - zeroMuninValues(&muninValues) case <-w.stopChan: w.wg.Done() return diff --git a/webgui/webgui_test.go b/plugins/webui/webgui_test.go similarity index 99% rename from webgui/webgui_test.go rename to plugins/webui/webgui_test.go index b7360c4..2032ae9 100644 --- a/webgui/webgui_test.go +++ b/plugins/webui/webgui_test.go @@ -28,7 +28,7 @@ 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 +package webui import ( "fmt"