Update / adjust config handling code so its more reliable and less prone to crashes ; tweak default values + help text to ensure folks know its only seconds/minutes/hours ; add fim restart handling
This commit is contained in:
parent
e979318132
commit
1ccbf4ee03
|
@ -22,21 +22,29 @@ func main() {
|
|||
// Load the config file
|
||||
pfConfig, _ := config.LoadConfig()
|
||||
|
||||
// For some reason the map isn't populated 'right away' and/or doesn't always come in via koanf
|
||||
// Work around by re-loading the config as necessary to get valid values
|
||||
for pfConfig.Float64Map(config.CONFIG_KEY_FAN_SPEEDS)[config.CONFIG_MAP_KEY_FAN_SPEED_100] == 0 {
|
||||
pfConfig, _ = config.LoadConfig()
|
||||
}
|
||||
log.Print("========================================")
|
||||
pfConfig.Print()
|
||||
log.Print("========================================")
|
||||
log.Print(pfConfig.Keys())
|
||||
log.Print("========================================")
|
||||
|
||||
// Get the various fan related config options as local variables
|
||||
speedMap := pfConfig.Float64Map(config.CONFIG_KEY_FAN_SPEEDS)
|
||||
POLL_INTERVAL := pfConfig.String(config.CONFIG_KEY_FAN_POLL_INTERVAL)
|
||||
SPEED_FULL_TEMP := speedMap[config.CONFIG_MAP_KEY_FAN_SPEED_100]
|
||||
SPEED_SEVENTY_FIVE_PERCENT_TEMP := speedMap[config.CONFIG_MAP_KEY_FAN_SPEED_75]
|
||||
SPEED_FIFTY_PERCENT_TEMP := speedMap[config.CONFIG_MAP_KEY_FAN_SPEED_50]
|
||||
SPEED_TWENTY_FIVE_PERCENT_TEMP := speedMap[config.CONFIG_MAP_KEY_FAN_SPEED_25]
|
||||
SPEED_FULL_TEMP := pfConfig.Float64(config.CONFIG_KEY_FAN_SPEEDS + "." + config.CONFIG_MAP_KEY_FAN_SPEED_100)
|
||||
SPEED_SEVENTY_FIVE_PERCENT_TEMP := pfConfig.Float64(config.CONFIG_KEY_FAN_SPEEDS + "." + config.CONFIG_MAP_KEY_FAN_SPEED_75)
|
||||
SPEED_FIFTY_PERCENT_TEMP := pfConfig.Float64(config.CONFIG_KEY_FAN_SPEEDS + "." + config.CONFIG_MAP_KEY_FAN_SPEED_50)
|
||||
SPEED_TWENTY_FIVE_PERCENT_TEMP := pfConfig.Float64(config.CONFIG_KEY_FAN_SPEEDS + "." + config.CONFIG_MAP_KEY_FAN_SPEED_25)
|
||||
SPEED_MINIMUM := pfConfig.Int(config.CONFIG_KEY_FAN_MIN_SPEED)
|
||||
|
||||
log.Print(speedMap)
|
||||
log.Print(POLL_INTERVAL)
|
||||
log.Print(SPEED_FULL_TEMP)
|
||||
log.Print(SPEED_SEVENTY_FIVE_PERCENT_TEMP)
|
||||
log.Print(SPEED_FIFTY_PERCENT_TEMP)
|
||||
log.Print(SPEED_TWENTY_FIVE_PERCENT_TEMP)
|
||||
log.Print(SPEED_MINIMUM)
|
||||
|
||||
// Setup fan and bail if we can't see it
|
||||
fan, err := argonFan.New(ADDRESS, BUS)
|
||||
if err != nil {
|
||||
|
@ -71,42 +79,52 @@ func main() {
|
|||
|
||||
if cpuTemp >= SPEED_FULL_TEMP || gpuTemp >= SPEED_FULL_TEMP {
|
||||
if SPEED_MINIMUM > 100 {
|
||||
log.Print("MIN speed in 100")
|
||||
fan.SetSpeed(SPEED_MINIMUM)
|
||||
} else {
|
||||
log.Print("Speed 100%")
|
||||
fan.SetSpeed(100)
|
||||
}
|
||||
continue
|
||||
}
|
||||
if cpuTemp >= SPEED_SEVENTY_FIVE_PERCENT_TEMP || gpuTemp >= SPEED_SEVENTY_FIVE_PERCENT_TEMP {
|
||||
if SPEED_MINIMUM > 75 {
|
||||
log.Print("MIN speed in 75")
|
||||
fan.SetSpeed(SPEED_MINIMUM)
|
||||
} else {
|
||||
log.Print("Speed 75%")
|
||||
fan.SetSpeed(75)
|
||||
}
|
||||
continue
|
||||
}
|
||||
if cpuTemp >= SPEED_FIFTY_PERCENT_TEMP || gpuTemp >= SPEED_FIFTY_PERCENT_TEMP {
|
||||
if SPEED_MINIMUM > 50 {
|
||||
log.Print("MIN speed in 50")
|
||||
fan.SetSpeed(SPEED_MINIMUM)
|
||||
} else {
|
||||
log.Print("Speed 50%")
|
||||
fan.SetSpeed(50)
|
||||
}
|
||||
continue
|
||||
}
|
||||
if cpuTemp >= SPEED_TWENTY_FIVE_PERCENT_TEMP || gpuTemp >= SPEED_TWENTY_FIVE_PERCENT_TEMP {
|
||||
if SPEED_MINIMUM > 25 {
|
||||
log.Print("MIN speed in 25")
|
||||
fan.SetSpeed(SPEED_MINIMUM)
|
||||
} else {
|
||||
log.Print("Speed 25%")
|
||||
fan.SetSpeed(25)
|
||||
}
|
||||
continue
|
||||
}
|
||||
if cpuTemp < SPEED_TWENTY_FIVE_PERCENT_TEMP || gpuTemp < SPEED_TWENTY_FIVE_PERCENT_TEMP {
|
||||
log.Print("MIN SPEED")
|
||||
fan.SetSpeed(SPEED_MINIMUM)
|
||||
continue
|
||||
}
|
||||
// We should never get here but...
|
||||
// Maxing fan to be on the safe side
|
||||
log.Print("This should never happen")
|
||||
fan.SetSpeed(100)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@ import (
|
|||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/knadh/koanf/providers/confmap"
|
||||
"github.com/knadh/koanf/providers/posflag"
|
||||
|
@ -15,6 +14,7 @@ import (
|
|||
)
|
||||
|
||||
func main() {
|
||||
log.Print("Starting up")
|
||||
// Command line flag handler
|
||||
f := flag.NewFlagSet("piframe", flag.ContinueOnError)
|
||||
f.Usage = func() {
|
||||
|
@ -22,6 +22,7 @@ func main() {
|
|||
os.Exit(0)
|
||||
}
|
||||
// Command line flags
|
||||
log.Print("Setting up CLI flags")
|
||||
f.Bool(config.CLI_FLAG_CONFIG_ONLY, false, "Only show the config UI, NOT the slideshow")
|
||||
cliFlag := f.Lookup(config.CLI_FLAG_CONFIG_ONLY)
|
||||
if cliFlag != nil {
|
||||
|
@ -30,30 +31,25 @@ func main() {
|
|||
// Process command line flags into handler
|
||||
f.Parse(os.Args[1:])
|
||||
|
||||
log.Print("Loading config")
|
||||
// Load the config file
|
||||
pfConfig, configFileProvider := config.LoadConfig()
|
||||
|
||||
// For some reason the restart interval comes through the config as 0s
|
||||
// Similar to the fan daemon, keep reloading config until we get a valid value
|
||||
restartDuration := pfConfig.Duration(config.CONFIG_KEY_SLIDESHOW_RESTART_INTERVAL)
|
||||
for restartDuration.Milliseconds() < 1 {
|
||||
pfConfig, configFileProvider = config.LoadConfig()
|
||||
restartDuration = pfConfig.Duration(config.CONFIG_KEY_SLIDESHOW_RESTART_INTERVAL)
|
||||
}
|
||||
pfConfig, _ := config.LoadConfig()
|
||||
log.Printf("%v", pfConfig)
|
||||
pfConfig.Print()
|
||||
|
||||
// Watch for config changes and re-load config if needed
|
||||
configFileProvider.Watch(func(event interface{}, err error) {
|
||||
if err != nil {
|
||||
log.Printf("Error setting up watch of config : %s", err)
|
||||
return
|
||||
}
|
||||
// configFileProvider.Watch(func(event interface{}, err error) {
|
||||
// if err != nil {
|
||||
// log.Printf("Error setting up watch of config : %s", err)
|
||||
// return
|
||||
// }
|
||||
|
||||
// Give the config UI a chance to save and exit clean
|
||||
time.Sleep(time.Minute)
|
||||
// // Give the config UI a chance to save and exit clean
|
||||
// time.Sleep(time.Minute)
|
||||
|
||||
// Bail on slideshow if there is a config change so it restarts with updated config
|
||||
log.Fatalf("Config file changed! Exiting!")
|
||||
})
|
||||
// // Bail on slideshow if there is a config change so it restarts with updated config
|
||||
// log.Fatalf("Config file changed! Exiting!")
|
||||
// })
|
||||
|
||||
// Process command line flags
|
||||
if err := pfConfig.Load(posflag.Provider(f, ".", pfConfig), nil); err != nil {
|
||||
|
|
|
@ -2,7 +2,6 @@ package config
|
|||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"github.com/knadh/koanf"
|
||||
"github.com/knadh/koanf/parsers/toml"
|
||||
|
@ -25,18 +24,20 @@ func LoadConfig() (*koanf.Koanf, *kfile.File) {
|
|||
CONFIG_KEY_FAN_POLL_INTERVAL: DEFAULT_FAN_POLL_INTERVAL,
|
||||
CONFIG_KEY_FAN_SPEEDS: DEFAULT_FAN_SPEEDS,
|
||||
CONFIG_KEY_FAN_MIN_SPEED: DEFAULT_FAN_MIN_SPEED,
|
||||
}, "."), nil)
|
||||
}, ""), nil)
|
||||
|
||||
// Bring in /etc/defaults/pf.toml if it exists
|
||||
configFileProvider := kfile.Provider(CONFIG_FILE_PATH)
|
||||
_, err := os.Stat(CONFIG_FILE_PATH)
|
||||
if os.IsNotExist(err) {
|
||||
//log.Printf("%s does not exist, USING DEFAULTS", CONFIG_FILE_PATH)
|
||||
} else {
|
||||
if errConfigFile := pfConfig.Load(configFileProvider, toml.Parser()); errConfigFile != nil {
|
||||
log.Fatalf("Error loading config : %s", err)
|
||||
}
|
||||
log.Print("========================================")
|
||||
if err := pfConfig.Load(configFileProvider, toml.Parser()); err != nil {
|
||||
log.Fatalf("Error loading config : %s", err)
|
||||
}
|
||||
log.Print("========================================")
|
||||
|
||||
log.Print("========================================")
|
||||
log.Print("Loaded Config")
|
||||
pfConfig.Print()
|
||||
log.Print("========================================")
|
||||
|
||||
return pfConfig, configFileProvider
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@ const (
|
|||
|
||||
const (
|
||||
DEFAULT_SLIDESHOW_INTERVAL = "300s"
|
||||
DEFAULT_SLIDESHOW_RESTART_INTERVAL = "7d"
|
||||
DEFAULT_SLIDESHOW_RESTART_INTERVAL = "168h"
|
||||
DEFAULT_HDMI_OFF = "*-*-* 00:00:00"
|
||||
DEFAULT_HDMI_ON = "*-*-* 06:00:00"
|
||||
DEFAULT_ALBUMS_ROOT = "/tank/pictures"
|
||||
|
|
|
@ -272,7 +272,7 @@ func ConfigGui(pfconfig *koanf.Koanf) {
|
|||
main.SetTitle("Configure Intervals")
|
||||
main.Clear()
|
||||
main.AddItem(intervalsForm, 0, 1, true)
|
||||
main.AddItem(tview.NewTextView().SetText("Intervals are a number + letter\n\nUse\ns for seconds\nm for minutes\nh for hours\nd for days\nw for weeks"), 0, 1, false)
|
||||
main.AddItem(tview.NewTextView().SetText("Intervals are a number + letter\n\nUse\ns for seconds\nm for minutes\nh for hours"), 0, 1, false)
|
||||
app.SetFocus(intervalsForm)
|
||||
}
|
||||
if title == "HDMI On/Off" {
|
||||
|
|
|
@ -25,6 +25,7 @@ var fim *exec.Cmd = nil
|
|||
var stdin io.WriteCloser = nil
|
||||
|
||||
func setupFim(PATH_TEMP_FOR_SLIDESHOW string) {
|
||||
log.Print("Setting up new fim process")
|
||||
// Prep slideshow command and arguments
|
||||
// NOTE: The random flag is seeded with time() ; this is bad as we will be restarting the slideshow at about the same time per the configurd schedule
|
||||
// We use the non-seeded form to ensure that it's a little more random (or at least hope it's a little more random)
|
||||
|
@ -56,6 +57,7 @@ func Slideshow(pfconfig *koanf.Koanf) {
|
|||
// /run is a tmpfs so this won't wear on the sd card storage
|
||||
|
||||
// Create temp folder
|
||||
log.Print("Creating temp folder for album selections")
|
||||
_, err := os.Stat(PATH_TEMP_FOR_SLIDESHOW)
|
||||
if os.IsNotExist(err) {
|
||||
errDir := os.MkdirAll(PATH_TEMP_FOR_SLIDESHOW, 0755)
|
||||
|
@ -65,6 +67,7 @@ func Slideshow(pfconfig *koanf.Koanf) {
|
|||
}
|
||||
|
||||
// Cleanup temp folder if it already existed
|
||||
log.Print("Cleaning up temp folder if it exists")
|
||||
dirRead, err := os.Open(PATH_TEMP_FOR_SLIDESHOW)
|
||||
if err != nil {
|
||||
log.Fatalf("Error setting up slideshow : %s", err)
|
||||
|
@ -90,6 +93,7 @@ func Slideshow(pfconfig *koanf.Koanf) {
|
|||
|
||||
// Setup symlinks to selected albums to be used with slideshow
|
||||
// Add albums full paths to command line args for fim
|
||||
log.Print("Setting up symlinks to selected albums")
|
||||
albumRootPath := pfconfig.String(config.CONFIG_KEY_ALBUMS_ROOT)
|
||||
for _, album := range pfconfig.Strings(config.CONFIG_KEY_ALBUMS_SELECTED) {
|
||||
source := albumRootPath + album
|
||||
|
@ -127,7 +131,13 @@ func Slideshow(pfconfig *koanf.Koanf) {
|
|||
setupFim(PATH_TEMP_FOR_SLIDESHOW)
|
||||
|
||||
// Advance slideshow every interval as defined in const()
|
||||
ticker := time.NewTicker(pfconfig.Duration(config.CONFIG_KEY_SLIDESHOW_INTERVAL))
|
||||
log.Print("Setting up slideshow advance slide ticker")
|
||||
slideshowAdvanceDurationString := pfconfig.String(config.CONFIG_KEY_SLIDESHOW_INTERVAL)
|
||||
slideshowAdvanceDuration, err := time.ParseDuration(slideshowAdvanceDurationString)
|
||||
if err != nil {
|
||||
log.Fatalf("Error parsing slide duration : %s", err)
|
||||
}
|
||||
ticker := time.NewTicker(slideshowAdvanceDuration)
|
||||
stop_ticker := make(chan struct{})
|
||||
go func() {
|
||||
for {
|
||||
|
@ -162,6 +172,7 @@ func Slideshow(pfconfig *koanf.Koanf) {
|
|||
STOP_SLIDESHOW := false
|
||||
|
||||
// Goroutine for tracking which keys are pressed and controlling fim if appropriate
|
||||
log.Print("Setting up keyboard listener")
|
||||
keyboardCtx, keyboardCancel := context.WithCancel(context.Background())
|
||||
go func(keyboardCtx context.Context) {
|
||||
for {
|
||||
|
@ -211,7 +222,13 @@ func Slideshow(pfconfig *koanf.Koanf) {
|
|||
}(keyboardCtx)
|
||||
|
||||
// Restart fim after configured timeout ; This is setup as a ticker due to KemoNine not getting CommandWithContext stuff to work properly (lots of pointer related crashes and the like)
|
||||
fimTicker := time.NewTicker(pfconfig.Duration(config.CONFIG_KEY_SLIDESHOW_RESTART_INTERVAL))
|
||||
log.Print("Setting up fim restart ticker")
|
||||
fimRestartDurationString := pfconfig.String(config.CONFIG_KEY_SLIDESHOW_RESTART_INTERVAL)
|
||||
fimRestartDuration, err := time.ParseDuration(fimRestartDurationString)
|
||||
if err != nil {
|
||||
log.Fatalf("Error parsing restart duration : %S", err)
|
||||
}
|
||||
fimTicker := time.NewTicker(fimRestartDuration)
|
||||
stop_fim_ticker := make(chan struct{})
|
||||
go func() {
|
||||
for {
|
||||
|
@ -234,6 +251,7 @@ func Slideshow(pfconfig *koanf.Koanf) {
|
|||
|
||||
// Run fim
|
||||
for !STOP_SLIDESHOW {
|
||||
log.Print("Top of fim slideshow loop")
|
||||
if err := fim.Run(); err != nil {
|
||||
// Unwrap the error a bit so we can find out if a signal killed fim or something else
|
||||
// An exit code of -1 means the program didn't exit in time or was terminated by a signal (per the docs)
|
||||
|
|
Loading…
Reference in a new issue