-
-
Notifications
You must be signed in to change notification settings - Fork 704
Description
Summary
Currently, Anthias scheduling is asset-based: each asset has start_date/end_date fields, and the viewer loops through all active assets in order. This works for simple setups but doesn't support common digital signage scenarios like:
- Time windows: "Show menu board from 11:00–14:00, promotions the rest of the day"
- Recurring schedules: "Play this playlist on weekdays only"
- Event interrupts: "At 15:00 sharp, play a special announcement once, then resume normal content"
- Default fallback: "When nothing else is scheduled, show this content"
Proposed solution: Schedule Slots
A slot-based scheduling system that sits on top of the existing asset model. Each slot is a named container of assets with time rules.
Three slot types
| Type | Purpose | Behavior |
|---|---|---|
| Default | Fallback content | Plays when no time/event slot is active. Only one allowed. |
| Time | Recurring windows | Activates during time_from–time_to on specified days_of_week. Supports overnight (22:00→06:00). |
| Event | One-time or scheduled interrupts | Plays all items once in order (no loop), then resumes normal schedule. Can be one-time or recurring. |
Priority
Event > Time > Default — events interrupt time slots, time slots override default.
Key features
- Per-item duration override: Each asset in a slot can have a custom duration (e.g., "show this image for 5s instead of the default 10s")
- Smart deadline timer: When a higher-priority slot is about to start, the current asset is interrupted mid-playback so transitions happen on time (not after the current asset finishes)
- Days of week: Time slots can be limited to specific days (Mon=1 ... Sun=7)
- Overnight support: A slot from 22:00 to 06:00 correctly spans midnight
- Backward compatible: When no slots are configured, the existing asset-based scheduling works exactly as before
Data model
ScheduleSlot
├── slot_type: 'default' | 'time' | 'event'
├── name: string
├── is_enabled: boolean
├── time_from: time (nullable, for time/event)
├── time_to: time (nullable, for time/event)
├── days_of_week: JSON array [1,2,3,4,5] (empty = all days)
├── start_date: date (nullable)
├── end_date: date (nullable)
├── is_default: boolean
├── no_loop: boolean (events play once)
└── items: [ScheduleSlotItem]
ScheduleSlotItem
├── slot: FK → ScheduleSlot
├── asset: FK → Asset
├── sort_order: integer
└── duration_override: integer (nullable, seconds)
API endpoints
GET/POST /api/v2/schedule/slots/
GET/PUT/DEL /api/v2/schedule/slots/{id}/
GET/POST /api/v2/schedule/slots/{id}/items/
PUT/DEL /api/v2/schedule/slots/{id}/items/{item_id}/
POST /api/v2/schedule/slots/{id}/items/order/
GET /api/v2/schedule/status/
The status endpoint returns which slot is currently active, when the next transition will happen, and whether the player is using the default slot.
Implementation status
I have a working implementation deployed on a Raspberry Pi 4, tested in production for several weeks. The scheduling engine (~420 lines), API views (~387 lines), serializers (~263 lines), and models (~170 lines) are ready.
Happy to submit a PR if the maintainers are interested. Given the size (~1,300 lines of backend code + migrations), I wanted to discuss the approach first.
Questions for maintainers
- Is this something you'd consider merging into Anthias?
- Should it be split into multiple PRs (e.g., models+engine first, then API)?
- Any concerns about the data model or API design?
- Should slots use Django ORM models (as proposed) or extend the existing SQLite-based approach?