OverviewFilesCommitsIssuesDocsReleasesPeers

cthuloid commits / 7dcd5d0

esp324xlight: `state` readback + _cthuloid._tcp mDNS advert (proto 2)
`state` reports the live pin values, fade flag, freq and gamma, so a controller that did not send the last command (the web UI while Blender drives the rig) can show what the lights are actually doing. Units now advertise _cthuloid._tcp on 1337 with TXT proto=2 -- the only advert was telnet/23, a port nothing listens on. Verified on studiolight via OTA: state answers, avahi-browse on stortron resolves the service. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
7dcd5d052e8ad29bdf6b0ffb73d1b419227f50e4
by plankatron <fleeky@gmail.com> · 2026-10-02T13:48:09.000Z

Changed files (2) +44 -1

esp324xlight/README.md +15 -1
……@@ -57,7 +57,9 @@ The protocol uses a 0..65535 range per channel. **Higher value = brighter LED**
57572. **Boot fade self-test** — all 12 channels fade off → on → off over 10 seconds.
5858 Confirms the chip is alive and PWM is working; visible immediately on power-up.
59593. WiFi associates with the configured SSID (`prsm space`).
604. mDNS responder starts with hostname `HOSTNAME` (defined near the top of the sketch).
604. mDNS responder starts with the stored hostname (NVS; `HOSTNAME` is the
61 first-boot fallback) and advertises `_cthuloid._tcp` on port 1337 with TXT
62 `proto=<CTHULOID_PROTO>`, which is how controllers discover units.
61635. TCP command server listens on port **1337**.
62646. ArduinoOTA listener starts on port **3232** for over-the-air firmware updates.
6365
……@@ -171,6 +173,18 @@ animation source misbehaves.
171173
172174Response: `OK stopfade`.
173175
176#### `state`
177Report what the pins are actually doing, so a controller that did not send the
178last command (e.g. the web UI while Blender drives the rig) can show the truth.
179Always answered, regardless of `verbose`/`plevel`:
180
181```
182state <fadeActive 0|1> <freq> <gammaB> <gammaG> <gammaR> <v1> ... <v12>
183```
184
185`v1..v12` are the current values in protocol space (0–65535, BGR order), live
186during a `pwm2` fade. Added in command-surface version 2 (`CTHULOID_PROTO`).
187
174188#### `freq [hz]`
175189Get or set the PWM frequency. With no argument, prints the current frequency.
176190With one argument, sets it (range 1 to `maxfreq`, currently 40000).
esp324xlight/esp324xlight.ino +29 -0
……@@ -17,6 +17,11 @@
1717// fallback. Change at runtime with the "hostname <name>" command, then "reboot".
1818#define HOSTNAME "studiolight"
1919
20// Version of the TCP command surface, advertised in the _cthuloid._tcp mDNS TXT
21// record so a controller can tell what a unit understands before sending to it.
22// 2 = adds `state`.
23#define CTHULOID_PROTO "2"
24
2025// Password required to push OTA updates. Change before flashing if you don't
2126// want anyone on the WiFi network to be able to overwrite the firmware.
2227#define OTA_PASSWORD "studiolight-ota"
……@@ -174,6 +179,7 @@ void cmdGamma();
174179void cmdHostname();
175180void cmdReboot();
176181void cmdStopFade();
182void cmdState();
177183void updateFade();
178184
179185// --- non-blocking pwm2 fade state ---
……@@ -202,6 +208,7 @@ SerialCommand::Entry CommandsList[] = {
202208 {"hostname", cmdHostname},
203209 {"reboot", cmdReboot},
204210 {"stopfade", cmdStopFade},
211 {"state", cmdState},
205212 {NULL, NULL}
206213};
207214SerialCommand CmdMgr(CommandsList, cmdUnrecognized);
……@@ -418,6 +425,24 @@ void cmdStopFade() {
418425 diagPrintln("OK stopfade");
419426}
420427
428// "state" — report what the pins are ACTUALLY doing, so a controller that did
429// not send the last command (e.g. a web UI while Blender drives the rig) can show
430// the truth. One line, always sent (not gated by verbose/plevel):
431// state <fadeActive 0|1> <freq> <gammaB> <gammaG> <gammaR> <v1> ... <v12>
432// v1..v12 are PinCurrentValues in protocol space (0..65535, BGR order), live
433// during a pwm2 fade.
434void cmdState() {
435 char buf[200];
436 int n = snprintf(buf, sizeof(buf), "state %d %d %.2f %.2f %.2f",
437 pwm2Fade.active ? 1 : 0, freq,
438 channelGamma[0], channelGamma[1], channelGamma[2]);
439 for (int i = 0; i < NumPWMPins && n < (int)sizeof(buf); i++) {
440 n += snprintf(buf + n, sizeof(buf) - n, " %d", PinCurrentValues[i]);
441 }
442 Serial.println(buf);
443 if (ActiveClient && ActiveClient->connected()) ActiveClient->println(buf);
444}
445
421446// expects space-delimited ints 0-65535, or space delimited <index>:<pwm> pairs
422447void cmdPWMPins() {
423448 diagPrintln("GOT pwm");
……@@ -681,6 +706,10 @@ void loop() {
681706 Serial.print(currentHostname);
682707 Serial.println(".local");
683708 MDNS.addService("telnet", "tcp", 23);
709 // The real command server, under a name only these units use, so a
710 // controller can discover lights without guessing from telnet adverts.
711 MDNS.addService("cthuloid", "tcp", 1337);
712 MDNS.addServiceTxt("cthuloid", "tcp", "proto", CTHULOID_PROTO);
684713 } else {
685714 Serial.println("MDNS.begin failed — continuing without mDNS");
686715 }