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?
Summary
Currently, Anthias scheduling is asset-based: each asset has
start_date/end_datefields, and the viewer loops through all active assets in order. This works for simple setups but doesn't support common digital signage scenarios like: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
time_from–time_toon specifieddays_of_week. Supports overnight (22:00→06:00).Priority
Event > Time > Default— events interrupt time slots, time slots override default.Key features
Data model
API endpoints
The
statusendpoint 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