/*
|
|
|
|
ESPurna
|
|
MQTT MODULE
|
|
|
|
Copyright (C) 2016 by Xose Pérez <xose dot perez at gmail dot com>
|
|
|
|
*/
|
|
|
|
#include <ESP8266WiFi.h>
|
|
#include <AsyncMqttClient.h>
|
|
|
|
AsyncMqttClient mqtt;
|
|
|
|
String mqttTopic;
|
|
bool isCallbackMessage = false;
|
|
|
|
// -----------------------------------------------------------------------------
|
|
// MQTT
|
|
// -----------------------------------------------------------------------------
|
|
|
|
bool mqttConnected() {
|
|
return mqtt.connected();
|
|
}
|
|
|
|
void mqttDisconnect() {
|
|
mqtt.disconnect();
|
|
}
|
|
|
|
void buildTopics() {
|
|
// Replace identifier
|
|
mqttTopic = getSetting("mqttTopic", MQTT_TOPIC);
|
|
mqttTopic.replace("{identifier}", getSetting("hostname"));
|
|
}
|
|
|
|
void mqttSend(char * topic, char * message) {
|
|
if (!mqtt.connected()) return;
|
|
if (isCallbackMessage) return;
|
|
String path = mqttTopic + String(topic);
|
|
DEBUG_MSG("[MQTT] Sending %s %s\n", (char *) path.c_str(), message);
|
|
mqtt.publish(path.c_str(), MQTT_QOS, MQTT_RETAIN, message);
|
|
}
|
|
|
|
void _mqttOnConnect(bool sessionPresent) {
|
|
|
|
DEBUG_MSG("[MQTT] Connected!\n");
|
|
|
|
// Send status via webSocket
|
|
wsSend((char *) "{\"mqttStatus\": true}");
|
|
|
|
// Build MQTT topics
|
|
buildTopics();
|
|
|
|
// Say hello and report our IP and VERSION
|
|
mqttSend((char *) MQTT_IP_TOPIC, (char *) getIP().c_str());
|
|
mqttSend((char *) MQTT_VERSION_TOPIC, (char *) APP_VERSION);
|
|
char buffer[10];
|
|
getFSVersion(buffer);
|
|
mqttSend((char *) MQTT_FSVERSION_TOPIC, buffer);
|
|
|
|
// Publish current relay status
|
|
mqttSend((char *) MQTT_STATUS_TOPIC, (char *) (relayStatus(0) ? "1" : "0"));
|
|
|
|
// Subscribe to topic
|
|
DEBUG_MSG("[MQTT] Subscribing to %s\n", (char *) mqttTopic.c_str());
|
|
mqtt.subscribe(mqttTopic.c_str(), MQTT_QOS);
|
|
|
|
}
|
|
|
|
void _mqttOnDisconnect(AsyncMqttClientDisconnectReason reason) {
|
|
|
|
// Send status via webSocket
|
|
wsSend((char *) "{\"mqttStatus\": false}");
|
|
|
|
}
|
|
|
|
void _mqttOnMessage(char* topic, char* payload, AsyncMqttClientMessageProperties properties, size_t len, size_t index, size_t total) {
|
|
|
|
static bool isFirstMessage = true;
|
|
|
|
payload[len] = '\0';
|
|
DEBUG_MSG("[MQTT] Received %s %s\n", topic, payload);
|
|
|
|
// If relayMode is not SAME avoid responding to a retained message
|
|
if (isFirstMessage) {
|
|
isFirstMessage = false;
|
|
byte relayMode = getSetting("relayMode", String(RELAY_MODE)).toInt();
|
|
if (relayMode != 2) return;
|
|
}
|
|
|
|
// Action to perform
|
|
if ((char)payload[0] == '0') {
|
|
isCallbackMessage = true;
|
|
relayStatus(0, false);
|
|
}
|
|
if ((char)payload[0] == '1') {
|
|
isCallbackMessage = true;
|
|
relayStatus(0, true);
|
|
}
|
|
if ((char)payload[0] == '2') {
|
|
relayToggle(0);
|
|
}
|
|
|
|
isCallbackMessage = false;
|
|
|
|
}
|
|
|
|
void mqttConnect() {
|
|
|
|
if (!mqtt.connected()) {
|
|
|
|
String host = getSetting("mqttServer", MQTT_SERVER);
|
|
String port = getSetting("mqttPort", String(MQTT_PORT));
|
|
String user = getSetting("mqttUser");
|
|
String pass = getSetting("mqttPassword");
|
|
|
|
if (host.length() == 0) return;
|
|
|
|
DEBUG_MSG("[MQTT] Connecting to broker at %s", (char *) host.c_str());
|
|
|
|
mqtt.setServer(host.c_str(), port.toInt());
|
|
mqtt
|
|
.setKeepAlive(MQTT_KEEPALIVE)
|
|
.setCleanSession(false)
|
|
//.setWill("topic/online", 2, true, "no")
|
|
.setClientId(getSetting("hostname", HOSTNAME).c_str());
|
|
|
|
if ((user != "") & (pass != "")) {
|
|
DEBUG_MSG(" as user %s.\n", (char *) user.c_str());
|
|
mqtt.setCredentials(user.c_str(), pass.c_str());
|
|
} else {
|
|
DEBUG_MSG(" anonymously\n");
|
|
}
|
|
|
|
mqtt.connect();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
void mqttSetup() {
|
|
mqtt.onConnect(_mqttOnConnect);
|
|
mqtt.onDisconnect(_mqttOnDisconnect);
|
|
mqtt.onMessage(_mqttOnMessage);
|
|
}
|
|
|
|
void mqttLoop() {
|
|
|
|
static unsigned long lastPeriod = 0;
|
|
|
|
if (WiFi.status() == WL_CONNECTED) {
|
|
|
|
if (!mqtt.connected()) {
|
|
|
|
unsigned long currPeriod = millis() / MQTT_RECONNECT_DELAY;
|
|
if (currPeriod != lastPeriod) {
|
|
lastPeriod = currPeriod;
|
|
mqttConnect();
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|