From 80b3c3a0daba7e6521039ebd936526346fd4ac80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrick=20Ha=C3=9Fel?= Date: Fri, 7 Mar 2025 10:26:21 +0100 Subject: [PATCH] mqtt custom subscribe for Devices --- src/node/Greenhouse/sensors.cpp | 4 ++++ src/patrix/Output.h | 19 ++++++++++++++- src/patrix/mqtt.cpp | 41 ++++++++++++++++++--------------- src/patrix/mqtt.h | 2 ++ 4 files changed, 47 insertions(+), 19 deletions(-) diff --git a/src/node/Greenhouse/sensors.cpp b/src/node/Greenhouse/sensors.cpp index ba15bff..55caaea 100644 --- a/src/node/Greenhouse/sensors.cpp +++ b/src/node/Greenhouse/sensors.cpp @@ -33,4 +33,8 @@ void sensorsLoop() { greenhouseDHT22.loop(); } +void mqttReceive(const String& topic, const String& payload) { + light.cmd(topic, payload); +} + #endif diff --git a/src/patrix/Output.h b/src/patrix/Output.h index 6b6ff06..a270ee7 100644 --- a/src/patrix/Output.h +++ b/src/patrix/Output.h @@ -47,13 +47,30 @@ public: } void setState(const boolean newState) { - this->state = newState; + if (this->state != newState) { + this->state = newState; + Log.info("State changed: name=%s, state=%s", name.c_str(), this->state ? "true" : "false"); + } } [[nodiscard]] boolean getState() const { return state; } + void cmd(const String& topic, const String& payload) { + const String expected = String("/cmd/" + name + "/setState"); + if (!topic.equals(expected)) { + return; + } + if (payload.equals("true")) { + setState(true); + } else if (payload.equals("false")) { + setState(false); + } else { + Log.error("Invalid payload for command: topic=%s, payload=%s", topic.c_str(), payload.c_str()); + } + } + }; #endif diff --git a/src/patrix/mqtt.cpp b/src/patrix/mqtt.cpp index 2c5b032..ad99866 100644 --- a/src/patrix/mqtt.cpp +++ b/src/patrix/mqtt.cpp @@ -17,28 +17,33 @@ unsigned long mqttFailureMillis = 0; // ReSharper disable once CppUseAuto const String logTopic = String("log/") + HOSTNAME; -// ReSharper disable once CppUseAuto -const String cmdTopic = String("cmd/") + HOSTNAME; - void mqttCallback(char* topic, const uint8_t* payload, unsigned int length) { char message[500]; length = min(sizeof message - 1, length); memcpy(message, payload, length); *(message + length) = 0; - Log.info(R"(MQTT received: topic="%s", message="%s")", topic, message); - if (strcmp(message, "help") == 0) { - Log.info("HELP"); - Log.info(" %s", "help"); - Log.info(" %s", "info"); - Log.info(" %s", "restart"); - } else if (strcmp(message, "info") == 0) { - Log.info("INFO"); - Log.info(" %-10s %s", "SSID:", WiFi.SSID().c_str()); - Log.info(" %-10s %s", "IP:", WiFi.localIP().toString().c_str()); - Log.info(" %-10s %d", "RSSI:", WiFi.RSSI()); - Log.info(" %-10s %s", "uptime:", uptimeString().c_str()); - } else if (strcmp(message, "restart") == 0) { - systemRequestRestart(); + const String topicStr = String(topic); + const String messageStr = String(message); + Log.info(R"(MQTT received: topic="%s", message="%s")", topicStr.c_str(), messageStr.c_str()); + if (topicStr.equals(String("/cmd/") + HOSTNAME)) { + if (messageStr.equals("help")) { + Log.info("HELP"); + Log.info(" %s", "help"); + Log.info(" %s", "info"); + Log.info(" %s", "restart"); + } else if (messageStr.equals("info")) { + Log.info("INFO"); + Log.info(" %-10s %s", "SSID:", WiFi.SSID().c_str()); + Log.info(" %-10s %s", "IP:", WiFi.localIP().toString().c_str()); + Log.info(" %-10s %d", "RSSI:", WiFi.RSSI()); + Log.info(" %-10s %s", "uptime:", uptimeString().c_str()); + } else if (messageStr.equals("restart")) { + systemRequestRestart(); + } else { + Log.warn("Unknown node command: %s", messageStr.c_str()); + } + } else { + mqttReceive(topicStr, messageStr); } } @@ -49,7 +54,7 @@ void mqttLoop() { yield(); mqttPublish(logTopic, "connected\n"); mqtt.setCallback(mqttCallback); - mqtt.subscribe(cmdTopic.c_str()); + mqtt.subscribe("/cmd/#"); Log.info("MQTT connected as \"%s\".", HOSTNAME); mqttFailureMillis = 0; } else { diff --git a/src/patrix/mqtt.h b/src/patrix/mqtt.h index bebd288..9399591 100644 --- a/src/patrix/mqtt.h +++ b/src/patrix/mqtt.h @@ -50,6 +50,8 @@ void mqttPublishValue(const String& name, const String& value, const char* unit) void mqttPublish(const String& topic, const String& payload); +void mqttReceive(const String& topic, const String& payload); + class LogClass final : public Stream { PubSubClient& mqtt;