From 5b27891ca156f43402f2d986675f5d5b1b8d68c1 Mon Sep 17 00:00:00 2001 From: Mike Shoup Date: Tue, 2 Oct 2018 08:47:19 -0600 Subject: [PATCH] Better handling of the current state of things --- thermostat.go | 11 +++++++++-- web.go | 28 +++++++++++++++------------- 2 files changed, 24 insertions(+), 15 deletions(-) diff --git a/thermostat.go b/thermostat.go index 62bff2b..ab7bba0 100644 --- a/thermostat.go +++ b/thermostat.go @@ -63,6 +63,8 @@ func ProcessSensor(sensor Sensor, state State) (State, error) { log.Panicln(err) } + state.When = time.Now() + // Initialize the pins cpin := rpio.Pin(sensor.CoolGPIO) cpin.Output() @@ -72,6 +74,11 @@ func ProcessSensor(sensor Sensor, state State) (State, error) { // Calculate duration duration := time.Since(state.Changed).Minutes() + // When things reach the right temperature, set the duration to the future + // TODO: Better handling of this. Changed should maintain when the state changed. + // Probably need a new flag in the State struct. + future := time.Now().AddDate(10, 0, 0) + switch { case temp > sensor.HighTemp && temp < sensor.LowTemp: log.Println("Invalid state! Temperature is too high AND too low!") @@ -79,7 +86,7 @@ func ProcessSensor(sensor Sensor, state State) (State, error) { case temp > sensor.LowTemp && state.Heating: PinSwitch(hpin, false, sensor.HeatInvert) state.Heating = false - state.Changed = time.Unix(1<<63-62135596801, 999999999) + state.Changed = future // Temperature is too high and the cooling switch is still on, do nothing case temp > sensor.HighTemp && state.Cooling: break @@ -95,7 +102,7 @@ func ProcessSensor(sensor Sensor, state State) (State, error) { case temp < sensor.HighTemp && state.Cooling: PinSwitch(cpin, false, sensor.CoolInvert) state.Cooling = false - state.Changed = time.Unix(1<<63-62135596801, 999999999) + state.Changed = future // Temperature is too low and the heating switch is on, do nothing case temp < sensor.LowTemp && state.Heating: break diff --git a/web.go b/web.go index 04c02b9..8b15705 100644 --- a/web.go +++ b/web.go @@ -13,26 +13,28 @@ import ( "github.com/gin-gonic/gin" ) -var states map[string]State - // PingHandler responds to get requests with the message "pong". func PingHandler(c *gin.Context) { c.String(http.StatusOK, "pong") } // StatusHandler responds to get requests with the current status of a sensor -func StatusHandler(c *gin.Context) { - if 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") +func StatusHandler(states *map[string]State) gin.HandlerFunc { + fn := func(c *gin.Context) { + if 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") + } } + + return gin.HandlerFunc(fn) } // SetupRouter initializes the gin router. -func SetupRouter() *gin.Engine { +func SetupRouter(states *map[string]State) *gin.Engine { r := gin.Default() gin.SetMode(gin.ReleaseMode) @@ -41,7 +43,7 @@ func SetupRouter() *gin.Engine { r.GET("/ping", PingHandler) // Status - r.GET("/api/status/*alias", StatusHandler) + r.GET("/api/status/*alias", StatusHandler(states)) return r } @@ -49,7 +51,7 @@ func SetupRouter() *gin.Engine { // RunWeb launches a web server. sc is used to update the states from the Thermostats. func RunWeb(sc <-chan State, wg *sync.WaitGroup) { // Update sensor states when a new state comes back from the thermostat. - states = make(map[string]State) + states := make(map[string]State) go func() { for { s := <-sc @@ -58,7 +60,7 @@ func RunWeb(sc <-chan State, wg *sync.WaitGroup) { }() // Launch the web server - r := SetupRouter() + r := SetupRouter(&states) srv := &http.Server{ Addr: ":8080", Handler: r,