diff --git a/icbm.ino b/icbm.ino index cb83fd8509e4a18a140a06e539773f54c7535da9..102c5fcaae279455a3148a6cf73ad7ddecb569fa 100644 --- a/icbm.ino +++ b/icbm.ino @@ -7,6 +7,9 @@ unsigned long start; extern bool eth_connected; extern SNMP::Manager snmp; +TaskHandle_t restServerTask; +TaskHandle_t powerProcedureTask; + void setup() { Serial.begin(115200); @@ -20,8 +23,15 @@ void setup() { PINS.last_triggered = millis(); PINS.stage = ""; PINS.ramping = false; + PINS.canDoPowerFromREST = false; start = millis(); + + // Run the web interface on core 0 + xTaskCreatePinnedToCore(webInterfaceLoop, "Web Interface", 10000, NULL, 1, &restServerTask, 0); + // Run the power procedure and interrupt handling on core 1, the default core + xTaskCreatePinnedToCore(mainLoop, "PowerProcedure Task", 10000, NULL, 1, &powerProcedureTask, + 1); } enum { @@ -37,13 +47,51 @@ void serialLoop() { } } -void loop() { - isr_check_loop(); - snmp.loop(); - restServer.handleClient(); - toggle_status_led(); - serialLoop(); - if (eth_connected) { // We may be triggered, but disconnected from the network. - powerOffCheckLoop(); +void waitEnvOk() { + // Poll port expander on initialiation to wait until environment all ok + // If the ICBM is booted before the detector is up, as it should be, + // then the environment will always be incorrect, creating a power down + PINS.stage = "Waiting for environment to be okay first time"; + + uint32_t lastIteration = millis(); + while (true) { + serialLoop(); + if (millis() - lastIteration >= 200) { // ms, faster polling makes for erroneous readings. + poll_port_expander(); + if (PINS.sib && PINS.plc && PINS.ups) { + break; + } + lastIteration = millis(); + } + } + + PINS.stage = ""; + PINS.canDoPowerFromREST = true; +} + +void webInterfaceLoop(void* pvParameters) { + Serial.print("Web loop running on core "); + Serial.println(xPortGetCoreID()); + while (true) { + restServer.handleClient(); + } +} + +void mainLoop(void* pvParameters) { + Serial.print("Main loop running on core "); + Serial.println(xPortGetCoreID()); + + waitEnvOk(); + + while (true) { + isr_check_loop(); + snmp.loop(); + toggle_status_led(); + serialLoop(); + if (eth_connected) { // We may be triggered, but disconnected from the network. + powerOffCheckLoop(); + } } } + +void loop() {} diff --git a/mpod.cpp b/mpod.cpp index c119546e72a021eb50293a0d15bd8fada38c6519..08ec1a0a3bc82dce49052d3b80cca910dc9b7e2b 100644 --- a/mpod.cpp +++ b/mpod.cpp @@ -260,6 +260,12 @@ void setChannelStateAndWait(const IPAddress *ipAddr, const uint16_t channel, con delay(MPOD_UPDATE_LATENCY); snmp.loop(); + if (mpod.getChannel() != channel) { + // We have stale information, because MPOD swallowed UDP request. + // Skip this update check and go for next iteration, where data will be requested + // or request resent. + continue; + } loopCount += 1; ramping = (mpod.isRampingUp() || mpod.isRampingDown()); if (!ramping) { @@ -267,7 +273,7 @@ void setChannelStateAndWait(const IPAddress *ipAddr, const uint16_t channel, con settingChannelState = false; } else if (loopCount >= 5) { // There were no changes in 5 reads, it might be that the command (UDP) - // got swallowed by the MPOD controller while doing something else. + // got swallowed by the MPOD controller while it was doing something else. Serial.print("!Resend command to "); Serial.println(channel); SNMP::Message *snmp_msg = mpod.setChannelState(channel, output); diff --git a/pins.cpp b/pins.cpp index 03a94ccebd9cbf5ef6bff9fca4021c4694b8c2d9..f689b3b3ca86f482a49aeaae01f943ec1ac43bda 100644 --- a/pins.cpp +++ b/pins.cpp @@ -72,6 +72,7 @@ void isr_check_loop() { // If not all ok, set the power down flag, later handled. if (!(PINS.sib && PINS.plc && PINS.ups)) { PERFORM_PROCEDURE_FROM_INTERRUPT = 1; + PINS.canDoPowerFromREST = true; } } diff --git a/pins.hpp b/pins.hpp index e1efb053f3824ff5eeb9d3b30c7312e44c2caec9..70a5ff37690a2998755db03a39bd308342e9194f 100644 --- a/pins.hpp +++ b/pins.hpp @@ -26,6 +26,7 @@ struct pins { int last_triggered; String stage; bool ramping; + bool canDoPowerFromREST; }; extern struct pins PINS; diff --git a/rest.cpp b/rest.cpp index c6536cc54d3bd9401416f7f988e43894e2623180..3a73c7f3ecaa6a83c2bf1c8943357ca80da360d7 100644 --- a/rest.cpp +++ b/rest.cpp @@ -25,6 +25,8 @@ void initializeRoutes() { restServer.on("/", panel); restServer.on("/poll", pollMPODChannel); + restServer.on("/mpodstatus", getMpodStatus); + restServer.on("/power", powerGroup); restServer.on("/alloff", powerAllOff); @@ -82,9 +84,9 @@ void identify() { message += "\"ramping\":"; message += PINS.ramping; message += ",\n"; - message += "\"stage\":"; + message += "\"stage\": \""; message += PINS.stage; - message += ",\n"; + message += "\"\n"; message += "\n}"; message += "\n}"; @@ -131,6 +133,10 @@ enum { }; void sendSNMP() { + if (PINS.ramping) { + restServer.send(403, "text/json", "{\"success\": 0, \"reason\": \"ramping ongoing\"}"); + return; + } uint8_t output = NONE; uint16_t channel = 0; bool success = false; @@ -177,7 +183,20 @@ void sendSNMP() { restServer.send(success ? 200 : 406, "text/json", http_msg); } +void getMpodStatus() { + if (PINS.ramping) { + restServer.send(403, "text/json", "{\"success\": 0, \"reason\": \"ramping ongoing\"}"); + return; + } + + restServer.send(200, "text/json", pproc.toJSON()); +} + void powerGroup() { + if (PINS.ramping) { + restServer.send(403, "text/json", "{\"success\": 0, \"reason\": \"ramping ongoing\"}"); + return; + } String output; String group; String ret; @@ -202,11 +221,19 @@ void powerGroup() { } if (output && group) { + PINS.ramping = true; + PINS.stage = group; + if (output == "on") { + PINS.stage += " going up"; success = pproc.powerOn(group); } else if (output == "off") { + PINS.stage += " going down"; success = pproc.powerOff(group); } + + PINS.ramping = false; + PINS.stage = ""; } String http_msg = "{\n"; @@ -224,6 +251,10 @@ void powerGroup() { } void powerAllOff() { + if (PINS.ramping) { + restServer.send(403, "text/json", "{\"success\": 0, \"reason\": \"ramping ongoing\"}"); + return; + } String group; String groups; bool success = false; diff --git a/rest.hpp b/rest.hpp index aab65f0e39d167aff2b2ca94e6fbe5a51a8ea192..8206b58b32915c3f35f047651124d91e8b785fd2 100644 --- a/rest.hpp +++ b/rest.hpp @@ -13,3 +13,4 @@ void panel(); // / show a status page void pollMPODChannel(); // /poll?ch=1 void powerGroup(); // /power?group=ASICS&output=on void powerAllOff(); // /alloff?token=CWH +void getMpodStatus(); // /mpodstatus