feat(scheduler): Display-Zeitplan-Scheduler Package
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
7e485e505e
commit
9b766f9086
1 changed files with 72 additions and 0 deletions
72
server/backend/internal/scheduler/scheduler.go
Normal file
72
server/backend/internal/scheduler/scheduler.go
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
// Package scheduler enthält den Display-Zeitplan-Scheduler.
|
||||
// Er prüft jede Minute ob ein Screen ein- oder ausgeschaltet werden soll.
|
||||
package scheduler
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log/slog"
|
||||
"time"
|
||||
|
||||
"git.az-it.net/az/morz-infoboard/server/backend/internal/store"
|
||||
)
|
||||
|
||||
// DisplayCommander sendet einen Display-Befehl per MQTT.
|
||||
type DisplayCommander interface {
|
||||
SendDisplayCommand(screenSlug, action string) error
|
||||
}
|
||||
|
||||
// ScreenSlugGetter lädt den Slug für eine Screen-ID.
|
||||
type ScreenSlugGetter interface {
|
||||
GetByID(ctx context.Context, id string) (*store.Screen, error)
|
||||
}
|
||||
|
||||
// Run startet den Scheduler-Loop. Blockiert bis ctx abgebrochen wird.
|
||||
func Run(ctx context.Context, schedules *store.ScreenScheduleStore, screens ScreenSlugGetter, notifier DisplayCommander) {
|
||||
ticker := time.NewTicker(1 * time.Minute)
|
||||
defer ticker.Stop()
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-ticker.C:
|
||||
check(ctx, schedules, screens, notifier)
|
||||
case <-ctx.Done():
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check prüft alle aktiven Zeitpläne und sendet ggf. Befehle.
|
||||
func check(ctx context.Context, schedules *store.ScreenScheduleStore, screens ScreenSlugGetter, notifier DisplayCommander) {
|
||||
now := time.Now().Format("15:04")
|
||||
|
||||
enabled, err := schedules.ListEnabled(ctx)
|
||||
if err != nil {
|
||||
slog.Error("scheduler: list enabled schedules failed", "err", err)
|
||||
return
|
||||
}
|
||||
|
||||
for _, sc := range enabled {
|
||||
screen, err := screens.GetByID(ctx, sc.ScreenID)
|
||||
if err != nil {
|
||||
slog.Warn("scheduler: screen not found", "screen_id", sc.ScreenID, "err", err)
|
||||
continue
|
||||
}
|
||||
|
||||
var action string
|
||||
if sc.PowerOnTime != "" && sc.PowerOnTime == now {
|
||||
action = "display_on"
|
||||
} else if sc.PowerOffTime != "" && sc.PowerOffTime == now {
|
||||
action = "display_off"
|
||||
}
|
||||
|
||||
if action == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
if err := notifier.SendDisplayCommand(screen.Slug, action); err != nil {
|
||||
slog.Error("scheduler: send command failed", "screen_id", sc.ScreenID, "action", action, "err", err)
|
||||
} else {
|
||||
slog.Info("scheduler: display command sent", "screen_id", sc.ScreenID, "slug", screen.Slug, "action", action)
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue