Fork of the espurna firmware for `mhsw` switches
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

165 lines
4.0 KiB

/*
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();
}
}
}
}