#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("/power", powerGroup); 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}"; // TODO: Add here power sequence status // is_ramping_down // current step // percentage 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); 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() { uint8_t output = NONE; uint16_t channel = 0; bool success = false; for (uint8_t i = 0; i < restServer.args(); i++) { if (restServer.argName(i) == "output") { if (restServer.arg(i) == "on") { output = ON; } else if (restServer.arg(i) == "off") { output = OFF; } } else if (restServer.argName(i) == "ch") { channel = restServer.arg(i).toInt(); } } auto ipAddr = IPAddress(192, 168, 140, 79); if (output != NONE && channel != 0) { setChannelAndWait(&ipAddr, channel, output); success = true; // validates input parameters, not MPOD status, reported separately } 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"; http_msg += mpod.toJSON(); } http_msg += "\n}"; restServer.send(success ? 200 : 406, "text/json", http_msg); } void powerGroup() { String output; String group; String ret; bool success = false; for (uint8_t i = 0; i < restServer.args(); i++) { if (restServer.argName(i) == "output") { if (restServer.arg(i) == "on" || restServer.arg(i) == "off") { output = restServer.arg(i); } } else if (restServer.argName(i) == "group") { group = restServer.arg(i); } } if (output && group) { if (output == "on") { success = pproc.powerOn(group); } else if (output == "off") { success = pproc.powerOff(group); } } 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 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; if (!channel) { ret = "\"reason\": \"Invalid channel\""; } else { auto ipAddr = IPAddress(192, 168, 140, 79); SNMP::Message *snmp_msg = mpod.read(channel); snmp.send(snmp_msg, ipAddr, SNMP::Port::SNMP); delete snmp_msg; delay(MPOD_UPDATE_LATENCY); snmp.loop(); // Force loop to update now ret = mpod.toJSON(); } String http_msg = "{\n"; http_msg += ret; http_msg += ",\"success\": "; http_msg += channel ? 1 : 0; http_msg += ",\"channel\": "; // TODO: test with invalid channel (request w/o "ch" arg). JSON invalid. http_msg += channel; http_msg += "\n}"; restServer.send(channel ? 200 : 406, "text/json", http_msg); }