pitrix/src/mqtt.cpp

180 lines
4.9 KiB
C++

#include "my_mqtt.h"
#include "config.h"
#ifndef MQTT_ENABLE
#pragma message "MQTT_ENABLE is false. Skipping MQTT."
#else
#include "my_wifi.h"
#include <PubSubClient.h>
#include "EffectEntry.h"
#include "Effect.h"
#include "effects.h"
#include "functions.h"
WiFiClient wifi;
PubSubClient mqtt_client(wifi);
long mqtt_last_reconnect_attempt = 0;
uint8_t weather_icon_ids[6] = {0, 0, 0, 0, 0, 0};
int8_t weather_temperatures[6] = {0, 0, 0, 0, 0, 0};
void mqtt_callback(char* original_topic, byte* pl, unsigned int length) {
pl[length] = '\0';
String payload((char*)pl);
String topic (original_topic);
if (topic.compareTo(MQTT_TOPIC "log")==0) return;
LOG("MQTT * Received data for topic "); LOG(topic); LOG(" with payload "); LOGln(payload);
if (topic.startsWith(MQTT_TOPIC_WEATHER)) {
// Weather stuff
topic.remove(0, strlen(MQTT_TOPIC_WEATHER));
LOG("MQTT * Weather stuff. Remaining topic: "); LOGln(topic.c_str());
if (topic.startsWith("icons/")) {
topic.remove(0, 6);
uint8_t id = topic.toInt();
if (id>=6) return;
uint8_t val = payload.toInt();
if (val==0) return;
weather_icon_ids[id] = val;
LOG("Set weather_icon_ids["); LOG(id); LOG("] to value "); LOGln(val);
} else if (topic.startsWith("temperatures/")) {
topic.remove(0, 13);
uint8_t id = topic.toInt();
if (id>=6) return;
uint8_t val = payload.toInt();
if (val==0) return;
weather_temperatures[id] = val;
LOG("Set weather_temperatures["); LOG(id); LOG("] to value "); LOGln(val);
}
return;
}
topic.remove(0, strlen(MQTT_TOPIC)); // Strip MQTT_TOPIC from the beginning
LOG("MQTT * Remaining topic is: "); LOGln(topic.c_str());
if (topic.compareTo("free_heap")==0 || topic.compareTo("uptime")==0 || topic.compareTo("status")==0 || topic.compareTo("fps")==0) {
// Ignore our own messages.
return;
}
if(topic.compareTo("mode")==0) {
LOGln("MQTT * Changing mode...");
for (int i=0; i<effects->size(); i++) {
EffectEntry e = effects->get(i);
if (payload.compareTo(e.name)==0) {
//Serial.printf("Effect found in mqtt_callback: %p\n", (void *)&e->effect);
current_effect->stop();
current_effect = e.effect;
current_effect->start();
return;
}
}
} else if (topic.compareTo("reboot")==0) {
LOGln("MQTT * Rebooting");
ESP.restart();
}
long value = payload.toInt();
LOG("MQTT * payload after converting to a number: "); LOGln(value);
if (topic.compareTo("brightness")==0) {
if (value > 0 && value <= 255) {
LOGln("MQTT * Changing brightness...");
FastLED.setBrightness(value);
} else {
LOG("MQTT * Ignoring brightness change: Value "); LOG(value); LOGln(" is out of bounds (0<x<=255).");
}
}
}
boolean mqtt_connect() {
char client_id[30];
int chipid;
#if defined( ESP8266 )
chipid = ESP.getChipId();
#elif defined( ESP32 )
chipid = ESP.getEfuseMac() & 0xFFFFFF;
#else
#error Neither ESP32 nor ESP8266 set.
#endif
snprintf(client_id, 30, HOSTNAME, chipid);
LOG("MQTT * Connecting to MQTT server with client id "); LOGln(client_id);
if (mqtt_client.connect(client_id, MQTT_USER, MQTT_PASS, MQTT_TOPIC "status", 0, true, "OFFLINE", true)) {
LOGln("MQTT * Connected.");
mqtt_client.publish(MQTT_TOPIC "status", "ONLINE");
mqtt_client.subscribe(MQTT_TOPIC "+");
mqtt_client.subscribe(MQTT_TOPIC_WEATHER "#");
}
return mqtt_client.connected();
}
void mqtt_setup() {
mqtt_client.setServer(MQTT_SERVER, MQTT_PORT);
mqtt_client.setCallback(mqtt_callback);
mqtt_last_reconnect_attempt = 0;
}
void mqtt_loop() {
if (!mqtt_client.connected()) {
long now = millis();
if (now - mqtt_last_reconnect_attempt > 5000) {
mqtt_last_reconnect_attempt = now;
if (mqtt_connect()) {
mqtt_last_reconnect_attempt = 0;
}
}
} else {
mqtt_client.loop();
}
}
String mqtt_log_str = String();
void mqtt_publish(const char* topic, int number) {
char t[127];
sprintf(t, MQTT_TOPIC "%s", topic);
char b[32];
sprintf(b, "%d", number);
mqtt_client.publish(t, b);
}
void mqtt_log(const char* message) {
mqtt_log_str.concat(message);
}
void mqtt_log(int number) {
mqtt_log(String(number).c_str());
}
void mqtt_log(long unsigned int number) { mqtt_log(String(number).c_str()); }
void mqtt_log(long int number) { mqtt_log(String(number).c_str()); }
void mqtt_log(String str) { mqtt_log(str.c_str()); }
void mqtt_log_ln(int number) {
mqtt_log_ln(String(number).c_str());
}
void mqtt_log_ln(long unsigned int number) { mqtt_log_ln(String(number).c_str()); }
void mqtt_log_ln(long int number) { mqtt_log_ln(String(number).c_str()); }
void mqtt_log_ln(String str) { mqtt_log_ln(str.c_str()); }
void mqtt_log_ln(const char* message) {
if (mqtt_log_str.length()==0) {
mqtt_log_send(message);
return;
} else {
mqtt_log_str.concat(message);
mqtt_log_send(mqtt_log_str.c_str());
mqtt_log_str = String();
}
}
void mqtt_log_send(const char* message) {
if (mqtt_client.connected()) {
mqtt_client.publish(MQTT_TOPIC "log", message);
}
}
#endif // MQTT_ENABLE