Skip to content

Feature proposal: Schedule slots engine (time-based & event-based scheduling) #2671

@Alex1981-tech

Description

@Alex1981-tech

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_fromtime_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

  1. Is this something you'd consider merging into Anthias?
  2. Should it be split into multiple PRs (e.g., models+engine first, then API)?
  3. Any concerns about the data model or API design?
  4. Should slots use Django ORM models (as proposed) or extend the existing SQLite-based approach?

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions