Projects
Nine things I have built, newest first. Language, stars, dates and live links come from
the GitHub API when the site builds.
Running a relay as a thermostat in Home Assistant means hand-writing an automation for every room. This panel puts relays on a board, binds each to a temperature sensor and a set point, and writes the automation itself. If a sensor goes unavailable, the relay switches off.
- JavaScript
- Node
- MariaDB
- Home Assistant
- self-hosted
Most Hyprland setups stitch together other people’s widgets, each with its own look and its own bugs. I wrote the whole shell in QML instead — bar, notifications, launcher, on-screen displays — so it behaves as one piece. It is what I run every day.
- QML
- Quickshell
- Hyprland
- Wayland
The Elegoo Centauri Carbon 2 has a single MQTT slot, so only one client can talk to it at a time. This service holds that slot and shares it: a web dashboard, Mainsail and Fluidd through a Moonraker-compatible API, Prometheus and Telegram all work at once. It began as a fork of runnane/elegoo-web.
- TypeScript
- Bun
- MQTT
- Moonraker
- Prometheus
A dozen self-hosted services means a dozen bookmarks and no idea which one is down. Tailboard puts them all on one page with their status, so the homelab has a front door instead of a folder of links.
- self-hosted
- homelab
- dashboard
Uptime Kuma’s status page wastes a wall-mounted screen: wide gaps, uptime numbers overlapping names, ragged heartbeat bars. This is one CSS file for the Custom CSS field that packs monitors into a full-width grid, with status-coloured uptime pills and bottom-aligned bars.
Every YouTube-to-MP3 site is an ad farm that wants your links on its server. This is one Go binary you run yourself: paste a playlist, get the files back, nothing leaves your machine.
- Go
- single binary
- self-hosted
Friends kept asking me to spin up Minecraft worlds, which meant an SSH session every time. Spawnpoint puts start, stop, backups and the server console in a browser, so they can do it without me.
- TypeScript
- self-hosted
- backups
- console
Estonian electricity prices swing hour to hour, but Home Assistant could not see them. This pulls Elering’s hourly rates into a sensor, so an automation can hold the dishwasher until the cheap window.
- Python
- Home Assistant
- Elering API
Some keyboard layouts hide the pipe character behind a combination a laptop cannot produce. This binds it to Escape in fish, so a key nobody uses at a prompt types the one you need constantly.