Pixelhome by cjimti

About

Scripts, not black boxes

I'm Craig Johnston. Pixelhome is the light show on my house's roofline. Every frame of light and every note of music on this site is computed by a Python script that AI and I wrote together. Even the voice that introduces each Halloween show is mine, read by an open-source model from a few seconds of me speaking.

Why

I've been a software developer for over 30 years, and I've fully embraced AI. But generative AI is often all or nothing: change one parameter, wait for a black box, and get back a whole new finished result. As of 2026 I only have one string of pixels around my house, and I wanted to get the most out of it.

So rather than asking AI to generate light sequences, I have it write configurable Python scripts that compute them. The music works the same way: Python writes each score note by note and plays it through great open-source instruments like the Surge XT free and open-source hybrid synthesizer and the VSCO 2 Community Edition orchestral samples. When something's off, I change a number, not a prompt.

Two ways to make a light show

All or nothing

Prompt Black box Finished show

Want the bats a little slower? Rewrite the prompt, wait, and get a different show.

Pixelhome

Idea AI writes Python BEAT = 0.5
GLOW = '#40ff70'
bats = 12
Rendered in ~1 s

Change one number and re-render. Everything else stays exactly as it was.

How a show gets made

Each sequence is one Python file with two functions that share the same timings. render() computes the lights and score() writes the music, so every hit lands on its flash and is panned to where it happens on the house. A VOICEOVER line gives it a spoken intro.

The house itself comes from two exceptional open-source projects: I laid out the pixels in xLights, and modeled the house in Blender. Pixelhome imports both, so every sequence knows where each pixel sits in 3D.

From an idea to the roofline
  1. The house as datahome.json: 501 pixels, their 3D positions and six runs, imported from my xLights layout and Blender model.
  2. A story"A ghost train stops at the porch station." AI writes one Python file in numpy against that layout.

Lights

  1. render(G)Every frame for every pixel at 40 fps.
  2. PreviewA timeline and stills images, plus brightness and strobe checks. I adjust and re-render.
  3. FSEQFPP's sequence format, zstd compressed.

Music

  1. score(M, G)Notes from the same timings, panned along the roofline.
  2. Surge XT + VSCO 2Synth patches and orchestral samples, mixed with Spotify's pedalboard.
  3. MP3Rendered on my Mac and committed with the script.

Voice

  1. VOICEOVERA line to set the mood, then the card's description of what happens.
  2. ChatterboxReads it in my cloned voice, over a quiet bed of choir, cello and music box.
  3. MP3 + waveformThe voice's loudness becomes a red waveform FSEQ for the house.
  1. git pushGitHub Actions re-renders only the sequences that changed and builds this site, with a 3D preview of each one.
  2. FPPThe FSEQ and MP3 go into a playlist, the intro just before its show, and the Pi plays the roofline.

Spoken intros

One string of pixels is abstract. A shape moving along the roofline could be a bat, a train or a skeleton, and from the street you can't always tell which. So, the way an opera is introduced with a synopsis, each Halloween show can open with a short spoken intro: a line to set the mood, then what happens and where to look.

The voice is mine. I recorded a few seconds of myself reading, and Chatterbox, Resemble AI's open-source text-to-speech model, reads each intro in that voice on my Mac. It's mixed over a quiet bed of choir, cello, music box and a distant bell, and while it speaks the house shows the voice as a red waveform growing out from the middle of the left wing, the porch front and the right wing.

On this site, the Intros switch next to Sound plays a sequence's intro before the show. For FPP, each intro is its own FSEQ and MP3, scheduled just before the show it introduces.

Open source

This site and everything behind it is open source on GitHub. Everything is tailored to my pixel runs and roofline. In the future I may make it easy to adjust the segments to fit other people's setups, and I plan on adding a lot more pixels.

ccbysa

Sequences and music

Every light sequence (FSEQ and the Python that makes it) and every soundtrack is licensed under Creative Commons Attribution-ShareAlike 4.0. Use them on your own house, remix them, even commercially: credit Craig Johnston / pixelhome.app and share what you make under the same license.

MIT

Code

The pixelhome engine, the site and the scripts are under the MIT License. Do what you like with it; keep the copyright notice.

Built with open source

None of this exists without these projects and the people who give their time to them.

The hardware

501 12V pixels (WS2811) in six straight runs along the roofline, driven by FPP on a Raspberry Pi 4 with a Falcon PiCap v2. Data leaves the controller at the back-left corner of the porch on two ports. One 12V supply powers the controller end, and power is injected again at the far end of each string so the last pixels stay as bright and as white as the first.

The roofline from above, street at the bottom
Side 81 Left 98 Porch Left 82 Porch Front 71 Porch Right 49 Right 120 Pi 4 + PiCap v2 FPP 9.4 · 2 ports 12V supply 12V injected 12V injected street
Port 1
Porch Left → Left → Side · 261 pixels
Port 2
Porch Front → Porch Right → Right · 240 pixels
Power
12V at the controller, injected at both far ends
Channels
501 × RGB = 1,503, at 80% brightness, gamma 1.0