Refactor configuration

This commit is contained in:
Søren Rasmussen 2022-08-02 07:26:41 +02:00
parent 613f7b6455
commit a5e506b0a5
7 changed files with 103 additions and 73 deletions

View file

@ -9,7 +9,7 @@ import (
"git.joco.dk/sng/fermentord/internal/metrics" "git.joco.dk/sng/fermentord/internal/metrics"
) )
func gpioSetState(state controllers.ChamberState, gpio *hw.Gpio, config *configuration.Configuration) { func gpioSetState(state controllers.ChamberState, gpio *hw.Gpio, config configuration.Configuration) {
switch state { switch state {
case controllers.ChamberStateIdle: case controllers.ChamberStateIdle:
log.Printf("Setting chamber state idle") log.Printf("Setting chamber state idle")

View file

@ -19,7 +19,7 @@ import (
"github.com/spf13/viper" "github.com/spf13/viper"
) )
func mainLoop(ctx context.Context, wg *sync.WaitGroup, js nats.JetStream, config *configuration.Configuration) { func mainLoop(ctx context.Context, wg *sync.WaitGroup, js nats.JetStream) {
defer wg.Done() defer wg.Done()
hub := sentry.CurrentHub().Clone() hub := sentry.CurrentHub().Clone()
@ -34,12 +34,14 @@ func mainLoop(ctx context.Context, wg *sync.WaitGroup, js nats.JetStream, config
defer display.Close() defer display.Close()
// Controller // Controller
ctrl := controllers.NewChamberController(*config) config := configuration.Global()
ctrl := controllers.NewChamberController(config)
// Configuration reload // Configuration reload
loadConfiguration := func() { loadConfiguration := func() {
temperature.ConfigUpdate <- *config cfg := configuration.Global()
ctrl.ConfigUpdates <- *config temperature.ConfigUpdate <- cfg
ctrl.ConfigUpdates <- cfg
//display.SetSetpointTemp(config.FermentationTemperature) //display.SetSetpointTemp(config.FermentationTemperature)
} }

View file

@ -29,9 +29,10 @@ func main() {
defer sentry.Flush(10 * time.Second) defer sentry.Flush(10 * time.Second)
// Configuration // Configuration
config := configuration.LoadConfiguration() configuration.LoadConfiguration()
// NATS // NATS
config := configuration.Global()
servers := strings.Join(config.NATS.Servers, ",") servers := strings.Join(config.NATS.Servers, ",")
userInfo := nats.UserInfo(config.NATS.Username, config.NATS.Password) userInfo := nats.UserInfo(config.NATS.Username, config.NATS.Password)
nc, err := nats.Connect(servers, userInfo) nc, err := nats.Connect(servers, userInfo)
@ -61,7 +62,7 @@ func main() {
wg := &sync.WaitGroup{} wg := &sync.WaitGroup{}
wg.Add(1) wg.Add(1)
go mainLoop(ctx, wg, js, config) go mainLoop(ctx, wg, js)
go srv.ListenAndServe() go srv.ListenAndServe()

View file

@ -2,78 +2,30 @@ package configuration
import ( import (
"log" "log"
"sync"
"github.com/getsentry/sentry-go" "github.com/getsentry/sentry-go"
"github.com/spf13/viper" "github.com/spf13/viper"
) )
type Configuration struct { var (
NATS struct { globalConfig Configuration
Servers []string `mapstructure:"servers"` globalLock *sync.Mutex
Username string `mapstructure:"username"` )
Password string `mapstructure:"password"`
Stream string `mapstructure:"stream"`
Subject struct {
Event string `mapstructure:"event"`
State string `mapstructure:"state"`
Temp string `mapstructure:"temp"`
Tilt string `mapstructure:"tilt"`
} `mapstructure:"subject"`
} `mapstructure:"nats"`
HTTP struct { func init() {
Port int16 `mapstructure:"port"` globalLock = &sync.Mutex{}
} `mapstructure:"http"`
Sensors struct {
Wort string `mapstructure:"wort"`
Chamber string `mapstructure:"chamber"`
Ambient string `mapstructure:"ambient"`
Weight float64 `mapstructure:"weight"`
} `mapstructure:"sensors"`
FermentationTemperature float64 `mapstructure:"fermentation_temp"`
DeltaTemperatureCool float64 `mapstructure:"delta_temp_cool"`
DeltaTemperatureHeat float64 `mapstructure:"delta_temp_heat"`
HeaterEnabled bool `mapstructure:"heater_enabled"`
CoolerEnabled bool `mapstructure:"cooler_enabled"`
Limits struct {
MinChamberTemperature float64 `mapstructure:"min_chamber_temp"`
MaxChamberTemperature float64 `mapstructure:"max_chamber_temp"`
MinCoolerRuntimeSecs float64 `mapstructure:"min_cooler_runtime_secs"`
MaxCoolerRuntimeSecs float64 `mapstructure:"max_cooler_runtime_secs"`
MinCoolerCooldownSecs float64 `mapstructure:"min_cooler_cooldown_secs"`
HeaterGraceTimeSecs float64 `mapstructure:"heater_grace_time_secs"`
} `mapstructure:"limits"`
PID struct {
Kp float64 `mapstructure:"kp"` // 2.0
Ki float64 `mapstructure:"ki"` // 0.0001
Kd float64 `mapstructure:"kd"` // 2.0
} `mapstructure:"pid"`
} }
func LoadConfiguration() *Configuration { func Global() (c Configuration) {
viper.SetDefault("cooler_enabled", true) globalLock.Lock()
viper.SetDefault("heater_enabled", true) c = globalConfig
viper.SetDefault("http.port", 8000) globalLock.Unlock()
viper.SetDefault("nats.stream", "DWJONDAHL") return
viper.SetDefault("nats.subject.event", "DWJONDAHL.ingest.fermentor.ingest_event") }
viper.SetDefault("nats.subject.state", "DWJONDAHL.ingest.fermentor.ingest_state")
viper.SetDefault("nats.subject.temp", "DWJONDAHL.ingest.fermentor.ingest_temperature_reading") func LoadConfiguration() {
viper.SetDefault("nats.subject.tilt", "DWJONDAHL.ingest.fermentor.ingest_tilt_reading") setDefaults()
viper.SetDefault("nats.url", "nats.service.consul")
viper.SetDefault("pid.kd", 2.0)
viper.SetDefault("pid.ki", 0.0001)
viper.SetDefault("pid.kp", 2.0)
viper.SetDefault("limits.heater_grace_time_secs", 1800)
viper.SetDefault("limits.max_chamber_temp", 40)
viper.SetDefault("limits.max_cooler_runtime_secs", 86400)
viper.SetDefault("limits.min_chamber_temp", 5)
viper.SetDefault("limits.min_cooler_cooldown_secs", 300)
viper.SetDefault("limits.min_cooler_runtime_secs", 300)
viper.SetDefault("sensors.weight", 0.8)
viper.AddConfigPath("/etc") viper.AddConfigPath("/etc")
viper.AddConfigPath("/usr/local/etc") viper.AddConfigPath("/usr/local/etc")
@ -91,5 +43,7 @@ func LoadConfiguration() *Configuration {
log.Fatal(err) log.Fatal(err)
} }
return config globalLock.Lock()
globalConfig = *config
globalLock.Unlock()
} }

View file

@ -0,0 +1,72 @@
package configuration
import "github.com/spf13/viper"
type Configuration struct {
NATS struct {
Servers []string `mapstructure:"servers"`
Username string `mapstructure:"username"`
Password string `mapstructure:"password"`
Stream string `mapstructure:"stream"`
Subject struct {
Event string `mapstructure:"event"`
State string `mapstructure:"state"`
Temp string `mapstructure:"temp"`
Tilt string `mapstructure:"tilt"`
} `mapstructure:"subject"`
} `mapstructure:"nats"`
HTTP struct {
Port int16 `mapstructure:"port"`
} `mapstructure:"http"`
Sensors struct {
Wort string `mapstructure:"wort"`
Chamber string `mapstructure:"chamber"`
Ambient string `mapstructure:"ambient"`
Weight float64 `mapstructure:"weight"`
} `mapstructure:"sensors"`
FermentationTemperature float64 `mapstructure:"fermentation_temp"`
DeltaTemperatureCool float64 `mapstructure:"delta_temp_cool"`
DeltaTemperatureHeat float64 `mapstructure:"delta_temp_heat"`
HeaterEnabled bool `mapstructure:"heater_enabled"`
CoolerEnabled bool `mapstructure:"cooler_enabled"`
Limits struct {
MinChamberTemperature float64 `mapstructure:"min_chamber_temp"`
MaxChamberTemperature float64 `mapstructure:"max_chamber_temp"`
MinCoolerRuntimeSecs float64 `mapstructure:"min_cooler_runtime_secs"`
MaxCoolerRuntimeSecs float64 `mapstructure:"max_cooler_runtime_secs"`
MinCoolerCooldownSecs float64 `mapstructure:"min_cooler_cooldown_secs"`
HeaterGraceTimeSecs float64 `mapstructure:"heater_grace_time_secs"`
} `mapstructure:"limits"`
PID struct {
Kp float64 `mapstructure:"kp"` // 2.0
Ki float64 `mapstructure:"ki"` // 0.0001
Kd float64 `mapstructure:"kd"` // 2.0
} `mapstructure:"pid"`
}
func setDefaults() {
viper.SetDefault("cooler_enabled", true)
viper.SetDefault("heater_enabled", true)
viper.SetDefault("http.port", 8000)
viper.SetDefault("nats.stream", "DWJONDAHL")
viper.SetDefault("nats.subject.event", "DWJONDAHL.ingest.fermentor.ingest_event")
viper.SetDefault("nats.subject.state", "DWJONDAHL.ingest.fermentor.ingest_state")
viper.SetDefault("nats.subject.temp", "DWJONDAHL.ingest.fermentor.ingest_temperature_reading")
viper.SetDefault("nats.subject.tilt", "DWJONDAHL.ingest.fermentor.ingest_tilt_reading")
viper.SetDefault("nats.url", "nats.service.consul")
viper.SetDefault("pid.kd", 2.0)
viper.SetDefault("pid.ki", 0.0001)
viper.SetDefault("pid.kp", 2.0)
viper.SetDefault("limits.heater_grace_time_secs", 1800)
viper.SetDefault("limits.max_chamber_temp", 40)
viper.SetDefault("limits.max_cooler_runtime_secs", 86400)
viper.SetDefault("limits.min_chamber_temp", 5)
viper.SetDefault("limits.min_cooler_cooldown_secs", 300)
viper.SetDefault("limits.min_cooler_runtime_secs", 300)
viper.SetDefault("sensors.weight", 0.8)
}

View file

@ -86,6 +86,7 @@ func (p *ChamberController) Run(ctx context.Context, wg *sync.WaitGroup) {
case c := <-p.ConfigUpdates: case c := <-p.ConfigUpdates:
p.config = c p.config = c
log.Printf("Fermentation temperature set to %v", p.config.FermentationTemperature)
case <-ctx.Done(): case <-ctx.Done():
ticker.Stop() ticker.Stop()

View file

@ -59,7 +59,7 @@ func (p *DWIngest) AddState(state controllers.ChamberState) {
} }
} }
func (p *DWIngest) Run(ctx context.Context, wg *sync.WaitGroup, config *configuration.Configuration) { func (p *DWIngest) Run(ctx context.Context, wg *sync.WaitGroup, config configuration.Configuration) {
defer wg.Done() defer wg.Done()
defer p.hub.Flush(10 * time.Second) defer p.hub.Flush(10 * time.Second)