Refactor configuration

This commit is contained in:
Søren Rasmussen 2022-03-11 21:06:33 +01:00
parent 43241991c0
commit 08ebdc5045
7 changed files with 119 additions and 111 deletions

View file

@ -1,63 +0,0 @@
package main
import (
"log"
"time"
"git.joco.dk/sng/fermentord/internal/controllers"
"git.joco.dk/sng/fermentord/pkg/temperature"
"github.com/getsentry/sentry-go"
"github.com/spf13/viper"
)
func loadConfiguration() *controllers.ControllerConfig {
hub := sentry.CurrentHub().Clone()
defer hub.Flush(10 * time.Second)
viper.SetDefault("http.port", 8000)
viper.SetDefault("main.data_path", "./data.txt")
viper.SetDefault("nats.stream", "FERMENTOR")
viper.SetDefault("nats.subject.state", "FERMENTOR.state")
viper.SetDefault("nats.subject.temp", "FERMENTOR.temp")
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("/usr/local/etc")
viper.AddConfigPath(".")
viper.SetConfigName("fermentord")
viper.SetConfigType("toml")
if err := viper.ReadInConfig(); err != nil {
log.Printf("Error loading configuration: %v", err)
}
config := &controllers.ControllerConfig{}
if err := viper.Unmarshal(config); err != nil {
hub.CaptureException(err)
log.Fatal(err)
}
return config
}
func reloadConfiguration(config *controllers.ControllerConfig, ctrl *controllers.ChamberController) {
log.Printf("Reloading configuration")
temperature.ConfigUpdates <- []string{
config.Sensors.Ambient,
config.Sensors.Chamber,
config.Sensors.Wort,
}
ctrl.ConfigUpdates <- *config
}

View file

@ -8,6 +8,7 @@ import (
"sync"
"time"
"git.joco.dk/sng/fermentord/internal/configuration"
"git.joco.dk/sng/fermentord/internal/controllers"
"git.joco.dk/sng/fermentord/pkg/temperature"
"github.com/getsentry/sentry-go"
@ -17,7 +18,7 @@ var (
f *os.File
)
func persistData(ctx context.Context, wg *sync.WaitGroup, chState <-chan controllers.ChamberState, chTemp <-chan temperature.TemperatureReading, config *controllers.ControllerConfig) {
func persistData(ctx context.Context, wg *sync.WaitGroup, chState <-chan controllers.ChamberState, chTemp <-chan temperature.TemperatureReading, config *configuration.ControllerConfig) {
var err error
hub := sentry.CurrentHub().Clone()

View file

@ -10,6 +10,7 @@ import (
"time"
"git.joco.dk/sng/fermentord/internal/api"
"git.joco.dk/sng/fermentord/internal/configuration"
"git.joco.dk/sng/fermentord/internal/controllers"
"git.joco.dk/sng/fermentord/internal/hw"
"git.joco.dk/sng/fermentord/internal/metrics"
@ -22,7 +23,7 @@ import (
"github.com/spf13/viper"
)
func mainLoop(ctx context.Context, wg *sync.WaitGroup, js nats.JetStream, config *controllers.ControllerConfig) {
func mainLoop(ctx context.Context, wg *sync.WaitGroup, js nats.JetStream, config *configuration.ControllerConfig) {
hub := sentry.CurrentHub().Clone()
defer hub.Flush(10 * time.Second)
defer wg.Done()
@ -36,10 +37,10 @@ func mainLoop(ctx context.Context, wg *sync.WaitGroup, js nats.JetStream, config
// Configuration reload
viper.OnConfigChange(func(in fsnotify.Event) {
reloadConfiguration(config, ctrl)
controllers.ReloadConfiguration(config, ctrl)
})
viper.WatchConfig()
reloadConfiguration(config, ctrl)
controllers.ReloadConfiguration(config, ctrl)
gpio, err := hw.NewGpio()
if err != nil {
@ -126,7 +127,7 @@ func main() {
defer sentry.Flush(10 * time.Second)
// Configuration
config := loadConfiguration()
config := configuration.LoadConfiguration()
// NATS
nc, err := nats.Connect(config.NATS.URL)

View file

@ -5,13 +5,13 @@ import (
"log"
"net/http"
"git.joco.dk/sng/fermentord/internal/controllers"
"git.joco.dk/sng/fermentord/internal/configuration"
"github.com/getsentry/sentry-go"
"github.com/nats-io/nats.go"
)
type API struct {
config *controllers.ControllerConfig
config *configuration.ControllerConfig
configChangeCallback func()
nc *nats.Conn
}

View file

@ -0,0 +1,92 @@
package configuration
import (
"log"
"time"
"github.com/getsentry/sentry-go"
"github.com/spf13/viper"
)
type ControllerConfig struct {
NATS struct {
URL string `mapstructure:"url"`
Stream string `mapstructure:"stream"`
Subject struct {
Temp string `mapstructure:"temp"`
State string `mapstructure:"state"`
} `mapstructure:"subject"`
} `mapstructure:"nats"`
HTTP struct {
Port int16 `mapstructure:"port"`
} `mapstructure:"http"`
DataPath string `mapstructure:"data_path"`
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"`
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() *ControllerConfig {
hub := sentry.CurrentHub().Clone()
defer hub.Flush(10 * time.Second)
viper.SetDefault("http.port", 8000)
viper.SetDefault("main.data_path", "./data.txt")
viper.SetDefault("nats.stream", "FERMENTOR")
viper.SetDefault("nats.subject.state", "FERMENTOR.state")
viper.SetDefault("nats.subject.temp", "FERMENTOR.temp")
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("/usr/local/etc")
viper.AddConfigPath(".")
viper.SetConfigName("fermentord")
viper.SetConfigType("toml")
if err := viper.ReadInConfig(); err != nil {
log.Printf("Error loading configuration: %v", err)
}
config := &ControllerConfig{}
if err := viper.Unmarshal(config); err != nil {
hub.CaptureException(err)
log.Fatal(err)
}
return config
}

View file

@ -7,6 +7,7 @@ import (
"sync"
"time"
"git.joco.dk/sng/fermentord/internal/configuration"
"git.joco.dk/sng/fermentord/pkg/temperature"
"github.com/getsentry/sentry-go"
)
@ -26,8 +27,8 @@ var ChamberStateMap = map[ChamberState]string{
}
type ChamberController struct {
ConfigUpdates chan ControllerConfig
config ControllerConfig
ConfigUpdates chan configuration.ControllerConfig
config configuration.ControllerConfig
// Current state.
chamberState ChamberState
@ -48,7 +49,7 @@ type ChamberController struct {
hub *sentry.Hub
}
func NewChamberController(name string, config ControllerConfig, chTemp <-chan temperature.TemperatureReading) *ChamberController {
func NewChamberController(name string, config configuration.ControllerConfig, chTemp <-chan temperature.TemperatureReading) *ChamberController {
return &ChamberController{
C: make(chan ChamberState),
name: name,
@ -56,7 +57,7 @@ func NewChamberController(name string, config ControllerConfig, chTemp <-chan te
pid: NewPIDController(config.PID.Kp, config.PID.Ki, config.PID.Kd),
chTemp: chTemp,
chamberState: ChamberStateIdle,
ConfigUpdates: make(chan ControllerConfig, 1),
ConfigUpdates: make(chan configuration.ControllerConfig, 1),
hub: sentry.CurrentHub().Clone(),
}
}

View file

@ -1,44 +1,20 @@
package controllers
type ControllerConfig struct {
NATS struct {
URL string `mapstructure:"url"`
Stream string `mapstructure:"stream"`
Subject struct {
Temp string `mapstructure:"temp"`
State string `mapstructure:"state"`
} `mapstructure:"subject"`
} `mapstructure:"nats"`
import (
"log"
HTTP struct {
Port int16 `mapstructure:"port"`
} `mapstructure:"http"`
"git.joco.dk/sng/fermentord/internal/configuration"
"git.joco.dk/sng/fermentord/pkg/temperature"
)
DataPath string `mapstructure:"data_path"`
func ReloadConfiguration(config *configuration.ControllerConfig, ctrl *ChamberController) {
log.Printf("Reloading configuration")
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"`
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"`
temperature.ConfigUpdates <- []string{
config.Sensors.Ambient,
config.Sensors.Chamber,
config.Sensors.Wort,
}
ctrl.ConfigUpdates <- *config
}