#pragma once #include "esphome.h" #include "esphome/components/web_server_base/web_server_base.h" #include "esphome/components/json/json_util.h" #include #include // Callback signature: void(device_id, cloud_alert, defrost_mode) using DisplayUpdateCallback = std::function; static DisplayUpdateCallback g_display_callback = nullptr; class DisplayApiHandler : public esphome::web_server_idf::AsyncWebHandler { public: bool canHandle(esphome::web_server_idf::AsyncWebServerRequest *request) const override { return request->url_to() == "/api/display"; } void handleRequest(esphome::web_server_idf::AsyncWebServerRequest *request) override { request->send(200, "application/json", "{\"status\":\"ok\"}"); } void handleBody(esphome::web_server_idf::AsyncWebServerRequest *request, uint8_t *data, size_t len, size_t index, size_t total) override { std::string body((char *)data, len); esphome::json::parse_json(body, [](JsonObject root) -> bool { std::string device_id = root["device_id"] | "unknown"; bool cloud_alert = root["cloud_alert"] | false; bool defrost_mode = root["defrost_mode"] | false; ESP_LOGI("custom_api", "Received update for %s (Alert: %d, Defrost: %d)", device_id.c_str(), cloud_alert, defrost_mode); // Execute the callback passed from YAML if (g_display_callback != nullptr) { g_display_callback(device_id, cloud_alert, defrost_mode); } return true; }); request->send(200, "application/json", "{\"status\":\"ok\"}"); } }; inline void setup_display_api(DisplayUpdateCallback callback) { g_display_callback = callback; if (esphome::web_server_base::global_web_server_base != nullptr) { esphome::web_server_base::global_web_server_base->add_handler(new DisplayApiHandler()); ESP_LOGI("custom_api", "Successfully registered /api/display POST handler"); } else { ESP_LOGE("custom_api", "Failed to register endpoint: global_web_server_base is null"); } }