Weather action
This commit is contained in:
parent
7df46e03e0
commit
1def1ff67a
@ -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
|
||||||
|
}
|
||||||
|
@ -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)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user