From 9ebdf41400086e7c5a3c8270cdfb4fdda85fdfd1 Mon Sep 17 00:00:00 2001 From: Mike Shoup Date: Tue, 2 Oct 2018 13:10:41 -0600 Subject: [PATCH] Add config endpoint --- config.go | 22 +++++++++++----------- main.go | 2 +- web.go | 53 ++++++++++++++++++++++++++++++++++++++++++++++++----- 3 files changed, 60 insertions(+), 17 deletions(-) diff --git a/config.go b/config.go index a0278df..e315a00 100644 --- a/config.go +++ b/config.go @@ -8,17 +8,17 @@ import ( // Sensor defines configuration for a temperature sensor. type Sensor struct { - ID string `yaml:"id"` - Alias string `yaml:"alias"` - HighTemp float64 `yaml:"hightemp"` - LowTemp float64 `yaml:"lowtemp"` - HeatGPIO int32 `yaml:"heatgpio"` - HeatInvert bool `yaml:"heatinvert"` - HeatMinutes float64 `yaml:"heatminutes"` - CoolGPIO int32 `yaml:"coolgpio"` - CoolInvert bool `yaml:"coolinvert"` - CoolMinutes float64 `yaml:"coolminutes"` - Verbose bool `yaml:"verbose"` + ID string `json:"id" yaml:"id"` + Alias string `json:"alias" yaml:"alias"` + HighTemp float64 `json:"hightemp" yaml:"hightemp"` + LowTemp float64 `json:"lowtemp" yaml:"lowtemp"` + HeatGPIO int32 `json:"heatgpio" yaml:"heatgpio"` + HeatInvert bool `json:"heatinvert" yaml:"heatinvert"` + HeatMinutes float64 `json:"heatminutes" yaml:"heatminutes"` + CoolGPIO int32 `json:"coolgpio" yaml:"coolgpio"` + CoolInvert bool `json:"coolinvert" yaml:"coolinvert"` + CoolMinutes float64 `json:"coolminutes" yaml:"coolminutes"` + Verbose bool `json:"verbose" yaml:"verbose"` } // Config contains the applications configuration diff --git a/main.go b/main.go index f2243f1..80d1188 100644 --- a/main.go +++ b/main.go @@ -30,7 +30,7 @@ func main() { // Launch the web frontend wg.Add(1) - RunWeb(sc, &wg) + RunWeb(args.ConfigFile, sc, &wg) // Wait for all threads to stop wg.Wait() diff --git a/web.go b/web.go index 8b15705..0bb7e1d 100644 --- a/web.go +++ b/web.go @@ -18,15 +18,37 @@ func PingHandler(c *gin.Context) { c.String(http.StatusOK, "pong") } +// ConfigHandler responds to get requests with the current configuration +func ConfigHandler(config *Config) gin.HandlerFunc { + fn := func(c *gin.Context) { + if c.Param("alias") != "/" && c.Param("alias") != "" { + alias := c.Param("alias")[1:] + found := false + for _, v := range config.Sensors { + if v.ID == alias { + c.JSON(http.StatusOK, v) + found = true + } + } + if !found { + c.String(http.StatusNotFound, "Not found") + } + } else { + c.JSON(http.StatusOK, *config) + } + } + return gin.HandlerFunc(fn) +} + // StatusHandler responds to get requests with the current status of a sensor func StatusHandler(states *map[string]State) gin.HandlerFunc { fn := func(c *gin.Context) { - if c.Param("alias") == "/" { + if c.Param("alias") == "/" || c.Param("alias") == "" { c.JSON(http.StatusOK, states) } else if val, ok := (*states)[c.Param("alias")[1:]]; ok { c.JSON(http.StatusOK, val) } else { - c.JSON(http.StatusNotFound, "Not found") + c.String(http.StatusNotFound, "Not found") } } @@ -34,7 +56,7 @@ func StatusHandler(states *map[string]State) gin.HandlerFunc { } // SetupRouter initializes the gin router. -func SetupRouter(states *map[string]State) *gin.Engine { +func SetupRouter(config *Config, states *map[string]State) *gin.Engine { r := gin.Default() gin.SetMode(gin.ReleaseMode) @@ -43,13 +65,18 @@ func SetupRouter(states *map[string]State) *gin.Engine { r.GET("/ping", PingHandler) // Status + r.GET("/api/status", StatusHandler(states)) r.GET("/api/status/*alias", StatusHandler(states)) + // Config + r.GET("/api/config", ConfigHandler(config)) + r.GET("/api/config/*alias", ConfigHandler(config)) + return r } // RunWeb launches a web server. sc is used to update the states from the Thermostats. -func RunWeb(sc <-chan State, wg *sync.WaitGroup) { +func RunWeb(configpath string, sc <-chan State, wg *sync.WaitGroup) { // Update sensor states when a new state comes back from the thermostat. states := make(map[string]State) go func() { @@ -59,8 +86,24 @@ func RunWeb(sc <-chan State, wg *sync.WaitGroup) { } }() + config, err := LoadConfig(configpath) + if err != nil { + log.Panicln(err) + } + hup := make(chan os.Signal) + signal.Notify(hup, os.Interrupt, syscall.SIGHUP) + go func() { + for { + <-hup + config, err = LoadConfig(configpath) + if err != nil { + log.Panicln(err) + } + } + }() + // Launch the web server - r := SetupRouter(&states) + r := SetupRouter(config, &states) srv := &http.Server{ Addr: ":8080", Handler: r,