Refactor configuration
This commit is contained in:
parent
43241991c0
commit
08ebdc5045
7 changed files with 119 additions and 111 deletions
|
@ -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
|
|
||||||
}
|
|
|
@ -8,6 +8,7 @@ import (
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"git.joco.dk/sng/fermentord/internal/configuration"
|
||||||
"git.joco.dk/sng/fermentord/internal/controllers"
|
"git.joco.dk/sng/fermentord/internal/controllers"
|
||||||
"git.joco.dk/sng/fermentord/pkg/temperature"
|
"git.joco.dk/sng/fermentord/pkg/temperature"
|
||||||
"github.com/getsentry/sentry-go"
|
"github.com/getsentry/sentry-go"
|
||||||
|
@ -17,7 +18,7 @@ var (
|
||||||
f *os.File
|
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
|
var err error
|
||||||
|
|
||||||
hub := sentry.CurrentHub().Clone()
|
hub := sentry.CurrentHub().Clone()
|
||||||
|
|
|
@ -10,6 +10,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"git.joco.dk/sng/fermentord/internal/api"
|
"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/controllers"
|
||||||
"git.joco.dk/sng/fermentord/internal/hw"
|
"git.joco.dk/sng/fermentord/internal/hw"
|
||||||
"git.joco.dk/sng/fermentord/internal/metrics"
|
"git.joco.dk/sng/fermentord/internal/metrics"
|
||||||
|
@ -22,7 +23,7 @@ import (
|
||||||
"github.com/spf13/viper"
|
"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()
|
hub := sentry.CurrentHub().Clone()
|
||||||
defer hub.Flush(10 * time.Second)
|
defer hub.Flush(10 * time.Second)
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
|
@ -36,10 +37,10 @@ func mainLoop(ctx context.Context, wg *sync.WaitGroup, js nats.JetStream, config
|
||||||
|
|
||||||
// Configuration reload
|
// Configuration reload
|
||||||
viper.OnConfigChange(func(in fsnotify.Event) {
|
viper.OnConfigChange(func(in fsnotify.Event) {
|
||||||
reloadConfiguration(config, ctrl)
|
controllers.ReloadConfiguration(config, ctrl)
|
||||||
})
|
})
|
||||||
viper.WatchConfig()
|
viper.WatchConfig()
|
||||||
reloadConfiguration(config, ctrl)
|
controllers.ReloadConfiguration(config, ctrl)
|
||||||
|
|
||||||
gpio, err := hw.NewGpio()
|
gpio, err := hw.NewGpio()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -126,7 +127,7 @@ func main() {
|
||||||
defer sentry.Flush(10 * time.Second)
|
defer sentry.Flush(10 * time.Second)
|
||||||
|
|
||||||
// Configuration
|
// Configuration
|
||||||
config := loadConfiguration()
|
config := configuration.LoadConfiguration()
|
||||||
|
|
||||||
// NATS
|
// NATS
|
||||||
nc, err := nats.Connect(config.NATS.URL)
|
nc, err := nats.Connect(config.NATS.URL)
|
||||||
|
|
|
@ -5,13 +5,13 @@ import (
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"git.joco.dk/sng/fermentord/internal/controllers"
|
"git.joco.dk/sng/fermentord/internal/configuration"
|
||||||
"github.com/getsentry/sentry-go"
|
"github.com/getsentry/sentry-go"
|
||||||
"github.com/nats-io/nats.go"
|
"github.com/nats-io/nats.go"
|
||||||
)
|
)
|
||||||
|
|
||||||
type API struct {
|
type API struct {
|
||||||
config *controllers.ControllerConfig
|
config *configuration.ControllerConfig
|
||||||
configChangeCallback func()
|
configChangeCallback func()
|
||||||
nc *nats.Conn
|
nc *nats.Conn
|
||||||
}
|
}
|
||||||
|
|
92
internal/configuration/config.go
Normal file
92
internal/configuration/config.go
Normal 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
|
||||||
|
}
|
|
@ -7,6 +7,7 @@ import (
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"git.joco.dk/sng/fermentord/internal/configuration"
|
||||||
"git.joco.dk/sng/fermentord/pkg/temperature"
|
"git.joco.dk/sng/fermentord/pkg/temperature"
|
||||||
"github.com/getsentry/sentry-go"
|
"github.com/getsentry/sentry-go"
|
||||||
)
|
)
|
||||||
|
@ -26,8 +27,8 @@ var ChamberStateMap = map[ChamberState]string{
|
||||||
}
|
}
|
||||||
|
|
||||||
type ChamberController struct {
|
type ChamberController struct {
|
||||||
ConfigUpdates chan ControllerConfig
|
ConfigUpdates chan configuration.ControllerConfig
|
||||||
config ControllerConfig
|
config configuration.ControllerConfig
|
||||||
|
|
||||||
// Current state.
|
// Current state.
|
||||||
chamberState ChamberState
|
chamberState ChamberState
|
||||||
|
@ -48,7 +49,7 @@ type ChamberController struct {
|
||||||
hub *sentry.Hub
|
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{
|
return &ChamberController{
|
||||||
C: make(chan ChamberState),
|
C: make(chan ChamberState),
|
||||||
name: name,
|
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),
|
pid: NewPIDController(config.PID.Kp, config.PID.Ki, config.PID.Kd),
|
||||||
chTemp: chTemp,
|
chTemp: chTemp,
|
||||||
chamberState: ChamberStateIdle,
|
chamberState: ChamberStateIdle,
|
||||||
ConfigUpdates: make(chan ControllerConfig, 1),
|
ConfigUpdates: make(chan configuration.ControllerConfig, 1),
|
||||||
hub: sentry.CurrentHub().Clone(),
|
hub: sentry.CurrentHub().Clone(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,44 +1,20 @@
|
||||||
package controllers
|
package controllers
|
||||||
|
|
||||||
type ControllerConfig struct {
|
import (
|
||||||
NATS struct {
|
"log"
|
||||||
URL string `mapstructure:"url"`
|
|
||||||
Stream string `mapstructure:"stream"`
|
|
||||||
Subject struct {
|
|
||||||
Temp string `mapstructure:"temp"`
|
|
||||||
State string `mapstructure:"state"`
|
|
||||||
} `mapstructure:"subject"`
|
|
||||||
} `mapstructure:"nats"`
|
|
||||||
|
|
||||||
HTTP struct {
|
"git.joco.dk/sng/fermentord/internal/configuration"
|
||||||
Port int16 `mapstructure:"port"`
|
"git.joco.dk/sng/fermentord/pkg/temperature"
|
||||||
} `mapstructure:"http"`
|
)
|
||||||
|
|
||||||
DataPath string `mapstructure:"data_path"`
|
func ReloadConfiguration(config *configuration.ControllerConfig, ctrl *ChamberController) {
|
||||||
|
log.Printf("Reloading configuration")
|
||||||
|
|
||||||
Sensors struct {
|
temperature.ConfigUpdates <- []string{
|
||||||
Wort string `mapstructure:"wort"`
|
config.Sensors.Ambient,
|
||||||
Chamber string `mapstructure:"chamber"`
|
config.Sensors.Chamber,
|
||||||
Ambient string `mapstructure:"ambient"`
|
config.Sensors.Wort,
|
||||||
Weight float64 `mapstructure:"weight"`
|
}
|
||||||
} `mapstructure:"sensors"`
|
|
||||||
|
|
||||||
FermentationTemperature float64 `mapstructure:"fermentation_temp"`
|
ctrl.ConfigUpdates <- *config
|
||||||
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"`
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue