diff --git a/app.go b/app.go index faaf258..88227ad 100644 --- a/app.go +++ b/app.go @@ -22,6 +22,7 @@ type App struct { srv *http.Server nextAlarm *time.Timer nextPreAlarm *time.Timer + ticker *time.Ticker } func NewApp(cfg *config.Config) *App { @@ -61,6 +62,10 @@ func NewApp(cfg *config.Config) *App { } func (app *App) Start() { + if app.ticker != nil { + app.ticker.Stop() + } + app.srv = &http.Server{ Addr: app.cfg.Bind, Handler: app.router, @@ -68,12 +73,28 @@ func (app *App) Start() { app.ResetTimer() + go app.CheckTime() + log.Printf("Ready, listening on %s\n", app.cfg.Bind) if err := app.srv.ListenAndServe(); err != nil && err != http.ErrServerClosed { log.Fatalf("listen: %s\n", err) } } +func (app *App) CheckTime() { + app.ticker = time.NewTicker(time.Minute) + + startTime := time.Now() + + for range app.ticker.C { + if time.Since(startTime).Round(time.Second).Seconds() != time.Since(startTime.Round(0)).Round(time.Second).Seconds() { + app.ResetTimer() + + startTime = time.Now() + } + } +} + func (app *App) ResetTimer() { if app.nextAlarm != nil { app.nextAlarm.Stop() @@ -137,6 +158,10 @@ func (app *App) Stop() { app.nextAlarm.Stop() } + if app.ticker != nil { + app.ticker.Stop() + } + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() if err := app.srv.Shutdown(ctx); err != nil { diff --git a/model/settings.go b/model/settings.go index fb9a02e..2602749 100644 --- a/model/settings.go +++ b/model/settings.go @@ -16,6 +16,8 @@ type Settings struct { PreAlarmAction string `json:"pre_alarm_action"` MaxRunTime time.Duration `json:"max_run_time"` MaxVolume uint16 `json:"max_volume"` + StartVolume uint16 `json:"start_volume"` + NoRandom bool `json:"no_random"` Federation map[string]FederationServer `json:"federation"` } diff --git a/player/player.go b/player/player.go index b493953..4761246 100644 --- a/player/player.go +++ b/player/player.go @@ -22,6 +22,8 @@ type Player struct { Playlist []string MaxRunTime time.Duration MaxVolume uint16 + StartVolume uint16 + NoRandom bool Stopper chan bool currentCmd *exec.Cmd currentCmdCh chan bool @@ -95,11 +97,13 @@ func NewPlayer(cfg *config.Config, routines []reveil.Identifier) (*Player, error currentCmdCh: make(chan bool, 1), MaxRunTime: settings.MaxRunTime * time.Minute, MaxVolume: uint16(settings.MaxVolume), + StartVolume: uint16(settings.StartVolume), + NoRandom: settings.NoRandom, weatherTime: settings.WeatherDelay * time.Minute, weatherAction: wact, claironTime: settings.GongInterval * time.Minute, claironFile: reveil.CurrentGongPath(cfg), - reverseOrder: int(time.Now().Unix()/86400)%2 == 0, + reverseOrder: !settings.NoRandom && int(time.Now().Unix()/86400)%2 == 0, } // Load routines @@ -129,11 +133,13 @@ func NewPlayer(cfg *config.Config, routines []reveil.Identifier) (*Player, error p.Playlist = append(p.Playlist, track.Path) } - log.Println("Shuffling playlist...") - // Shuffle the playlist - rand.Shuffle(len(p.Playlist), func(i, j int) { - p.Playlist[i], p.Playlist[j] = p.Playlist[j], p.Playlist[i] - }) + if !p.NoRandom { + log.Println("Shuffling playlist...") + // Shuffle the playlist + rand.Shuffle(len(p.Playlist), func(i, j int) { + p.Playlist[i], p.Playlist[j] = p.Playlist[j], p.Playlist[i] + }) + } return &p, nil } @@ -204,7 +210,7 @@ loop: } else { p.dontUpdateVolume = false p.volume = uint16(math.Log(1+float64(p.ntick)/8) * 9500) - p.SetVolume(p.volume) + p.SetVolume(p.StartVolume + p.volume) if p.reverseOrder { p.playedItem -= 1 @@ -226,7 +232,7 @@ loop: p.ntick += 1 if !p.dontUpdateVolume { p.volume = 3500 + uint16(math.Log(1+float64(p.ntick)/8)*9500) - p.SetVolume(p.volume) + p.SetVolume(p.StartVolume + p.volume) } case <-p.Stopper: @@ -249,8 +255,12 @@ loopcalm: for i := 0; i < 128 && p.volume >= 768; i += 1 { timer := time.NewTimer(40 * time.Millisecond) - p.volume -= 768 - p.SetVolume(p.volume) + if p.volume <= 0 { + p.StartVolume -= 768 + } else { + p.volume -= 768 + } + p.SetVolume(p.StartVolume + p.volume) select { case <-p.Stopper: diff --git a/ui/package.json b/ui/package.json index 7639583..a570f83 100644 --- a/ui/package.json +++ b/ui/package.json @@ -37,6 +37,6 @@ "sass": "^1.49.7", "sass-loader": "^16.0.0", "@sveltestrap/sveltestrap": "^7.0.0", - "vite": "^7.0.0" + "vite": "^6.0.0" } } diff --git a/ui/src/lib/settings.js b/ui/src/lib/settings.js index 064cd9a..ca9d1c6 100644 --- a/ui/src/lib/settings.js +++ b/ui/src/lib/settings.js @@ -5,7 +5,7 @@ export class Settings { } } - update({ language, gong_interval, weather_delay, weather_action, pre_alarm_delay, pre_alarm_action, max_run_time, max_volume, federation }) { + update({ language, gong_interval, weather_delay, weather_action, pre_alarm_delay, pre_alarm_action, max_run_time, max_volume, start_volume, no_random, federation }) { this.language = language; this.gong_interval = gong_interval; this.weather_delay = weather_delay; @@ -14,6 +14,8 @@ export class Settings { this.pre_alarm_action = pre_alarm_action; this.max_run_time = max_run_time; this.max_volume = max_volume; + this.start_volume = start_volume; + this.no_random = no_random; this.federation = federation; } diff --git a/ui/src/routes/settings/+page.svelte b/ui/src/routes/settings/+page.svelte index d3c6911..8d75632 100644 --- a/ui/src/routes/settings/+page.svelte +++ b/ui/src/routes/settings/+page.svelte @@ -160,6 +160,29 @@ + + + + submitSettings(settings)} + /> + + + + + submitSettings(settings)} + /> + +