Files
2026-07-15 17:32:04 -04:00

5.5 KiB

Digital Signage CMS — Project Overview

Concept

Multi-tenant digital signage platform. Customers upload content (images, video) via a web portal, create playlists, and Raspberry Pi players pull and display content in fullscreen kiosk mode.

Architecture

┌─────────────────────────────┐     ┌──────────────────────────────┐
│   Customer Portal (Web)      │     │   Raspberry Pi Player        │
│                               │     │                              │
│  ┌───────────────────────┐  │     │  ┌────────────────────────┐  │
│  │ Login (auth per       │  │     │  │ Registration script     │  │
│  │ customer/tenant)      │  │     │  │ P: POST /api/register   │  │
│  ├───────────────────────┤  │     │  │  → gets device token    │  │
│  │ Dashboard             │  │     │  ├────────────────────────┤  │
│  │  - My Screens         │  │     │  │ Polling script          │  │
│  │  - Content Library    │  │     │  │ GET /api/playlist/:id   │  │
│  │  - Playlists          │  │     │  │  → returns content URLs │  │
│  │  - Upload             │  │     │  ├────────────────────────┤  │
│  ├───────────────────────┤  │     │  │ Chromium kiosk          │  │
│  │ Admin (ITPP)          │  │     │  │ --kiosk --no-sandbox    │  │
│  │  - All tenants        │  │     │  └────────────────────────┘  │
│  │  - Device management  │  │     └──────────────────────────────┘
│  └───────────────────────┘  │
└─────────────────────────────┘
              │
              ▼
     ┌─────────────────┐
     │  API + Storage   │
     │                  │
     │  FastAPI backend │
     │  SQLite/S3       │
     │  per tenant      │
     └─────────────────┘

Multi-Tenant Architecture

Tenant Hierarchy

Signage CMS (Platform)
├── Tenant: Joe's Diner
│   ├── User: alice@joesdiner.com (admin)
│   ├── Device: Main Lobby Pi
│   │   ├── Serial: 10000000a1b2c3d4
│   │   ├── Status: Online
│   │   └── Playlist: Main Menu Loop
│   ├── Device: Menu Board Pi
│   │   ├── Serial: 10000000e5f6g7h8
│   │   ├── Status: Online
│   │   └── Playlist: Daily Specials
│   ├── Device: Waiting Room Pi
│   │   ├── Serial: 10000000i9j0k1l2
│   │   ├── Status: Offline
│   │   └── Playlist: Promo Rotation
│   └── Content: 8 items (4 images, 4 videos)
│
├── Tenant: Main Street Gym
│   ├── User: owner@mainstreetgym.com
│   └── Device: Front Desk Pi
│
└── Tenant: Third Coast Dental
    ├── User: frontdesk@thirdcoast.com
    ├── Device: Waiting Room Pi
    ├── Device: Exam Room Pi
    └── Device: Hallway Pi

Key Design Points

  • One customer = one tenant = unlimited devices
  • Each device registers independently with a unique code + serial
  • Devices belong to a tenant, not directly to a user
  • Multiple users can manage the same tenant (owner + staff accounts)
  • Content libraries are per-tenant (shared across all their devices)
  • Playlists can be assigned to one or multiple devices
  • A device can only play ONE playlist at a time

Pi Registration Flow

1. Customer gets Pi with a unique registration code (printed or emailed)
2. Pi boots → runs registration script
3. Script calls POST /api/register with code + Pi serial number
4. Server registers device under that tenant
5. Pi receives device_id + auth token
6. Pi starts polling GET /api/playlist/:device_id every 60s
7. CMS pushes updates → Pi picks up new playlist on next poll

Registration Script (on Pi)

#!/bin/bash
# register-pi.sh
REG_CODE="$1"
PI_SERIAL=$(cat /proc/cpuinfo | grep Serial | awk '{print $3}')
API="https://signage.itpropartner.com/api"

curl -X POST "$API/register" \
  -H "Content-Type: application/json" \
  -d "{\"code\":\"$REG_CODE\",\"serial\":\"$PI_SERIAL\"}"

MVP Scope (Phase 1)

Feature Status
Customer login To build
Content upload (images + video) To build
Simple playlist (ordered) To build
Pi kiosk player script To build
Multi-tenant (tenant isolation) To build
Cloudflare proxy Future
Scheduling Future
Shuffled/random play Future
4K detection via EDID To research

Stack

  • Backend: FastAPI + SQLite (same pattern as ops portal)
  • Frontend: Dark theme, mobile-responsive (PWA-ready)
  • Player: Raspberry Pi 3/4/5, Chromium kiosk, auto-updating
  • Storage: Local filesystem → S3 in future
  • Auth: JWT per tenant, admin override

Status

📝 Project created — MVP design underway