ESP32 Printago print-farm button — fork of spuder/PrintFarmButton with a printer-list scaling fix (scales to hundreds of printers)
  • JavaScript 42.2%
  • HTML 27.5%
  • Shell 21.6%
  • Makefile 8.7%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
jdh 3de68c460a fix: log firmware fetches — the key-rotation gate was unverifiable by construction
The rotation runbook gates the Printago key on 'buttons report 1.0.16', but
devices never phone home a version and the flasher logged nothing per request.
One line per /firmware/ fetch (method, path, User-Agent, peer) makes the
ESPHome updater's hourly manifest pull the observable fleet signal. Web-asset
traffic is deliberately not logged — that's operator browsers, not fleet.

Red test first (no [pfb] fw line in stdout), green after. Full test file passes.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018WP7AV4hUu7nkyieDrn6hM
2026-08-02 16:39:05 -04:00
firmware firmware 1.0.16: publish the security build so the fleet auto-updates 2026-08-01 11:16:41 -04:00
test fix: log firmware fetches — the key-rotation gate was unverifiable by construction 2026-08-02 16:39:05 -04:00
web server: stop publishing the entire private repo to the internet 2026-07-28 19:24:39 -04:00
.gitignore firmware: the button web UI and OTA were both unauthenticated 2026-07-29 11:38:35 -04:00
build.sh firmware 1.0.16: publish the security build so the fleet auto-updates 2026-08-01 11:16:41 -04:00
NOTICE PrintFarmButton-3DH: printer-list scaling fix + Forgejo OTA 2026-07-07 13:54:00 -04:00
README.md v1.0.15: chronic HMS classes demoted to amber — X1Cs green while printing 2026-07-24 16:56:46 -04:00
server.mjs fix: log firmware fetches — the key-rotation gate was unverifiable by construction 2026-08-02 16:39:05 -04:00

PrintFarmButton-3DH

A fork of spuder/PrintFarmButton — an ESP32 button that talks to a Printago print farm — with one fix that makes the printer list scale to hundreds of printers.

The problem this fixes

The stock firmware fetches GET /v1/printers (the full printer objects, ~1290 bytes each) into an 8192-byte buffer. A store with roughly 6+ printers overflows it → the JSON is truncated → the picker shows "No printers found" and you can't select a printer at all.

The fix (two lines, in firmware/esphome/conf.d/cloud_printago.yaml)

  1. ?fields=id,name on the fetch URL — Printago returns only id + name (~50 bytes/printer instead of ~1290). 6 printers: 8218 B → ~304 B.
  2. buffer 819232768 — headroom for ~600 printers.

&limit=500 caps the request. Scales to hundreds of printers on the same hardware, no other changes.

Flash it

Open web/index.html in Chrome or Edge (Web Serial), plug the board in via USB, pick your board, click Connect & Flash. Then join the button's Wi-Fi setup and enter your Printago API Key + Store ID. Credentials are entered on the device — they never touch the flasher page.

Auto-update (OTA)

The firmware checks firmware/output/manifest-<board>.json on this repo hourly and, with "Auto Update" on (default), installs new builds. The source URL lives in firmware/esphome/conf.d/update.yamlif you fork this, change the owner/repo there so your buttons pull your builds, not someone else's.

Build a board

Needs ESPHome 2025.7.0 (the version spuder's custom template_select component compiles against — newer cores break it):

pip install "esphome==2025.7.0"
./build.sh atom-matrix          # or: esp32c3-supermini, esp32c3-zero, esp32s3-*

build.sh compiles and copies the .factory.bin + .ota.bin + refreshed manifest into firmware/output/.

LED states — the complete color language (v1.0.15)

One glance from across the shop tells you what every printer needs. States are listed in priority order — when several are true, the highest one wins.

State Light What it means Tap does
🟥 Error solid red · 85% Real HMS printer error — suppressed while Press me is pending (v1.0.14: Bambu HMS entries linger past print end and were masking the confirm pulse). Known-chronic HMS classes never reach this state (v1.0.15)
🟥 Paused / Aborted red fast pulse · 100% Mid-print pause or abort — the printer is waiting on you
🟪 Press me magenta pulse · 100% Print done — clear the bed, then tap to mark the printer ready Mark printer ready
🟦 Downloading / Starting blue↔white flowing pulse Job received through the whole pre-first-layer phase (download, bed level, purge, calibration)
🟩 Printing solid green · 85% First layer is down and running — green means printing, nothing else, no matter what nags exist
🟨 Warning solid amber · 85% Informational HMS warning or a known-chronic HMS error class (v1.0.15: the micro-lidar 0C00-0100 "clean the lens" nag that sits on the X1Cs for entire prints); shows only when the printer is idle
🟦 Ready solid blue · 85% Idle, confirmed ready, no nags — waiting for work
Fallback white · 90% Connected but no recognizable state

Design rules the scheme lives by:

  • Green = printing, uniquely. Downloading moved to the blue family in v1.0.11 so blue reads as getting ready → ready (pulse → solid).
  • Moving light = transient phase, solid light = stable state. Amber warning is the only orange-family light, and it is static.
  • Chronic HMS classes are amber, not red (v1.0.15). Some Bambu HMS codes are permanent nags, not failures — the micro-lidar 0C00-0100 class sat in health.errors for entire prints on all three X1Cs, keeping their buttons solid red mid-print. Those classes now feed the warning signal: printing stays green, and the nag waits until the printer is idle to show amber.
  • Magenta is sacred — it only ever means "a human needs to tap me." And it must never be masked by a stale signal: a finished print awaiting bed-clear shows magenta even if a lingering HMS error is still set (mid-print errors stay red; paused/abort keeps its flashing red).
  • Colors deliberately diverge from the jaeitee fork where its choices collided with the above (its purple finished vs our magenta press-me).

Layout

firmware/esphome/      ESPHome source (the fix is in conf.d/cloud_printago.yaml)
firmware/output/       built .bin + manifest per board (flash + OTA source)
firmware/output-stock/ spuder's original bins (reference; carry the bug)
web/index.html         browser flasher (ESP Web Tools)
build.sh               compile + stage a board's artifacts

Credit & license

Derived from spuder/PrintFarmButton and spuder/OpenSpool. See NOTICE. The upstream carries no license (all rights reserved) — this fork exists to run our own hardware and to offer the scaling fix back upstream. Please credit spuder and coordinate with the upstream before redistributing widely.