Reset 1-wire bus when temperature readings fail 60 consecutive times
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
Søren Rasmussen 2022-08-01 19:49:52 +02:00
parent dac484d802
commit e25905c20f
5 changed files with 79 additions and 26 deletions

View file

@ -2,7 +2,6 @@ package main
import (
"context"
"encoding/json"
"log"
"sync"
"time"
@ -68,6 +67,11 @@ func mainLoop(ctx context.Context, wg *sync.WaitGroup, js nats.JetStream, config
go temperature.PollSensors(ctx, wg, 1*time.Second, config.Sensors.Weight)
go tilt.PollSensors(ctx, wg, 1*time.Minute, 20*time.Second)
oneWirePowerUpChannel := make(chan bool)
oneWirePowerUpTimer := time.AfterFunc(1*time.Millisecond, func() {
oneWirePowerUpChannel <- true
})
for {
select {
case reading := <-temperature.Reading:
@ -75,6 +79,25 @@ func mainLoop(ctx context.Context, wg *sync.WaitGroup, js nats.JetStream, config
ingest.AddReading(reading)
//display.SetTemperature(reading)
case <-temperature.RequestReset:
log.Print("Powering down one wire bus for 20 seconds")
gpio.StopOneWirePower()
oneWirePowerUpTimer.Reset(20 * time.Second)
// Publish to NATS
e := dwingest.Event{
Time: time.Now().UTC(),
Event: "ONEWIRE_RESET",
}
if err := ingest.Publish(config.NATS.Subject.Event, js, e); err != nil {
hub.CaptureException(err)
log.Print(err)
}
case <-oneWirePowerUpChannel:
log.Print("Powering up one wire bus")
gpio.StartOneWirePower()
case ev := <-gpio.C:
var evs string
@ -96,19 +119,12 @@ func mainLoop(ctx context.Context, wg *sync.WaitGroup, js nats.JetStream, config
evs = "DOOR_OPENED"
}
b, err := json.Marshal(map[string]interface{}{
"time": time.Now().UTC(),
"event": evs,
})
if err != nil {
hub.CaptureException(err)
log.Printf("Error marshaling JSON: %v", err)
break
}
// Publish to NATS
_, err = js.Publish(config.NATS.Subject.Event, b, nats.AckWait(1*time.Second))
if err != nil {
e := dwingest.Event{
Time: time.Now().UTC(),
Event: evs,
}
if err := ingest.Publish(config.NATS.Subject.Event, js, e); err != nil {
hub.CaptureException(err)
log.Print(err)
}

View file

@ -64,16 +64,16 @@ func (p *DWIngest) Run(ctx context.Context, wg *sync.WaitGroup, js nats.JetStrea
for {
select {
case reading := <-p.chTemperatureReading:
p.publish(config.NATS.Subject.Temp, js, reading)
p.Publish(config.NATS.Subject.Temp, js, reading)
case state := <-p.chState:
p.publish(config.NATS.Subject.State, js, State{
p.Publish(config.NATS.Subject.State, js, State{
Time: time.Now().UTC(),
State: controllers.ChamberStateMap[state],
})
case t := <-tilt.C:
p.publish(config.NATS.Subject.Tilt, js, Tilt{
p.Publish(config.NATS.Subject.Tilt, js, Tilt{
Time: time.Now().UTC(),
Color: string(t.Color()),
Gravity: t.Gravity(),
@ -86,7 +86,7 @@ func (p *DWIngest) Run(ctx context.Context, wg *sync.WaitGroup, js nats.JetStrea
}
}
func (p *DWIngest) publish(subject string, js nats.JetStream, reading any) error {
func (p *DWIngest) Publish(subject string, js nats.JetStream, reading any) error {
b, err := json.Marshal(reading)
if err != nil {
p.hub.CaptureException(err)

View file

@ -13,3 +13,8 @@ type Tilt struct {
Gravity float64 `json:"gravity"`
Temperature float64 `json:"temperature"`
}
type Event struct {
Time time.Time `json:"time"`
Event string `json:"event"`
}

View file

@ -13,6 +13,10 @@ const (
pinHeaterPower = 24
pinLightsPower = 25
// GPIO21 is located at pin 13 on RPi 1B rev 1. Rev 2 and never boards
// has GPIO27 here.
pinOneWirePower = 21
off = 0
on = 1
)
@ -26,12 +30,13 @@ const (
)
type Gpio struct {
chip *gpiod.Chip
doorOpen *gpiod.Line
lightsPower *gpiod.Line
fanPower *gpiod.Line
coolerPower *gpiod.Line
heaterPower *gpiod.Line
chip *gpiod.Chip
doorOpen *gpiod.Line
oneWirePower *gpiod.Line
lightsPower *gpiod.Line
fanPower *gpiod.Line
coolerPower *gpiod.Line
heaterPower *gpiod.Line
C chan HWEvent
}
@ -71,6 +76,11 @@ func NewGpio() (*Gpio, error) {
p.C <- DoorClosed
}
p.oneWirePower, err = p.chip.RequestLine(pinOneWirePower, gpiod.AsOutput(0))
if err != nil {
return nil, err
}
p.lightsPower, err = p.chip.RequestLine(pinLightsPower, gpiod.AsOutput(0))
if err != nil {
return nil, err
@ -99,7 +109,9 @@ func (p *Gpio) Close() {
p.heaterPower.SetValue(off)
p.fanPower.SetValue(off)
p.lightsPower.SetValue(off)
p.oneWirePower.SetValue(off)
p.oneWirePower.Close()
p.heaterPower.Close()
p.coolerPower.Close()
p.fanPower.Close()
@ -142,6 +154,16 @@ func (p *Gpio) LightsOff() {
p.lightsPower.SetValue(off)
}
func (p *Gpio) StartOneWirePower() {
// Inverted logic due to PNP transistor switch
p.oneWirePower.SetValue(off)
}
func (p *Gpio) StopOneWirePower() {
// Inverted logic due to PNP transistor switch
p.oneWirePower.SetValue(on)
}
func (p *Gpio) onDoorStateChanged(le gpiod.LineEvent) {
switch le.Type {
case gpiod.LineEventFallingEdge:

View file

@ -42,6 +42,7 @@ var (
// Reading receives the temperature readings
Reading chan TemperatureReading
ConfigUpdate chan configuration.Configuration
RequestReset chan bool
accErrTrigger int
sensors []Sensor
@ -50,6 +51,7 @@ var (
func init() {
Reading = make(chan TemperatureReading, 30)
ConfigUpdate = make(chan configuration.Configuration, 1)
RequestReset = make(chan bool)
sensors = make([]Sensor, 0)
}
@ -75,7 +77,6 @@ func PollSensors(ctx context.Context, wg *sync.WaitGroup, readingInterval time.D
defer ticker.Stop()
for {
work_loop:
select {
case <-ticker.C:
poll_bus:
@ -100,7 +101,7 @@ func PollSensors(ctx context.Context, wg *sync.WaitGroup, readingInterval time.D
accErrTrigger++
hub.CaptureException(err)
log.Print(err)
break work_loop
break
}
accErrTrigger = 0
@ -119,7 +120,16 @@ func PollSensors(ctx context.Context, wg *sync.WaitGroup, readingInterval time.D
}
if accErrTrigger > 60 {
log.Fatal("Thermal bulk read failed 60 times in a row -- terminating")
select {
case RequestReset <- true:
log.Print("Thermal bulk read failed 60 times in a row -- bus reset")
// Reset counter to allow 60 more reads
accErrTrigger = 0
default:
log.Fatal("Thermal bulk read failed 60 times in a row -- terminating")
}
}
case c := <-ConfigUpdate: