GlowUp
May 16, 2026 · View on GitHub
Copyright (c) 2026 Perry Kivolowitz. All rights reserved. Licensed under the MIT License. See LICENSE for details.
This project utilizes AI assistance (Claude 4.6) for boilerplate and logic expansion. All final architectural decisions, algorithmic validation, and code integration are performed by Perry Kivolowitz, the sole Human Author.
Basic Release Scope
This manual describes the supported Basic release surface.
Included:
- LIFX discovery
- naming bulbs
- groups
- effects
- simulator
- standalone install
- Linux server install
- dashboard
- schedules
Not included in Basic support:
- sensors
- Matter
- distributed workers
- MIDI
What GlowUp Basic Does
GlowUp Basic (hereafter GlowUp) drives LIFX lights. It runs animated effects (a Larson scanner, an aurora, fireworks, a slow breathe), it groups bulbs together so an effect spans a whole room as one virtual strip, and it gives every bulb a human-readable name so you never type IP addresses.
GlowUp ships in two flavors. You pick one. You can move from the first to the second later without losing your work.
Which Mode
Standalone runs on the machine in front of you — your Mac, your laptop, your
Windows desktop. You type a command, the lights respond. When you exit the
program or close the terminal, GlowUp stops. Nothing runs in the background.
There is no server, no service, no sudo, no daemon. Your bulb names and groups
are stored in a small folder under your home directory. Standalone is the right
choice if you want to play with effects, drive a few bulbs from the keyboard, or
get a feel for GlowUp before deciding whether you want more.
Server runs on an always-on Linux box — a Raspberry Pi, a small
NUC, an old desktop. The server keeps your bulb registry, your
groups, your schedules, and a web dashboard alive even when your
laptop is asleep or off. You gain sunrise/sunset schedules, a dashboard
in your browser, and the ability to drive lights from any device on
your network. You give up portability — the server wants to live
on Linux with systemd, owns config under /etc/glowup, and asks
for sudo during install. Server is the right choice if you want
your lights to do something at sunset whether you're home or not.
You don't have to decide forever. The bulb names and groups you build in standalone mode upgrade cleanly into a server install — just copy the files. Start standalone, switch when you're ready.
Standalone
What You Need
A computer running macOS, Linux, or Windows with Python 3.11 or later. Any LIFX bulb on the same Wi-Fi network. That's it.
The optional simulator (a preview window that shows what an effect
looks like without sending packets to real lights) needs tkinter,
which ships with macOS and Windows Python and is one apt-install on
Linux (sudo apt install python3-tk).
Installing
Clone the repository and run the installer:
git clone https://github.com/pkivolowitz/glowup.git
cd glowup
./install.sh
The installer creates a Python virtual environment at
~/.glowup/venv/ (per-user, no sudo for standalone), installs the
small set of packages GlowUp needs, and drops a small launcher
script at ~/.local/bin/glowup that knows how to find the venv.
The installer asks permission before adding ~/.local/bin to your
shell's PATH — if you say yes, it backs up your shell rc file
(.zshrc, .bashrc, etc.) and appends one line. If you say no, you
can run GlowUp by its full path and add it to PATH yourself later.
When the installer finishes, open a new terminal (or source your
shell rc) and glowup discover should work from anywhere.
The clone itself is just source code — the venv lives outside it,
so you can git pull and re-run ./install.sh to upgrade without
rebuilding the venv from scratch. Running ./install.sh a second
time is the upgrade path: it re-syncs the venv against the new
requirements.txt, leaves your data in ~/.glowup/ alone, and
reports what changed.
On macOS, that's the whole story.
On Linux, ./install.sh defaults to the server flavor (see below)
because the typical Linux box running GlowUp is a Pi or a small
server. If you're on a Linux laptop and want standalone, the
installer asks once at the top of the run — answer "standalone" or
press s. If you're scripting the install (Ansible, cloud-init,
etc.) and need to skip the prompt, pass --standalone or
--server on the command line.
On Windows there is a small PowerShell installer:
git clone https://github.com/pkivolowitz/glowup.git
cd glowup
.\install.ps1
install.ps1 does the same thing the macOS/Linux standalone
installer does — creates %USERPROFILE%\.glowup\venv\, installs
GlowUp's packages into it, and drops a glowup.cmd shim into
%USERPROFILE%\bin\ (asking permission before adding that
directory to your user PATH via the registry). No Administrator
rights, no Windows service, no files outside your user profile.
Finding Your Lights
Run discover:
glowup discover
Discover broadcasts on your local network and listens for replies. It also walks the system ARP cache and runs a short ARP sweep to catch bulbs that ignored the broadcast — LIFX bulbs frequently don't answer broadcasts, especially on mesh routers, so the sweep is there to fill in the gaps.
A typical run prints a table:
LABEL PRODUCT IP MAC ZONES
A19 KITCHEN A19 192.168.1.41 d0:73:d5:01:23:ab 1
PORCH STRING LIGHTS String 36 192.168.1.42 d0:73:d5:04:56:cd 36
DESK NEON Neon 192.168.1.43 d0:73:d5:07:89:ef 36
If discover finishes and prints a line like "some lights may have
been missed — check your router's client list for unknown
50:C7:BF or D0:73:D5 MAC addresses," take it seriously. LIFX
bulbs sometimes hide from discovery and the only way to find them is
the router's admin page. Note their IPs and pass them with --ip
on later commands.
Naming Your Lights
After discover gives you IPs, you walk through the house and tell GlowUp which bulb is which. Pick an IP, pulse it, watch for the breathing bulb, give it a name:
glowup identify --ip 192.168.1.41
The bulb breathes warm white until you press Ctrl+C. Once you've spotted it, name it:
glowup name --ip 192.168.1.41 "Kitchen Bulb"
The IP, MAC, and label are stored in ~/.glowup/devices.json.
The schema for that file (and for groups.json once you start
making groups) is documented in ~/.glowup/README.md, dropped
there by the installer alongside the JSON files. The runtime
preserves keys starting with _ on read but never writes new
ones, so you can drop hand-written notes into the JSON files
and the dashboard or CLI won't strip them.
From now on you can address that bulb by name instead of by IP:
glowup play breathe --device "Kitchen Bulb"
Repeat for each bulb. The file accumulates as you go.
Grouping Lights
A group is a named set of bulbs that an effect can animate together as if they were one long strip:
glowup group add bedroom "Kitchen Bulb" "Hallway Bulb"
glowup group list
glowup group show bedroom
glowup group rm bedroom
Group definitions live in ~/.glowup/groups.json. Order matters —
the first bulb in the group is the leftmost zone of the virtual
strip, the next bulb is to its right, and so on. If an effect
animates in the wrong direction, change the order.
A group of one bulb is fine. A group of one multi-zone string light is also fine — the effect will animate across the string's zones.
Running Effects
To list every effect GlowUp knows:
glowup effects
To run one:
glowup play cylon --device "Kitchen Bulb"
glowup play aurora --group bedroom
glowup play breathe --ip 192.168.1.42 --speed 8 --hue 240
Each effect has its own parameters. The default behavior is sane; if you want to tune, ask the effect what it accepts:
glowup play cylon --help
That prints every parameter, its default, and its valid range.
Press Ctrl+C to stop. The lights fade to black over half a second.
Previewing Without Bulbs
If you want to see what an effect looks like before pointing it at real lights — or you don't have lights handy — open the simulator:
glowup play aurora --sim-only --zones 36
A small window opens showing the rendered animation. No packets are sent to any device.
When Things Go Wrong
Discover finds nothing. You're probably on a mesh router that
eats UDP broadcasts. TP-Link Deco does this, and so do some Eero
configurations. Plug the bulbs into a flat unsegmented network if you
can. Otherwise, look up bulb IPs in your router's client list (LIFX
MAC prefixes start with 50:C7:BF or D0:73:D5) and use --ip.
A bulb shows up but won't respond to play. Power-cycle it from the wall switch. LIFX bulbs occasionally get into a state where they ignore commands until they're rebooted. Once they come back up, they'll work normally.
Discover prints stale IPs. Your router reassigned addresses after a reboot. Re-run discover and re-name any bulbs whose IP changed. The MAC stays the same, so the names stick.
To stop this from happening, set a static DHCP reservation in your router for each bulb. A bulb's MAC address never changes, so most home routers can be told to hand out the same IP every time that MAC asks for one. Once reserved, the bulb's IP is permanent across reboots and network outages — and you never have to re-run discover to chase a moved address.
Effects look fine in the simulator but wrong on the lights. Check the bulb count and zone count in the discover table. If a 36-zone string light is showing up as a 1-zone bulb, the device is in a weird firmware state — power-cycle it.
Server
What You Gain Over Standalone
A web dashboard you can pull up from any device on your network. A scheduler that turns on the porch lights at sunset, runs a flag animation in the morning, fades to a soft glow at bedtime. The dashboard manages your bulb registry and groups for you — point, click, name, group — instead of editing JSON. Effects keep running even when your laptop is closed and on a plane.
What It Costs
You need an always-on Linux box. A Raspberry Pi 4 is plenty; a retired desktop with Ubuntu works just as well. Debian and Ubuntu derivatives are supported in this release; other distributions (Fedora, Arch, etc.) may work but aren't tested.
The installer asks for sudo because it writes systemd unit
files, creates /etc/glowup/ for read-only config, creates
/var/lib/glowup/ for the dashboard's writable data, and creates
a dedicated glowup system user that owns the service. The
server runs as that glowup user — you won't see it in your
terminal, you'll see it in systemctl status glowup-server. If
you've never used systemctl, the install will walk you through
the few commands you need.
There is no Windows or macOS server flavor. The server is Linux only.
Installing
On the Linux box, clone and run the installer:
git clone https://github.com/pkivolowitz/glowup.git
cd glowup
./install.sh
The installer creates a virtual environment, writes read-only
site config to /etc/glowup/site.json and /etc/glowup/server.json,
seeds writable state files at /var/lib/glowup/devices.json and
/var/lib/glowup/groups.json (both empty {} to start), drops a
matching ~/.glowup/README.md-style schema doc into
/var/lib/glowup/, drops a systemd unit, and starts the server.
When it finishes, it prints a URL — point your browser at it.
Re-running ./install.sh after a git pull is the upgrade path.
It re-syncs the venv against the new requirements.txt, re-renders
the systemd unit, and leaves /etc/glowup/server.json and
everything in /var/lib/glowup/ alone unless the schema has
changed.
If you used GlowUp standalone first, copy your bulb registry and
groups across before the server starts. The server reads them from
/var/lib/glowup/, not /etc/glowup/, because they're data the
service writes to (schedules edited in the dashboard, new bulbs
named via the CLI):
sudo install -o glowup -g glowup -m 0640 \
~/.glowup/devices.json /var/lib/glowup/devices.json
sudo install -o glowup -g glowup -m 0640 \
~/.glowup/groups.json /var/lib/glowup/groups.json
sudo systemctl restart glowup-server
install (rather than cp) sets ownership and permissions in one
shot so the glowup service user can read and write the migrated
files. The server reads the same file shape standalone wrote, fills
in the extra fields it cares about with defaults, and your names
and groups appear in the dashboard.
Using The Dashboard
The dashboard lives at the URL the installer printed (typically
http://<your-server>:8420/). From there you can:
- See every bulb the server knows about, with current status.
- Run identify on a bulb (the bulb breathes; you walk over and look at it).
- Rename bulbs.
- Create, edit, and delete groups.
- Browse the effect catalog and launch effects against bulbs or groups.
- View the schedule, edit entries, add new ones.
The dashboard covers the normal registry, group, effect, and schedule workflows. The CLI remains available for scripting and direct control.
Telling The Server Where You Are
If you want sunrise and sunset to mean anything, the server has to
know where it is. The installer asks for your latitude and longitude
during setup; you can also edit them later in
/etc/glowup/site.json. Decimal degrees, four or five places of
precision is plenty. Without them, symbolic times like sunset-30m
have nothing to compute against.
Schedules
A schedule entry says "between time X and time Y, run effect E on
group G with parameters P." Times can be wall-clock (07:00,
23:30) or symbolic (sunset-30m, sunrise+15m). The server uses
your latitude and longitude — entered during install — to compute
sunrise and sunset for the day.
Add an entry from the dashboard, or edit
/var/lib/glowup/schedules.json directly (the dashboard writes
back to that file, so hand-edits and dashboard edits live in the
same place). A typical entry looks like:
{
"name": "porch evening aurora",
"group": "porch",
"start": "sunset-30m",
"stop": "23:00",
"effect": "aurora",
"params": {
"speed": 10.0,
"brightness": 60
}
}
Multiple groups can run different schedules at the same time. The server checks every thirty seconds whether the active entry should change; when it does, the old effect fades out and the new one starts.
If you want to override a schedule manually — "forget the schedule,
turn the porch off right now" — use the dashboard's override panel
or run a play command from the CLI. The override holds until you
release it.
When Things Go Wrong
The dashboard URL doesn't load. Check the server is running:
sudo systemctl status glowup-server
If it's not, look at the logs:
sudo journalctl -u glowup-server -n 50
A schedule entry doesn't fire. The server polls every thirty
seconds, so allow a minute. If the entry still doesn't run, check
the entry's days field (if set) and confirm your latitude and
longitude in /etc/glowup/site.json are right — sunrise/sunset
math depends on them.
A bulb that worked yesterday is unreachable today. Your router
probably reassigned its IP. The server's ARP keepalive should pick
the new IP up automatically; give it a minute. If it doesn't, run
glowup discover from the server and re-confirm the bulb is on the
network. For lights that vanish repeatedly, set a static DHCP
reservation in your router so the bulb's IP stops changing in the
first place — most home routers can pin an IP to a MAC address with
a few clicks.
The server starts but no bulbs respond. /var/lib/glowup/groups.json
may still be empty (or only contain a placeholder entry pointing at
the unreachable 192.0.2.1). Use the dashboard, or glowup name
and glowup group add from the CLI on the server, to populate
real bulbs and groups. Restart the server if you edited the file
by hand instead of via dashboard or CLI.
Where To Go Next
Stop here if standalone or a basic server install is enough for you. GlowUp does more — sensor adapters, distributed workers, MIDI pipelines, screen-reactive lighting, custom effect development — but none of that is necessary to drive your lights.
If you want any of those, the project's deeper documentation
covers them. Open the docs/ folder and look at ADVANCED.md.
Know, however, more sophisticated installers have not been provided
as yet.