← Build log
2026-10-28

Teaching Gears to Belong to Groups

Teaching Gears to Belong to Groups

A lighting group should be something you can build by hand, not something a commissioning engineer configures once with a laptop and a manual.

The shape of the problem

The lighting gear has its own concept of group membership — a bitmask, one bit per group, stored in the gear itself. So a group isn’t a software construct. It’s a fact about a physical device.

That distinction is the whole design problem. If membership lives only in my database, the software and the hardware drift apart the first time someone unplugs a cable, and the interface will happily describe a group that no longer exists.

Dragging a light onto a group

So the interaction is literal: drag a light card onto a group card. Behind it, two steps that both have to succeed.

  1. Write the new bitmask to the gear.
  2. Read the mask back from the gear and check it matches.

The second step is the one that matters. A write that isn’t confirmed isn’t a change — it’s a hope. So the interface treats a chip as pending until the gear agrees, and a group only counts as verified when the gear has been asked and has answered.

Where it went wrong

  • Membership writes are not level writes. A membership command lives in a different address space than a dim command. Sending one where the other belongs does nothing at all — and “nothing at all” looks exactly like success if you only check that the broker accepted it.
  • The mask is a live value, not a cached one. The gear moves under you. A mask read ten minutes ago is not evidence about the gear now. Every verification reads fresh.
  • Some gears don’t answer. Three of them on the live rig report a not-responding status while the controller itself is perfectly healthy. The honest thing was to show that state, not hide it behind a last-known value. A dashboard that smooths over a dead gear is worse than one with no dashboard.
  • Editing one bit must not disturb the others. Every membership change has to preserve the rest of the mask exactly. The only way to know is to read back and compare bit by bit, not just check that the target group turned on.

What the interface ended up doing

Dashed chips for anything unverified. Solid chips for anything confirmed against the gear. A “read back everything” action that asks each gear directly rather than trusting what the database remembers. And a membership editor that shows the mask before and after, so a mistake is visible rather than something you find out about later.

The nicest part of the work is that the drag-and-drop is trivial. All the difficulty is underneath it, and all of it is about not lying.