/* * MQTT communication protocol for home automation */ #define WLED_MQTT_PORT 1883 void parseMQTTBriPayload(char* payload) { if (strcmp(payload, "ON") == 0 || strcmp(payload, "on") == 0) {bri = briLast; colorUpdated(1);} else if (strcmp(payload, "T" ) == 0 || strcmp(payload, "t" ) == 0) {toggleOnOff(); colorUpdated(1);} else { uint8_t in = strtoul(payload, NULL, 10); if (in == 0 && bri > 0) briLast = bri; bri = in; colorUpdated(1); } } void onMqttConnect(bool sessionPresent) { //(re)subscribe to required topics char subuf[38]; strcpy(subuf, mqttDeviceTopic); if (mqttDeviceTopic[0] != 0) { strcpy(subuf, mqttDeviceTopic); mqtt->subscribe(subuf, 0); strcat(subuf, "/col"); mqtt->subscribe(subuf, 0); strcpy(subuf, mqttDeviceTopic); strcat(subuf, "/api"); mqtt->subscribe(subuf, 0); } if (mqttGroupTopic[0] != 0) { strcpy(subuf, mqttGroupTopic); mqtt->subscribe(subuf, 0); strcat(subuf, "/col"); mqtt->subscribe(subuf, 0); strcpy(subuf, mqttGroupTopic); strcat(subuf, "/api"); mqtt->subscribe(subuf, 0); } publishMqtt(); } void onMqttMessage(char* topic, char* payload, AsyncMqttClientMessageProperties properties, size_t len, size_t index, size_t total) { DEBUG_PRINT("MQTT callb rec: "); DEBUG_PRINTLN(topic); DEBUG_PRINTLN(payload); //no need to check the topic because we only get topics we are subscribed to if (strstr(topic, "/col")) { colorFromDecOrHexString(col, (char*)payload); colorUpdated(1); } else if (strstr(topic, "/api")) { String apireq = "win&"; apireq += (char*)payload; handleSet(nullptr, apireq); } else parseMQTTBriPayload(payload); } void publishMqtt() { if (mqtt == NULL) return; 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, 0, true, s); sprintf(s, "#%X", col[3]*16777216 + col[0]*65536 + col[1]*256 + col[2]); strcpy(subuf, mqttDeviceTopic); strcat(subuf, "/c"); mqtt->publish(subuf, 0, true, s); strcpy(subuf, mqttDeviceTopic); strcat(subuf, "/v"); mqtt->publish(subuf, 0, true, XML_response(nullptr, false)); } 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, WLED_MQTT_PORT); } else { mqtt->setServer(mqttServer, WLED_MQTT_PORT); } mqtt->setClientId(escapedMac.c_str()); mqtt->onMessage(onMqttMessage); mqtt->onConnect(onMqttConnect); mqtt->connect(); DEBUG_PRINTLN("MQTT ready."); return true; }