Helligkeit/src/patrix/mqtt.cpp

104 lines
3.1 KiB
C++

#include "mqtt.h"
#include "wifi.h"
#include <ESP8266WiFi.h>
#include "PubSubClient.h"
#include <WiFiClient.h>
WiFiClient client;
PubSubClient mqtt(client);
LogClass Log(mqtt);
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", "reboot");
} 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, "reboot") == 0) {
Log.info("rebooting...");
delay(500);
mqtt.disconnect();
delay(500);
EspClass::restart();
}
}
void mqttLoop() {
if (!mqtt.loop() && isWifiConnected() && (mqttFailureMillis == 0 || millis() - mqttFailureMillis >= 3000)) {
mqtt.setServer("10.0.0.50", 1883);
if (mqtt.connect(HOSTNAME, logTopic.c_str(), 0, false, "disconnected\n")) {
yield();
mqttPublish(logTopic, "connected\n");
mqtt.setCallback(mqttCallback);
mqtt.subscribe(cmdTopic.c_str());
Log.info("MQTT connected as \"%s\".", HOSTNAME);
mqttFailureMillis = 0;
} else {
Log.error("Failed to connect MQTT.");
mqttFailureMillis = max(1UL, millis());
}
}
}
void mqttPublishValue(const String& name, const int32_t value, const char *unit) {
mqttPublishValue(name, String(value), unit);
}
void mqttPublishValue(const String& name, const int64_t value, const char *unit) {
mqttPublishValue(name, String(value), unit);
}
void mqttPublishValue(const String& name, const uint32_t value, const char *unit) {
mqttPublishValue(name, String(value), unit);
}
void mqttPublishValue(const String& name, const uint64_t value, const char *unit) {
mqttPublishValue(name, String(value), unit);
}
void mqttPublishValue(const String& name, const float value, const char *unit) {
if (isnan(value)) {
return;
}
mqttPublishValue(name, String(value), unit);
}
void mqttPublishValue(const String& name, const double value, const char *unit) {
if (isnan(value)) {
return;
}
mqttPublishValue(name, String(value), unit);
}
void mqttPublishValue(const String& name, const String& value, const char *unit) {
char buffer[200];
snprintf(buffer, sizeof buffer, R"({"name": "%s", "timestamp": %lld, "value": %s, "unit": "%s"})", name.c_str(), time(nullptr), value.c_str(), unit);
mqttPublish(name + "/SimpleJson", buffer);
}
void mqttPublish(const String& topic, const String& payload) {
mqtt.publish(topic.c_str(), payload.c_str());
}