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>
4.2 KiB
PiP Crypto Ticker
A live cryptocurrency price ticker for ScreenTinker screens. Polls
CoinGecko's keyless simple/price endpoint and
pushes a wide ticker-strip overlay via the PiP API. Each poll refreshes the same
overlay in place; prices update without a flash.
No API key required. Zero runtime dependencies (Node 18+ global fetch).
┌────────────────────────────────────────────────────────────────┐
│ BTC $64,012.34 ▲ +1.23% • ETH $3,380.10 ▼ -0.46% • SOL … │
└────────────────────────────────────────────────────────────────┘
How it works
ticker.jsfetchesGET /api/v3/simple/price?ids=…&vs_currencies=…&include_24hr_change=true.- It normalises the response into ordered items and encodes them compactly into the
overlay URL's query string (
items=BTC:64012.34:+1.23,…). - It pushes a
type: "web"PiP overlay (duration: 0, i.e. persistent) pointing atticker-overlay.html, which renders the strip. Up = green ▲, down = red ▼, flat = grey. - On the next poll it pushes again — the player keeps a single overlay slot (last-show-wins), so the numbers refresh in place.
Ctrl-C(SIGINT) clears the overlay.
Files
| file | purpose |
|---|---|
ticker.js |
poller + PiP pusher (and the pure, exported normaliser/encoder) |
ticker-overlay.html / ticker-overlay.js |
the overlay page (served by the signage server) |
config.example.json |
copy to config.json and fill in |
fixture-prices.json |
a saved CoinGecko response for the offline test |
test.js |
offline test — no network, no PiP push |
Setup
The overlay page must be served same-origin with the signage server (the player loads it in an iframe, and the server CSP only allows same-origin scripts). Copy the two overlay files into the server's static frontend directory:
cp ticker-overlay.html ticker-overlay.js /path/to/screentinker/frontend/
Then they're reachable at https://<your-server>/ticker-overlay.html.
Create a full-scope st_ API token in the dashboard (Settings → API tokens), then:
cp config.example.json config.json
# edit config.json: api_base, api_token, overlay_base_url, device_id, coins
node ticker.js
device_id may be a single device or a device group id.
Config
| key | meaning |
|---|---|
api_base |
signage server base URL |
api_token |
full-scope st_ token |
overlay_base_url |
URL of the served ticker-overlay.html |
device_id |
target device or group id |
vs_currency |
usd, eur, gbp, … |
coins |
array of { id, symbol } — id is the CoinGecko id |
poll_interval_sec |
refresh cadence (default 120; respect CoinGecko rate limits) |
position |
bottom-right (default), top-left, … |
width / height |
overlay box px (default 1100×110) |
Local quick-start (this machine)
A local ScreenTinker instance is already running on https://localhost:3443 with a
paired web player (device DEVICE_OR_GROUP_ID). It uses a self-signed
cert, so set NODE_TLS_REJECT_UNAUTHORIZED=0.
# 1. serve the overlay assets from the local frontend dir
cp ticker-overlay.html ticker-overlay.js /home/owner/Downloads/remote_display/frontend/
# 2. config.json
cat > config.json <<'JSON'
{
"api_base": "https://localhost:3443/",
"api_token": "st_REPLACE_WITH_A_FULL_SCOPE_TOKEN",
"overlay_base_url": "https://localhost:3443/ticker-overlay.html",
"device_id": "DEVICE_OR_GROUP_ID",
"vs_currency": "usd",
"coins": [
{ "id": "bitcoin", "symbol": "BTC" },
{ "id": "ethereum", "symbol": "ETH" },
{ "id": "solana", "symbol": "SOL" }
],
"poll_interval_sec": 120,
"position": "bottom-right"
}
JSON
# 3. run
NODE_TLS_REJECT_UNAUTHORIZED=0 node ticker.js
Test (offline)
npm test
Validates price/percent formatting, up/down/flat direction, and that the compact
items encoding round-trips through the overlay's decoder. Prints RESULT: PASS ✅.