WLED/wled00/wled17_mqtt.ino

135 lines
3.2 KiB
Arduino
Raw Normal View History

/*
* MQTT communication protocol for home automation
*/
void parseMQTTBriPayload(char* payload)
{
if (strcmp(payload, "ON") == 0) {bri = briLast; colorUpdated(1);}
else if (strcmp(payload, "T" ) == 0) {handleSet("win&T=2");}
else {
uint8_t in = strtoul(payload, NULL, 10);
if (in == 0 && bri > 0) briLast = bri;
bri = in;
colorUpdated(1);
}
}
void callbackMQTT(char* topic, byte* payload, unsigned int length) {
DEBUG_PRINT("MQTT callb rec: ");
DEBUG_PRINTLN(topic);
DEBUG_PRINTLN((char*)payload);
//no need to check the topic because we only get topics we are subscribed to
if (strstr(topic, "/col"))
{
colorFromDecOrHexString(col, &white, (char*)payload);
colorUpdated(1);
} else if (strstr(topic, "/api"))
{
String apireq = "win&";
handleSet(apireq += (char*)payload));
} else
{
parseMQTTBriPayload((char*)payload);
}
}
void publishMQTT()
{
if (!mqtt.connected()) return;
DEBUG_PRINTLN("Publish MQTT");
char s[10];
char subuf[38];
sprintf(s, "%ld", bri);
strcpy(subuf, mqttDeviceTopic);
strcat(subuf, "/g");
mqtt.publish(subuf, s);
sprintf(s, "#%X", white*16777216 + col[0]*65536 + col[1]*256 + col[2]);
strcpy(subuf, mqttDeviceTopic);
strcat(subuf, "/c");
mqtt.publish(subuf, s);
//if you want to use this, increase the MQTT buffer in PubSubClient.h to 350+
//it will publish the API response to MQTT
/*XML_response(false);
strcpy(subuf, mqttDeviceTopic);
strcat(subuf, "/v");
mqtt.publish(subuf, obuf);*/
}
bool reconnectMQTT()
{
if (mqtt.connect(escapedMac.c_str()))
{
//re-subscribe to required topics
char subuf[38];
strcpy(subuf, mqttDeviceTopic);
if (mqttDeviceTopic[0] != 0)
{
strcpy(subuf, mqttDeviceTopic);
mqtt.subscribe(subuf);
strcat(subuf, "/col");
mqtt.subscribe(subuf);
strcpy(subuf, mqttDeviceTopic);
strcat(subuf, "/api");
mqtt.subscribe(subuf);
}
if (mqttGroupTopic[0] != 0)
{
strcpy(subuf, mqttGroupTopic);
mqtt.subscribe(subuf);
strcat(subuf, "/col");
mqtt.subscribe(subuf);
strcpy(subuf, mqttGroupTopic);
strcat(subuf, "/api");
mqtt.subscribe(subuf);
}
}
return mqtt.connected();
}
bool initMQTT()
{
if (WiFi.status() != WL_CONNECTED) return false;
if (mqttServer[0] == 0) return false;
IPAddress mqttIP;
if (mqttIP.fromString(mqttServer)) //see if server is IP or domain
{
mqtt.setServer(mqttIP,1883);
} else {
mqtt.setServer(mqttServer,1883);
}
mqtt.setCallback(callbackMQTT);
DEBUG_PRINTLN("MQTT ready.");
return true;
}
void handleMQTT()
{
if (WiFi.status() != WL_CONNECTED || !mqttInit) return;
//every time connection is unsuccessful, the attempt interval is increased, since attempt will block program for 7 sec each time
if (!mqtt.connected() && millis() - lastMQTTReconnectAttempt > 5000 + (5000 * mqttFailedConAttempts * mqttFailedConAttempts))
{
DEBUG_PRINTLN("Attempting to connect MQTT...");
lastMQTTReconnectAttempt = millis();
if (!reconnectMQTT())
{
//still attempt reconnect about once daily
if (mqttFailedConAttempts < 120) mqttFailedConAttempts++;
return;
}
DEBUG_PRINTLN("MQTT con!");
mqttFailedConAttempts = 0;
}
mqtt.loop();
}