Skip to content

Releases: csader/splitflap-os

v0.2.4

30 May 00:41

Choose a tag to compare

Continuous Random Spin

Fixes the Random Spin app so modules move independently and continuously, with no collective pause.

Changes

  • Each module maintains independent dwell/spin state (no synchronized frame replacements)
  • Added skip_rotation_wait manifest flag — server no longer waits for all modules to settle before sending the next frame
  • Modules receive new targets before finishing their current move, producing constant chaotic motion

Also included (since v0.2.1)

  • Fix update poll to verify version actually changed before declaring success (v0.2.2)
  • Fix /apply_update 500 errors: safe.directory, dirty tree handling, better error messages (v0.2.3)

Upgrade note

If you are on v0.2.0, the update button has a bug. Update manually once:

cd /opt/splitflap-os
git pull origin main
sudo systemctl restart splitflap.service

After that, future UI updates will work correctly.

v0.2.2

29 May 16:01

Choose a tag to compare

Fixes

Update mechanism now verifies version change (#47 feedback)

The update poll was declaring success as soon as the server responded, without checking if the version actually changed. If the service restart failed or hadn't happened yet, it would show "Update complete! v0.2.0" while still on the old version.

Now waits for the server to either go down or return a different version before declaring success. Shows a clear failure message if the version never changes.

Independent per-module random spin (v0.2.1)

Each module now maintains its own dwell/spin state instead of generating synchronized full-frame replacements. No more full-line reveal where all modules pause together.

v0.2.1

29 May 15:47

Choose a tag to compare

Fix: Independent per-module random spin

Resolves feedback on #47 — each module now maintains its own dwell/spin state instead of generating synchronized full-frame replacements. No more "full line reveal" where all modules pause together.

Changes

  • Each module independently dwells and spins on its own schedule
  • ~8% chance per tick of a module arriving at its target (naturally staggers stops)
  • Configurable dwell time via anim_speed setting
  • Version bump to 0.2.1

v0.2.0

29 May 04:08

Choose a tag to compare

What's New

  • Unified transition style + speed — 13 order-based styles (diagonal, spiral, center-out, etc.) + sync + slot machine. Global default in Settings, per-app override, per-page override in compose and playlists.
  • Schedules + Quiet Hours — time-based app/playlist switching with day-of-week support and overnight ranges. Quiet hours stop the display and suppress notifications.
  • App Triggers — event-driven display interrupts. 16 trigger-capable apps (sports score changes, weather alerts, stock thresholds, ISS overhead, and more). Background check loop with exponential backoff and per-trigger cooldowns.
  • Global location support — location search replaces US-only ZIP code. Works worldwide. Auto-sets timezone. Per-app location override for weather.
  • Random Spin animation — continuous random flaps with staggered module timing for organic motion and sound.

Improvements

  • Default (global) option in compose and playlist style dropdowns
  • Sim reflects active transition style in real-time
  • Smart speed defaults per style (slot→80ms, sync→0ms)
  • Trigger system caches geocoding and 52-week stock data to reduce API load
  • Exponential backoff on trigger failures prevents rate-limit issues on Pi
  • Weather, ISS, and dashboard apps use coordinates directly (no more US-only geocoding)

v0.1.13 — Currency, Venv Install & Bug Fixes

18 May 22:15

Choose a tag to compare

What's New

Currency Symbol Setting

  • New Currency Symbol setting in Settings (default $)
  • Set to £, , ¥, etc. — Stocks and Crypto apps display your currency automatically
  • Works transparently: apps output $, the server maps it to the correct flap position

Multi-Countdown Support (by @InertiaImpact)

  • Up to 5 simultaneous countdowns, each with its own name and target date
  • Per-slot enable/disable toggles
  • Improved display handling for narrow signs

BirdNET Fixes

  • Last 3 mode now shows last 3 unique species instead of last 3 detections
  • Fixed cache not invalidating when display mode changes
  • Fixed settings not being read correctly

Bug Fixes & Improvements

Install & Compatibility

  • Trixie/Bookworm fix: installer now uses a Python venv, avoiding PEP 668 externally-managed-environment errors
  • --prefer-binary flag for much faster installs on Pi Zero W (uses pre-built wheels instead of compiling)
  • OTA updater now detects missing venv and runs install.sh automatically on first update

Data Hygiene

  • Removed legacy defaults that showed other people's data to new users: nhl_teams (BOS,DAL), stocks_list (MSFT,GOOG,NVDA), yt_channel_id, mbta_stop/mbta_route
  • Removed broken migration code that caused NHL scores to appear even with no teams configured

v0.1.12 — Weather, Planes, Calibration & More

12 May 20:14

Choose a tag to compare

What's New

Weather App — Major Update (by @InertiaImpact)

  • 4 providers: Open-Meteo (free, no key), WeatherAPI.com, QWeather, OpenWeather
  • Open-Meteo is now the default — works out of the box with no API key
  • AQI, UV index, pollen — optional pages with color-coded status
  • Temperature units: F, C, K
  • Configurable refresh rate
  • Adapts to any grid size including 4+ rows
  • Caches last good pages on error

Existing users: If you had an OpenWeather API key, the provider defaulted to Open-Meteo after this update. Go to Weather settings and switch back to OpenWeather if needed.

Planes Overhead — API Usage Estimates (by @InertiaImpact)

  • Per-provider API usage estimates with free tier warnings

Settings System Improvements (by @InertiaImpact)

  • notice field type — info/warning/success/error boxes in settings modals
  • disabled_when — conditionally disable fields based on other values
  • polling_usage_estimate — config-driven API usage calculator with provider profiles
  • Better merge logic for live schema updates

Calibration Improvements

  • Reset Offset button — jump to 2832 in one click (no more clicking +32 hundreds of times, closes #26)
  • Direct offset input — type a target value and hit Set
  • Auto fine-tune direction fixed — now goes 1→63 (1 step per transition) instead of 63→1 (~63 steps per transition)

Simulator

  • Flap animation speed matches real hardware timing (~4.2s for full home, closes #27)

BirdNET App

  • Compact display: bird name + confidence on one line
  • Smart name shortening (White-Winged Dove → WW Dove, Carolina Chickadee → C. Chickadee)
  • Leaderboard: single page with one bird per row, fills grid height
  • Lucide icon
  • Removed guessed color indicators

v0.1.11 — Inbox, BirdNET & Bug Fixes

11 May 01:12

Choose a tag to compare

What's New

Inbox — Push Messages to the Display

External services can now push messages directly to the display via HTTP, regardless of what app is running.

High-priority messages interrupt between pages — your display reacts to your world in real time.

curl -X POST http://splitflap.local/inbox \
  -H "Authorization: Bearer <your-key>" \
  -d '{"text": "CHICKEN DETECTED", "priority": "high"}'

Setup: Settings > Inbox > Enable > Add Source. Each integration (Frigate, HA, n8n, OpenClaw, etc.) gets its own revocable API key.

Use cases: Frigate detections, laundry done, 3D print complete, calendar reminders, solar milestones, agent notifications, "WELCOME HOME" on arrival.

Endpoints:

  • POST /inbox — push a message (requires Bearer token)
  • GET /inbox — list queue
  • DELETE /inbox — clear queue or by source

BirdNET App

Polls a BirdNET-Pi instance for live bird detections. Shows latest detection, last 3 birds, or today's leaderboard. Maps bird species to flap color characters (cardinal→red, jay→blue, goldfinch→yellow, etc.).

Bug Fixes (v0.1.10)

  • PUSH TO DISPLAY was silently failing (broken after Compose tab simplification)
  • Compose grid not resizing when grid dimensions change
  • Compose grid crash on init (race condition)
  • Stale CSS/JS after update — now uses version as cache-busting string
  • Update modal stuck on spinner after server restarts
  • savedPlaylistList null error

v0.1.10 — Bug Fixes

09 May 12:44

Choose a tag to compare

Bug Fixes

PUSH TO DISPLAY was broken

sync() was reading removed DOM elements (modeToggle, delayInput, styleInput, speedInput) which returned null and threw a TypeError before the fetch fired. Fixed by removing dead references and using defaults.

Compose grid not resizing with grid dimensions

initComposeGrid() was missing from applyGridConfig() and the polling loop's dimension-change handler. All three code paths that change grid size now also resize the compose grid.

Compose grid crash on init

onChange fired during createComposeGrid initialization before composeGrid was assigned, causing getBuffer() on null. Fixed with a local _grid reference.

Stale CSS/JS after update

Static asset URLs now use the app version as the cache-busting string (?v=0.1.10). After each update, browsers automatically fetch fresh CSS/JS — no more unstyled page after clicking Reload.

Update modal stuck on spinner

Race condition where the poll could complete and show "Update complete" before the fetch().catch() fired, which then overwrote the state with "Restarting…". Fixed with a done flag.

savedPlaylistList null error

renderSavedPlaylists was crashing when the element didn't exist (removed from Compose tab). Added a null guard.

v0.1.9 — Bug Fixes

08 May 23:52

Choose a tag to compare

Bug Fixes

PUSH TO DISPLAY was broken

The Compose tab's "PUSH TO DISPLAY" button was silently failing. When we simplified the Compose tab (moving multi-page playlists to the Playlists tab), we removed the modeToggle, delayInput, styleInput, and speedInput elements — but sync() still tried to read them. document.getElementById() returned null, causing a TypeError before the fetch ever fired. Fixed by removing the dead references and using sensible defaults.

Compose grid not resizing with grid dimensions

The compose grid wasn't updating when grid dimensions were changed via Settings or applyGridConfig(). initComposeGrid() was missing from two code paths that change grid size — now all three paths (initial load, settings save, polling loop) resize the compose grid correctly.

v0.1.8 — Update Modal & UX Fixes

08 May 21:40

Choose a tag to compare

What's New

Update Progress Modal

  • Clicking "Update Now" now opens a modal with step-by-step progress
  • Shows: Downloading → Restarting → Complete
  • Spinner animation during active steps
  • Reload Page button appears when server comes back (no surprise auto-reload)
  • Error state with Close button if update fails

Bug Fixes

  • Fixed clicking the "update available" badge opening the hamburger menu instead of navigating to Settings
  • Hamburger menu now closes (not toggles) when navigating to a settings page from outside the drawer