diff --git a/config.go b/config.go index 6a77964..f24e29e 100644 --- a/config.go +++ b/config.go @@ -5,7 +5,7 @@ import ( "encoding/base64" "encoding/json" "flag" - "io/ioutil" + "os" "path/filepath" "time" @@ -50,6 +50,7 @@ type PersistedConfig struct { Disabled bool ButtonDisabled bool SolarDisabled bool + CoolDisabled bool Auth string Pin string Target float64 @@ -146,14 +147,14 @@ func (c *Config) Save() error { } cfgFilename := filepath.Join(*c.dataDirectory, serverConfiguration) Info("Writing config file to: %s\n%s", cfgFilename, string(buf)) - err = ioutil.WriteFile(cfgFilename, buf, 0600) + err = os.WriteFile(cfgFilename, buf, 0600) return err } // Read reads the config from the fileystem func (c *Config) Read() error { cfgFilename := filepath.Join(*c.dataDirectory, serverConfiguration) - cfg, err := ioutil.ReadFile(cfgFilename) + cfg, err := os.ReadFile(cfgFilename) if err != nil { Error("Unable to read configuration file: %s", err.Error()) return err diff --git a/main.go b/main.go index 98b9a5d..00e98e6 100644 --- a/main.go +++ b/main.go @@ -3,7 +3,6 @@ package main import ( "flag" "fmt" - "io/ioutil" "os" "github.com/brutella/hc" @@ -26,7 +25,7 @@ func main() { Info("Args: %s", os.Args[1:]) // Write PID - err := ioutil.WriteFile(*config.pidfile, []byte(fmt.Sprintf("%d", os.Getpid())), 0644) + err := os.WriteFile(*config.pidfile, []byte(fmt.Sprintf("%d", os.Getpid())), 0644) if err != nil { Fatal("Could not write pid file: %s", err.Error()) } diff --git a/poolpump.go b/poolpump.go index 622b4e5..7258177 100644 --- a/poolpump.go +++ b/poolpump.go @@ -88,11 +88,11 @@ func (ppc *PoolPumpController) Update() error { // (probably at night), running the pumps with solar on would help bring the water // down to the target temperature. func (ppc *PoolPumpController) shouldCool() bool { - if ppc.config.cfg.SolarDisabled { + if ppc.config.cfg.SolarDisabled || ppc.config.cfg.CoolDisabled { return false } - return ppc.pumpTemp.Temperature() > (ppc.config.cfg.Target+ppc.config.cfg.Tolerance) && - ppc.pumpTemp.Temperature() > (ppc.roofTemp.Temperature()+ppc.config.cfg.DeltaT) + return ppc.runningTemp.Temperature() > (ppc.config.cfg.Target+(2*ppc.config.cfg.Tolerance)) && + ppc.runningTemp.Temperature() > (ppc.roofTemp.Temperature()+ppc.config.cfg.DeltaT) } // A return value of 'True' indicates that the pool is too cool and the roof is hot, running @@ -103,19 +103,20 @@ func (ppc *PoolPumpController) shouldWarm() bool { return false } - waterCold := ppc.pumpTemp.Temperature() < (ppc.config.cfg.Target - ppc.config.cfg.Tolerance) - roofHot := ppc.pumpTemp.Temperature() < (ppc.roofTemp.Temperature() - ppc.config.cfg.DeltaT) + waterCold := ppc.runningTemp.Temperature() < (ppc.config.cfg.Target - ppc.config.cfg.Tolerance) + roofHot := ppc.runningTemp.Temperature() < (ppc.roofTemp.Temperature() - ppc.config.cfg.DeltaT) warm := waterCold && roofHot if warm { Info("ShouldWarm: %t waterCold(%t) roofHot(%t)", warm, waterCold, roofHot) + Info(ppc.Status()) Info("Temp(%0.3f) < %0.3f {Target(%0.3f) - Tolerance(%0.3f)} : WaterCold(%t)", - ppc.pumpTemp.Temperature(), + ppc.runningTemp.Temperature(), ppc.config.cfg.Target-ppc.config.cfg.Tolerance, ppc.config.cfg.Target, ppc.config.cfg.Tolerance, waterCold) Info("Temp(%0.3f) < %0.3f {Roof(%0.3f) - DeltaT(%0.3f)} : RoofHot(%t)", - ppc.pumpTemp.Temperature(), + ppc.runningTemp.Temperature(), ppc.roofTemp.Temperature()-ppc.config.cfg.DeltaT, ppc.roofTemp.Temperature(), ppc.config.cfg.DeltaT, @@ -150,8 +151,8 @@ func (ppc *PoolPumpController) RunPumpsIfNeeded() { return } Info("ShouldCool(%t) - ShouldWarm(%t)", ppc.shouldCool(), ppc.shouldWarm()) - if ppc.pumpTemp.Temperature() < ppc.config.cfg.Target-ppc.config.cfg.DeltaT || - ppc.pumpTemp.Temperature() > ppc.config.cfg.Target+ppc.config.cfg.Tolerance { + if ppc.runningTemp.Temperature() < ppc.config.cfg.Target-ppc.config.cfg.DeltaT || + ppc.runningTemp.Temperature() > ppc.config.cfg.Target+(2*ppc.config.cfg.Tolerance) { ppc.switches.SetState(MIXING, false, ppc.config.cfg.RunTime) } else { // Just push water through the panels @@ -172,7 +173,7 @@ func (ppc *PoolPumpController) RunPumpsIfNeeded() { return } // If there is no reason to turn on the pumps and it's not manual, turn off - if state > OFF && ppc.switches.GetStartTime().Add(time.Hour).Before(time.Now()) { + if state > OFF && ppc.switches.GetStartTime().Add(time.Minute*5).Before(time.Now()) { ppc.switches.StopAll(false) } } diff --git a/server.go b/server.go index fc8e0c9..e782afb 100644 --- a/server.go +++ b/server.go @@ -476,6 +476,9 @@ func (h *Handler) processForm(r *http.Request, c *Config) { if processBoolUpdate(r, "solar_disabled", &c.cfg.SolarDisabled) { foundone = true } + if processBoolUpdate(r, "cool_disabled", &c.cfg.CoolDisabled) { + foundone = true + } if processFloatUpdate(r, "daily_freq", &c.cfg.DailyFrequency) { foundone = true } @@ -547,6 +550,7 @@ func (h *Handler) configHandler(w http.ResponseWriter, r *http.Request) { html += h.configBoolRow("Disable all pumps", "disabled", c.cfg.Disabled) html += h.configBoolRow("Disable button", "button_disabled", c.cfg.ButtonDisabled) html += h.configBoolRow("Disable solar", "solar_disabled", c.cfg.SolarDisabled) + html += h.configBoolRow("Disable cooling", "cool_disabled", c.cfg.CoolDisabled) html += "\n" html += "\n" diff --git a/switches.go b/switches.go index 0dc30ac..8a7696d 100644 --- a/switches.go +++ b/switches.go @@ -118,10 +118,11 @@ func (p *Switches) bindHK() { state := p.state switch p.state { case SWEEP: - case MIXING: if on { state = MIXING - } else { + } + case MIXING: + if !on { state = SWEEP } case SOLAR: @@ -182,11 +183,7 @@ func (p *Switches) setSwitches(pumpOn, sweepOn, solarOn, isManual bool, state St turnOn(p.sweep, sweepOn) turnOn(p.solar, solarOn) // deal with solar valve last because it takes time if isManual { - if p.GetStartTime().After(p.GetStopTime()) { - p.manualOp = p.GetStartTime() - } else { - p.manualOp = p.GetStopTime() - } + p.manualOp = time.Now() } p.state = state } @@ -253,14 +250,5 @@ func DurationFromHours(hours float64, minHours float64) time.Duration { // ManualState returns true if the pumps were started or stopped manually func (p *Switches) ManualState(runtime float64) bool { - if time.Since(p.manualOp) > DurationFromHours(runtime, 2.0) { - return false - } - if p.manualOp.Equal(p.GetStartTime()) && p.GetStartTime().After(p.GetStopTime()) { - return true - } - if p.manualOp.Equal(p.GetStopTime()) && p.GetStopTime().After(p.GetStartTime()) { - return true - } - return false + return time.Since(p.manualOp) < DurationFromHours(runtime, 2.0) } diff --git a/thermometer.go b/thermometer.go index c0947ee..f7c2f79 100644 --- a/thermometer.go +++ b/thermometer.go @@ -234,7 +234,7 @@ func (t *GpioThermometer) Update() error { stdd := t.history.Stddev() avg := t.history.Average() med := t.history.Median() - dev := stdd * 3 + dev := stdd * 2 // Throw away bad results if math.Abs(avg-h.Median()) > dev { @@ -247,7 +247,7 @@ func (t *GpioThermometer) Update() error { dev/MillisecondFloat) return fmt.Errorf("could not update temperature successfully") } - ohms := t.getOhms(time.Duration(int64(h.Median()))) + ohms := t.getOhms(time.Duration(int64(avg))) temp := t.getTemp(ohms) Debug("Calculating temperature (%f) for %s: %f ohms, median %s", temp, t.name, ohms, time.Duration(int64(h.Median()))) t.accessory.TempSensor.CurrentTemperature.SetValue(temp)