| … | … | @@ -17,6 +17,11 @@ |
| 17 | 17 | // fallback. Change at runtime with the "hostname <name>" command, then "reboot". |
| 18 | 18 | #define HOSTNAME "studiolight" |
| 19 | 19 | |
| 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 | |
| 20 | 25 | // Password required to push OTA updates. Change before flashing if you don't |
| 21 | 26 | // want anyone on the WiFi network to be able to overwrite the firmware. |
| 22 | 27 | #define OTA_PASSWORD "studiolight-ota" |
| … | … | @@ -174,6 +179,7 @@ void cmdGamma(); |
| 174 | 179 | void cmdHostname(); |
| 175 | 180 | void cmdReboot(); |
| 176 | 181 | void cmdStopFade(); |
| 182 | void cmdState(); |
| 177 | 183 | void updateFade(); |
| 178 | 184 | |
| 179 | 185 | // --- non-blocking pwm2 fade state --- |
| … | … | @@ -202,6 +208,7 @@ SerialCommand::Entry CommandsList[] = { |
| 202 | 208 | {"hostname", cmdHostname}, |
| 203 | 209 | {"reboot", cmdReboot}, |
| 204 | 210 | {"stopfade", cmdStopFade}, |
| 211 | {"state", cmdState}, |
| 205 | 212 | {NULL, NULL} |
| 206 | 213 | }; |
| 207 | 214 | SerialCommand CmdMgr(CommandsList, cmdUnrecognized); |
| … | … | @@ -418,6 +425,24 @@ void cmdStopFade() { |
| 418 | 425 | diagPrintln("OK stopfade"); |
| 419 | 426 | } |
| 420 | 427 | |
| 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. |
| 434 | void 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 | |
| 421 | 446 | // expects space-delimited ints 0-65535, or space delimited <index>:<pwm> pairs |
| 422 | 447 | void cmdPWMPins() { |
| 423 | 448 | diagPrintln("GOT pwm"); |
| … | … | @@ -681,6 +706,10 @@ void loop() { |
| 681 | 706 | Serial.print(currentHostname); |
| 682 | 707 | Serial.println(".local"); |
| 683 | 708 | 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); |
| 684 | 713 | } else { |
| 685 | 714 | Serial.println("MDNS.begin failed — continuing without mDNS"); |
| 686 | 715 | } |