Files
spore/examples/relay/RelayService.cpp
2025-10-14 18:01:37 +02:00

89 lines
2.6 KiB
C++

#include "RelayService.h"
#include "spore/core/ApiServer.h"
#include "spore/util/Logging.h"
RelayService::RelayService(NodeContext& ctx, TaskManager& taskMgr, int pin)
: ctx(ctx), taskManager(taskMgr), relayPin(pin), relayOn(false) {
pinMode(relayPin, OUTPUT);
// Many relay modules are active LOW. Start in OFF state (relay de-energized).
digitalWrite(relayPin, HIGH);
}
void RelayService::registerEndpoints(ApiServer& api) {
api.registerEndpoint("/api/relay/status", HTTP_GET,
[this](AsyncWebServerRequest* request) { handleStatusRequest(request); },
std::vector<ParamSpec>{});
api.registerEndpoint("/api/relay", HTTP_POST,
[this](AsyncWebServerRequest* request) { handleControlRequest(request); },
std::vector<ParamSpec>{
ParamSpec{String("state"), true, String("body"), String("string"),
{String("on"), String("off"), String("toggle")}}
});
}
void RelayService::handleStatusRequest(AsyncWebServerRequest* request) {
JsonDocument doc;
doc["pin"] = relayPin;
doc["state"] = relayOn ? "on" : "off";
doc["uptime"] = millis();
String json;
serializeJson(doc, json);
request->send(200, "application/json", json);
}
void RelayService::handleControlRequest(AsyncWebServerRequest* request) {
String state = request->hasParam("state", true) ? request->getParam("state", true)->value() : "";
bool ok = false;
if (state.equalsIgnoreCase("on")) {
turnOn();
ok = true;
} else if (state.equalsIgnoreCase("off")) {
turnOff();
ok = true;
} else if (state.equalsIgnoreCase("toggle")) {
toggle();
ok = true;
}
JsonDocument resp;
resp["success"] = ok;
resp["state"] = relayOn ? "on" : "off";
if (!ok) {
resp["message"] = "Invalid state. Use: on, off, or toggle";
}
String json;
serializeJson(resp, json);
request->send(ok ? 200 : 400, "application/json", json);
}
void RelayService::turnOn() {
relayOn = true;
// Active LOW relay
digitalWrite(relayPin, LOW);
LOG_INFO("RelayService", "Relay ON");
}
void RelayService::turnOff() {
relayOn = false;
digitalWrite(relayPin, HIGH);
LOG_INFO("RelayService", "Relay OFF");
}
void RelayService::toggle() {
if (relayOn) {
turnOff();
} else {
turnOn();
}
}
void RelayService::registerTasks(TaskManager& taskManager) {
taskManager.registerTask("relay_status_print", 5000, [this]() {
LOG_INFO("RelayService", "Status - pin: " + String(relayPin) + ", state: " + (relayOn ? "ON" : "OFF"));
});
}