Skip to content

gancim/SurfPixel

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

12 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

SurfPixel 🌊

Live weather, wave and tide forecast on a desk-sized LED matrix — so you know whether to grab the board before you've had coffee.

SurfPixel rendering on a 32x32 LED matrix: temperature and wind on top, wave height in the middle, swell period, and a tide curve along the bottom

SurfPixel fetches the marine forecast for your surf spot, renders it into a single dense 32×32 frame with hand-made pixel fonts, and pushes it to an iDotMatrix LED display over Bluetooth — refreshed every few minutes, no phone app required.

What's an iDotMatrix?

iDotMatrix is a family of inexpensive LED pixel displays (16×16, 32×32, 64×64) sold on AliExpress, Amazon and elsewhere, normally driven by a phone app of the same name. There's no Wi-Fi and no cloud — the panel is a dumb Bluetooth LE device that accepts commands on a single GATT characteristic. The community reverse-engineered the protocol (see python3-idotmatrix-library), which means anything that speaks BLE can own the screen. SurfPixel renders a PNG and sends it raw:

  • device advertises a name starting with IDM-
  • writes go to characteristic FA02, no response
  • [5, 0, 4, 1, 1] enters DIY draw mode, [5, 0, 4, 128, n] sets brightness
  • the PNG is chunked and prefixed with a small length header — that's it

The screen

Designed for a surfer's glance: waves and tide get the pixels, weather gets a corner.

Zone Rows Content
Weather strip 0–4 condition icon, air temperature °C, wind speed + direction arrow (unit configurable: m/s, knots, km/h or mph — default m/s)
Wave height 8–14 significant wave height in meters, big — plus the swell's travel-direction arrow
Swell period 16–20 ~ glyph + period in seconds — green when ≥ your "good" threshold (default 8 s), red when it's short wind chop; tide trend triangle at right (green ▲ rising / red ▼ falling)
Tide 22–31 sea level curve, 1 pixel per hour (3 h back → 28 h ahead), white dotted line = now

Forecast data comes from Open-Meteo's weather and marine APIs — free, no API key.

macOS menu bar app (recommended)

A native Swift app — no Python, no terminal. It lives in the menu bar as a small wave icon and keeps the display updated in the background.

⬇ Download the latest release (universal binary, macOS 13+). The app isn't notarized, so on first launch right-click → Open, or run xattr -d com.apple.quarantine /Applications/SurfPixel.app.

Or build it yourself:

cd SurfPixelApp
./build_app.sh
open dist/SurfPixel.app

macOS will ask for Bluetooth permission on first run; the display must be powered on and in range (the app remembers it for instant reconnects).

Menu: Update Now · Preview Frame (see the frame without the device) · Settings… · Start at Login. Settings covers everything: spot name, weather and surf coordinates, timezone, refresh interval, brightness, the good-period threshold, and a color well for every element on screen. Stored at ~/Library/Application Support/SurfPixel/config.json.

SurfPixel settings window with location, refresh and color options

Requires macOS 13+ and Xcode command line tools to build.

Python CLI

The same screen, scriptable — handy for a Raspberry Pi sitting next to the display.

python3 -m venv .venv
.venv/bin/pip install -r requirements.txt

.venv/bin/python -m surfpixel --preview out.png   # render without the device
.venv/bin/python -m surfpixel --scan              # find your display
.venv/bin/python -m surfpixel --once              # push one frame and exit
.venv/bin/python -m surfpixel                     # run forever

Configuration lives in config.yaml: coordinates, brightness, refresh interval, the good-period threshold, and every color.

The default spot is Chisan (Hamasuka, Chigasaki, Japan) — point location.weather and location.surf anywhere on a coast. The surf coordinates must be over water for the marine model to resolve.

How it works

Open-Meteo weather API ─┐
                        ├─→ 32×32 renderer ─→ PNG ─→ Bluetooth LE ─→ iDotMatrix
Open-Meteo marine API ──┘    (pixel fonts,
 (waves, tide)                icons, tide curve)

Both implementations draw the identical frame: a 3×5 pixel font for small text, 4×7 digits for the wave height, 5×5 weather icons and direction arrows, and an auto-scaled tide sparkline. The Swift app uses CoreBluetooth and CoreGraphics; the Python CLI uses bleak (via the idotmatrix library) and Pillow.

Credits

License

MIT

About

Local weather, wave and tide forecast on an iDotMatrix 32x32 LED display — native macOS menu bar app + Python CLI

Topics

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors