1
0
Fork 0
mirror of https://github.com/shouptech/tempgopher.git synced 2026-02-03 16:49:42 +00:00

Basic thermostat stuff

This commit is contained in:
Emma 2018-09-28 15:26:27 -06:00
parent 44f0358259
commit 18fb4bad6d
3 changed files with 77 additions and 10 deletions

View file

@ -14,10 +14,10 @@ type Sensor struct {
LowTemp float64 `yaml:"lowtemp"` LowTemp float64 `yaml:"lowtemp"`
HeatGPIO int32 `yaml:"heatgpio"` HeatGPIO int32 `yaml:"heatgpio"`
HeatPullup bool `yaml:"heatpullup"` HeatPullup bool `yaml:"heatpullup"`
HeatMinutes int32 `yaml:"heatminutes"` HeatMinutes float64 `yaml:"heatminutes"`
CoolGPIO int32 `yaml:"coolgpio"` CoolGPIO int32 `yaml:"coolgpio"`
CoolPullup bool `yaml:"coolpullup"` CoolPullup bool `yaml:"coolpullup"`
CoolMinutes int32 `yaml:"coolminutes"` CoolMinutes float64 `yaml:"coolminutes"`
} }
// Config contains the applications configuration // Config contains the applications configuration

15
main.go
View file

@ -4,7 +4,8 @@ import (
"log" "log"
"sync" "sync"
arg "github.com/alexflint/go-arg" "github.com/alexflint/go-arg"
"github.com/stianeikeland/go-rpio"
) )
func main() { func main() {
@ -23,12 +24,20 @@ func main() {
log.Fatal(err) log.Fatal(err)
} }
var wg sync.WaitGroup // Prep for GPIO access
err = rpio.Open()
if err != nil {
log.Fatal(err)
}
// Launch the thermostat go routines
var wg sync.WaitGroup
for _, sensor := range config.Sensors { for _, sensor := range config.Sensors {
wg.Add(1) wg.Add(1)
go RunThermostat(sensor) go RunThermostat(sensor)
} }
wg.Wait() wg.Wait()
// Close the GPIO access
rpio.Close()
} }

62
run.go
View file

@ -5,6 +5,7 @@ import (
"log" "log"
"time" "time"
"github.com/stianeikeland/go-rpio"
"github.com/yryz/ds18b20" "github.com/yryz/ds18b20"
) )
@ -13,7 +14,7 @@ type State struct {
Temp float64 Temp float64
Cooling bool Cooling bool
Heating bool Heating bool
Duration time.Duration Changed time.Time
} }
// ReadTemperature will return the current temperature (in degrees celsius) of a specific sensor. // ReadTemperature will return the current temperature (in degrees celsius) of a specific sensor.
@ -33,9 +34,42 @@ func ReadTemperature(id string) (float64, error) {
return 0.0, errors.New("Sensor not found") return 0.0, errors.New("Sensor not found")
} }
// SetPinState is used to turn a pin on or off.
// If pullup is true, the pin will be pulled up when turned on, and pulled down when turned off.
func SetPinState(pin rpio.Pin, on bool, pullup bool) {
switch {
case on && pullup:
pin.PullUp()
case on && !pullup:
pin.PullDown()
case !on && !pullup:
pin.PullUp()
default:
pin.PullDown()
}
}
// GetPinState will return true if the pin is on.
// If pullup is true, the pin will be on when pulled up.
func GetPinState(pin rpio.Pin, pullup bool) bool {
switch pin.Read() {
case rpio.High:
return pullup
default:
return !pullup
}
}
// RunThermostat monitors the temperature of the supplied sensor and does its best to keep it at the desired state. // RunThermostat monitors the temperature of the supplied sensor and does its best to keep it at the desired state.
func RunThermostat(sensor Sensor) { func RunThermostat(sensor Sensor) {
var s State var s State
s.Changed = time.Now()
cpin := rpio.Pin(sensor.CoolGPIO)
cpin.Output()
hpin := rpio.Pin(sensor.HeatGPIO)
hpin.Output()
for { for {
t, err := ReadTemperature(sensor.ID) t, err := ReadTemperature(sensor.ID)
@ -43,7 +77,31 @@ func RunThermostat(sensor Sensor) {
log.Panicln(err) log.Panicln(err)
} }
min := time.Since(s.Changed).Minutes()
switch {
case t > sensor.HighTemp && t < sensor.HighTemp:
log.Panic("Invalid state! Temperature is too high AND too low!")
case t > sensor.HighTemp && GetPinState(hpin, sensor.HeatPullup):
SetPinState(hpin, false, sensor.HeatPullup)
case t > sensor.HighTemp && min > sensor.CoolMinutes:
SetPinState(cpin, true, sensor.CoolPullup)
case t > sensor.HighTemp:
break
case t < sensor.LowTemp && GetPinState(cpin, sensor.CoolPullup):
SetPinState(cpin, false, sensor.CoolPullup)
case t < sensor.LowTemp && min > sensor.HeatMinutes:
SetPinState(hpin, true, sensor.HeatPullup)
case t < sensor.LowTemp:
break
default: // Turn off both switches
SetPinState(cpin, false, sensor.CoolPullup)
SetPinState(hpin, false, sensor.HeatPullup)
}
s.Temp = t s.Temp = t
log.Printf("Temp: %.2f, Cooling: %t, Heating: %t Duration: %d", s.Temp, s.Cooling, s.Heating, s.Duration) s.Cooling = GetPinState(cpin, sensor.CoolPullup)
s.Heating = GetPinState(hpin, sensor.HeatPullup)
log.Printf("Temp: %.2f, Cooling: %t, Heating: %t, Changed: %s", s.Temp, s.Cooling, s.Heating, s.Changed)
} }
} }