Self-contained examples for the PiP overlay API (POST /api/pip), each with a CSP-safe query-param overlay (external JS), config.example.json, zero runtime deps, an offline test, and a README: - PIP-Announce-Broadcast manual one-shot message to a screen/group - PIP-Weather-Widget Open-Meteo current conditions (keyless) - PIP-Air-Quality Open-Meteo US AQI widget (keyless) - PIP-Crypto-Ticker CoinGecko price strip (keyless) - PIP-News-Ticker scrolling RSS/Atom headlines - PIP-Room-Status-Calendar ICS-driven Available/Busy room sign - PIP-Event-Countdown client-side countdown, auto-clears at zero - PIP-Welcome-Board rotating welcome/birthday cards from CSV - PIP-Fundraiser-Thermometer goal-progress bar from local/URL JSON - PIP-QR-Rotator rotating QR codes, encoded client-side - PIP-Incident-Webhook event-driven: red on firing, clear on resolved Also includes the CAP-AU (NSW RFS) and US NWS/NOAA emergency-alert monitors that push expiry-aware PiP overlays. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|---|---|---|
| .. | ||
| .gitignore | ||
| config.example.json | ||
| countdown-overlay.html | ||
| countdown-overlay.js | ||
| countdown.js | ||
| package.json | ||
| README.md | ||
| test.js | ||
PiP Event Countdown
Push a live, self-clearing countdown overlay to a ScreenTinker screen (or group) with
the PiP API. The overlay ticks down DD : HH : MM : SS in real time and — the fun part —
removes itself the instant the target time arrives. There is no clearing poll: the
script sets the PiP duration to "seconds until the target", so the player drops the
overlay at exactly zero and shows a quick 🎉 first.
Great for: New Year's Eve, product launches, store opening / closing, shift changes, webinar "starts in…", conference session timers, "back in 15 minutes".
How it works
countdown.js --(POST /api/pip, type:web, duration = seconds-to-target)--> player
|
overlay_base_url/countdown-overlay.html?target=<ms>&title=<text> |
v
countdown-overlay.js ticks the clock every second; at zero shows 🎉 <title>
...and the player auto-removes the PiP at the same moment (duration elapsed)
countdown.js is a one-shot push — it doesn't stay running. Re-run it to change the
target or title; the player keeps last-show-wins, so the new overlay replaces the old.
Files
| File | Purpose |
|---|---|
countdown.js |
Computes seconds-to-target and pushes one PiP. --clear removes it early. |
countdown-overlay.html / countdown-overlay.js |
The overlay page the player loads in an iframe. Must be served by your ScreenTinker host (same-origin with the player). |
config.example.json |
Copy to config.json and fill in. |
test.js |
Offline unit test of the date math (npm test). |
Setup
-
Mint a token. In the dashboard create an API token with the
fullscope (PiP is fleet-affecting and can render arbitrary web content, so it requiresfull). -
Serve the overlay assets. Copy
countdown-overlay.htmlandcountdown-overlay.jsinto the directory your ScreenTinker server serves at the web root (the same placeindex.htmlis served from — thefrontend/dir in this repo). They must be reachable atoverlay_base_url, and same-origin with the player so the server's CSP (script-src 'self') allowscountdown-overlay.js. (Inline scripts are blocked by the CSP — that's why the JS is a separate file.) -
Configure.
cp config.example.json config.json # edit config.json: api_base, api_token, overlay_base_url, device_id, target, title -
Run.
node countdown.js # or override target/title on the CLI: node countdown.js "2026-07-04T21:00:00-05:00" "Fireworks!" # clear it early: node countdown.js --clear
config.json
| Key | Meaning |
|---|---|
api_base |
Base URL of your ScreenTinker server, e.g. https://signage.example.com. |
api_token |
A full-scope st_… token. |
overlay_base_url |
Public URL of countdown-overlay.html (served by your host). |
device_id |
A device or group id to show on. |
target |
Target datetime, any Date.parse-able string (ISO 8601 recommended, include a TZ offset). |
title |
Heading shown above the clock, and the 🎉 message at zero. |
position |
center (default), top-right, top-left, bottom-right, bottom-left. |
Local quick-start (this repo's dev instance)
The dev server runs at https://localhost:3443/ with a self-signed cert, so disable TLS
verification for the run. Copy the overlay assets into the served frontend/ dir first so
https://localhost:3443/countdown-overlay.html resolves.
cp config.example.json config.json
# config.json:
# "api_base": "https://localhost:3443/"
# "api_token": "st_REPLACE_WITH_A_FULL_SCOPE_TOKEN"
# "overlay_base_url": "https://localhost:3443/countdown-overlay.html"
# "device_id": "DEVICE_OR_GROUP_ID"
# "target": a time ~2 minutes out, e.g. "2026-06-18T19:42:00-05:00"
# "title": "Demo"
NODE_TLS_REJECT_UNAUTHORIZED=0 node countdown.js
Watch the screen count down and disappear on its own at zero. (config.json is
git-ignored so your token never gets committed.)
Notes & limits
- The PiP
durationcaps at 24h (86400s). For a target more than a day out the overlay still shows, but it can't auto-clear at zero — re-run within 24h of the target for the self-clear effect. The script warns you when the target is beyond the cap. - PiP is ephemeral: it isn't part of the device's saved layout, so a player reboot
clears it. Re-run
countdown.jsafter a reboot if needed. - Offline devices are reported, not queued — show it while the screen is online.