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:
parent
44f0358259
commit
18fb4bad6d
3 changed files with 77 additions and 10 deletions
|
|
@ -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
15
main.go
|
|
@ -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
62
run.go
|
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue