#include "rest.hpp" #include <ETH.h> #include "mpod.hpp" #include "panel.hpp" #include "pins.hpp" #include "powerproc.hpp" #ifndef ICBM_GIT_VERSION #define ICBM_GIT_VERSION "DEVEL" #endif #ifndef ICBM_GIT_TIMESTAMP #define ICBM_GIT_TIMESTAMP "UNKNOWN" #endif WebServer restServer(80); void initializeRoutes() { restServer.on("/idn", identify); restServer.on("/restart", restart); restServer.onNotFound(notFound); restServer.on("/send", sendSNMP); restServer.on("/", panel); restServer.on("/poll", pollMPODChannel); restServer.on("/mpodstatus", getMpodStatus); restServer.on("/power", powerGroup); restServer.on("/alloff", powerAllOff); restServer.begin(); Serial.println("REST Server Started"); } void identify() { int seconds = millis() / 1000; int hours = seconds / 3600; int minutes = (seconds / 60) % 60; seconds = seconds % 60; String message = "{\n"; message += "\"mac\":\""; message += ETH.macAddress(); message += "\",\n"; message += "\"version\":\""; message += ICBM_GIT_VERSION; message += "\",\n"; message += "\"build date\":\""; message += ICBM_GIT_TIMESTAMP; message += "\",\n"; message += "\"uptime\": \""; message += hours; message += ":"; message += minutes; message += ":"; message += seconds; message += "\",\n"; message += "\"inputs\":{\n"; message += "\"sib\":"; message += PINS.sib; message += ",\n"; message += "\"plc\":"; message += PINS.plc; message += ",\n"; message += "\"ups\":"; message += PINS.ups; message += ",\n"; unsigned long elapsed_seconds = (millis() - PINS.last_triggered) / 1000; message += "\"sec_since_interrupt\":"; message += elapsed_seconds; message += "\n},"; message += "\"status\":{\n"; message += "\"ramping\":"; message += PINS.ramping; message += ",\n"; message += "\"stage\": \""; message += PINS.stage; message += "\"\n"; message += "\n}"; message += "\n}"; restServer.send(418, "text/json", message); } void panel() { unsigned long elapsed_seconds = (millis() - PINS.last_triggered) / 1000; String content = buildPanel(PINS.sib, PINS.plc, PINS.ups, elapsed_seconds, PINS.stage, PINS.ramping); restServer.send(200, "text/html", content); } void notFound() { String message = "{\n"; message += "\"uri\":\""; message += restServer.uri(); message += "\",\n\"method\":\""; message += (restServer.method() == HTTP_GET) ? "GET" : "POST"; message += "\",\n\"arguments\":{"; for (uint8_t i = 0; i < restServer.args(); i++) { message += "\n\"" + restServer.argName(i) + "\":\"" + restServer.arg(i) + "\","; } if (restServer.args() != 0) { message.remove(message.length() - 1); // remove trailing comma for valid json } message += "\n}\n}"; restServer.send(404, "text/json", message); Serial.println(message); } void restart() { restServer.send(200); ESP.restart(); } enum { OFF = 0, ON = 1, NONE = -1, }; 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; String argName; String argVal; for (uint8_t i = 0; i < restServer.args(); i++) { argName = restServer.argName(i); argName.toLowerCase(); argVal = restServer.arg(i); if (argName == "output") { argVal.toLowerCase(); if (argVal == "on") { output = ON; } else if (argVal == "off") { output = OFF; } } else if (argName == "ch") { channel = argVal.toInt(); } } auto ipAddr = pproc.ipAddr; if (output != NONE && channel != 0) { setChannelStateAndWait(&ipAddr, channel, output); success = mpod.getChannel() ? true : false; } String http_msg = "{\n"; http_msg += "\"target\":\"" + ipAddr.toString() + "\",\n"; http_msg += "\"arguments\":{"; http_msg += "\"channel\":" + String(channel) + ","; http_msg += "\"output\":" + String(output) + "},\n"; http_msg += "\"success\":" + String(success); if (success) { http_msg += ",\n\"status\":"; http_msg += mpod.toJSON(); } http_msg += "\n}"; 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; bool success = false; String argName; String argVal; for (uint8_t i = 0; i < restServer.args(); i++) { argName = restServer.argName(i); argName.toLowerCase(); argVal = restServer.arg(i); argVal.toLowerCase(); if (argName == "output") { if (argVal == "on" || argVal == "off") { output = argVal; } } else if (argName == "group") { argVal.toUpperCase(); // Uppercase to match Karabo definitions group = argVal; } } 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"; http_msg += "\"arguments\":{"; http_msg += "\"group\":\"" + group + "\","; http_msg += "\"output\":\"" + output + "\"},\n"; http_msg += "\"success\":" + String(success); if (success) { http_msg += ",\n\"status\":\n"; http_msg += pproc.toJSON(); } http_msg += "\n}"; restServer.send(success ? 200 : 406, "text/json", http_msg); } void powerAllOff() { if (PINS.ramping) { restServer.send(403, "text/json", "{\"success\": 0, \"reason\": \"ramping ongoing\"}"); return; } String group; String groups; bool success = false; for (uint8_t i = 0; i < restServer.args(); i++) { // Check for token to prevent accidental power down if (restServer.argName(i) == "token" && restServer.arg(i) == "CWH") { success = true; } } if (success) { PINS.ramping = true; for (int8_t groupIdx = pproc.stagesCount - 1; groupIdx >= 0; groupIdx--) { group = pproc.stages[groupIdx].name; groups += group; groups += ","; PINS.stage = group; success = pproc.powerOff(group); if (!success) { break; } } PINS.ramping = false; } String http_msg = "{\n"; http_msg += "\"groups\":\"" + groups + "\","; http_msg += "\"success\":" + String(success); // if (success) { // http_msg += ",\n\"status\":\n"; // http_msg += pproc.toJSON(); // } http_msg += "\n}"; restServer.send(success ? 200 : 406, "text/json", http_msg); } void pollMPODChannel() { uint16_t channel = 0; for (uint8_t i = 0; i < restServer.args(); i++) { if (restServer.argName(i) == "ch") { channel = restServer.arg(i).toInt(); } } String ret = "\"Invalid channel\""; if (channel) { SNMP::Message *snmp_msg = mpod.read(channel); snmp.send(snmp_msg, pproc.ipAddr, SNMP::Port::SNMP); delete snmp_msg; delay(MPOD_UPDATE_LATENCY); snmp.loop(); // Force loop to update now if (mpod.getChannel()) { // Valid channel requested ret = mpod.toJSON(); } } String http_msg = "{\n"; http_msg += "\"success\": "; http_msg += channel ? 1 : 0; http_msg += ",\n"; http_msg += "\"arguments\": {"; http_msg += "\"channel\": "; http_msg += channel; http_msg += "},\n"; // arguments http_msg += "\"status\": "; http_msg += ret; http_msg += "}"; restServer.send(channel ? 200 : 406, "text/json", http_msg); }