1
0
Fork 0
mirror of https://github.com/shouptech/tempgopher.git synced 2026-02-03 08:39:43 +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"`
HeatGPIO int32 `yaml:"heatgpio"`
HeatPullup bool `yaml:"heatpullup"`
HeatMinutes int32 `yaml:"heatminutes"`
HeatMinutes float64 `yaml:"heatminutes"`
CoolGPIO int32 `yaml:"coolgpio"`
CoolPullup bool `yaml:"coolpullup"`
CoolMinutes int32 `yaml:"coolminutes"`
CoolMinutes float64 `yaml:"coolminutes"`
}
// Config contains the applications configuration

15
main.go
View file

@ -4,7 +4,8 @@ import (
"log"
"sync"
arg "github.com/alexflint/go-arg"
"github.com/alexflint/go-arg"
"github.com/stianeikeland/go-rpio"
)
func main() {
@ -23,12 +24,20 @@ func main() {
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 {
wg.Add(1)
go RunThermostat(sensor)
}
wg.Wait()
// Close the GPIO access
rpio.Close()
}

68
run.go
View file

@ -5,15 +5,16 @@ import (
"log"
"time"
"github.com/stianeikeland/go-rpio"
"github.com/yryz/ds18b20"
)
// State represents the current state of the thermostat
type State struct {
Temp float64
Cooling bool
Heating bool
Duration time.Duration
Temp float64
Cooling bool
Heating bool
Changed time.Time
}
// 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")
}
// 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.
func RunThermostat(sensor Sensor) {
var s State
s.Changed = time.Now()
cpin := rpio.Pin(sensor.CoolGPIO)
cpin.Output()
hpin := rpio.Pin(sensor.HeatGPIO)
hpin.Output()
for {
t, err := ReadTemperature(sensor.ID)
@ -43,7 +77,31 @@ func RunThermostat(sensor Sensor) {
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
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)
}
}