diff --git a/powerproc.cpp b/powerproc.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b43eb80f6383228dc457954e13c6d3f73ddd0895 --- /dev/null +++ b/powerproc.cpp @@ -0,0 +1,85 @@ +#include "powerproc.hpp" + +#include "mpod.hpp" + +PowerProcedure::PowerProcedure(const IPAddress& ipAddr) + : ipAddr(ipAddr), currentStage(""), currentChannel(-1) { + stages[0].name = "ASICS"; + stages[0].size = 4; + stages[0].channels = new int[stages[0].size]{1, 2, 3, 8}; + + stages[1].name = "HV"; + stages[1].size = 4; + stages[1].channels = new int[stages[1].size]{4, 5, 6, 7}; +} + +PowerProcedure::~PowerProcedure() { + size_t stagesCount = sizeof(stages) / sizeof(stages[0]); + for (size_t stageIdx = 0; stageIdx < stagesCount; stageIdx++) { + delete[] stages[stageIdx].channels; + } +} + +String PowerProcedure::toJSON() { + String json = "{\n"; + json += "\"target\":\"" + ipAddr.toString() + "\",\n"; + json += "\"groups\": [\n"; + + Stage* currentStage = stages; + Stage* lastStage = stages + sizeof(stages) / sizeof(stages[0]); + for (currentStage; currentStage < lastStage; currentStage++) { + json += "{\"name\":\"" + currentStage->name + "\","; + json += "\"channels\":[\n"; + + for (size_t ch = 0; ch < currentStage->size; ch++) { + SNMP::Message* snmp_msg = mpod.read(currentStage->channels[ch]); + snmp.send(snmp_msg, ipAddr, SNMP::Port::SNMP); + delete snmp_msg; + + delay(MPOD_UPDATE_LATENCY); + snmp.loop(); // Force loop to update now + + json += mpod.toJSON(); + json += ",\n"; + } + json.remove(json.length() - 2, 1); // Remove trailing comma of last entry + + json += "]\n"; + json += "},\n"; + } + json.remove(json.length() - 2, 1); // Remove trailing comma of last entry + + json += "]\n"; // groups body + json += "}"; // json body + return json; +} + +bool PowerProcedure::powerOn(const String& stage) { + Stage* currentStage = stages; + Stage* lastStage = stages + sizeof(stages) / sizeof(stages[0]); + for (currentStage; currentStage < lastStage; currentStage++) { + if (currentStage->name == stage) { + for (size_t chIdx = 0; chIdx < currentStage->size; chIdx++) { + setChannelAndWait(&ipAddr, currentStage->channels[chIdx], 1); // 1 == ON + } + return true; + } + } + return false; // Invalid group name +} + +bool PowerProcedure::powerOff(const String& stage) { + Stage* currentStage = stages; + Stage* lastStage = stages + sizeof(stages) / sizeof(stages[0]); + for (currentStage; currentStage < lastStage; currentStage++) { + if (currentStage->name == stage) { + for (int chIdx = currentStage->size - 1; chIdx >= 0; chIdx--) { + setChannelAndWait(&ipAddr, currentStage->channels[chIdx], 0); // 0 == OFF + } + return true; + } + } + return false; // Invalid group name +} + +PowerProcedure pproc(IPAddress(192, 168, 140, 79)); diff --git a/powerproc.hpp b/powerproc.hpp new file mode 100644 index 0000000000000000000000000000000000000000..37f2b666d2b0ededf37e35d22fbda34199b11fa0 --- /dev/null +++ b/powerproc.hpp @@ -0,0 +1,26 @@ +#pragma once +#include <Arduino.h> + +class PowerProcedure { +private: + String currentStage; // Stores the current stage name + int currentChannel; // Stores the current channel + struct Stage { + String name; // Name of the stage (e.g., "ASICS") + int* channels; // Pointer to dynamically allocated channel array + size_t size; // Number of channels in the stage + }; + Stage stages[2]; // Array to hold stages + +public: + const IPAddress ipAddr; // Stores the IP address + + PowerProcedure(const IPAddress& ipAddr); + ~PowerProcedure(); + + bool powerOn(const String& stage); + bool powerOff(const String& stage); + String toJSON(); +}; + +extern PowerProcedure pproc; diff --git a/rest.cpp b/rest.cpp index 83d385d005e17b226646eda8257e6bc7af1ea0ee..384d135f7ac908947e9e35afc940093886f8cf0e 100644 --- a/rest.cpp +++ b/rest.cpp @@ -5,6 +5,7 @@ #include "mpod.hpp" #include "panel.hpp" #include "pins.hpp" +#include "powerproc.hpp" #ifndef ICBM_GIT_VERSION #define ICBM_GIT_VERSION "DEVEL" @@ -24,6 +25,8 @@ void initializeRoutes() { restServer.on("/", panel); restServer.on("/poll", pollMPODChannel); + restServer.on("/power", powerGroup); + restServer.begin(); Serial.println("REST Server Started"); } @@ -162,6 +165,45 @@ void sendSNMP() { restServer.send(200, "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 += "\"target\":\"" + pproc.ipAddr.toString() + "\",\n"; + http_msg += "\"arguments\":{"; + http_msg += "\"group\":\"" + group + "\","; + http_msg += "\"output\":\"" + output + "\"},\n"; + http_msg += "\"success\":" + String(success) + ",\n"; + if (success) { + http_msg += "\"status\":\n"; + http_msg += pproc.toJSON(); + } + http_msg += "\n}"; + + restServer.send(200, "text/json", http_msg); +} + void pollMPODChannel() { uint16_t channel = 0; for (uint8_t i = 0; i < restServer.args(); i++) { diff --git a/rest.hpp b/rest.hpp index c62ab9b2a020b977bdb240cf42bc752f2c25f541..a665337da3bb9f1c25a5068a0fc1faa44aa1ae2c 100644 --- a/rest.hpp +++ b/rest.hpp @@ -11,3 +11,4 @@ void restart(); // /restart void sendSNMP(); // /send?ch=107&output=on void panel(); // / show a status page void pollMPODChannel(); // /poll?ch=1 +void powerGroup(); // /power?group=ASICS&output=on