Weather action

This commit is contained in:
nemunaire 2022-12-08 17:49:15 +01:00
parent 7df46e03e0
commit 1def1ff67a
2 changed files with 84 additions and 8 deletions

View File

@ -4,9 +4,11 @@ import (
"bufio" "bufio"
"crypto/sha512" "crypto/sha512"
"errors" "errors"
"fmt"
"io/fs" "io/fs"
"log" "log"
"os" "os"
"os/exec"
"path/filepath" "path/filepath"
"strings" "strings"
@ -19,9 +21,10 @@ type Action struct {
Description string `json:"description,omitempty"` Description string `json:"description,omitempty"`
Path string `json:"path"` Path string `json:"path"`
Enabled bool `json:"enabled"` Enabled bool `json:"enabled"`
fullPath string
} }
func LoadAction(path string) (string, string, error) { func loadAction(path string) (string, string, error) {
fd, err := os.Open(path) fd, err := os.Open(path)
if err != nil { if err != nil {
return "", "", err return "", "", err
@ -64,6 +67,45 @@ func LoadAction(path string) (string, string, error) {
return name, description, nil return name, description, nil
} }
func LoadAction(cfg *config.Config, path string) (*Action, error) {
actionsDir, err := filepath.Abs(cfg.ActionsDir)
if err != nil {
return nil, err
}
path = filepath.Join(actionsDir, path)
d, err := os.Stat(path)
if err != nil {
return nil, err
}
if !d.Mode().IsRegular() {
return nil, fmt.Errorf("%q is not a file, it cannot be an action.", path)
}
hash := sha512.Sum512([]byte(path))
// Parse content
name, description, err := loadAction(path)
if err != nil {
return nil, fmt.Errorf("Invalid action file (trying to parse %s): %s", path, err.Error())
}
if apath, err := filepath.Abs(path); err == nil {
path = apath
}
return &Action{
Id: hash[:],
Name: name,
Description: description,
Path: strings.TrimPrefix(path, actionsDir+"/"),
Enabled: d.Mode().Perm()&0111 != 0,
fullPath: path,
}, nil
}
func LoadActions(cfg *config.Config) (actions []*Action, err error) { func LoadActions(cfg *config.Config) (actions []*Action, err error) {
actionsDir, err := filepath.Abs(cfg.ActionsDir) actionsDir, err := filepath.Abs(cfg.ActionsDir)
if err != nil { if err != nil {
@ -75,7 +117,7 @@ func LoadActions(cfg *config.Config) (actions []*Action, err error) {
hash := sha512.Sum512([]byte(path)) hash := sha512.Sum512([]byte(path))
// Parse content // Parse content
name, description, err := LoadAction(path) name, description, err := loadAction(path)
if err != nil { if err != nil {
log.Printf("Invalid action file (trying to parse %s): %s", path, err.Error()) log.Printf("Invalid action file (trying to parse %s): %s", path, err.Error())
// Ignore invalid files // Ignore invalid files
@ -96,6 +138,7 @@ func LoadActions(cfg *config.Config) (actions []*Action, err error) {
Description: description, Description: description,
Path: strings.TrimPrefix(path, actionsDir+"/"), Path: strings.TrimPrefix(path, actionsDir+"/"),
Enabled: d.Mode().Perm()&0111 != 0, Enabled: d.Mode().Perm()&0111 != 0,
fullPath: path,
}) })
} }
@ -130,3 +173,9 @@ func (a *Action) Disable() error {
func (a *Action) Remove() error { func (a *Action) Remove() error {
return os.Remove(a.Path) return os.Remove(a.Path)
} }
func (a *Action) Launch() (cmd *exec.Cmd, err error) {
cmd = exec.Command(a.fullPath)
err = cmd.Start()
return
}

View File

@ -25,11 +25,15 @@ type Player struct {
currentCmd *exec.Cmd currentCmd *exec.Cmd
currentCmdCh chan bool currentCmdCh chan bool
weatherTime time.Duration
weatherAction *reveil.Action
claironTime time.Duration claironTime time.Duration
claironFile string claironFile string
ntick int64 ntick int64
hasClaironed bool hasClaironed bool
hasSpokeWeather bool
launched time.Time launched time.Time
volume uint16 volume uint16
dontUpdateVolume bool dontUpdateVolume bool
@ -62,13 +66,21 @@ func NewPlayer(cfg *config.Config) (*Player, error) {
return nil, fmt.Errorf("Unable to read settings: %w", err) return nil, fmt.Errorf("Unable to read settings: %w", err)
} }
// Load weather action
wact, err := reveil.LoadAction(cfg, settings.WeatherAction)
if err != nil {
log.Println("Unable to load weather action:", err.Error())
}
p := Player{ p := Player{
Stopper: make(chan bool, 1), Stopper: make(chan bool, 1),
currentCmdCh: make(chan bool, 1), currentCmdCh: make(chan bool, 1),
MaxRunTime: settings.MaxRunTime * time.Minute, MaxRunTime: settings.MaxRunTime * time.Minute,
claironTime: settings.GongInterval * time.Minute, weatherTime: settings.WeatherDelay * time.Minute,
claironFile: reveil.CurrentGongPath(cfg), weatherAction: wact,
reverseOrder: int(time.Now().Unix()/86400)%2 == 0, claironTime: settings.GongInterval * time.Minute,
claironFile: reveil.CurrentGongPath(cfg),
reverseOrder: int(time.Now().Unix()/86400)%2 == 0,
} }
// Load our track list // Load our track list
@ -98,6 +110,16 @@ func NewPlayer(cfg *config.Config) (*Player, error) {
return &p, nil return &p, nil
} }
func (p *Player) launchAction(a *reveil.Action) (err error) {
p.currentCmd, err = a.Launch()
log.Println("Running action ", a.Name)
err = p.currentCmd.Wait()
p.currentCmdCh <- true
return
}
func (p *Player) playFile(filepath string) (err error) { func (p *Player) playFile(filepath string) (err error) {
p.currentCmd = exec.Command("paplay", filepath) p.currentCmd = exec.Command("paplay", filepath)
if err = p.currentCmd.Start(); err != nil { if err = p.currentCmd.Start(); err != nil {
@ -141,6 +163,11 @@ loop:
p.SetVolume(65535) p.SetVolume(65535)
p.dontUpdateVolume = true p.dontUpdateVolume = true
go p.playFile(p.claironFile) go p.playFile(p.claironFile)
} else if p.weatherAction != nil && !p.hasSpokeWeather && time.Since(p.launched) >= p.weatherTime {
log.Println("weather time!")
p.SetVolume(65535)
p.dontUpdateVolume = true
go p.launchAction(p.weatherAction)
} else { } else {
p.dontUpdateVolume = false p.dontUpdateVolume = false
p.volume = 3500 + uint16(math.Log(1+float64(p.ntick)/8)*9500) p.volume = 3500 + uint16(math.Log(1+float64(p.ntick)/8)*9500)