diff --git a/src/ha.h b/src/ha.h index 3559738..f4168b0 100644 --- a/src/ha.h +++ b/src/ha.h @@ -175,17 +175,27 @@ namespace Ha { char stateTopic[TOPIC_SIZE] = {}; const char* jsonAttributesTemplate = nullptr; const char* valueTemplate = nullptr; + char state[32] = ""; + inline static unordered_map mapStateIds; - State(Component* cmp) : cmp(cmp) {} + State(Component* cmp) : cmp(cmp) { + mapStateIds.insert({ string(cmp->id), this }); + } void withStateTopic() { snprintf(stateTopic, sizeof(stateTopic), BASE_TOPIC"/state", cmp->type, MAIN_DEVICE_ID, cmp->id); } void updateState(const char* message) { + strncpy(state, message, 32); if (stateTopic[0]) publisher(stateTopic, message); } + void toJson(JsonDocument& jsonDoc) { + cmp->toJson(jsonDoc); + jsonDoc["state"] = state; + } + protected: void buildConfig(JsonDocument& jsonDoc) override { if (stateTopic[0]) { diff --git a/src/webserver.h b/src/webserver.h index 01c3db7..5f3373f 100644 --- a/src/webserver.h +++ b/src/webserver.h @@ -10,7 +10,46 @@ AsyncWebServer server(80); namespace WebServer { + class ComandRequestHandler : public AsyncWebHandler { + const char* PREFIX_URL = "/command/"; + public: + + bool canHandle(AsyncWebServerRequest *request) { + if ((request->method() == HTTP_GET || request->method() == HTTP_PUT) + && request->url().startsWith(PREFIX_URL)) { + return true; + } + return false; + } + + void handleRequest(AsyncWebServerRequest *request) { + auto indexStart = request->url().indexOf("PREFIX_URL") + strlen("PREFIX_URL"); + auto id = request->url().substring(indexStart).c_str(); + if (request->method() == HTTP_GET) { + AsyncResponseStream *response = request->beginResponseStream("application/json"); + auto cmp = State::mapStateIds[id]; + if (cmp) { + StaticJsonDocument jsonDoc; + cmp->toJson(jsonDoc); + serializeJson(jsonDoc, *response); + request->send(response); + return; + } + } + if (request->method() == HTTP_PUT) { + auto cmd = Command::mapCommandIds[id]; + if (cmd) { + // cmd->onCommand(switchState->value().c_str()); + // request->send(200, "text/plain", switchState->value().c_str()); + // return; + } + } + request->send(404, "text/plain", id); + } + }; + void setup() { + server.addHandler(new ComandRequestHandler()); server.on("/commands", HTTP_POST, [](AsyncWebServerRequest *request) { if (request->hasParam("id", true) && request->hasParam("state", true)) { @@ -30,7 +69,7 @@ namespace WebServer { server.on("/commands", HTTP_GET, [](AsyncWebServerRequest *request) { AsyncResponseStream *response = request->beginResponseStream("application/json"); - + DynamicJsonDocument jsonResponse(JSON_SIZE*10); JsonArray array = jsonResponse.to(); for (auto it = Command::mapCommandIds.begin(); it != Command::mapCommandIds.end(); ++it) { @@ -39,7 +78,22 @@ namespace WebServer { array.add(jsonDoc); } serializeJson(jsonResponse, *response); - + + request->send(response); + }); + + server.on("/states", HTTP_GET, [](AsyncWebServerRequest *request) { + AsyncResponseStream *response = request->beginResponseStream("application/json"); + + DynamicJsonDocument jsonResponse(JSON_SIZE * 20); + JsonArray array = jsonResponse.to(); + for (auto it = State::mapStateIds.begin(); it != State::mapStateIds.end(); ++it) { + StaticJsonDocument jsonDoc; + it->second->toJson(jsonDoc); + array.add(jsonDoc); + } + serializeJson(jsonResponse, *response); + request->send(response); });