Add read-only mode support and enhance logging throughout the application
Some checks failed
continuous-integration/drone/push Build is failing
Some checks failed
continuous-integration/drone/push Build is failing
This commit is contained in:
@@ -9,8 +9,9 @@ import (
|
||||
)
|
||||
|
||||
type config struct {
|
||||
Address string `long:"address" env:"ADDRESS" default:":8080" description:"The IP/DNS and port of the machine that the application is running on."`
|
||||
Data struct {
|
||||
Address string `long:"address" env:"ADDRESS" default:":8080" description:"The IP/DNS and port of the machine that the application is running on."`
|
||||
ReadOnly bool `long:"read_only" env:"READ_ONLY" description:"Disable all write operations and run in monitoring-only mode."`
|
||||
Data struct {
|
||||
Source string `long:"data.source" env:"DATA_SOURCE" default:"serial" description:"Set the source of data for the inverter gui. \"serial\", \"tcp\" or \"mock\""`
|
||||
Host string `long:"data.host" env:"DATA_HOST" default:"localhost:8139" description:"Host to connect when source is set to tcp."`
|
||||
Device string `long:"data.device" env:"DATA_DEVICE" default:"/dev/ttyUSB0" description:"TTY device to use when source is set to serial."`
|
||||
|
||||
@@ -55,6 +55,7 @@ var log = logrus.WithField("ctx", "inverter-gui")
|
||||
func main() {
|
||||
conf, err := parseConfig()
|
||||
if err != nil {
|
||||
log.WithError(err).Error("Could not parse configuration")
|
||||
os.Exit(1)
|
||||
}
|
||||
log.Info("Starting invertergui")
|
||||
@@ -63,16 +64,33 @@ func main() {
|
||||
log.Fatalf("Could not parse log level: %v", err)
|
||||
}
|
||||
logrus.SetLevel(logLevel)
|
||||
log.WithFields(logrus.Fields{
|
||||
"loglevel": conf.Loglevel,
|
||||
"address": conf.Address,
|
||||
"read_only": conf.ReadOnly,
|
||||
"data_source": conf.Data.Source,
|
||||
"data_host": conf.Data.Host,
|
||||
"data_device": conf.Data.Device,
|
||||
"cli_enabled": conf.Cli.Enabled,
|
||||
"mqtt_enabled": conf.MQTT.Enabled,
|
||||
"mqtt_broker": conf.MQTT.Broker,
|
||||
"mqtt_topic": conf.MQTT.Topic,
|
||||
"mqtt_command_topic": conf.MQTT.CommandTopic,
|
||||
"mqtt_status_topic": conf.MQTT.StatusTopic,
|
||||
"mqtt_ha_enabled": conf.MQTT.HA.Enabled,
|
||||
}).Info("Configuration loaded")
|
||||
|
||||
mk2, err := getMk2Device(conf.Data.Source, conf.Data.Host, conf.Data.Device)
|
||||
if err != nil {
|
||||
log.Fatalf("Could not open data source: %v", err)
|
||||
}
|
||||
defer mk2.Close()
|
||||
log.Info("MK2 device connection established")
|
||||
|
||||
core := mk2core.NewCore(mk2)
|
||||
|
||||
if conf.Cli.Enabled {
|
||||
log.Info("CLI plugin enabled")
|
||||
cli.NewCli(core.NewSubscription())
|
||||
}
|
||||
|
||||
@@ -80,21 +98,35 @@ func main() {
|
||||
var writer mk2driver.SettingsWriter
|
||||
if w, ok := mk2.(mk2driver.SettingsWriter); ok {
|
||||
writer = w
|
||||
log.Info("MK2 data source supports settings writes")
|
||||
} else {
|
||||
log.Warn("MK2 data source does not support settings writes")
|
||||
}
|
||||
if conf.ReadOnly {
|
||||
if writer != nil {
|
||||
log.Warn("READ_ONLY enabled; disabling all write operations")
|
||||
} else {
|
||||
log.Info("READ_ONLY enabled")
|
||||
}
|
||||
writer = nil
|
||||
}
|
||||
gui := webui.NewWebGui(core.NewSubscription(), writer)
|
||||
http.Handle("/", static.New())
|
||||
http.Handle("/ws", http.HandlerFunc(gui.ServeHub))
|
||||
http.Handle("/api/remote-panel/state", http.HandlerFunc(gui.ServeRemotePanelState))
|
||||
http.Handle("/api/remote-panel/standby", http.HandlerFunc(gui.ServeRemotePanelStandby))
|
||||
log.Info("Web UI routes registered")
|
||||
|
||||
// Munin
|
||||
mu := munin.NewMunin(core.NewSubscription())
|
||||
http.Handle("/munin", http.HandlerFunc(mu.ServeMuninHTTP))
|
||||
http.Handle("/muninconfig", http.HandlerFunc(mu.ServeMuninConfigHTTP))
|
||||
log.Info("Munin routes registered")
|
||||
|
||||
// Prometheus
|
||||
prometheus.NewPrometheus(core.NewSubscription())
|
||||
http.Handle("/metrics", promhttp.Handler())
|
||||
log.Info("Prometheus route registered")
|
||||
|
||||
// MQTT
|
||||
if conf.MQTT.Enabled {
|
||||
@@ -119,6 +151,7 @@ func main() {
|
||||
if err := mqttclient.New(core.NewSubscription(), writer, mqttConf); err != nil {
|
||||
log.Fatalf("Could not setup MQTT client: %v", err)
|
||||
}
|
||||
log.Info("MQTT client initialized")
|
||||
}
|
||||
log.Infof("Invertergui web server starting on: %v", conf.Address)
|
||||
|
||||
@@ -134,12 +167,14 @@ func getMk2Device(source, ip, dev string) (mk2driver.Mk2, error) {
|
||||
|
||||
switch source {
|
||||
case "serial":
|
||||
log.WithField("device", dev).Info("Opening serial MK2 source")
|
||||
serialConfig := &serial.Config{Name: dev, Baud: 2400}
|
||||
p, err = serial.OpenPort(serialConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
case "tcp":
|
||||
log.WithField("host", ip).Info("Opening TCP MK2 source")
|
||||
tcpAddr, err = net.ResolveTCPAddr("tcp", ip)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -149,6 +184,7 @@ func getMk2Device(source, ip, dev string) (mk2driver.Mk2, error) {
|
||||
return nil, err
|
||||
}
|
||||
case "mock":
|
||||
log.Info("Using mock MK2 data source")
|
||||
return mk2driver.NewMk2Mock(), nil
|
||||
default:
|
||||
return nil, fmt.Errorf("Invalid source selection: %v\nUse \"serial\", \"tcp\" or \"mock\"", source)
|
||||
@@ -158,6 +194,7 @@ func getMk2Device(source, ip, dev string) (mk2driver.Mk2, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
log.WithField("source", source).Info("MK2 connection ready")
|
||||
|
||||
return mk2, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user