Compare commits
3 commits
d9d19a8b3f
...
8cdfde856e
| Author | SHA1 | Date | |
|---|---|---|---|
| 8cdfde856e | |||
| 34917043ce | |||
| b7b6d3f0a7 |
6 changed files with 74 additions and 12 deletions
25
app.go
25
app.go
|
|
@ -22,6 +22,7 @@ type App struct {
|
||||||
srv *http.Server
|
srv *http.Server
|
||||||
nextAlarm *time.Timer
|
nextAlarm *time.Timer
|
||||||
nextPreAlarm *time.Timer
|
nextPreAlarm *time.Timer
|
||||||
|
ticker *time.Ticker
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewApp(cfg *config.Config) *App {
|
func NewApp(cfg *config.Config) *App {
|
||||||
|
|
@ -61,6 +62,10 @@ func NewApp(cfg *config.Config) *App {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app *App) Start() {
|
func (app *App) Start() {
|
||||||
|
if app.ticker != nil {
|
||||||
|
app.ticker.Stop()
|
||||||
|
}
|
||||||
|
|
||||||
app.srv = &http.Server{
|
app.srv = &http.Server{
|
||||||
Addr: app.cfg.Bind,
|
Addr: app.cfg.Bind,
|
||||||
Handler: app.router,
|
Handler: app.router,
|
||||||
|
|
@ -68,12 +73,28 @@ func (app *App) Start() {
|
||||||
|
|
||||||
app.ResetTimer()
|
app.ResetTimer()
|
||||||
|
|
||||||
|
go app.CheckTime()
|
||||||
|
|
||||||
log.Printf("Ready, listening on %s\n", app.cfg.Bind)
|
log.Printf("Ready, listening on %s\n", app.cfg.Bind)
|
||||||
if err := app.srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
|
if err := app.srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
|
||||||
log.Fatalf("listen: %s\n", err)
|
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() {
|
func (app *App) ResetTimer() {
|
||||||
if app.nextAlarm != nil {
|
if app.nextAlarm != nil {
|
||||||
app.nextAlarm.Stop()
|
app.nextAlarm.Stop()
|
||||||
|
|
@ -137,6 +158,10 @@ func (app *App) Stop() {
|
||||||
app.nextAlarm.Stop()
|
app.nextAlarm.Stop()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if app.ticker != nil {
|
||||||
|
app.ticker.Stop()
|
||||||
|
}
|
||||||
|
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
if err := app.srv.Shutdown(ctx); err != nil {
|
if err := app.srv.Shutdown(ctx); err != nil {
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,8 @@ type Settings struct {
|
||||||
PreAlarmAction string `json:"pre_alarm_action"`
|
PreAlarmAction string `json:"pre_alarm_action"`
|
||||||
MaxRunTime time.Duration `json:"max_run_time"`
|
MaxRunTime time.Duration `json:"max_run_time"`
|
||||||
MaxVolume uint16 `json:"max_volume"`
|
MaxVolume uint16 `json:"max_volume"`
|
||||||
|
StartVolume uint16 `json:"start_volume"`
|
||||||
|
NoRandom bool `json:"no_random"`
|
||||||
Federation map[string]FederationServer `json:"federation"`
|
Federation map[string]FederationServer `json:"federation"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,8 @@ type Player struct {
|
||||||
Playlist []string
|
Playlist []string
|
||||||
MaxRunTime time.Duration
|
MaxRunTime time.Duration
|
||||||
MaxVolume uint16
|
MaxVolume uint16
|
||||||
|
StartVolume uint16
|
||||||
|
NoRandom bool
|
||||||
Stopper chan bool
|
Stopper chan bool
|
||||||
currentCmd *exec.Cmd
|
currentCmd *exec.Cmd
|
||||||
currentCmdCh chan bool
|
currentCmdCh chan bool
|
||||||
|
|
@ -95,11 +97,13 @@ func NewPlayer(cfg *config.Config, routines []reveil.Identifier) (*Player, error
|
||||||
currentCmdCh: make(chan bool, 1),
|
currentCmdCh: make(chan bool, 1),
|
||||||
MaxRunTime: settings.MaxRunTime * time.Minute,
|
MaxRunTime: settings.MaxRunTime * time.Minute,
|
||||||
MaxVolume: uint16(settings.MaxVolume),
|
MaxVolume: uint16(settings.MaxVolume),
|
||||||
|
StartVolume: uint16(settings.StartVolume),
|
||||||
|
NoRandom: settings.NoRandom,
|
||||||
weatherTime: settings.WeatherDelay * time.Minute,
|
weatherTime: settings.WeatherDelay * time.Minute,
|
||||||
weatherAction: wact,
|
weatherAction: wact,
|
||||||
claironTime: settings.GongInterval * time.Minute,
|
claironTime: settings.GongInterval * time.Minute,
|
||||||
claironFile: reveil.CurrentGongPath(cfg),
|
claironFile: reveil.CurrentGongPath(cfg),
|
||||||
reverseOrder: int(time.Now().Unix()/86400)%2 == 0,
|
reverseOrder: !settings.NoRandom && int(time.Now().Unix()/86400)%2 == 0,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load routines
|
// Load routines
|
||||||
|
|
@ -129,11 +133,13 @@ func NewPlayer(cfg *config.Config, routines []reveil.Identifier) (*Player, error
|
||||||
p.Playlist = append(p.Playlist, track.Path)
|
p.Playlist = append(p.Playlist, track.Path)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !p.NoRandom {
|
||||||
log.Println("Shuffling playlist...")
|
log.Println("Shuffling playlist...")
|
||||||
// Shuffle the playlist
|
// Shuffle the playlist
|
||||||
rand.Shuffle(len(p.Playlist), func(i, j int) {
|
rand.Shuffle(len(p.Playlist), func(i, j int) {
|
||||||
p.Playlist[i], p.Playlist[j] = p.Playlist[j], p.Playlist[i]
|
p.Playlist[i], p.Playlist[j] = p.Playlist[j], p.Playlist[i]
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
|
||||||
return &p, nil
|
return &p, nil
|
||||||
}
|
}
|
||||||
|
|
@ -204,7 +210,7 @@ loop:
|
||||||
} else {
|
} else {
|
||||||
p.dontUpdateVolume = false
|
p.dontUpdateVolume = false
|
||||||
p.volume = uint16(math.Log(1+float64(p.ntick)/8) * 9500)
|
p.volume = uint16(math.Log(1+float64(p.ntick)/8) * 9500)
|
||||||
p.SetVolume(p.volume)
|
p.SetVolume(p.StartVolume + p.volume)
|
||||||
|
|
||||||
if p.reverseOrder {
|
if p.reverseOrder {
|
||||||
p.playedItem -= 1
|
p.playedItem -= 1
|
||||||
|
|
@ -226,7 +232,7 @@ loop:
|
||||||
p.ntick += 1
|
p.ntick += 1
|
||||||
if !p.dontUpdateVolume {
|
if !p.dontUpdateVolume {
|
||||||
p.volume = 3500 + uint16(math.Log(1+float64(p.ntick)/8)*9500)
|
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:
|
case <-p.Stopper:
|
||||||
|
|
@ -249,8 +255,12 @@ loopcalm:
|
||||||
for i := 0; i < 128 && p.volume >= 768; i += 1 {
|
for i := 0; i < 128 && p.volume >= 768; i += 1 {
|
||||||
timer := time.NewTimer(40 * time.Millisecond)
|
timer := time.NewTimer(40 * time.Millisecond)
|
||||||
|
|
||||||
|
if p.volume <= 0 {
|
||||||
|
p.StartVolume -= 768
|
||||||
|
} else {
|
||||||
p.volume -= 768
|
p.volume -= 768
|
||||||
p.SetVolume(p.volume)
|
}
|
||||||
|
p.SetVolume(p.StartVolume + p.volume)
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case <-p.Stopper:
|
case <-p.Stopper:
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,6 @@
|
||||||
"sass": "^1.49.7",
|
"sass": "^1.49.7",
|
||||||
"sass-loader": "^16.0.0",
|
"sass-loader": "^16.0.0",
|
||||||
"@sveltestrap/sveltestrap": "^7.0.0",
|
"@sveltestrap/sveltestrap": "^7.0.0",
|
||||||
"vite": "^7.0.0"
|
"vite": "^6.0.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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.language = language;
|
||||||
this.gong_interval = gong_interval;
|
this.gong_interval = gong_interval;
|
||||||
this.weather_delay = weather_delay;
|
this.weather_delay = weather_delay;
|
||||||
|
|
@ -14,6 +14,8 @@ export class Settings {
|
||||||
this.pre_alarm_action = pre_alarm_action;
|
this.pre_alarm_action = pre_alarm_action;
|
||||||
this.max_run_time = max_run_time;
|
this.max_run_time = max_run_time;
|
||||||
this.max_volume = max_volume;
|
this.max_volume = max_volume;
|
||||||
|
this.start_volume = start_volume;
|
||||||
|
this.no_random = no_random;
|
||||||
this.federation = federation;
|
this.federation = federation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -160,6 +160,29 @@
|
||||||
</InputGroup>
|
</InputGroup>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
|
|
||||||
|
<FormGroup>
|
||||||
|
<Label for="startVolume">Volume de départ</Label>
|
||||||
|
<InputGroup>
|
||||||
|
<Input
|
||||||
|
type="range"
|
||||||
|
id="startVolume"
|
||||||
|
min="0"
|
||||||
|
max="65535"
|
||||||
|
bind:value={settings.start_volume}
|
||||||
|
on:input={() => submitSettings(settings)}
|
||||||
|
/>
|
||||||
|
</InputGroup>
|
||||||
|
</FormGroup>
|
||||||
|
|
||||||
|
<FormGroup>
|
||||||
|
<Input
|
||||||
|
type="switch"
|
||||||
|
label="Ne pas mélanger la liste de lecture"
|
||||||
|
bind:checked={settings.no_random}
|
||||||
|
on:input={() => submitSettings(settings)}
|
||||||
|
/>
|
||||||
|
</FormGroup>
|
||||||
|
|
||||||
<FormGroup>
|
<FormGroup>
|
||||||
<Label for="federation">Federation</Label>
|
<Label for="federation">Federation</Label>
|
||||||
<FederationSettings
|
<FederationSettings
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue