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.
 
 
 
 
 
 

155 lines
3.8 KiB

/*
ESPurna
MQTT MODULE
Copyright (C) 2016 by Xose Pérez <xose dot perez at gmail dot com>
*/
#include <PubSubClient.h>
#include <ESP8266WiFi.h>
WiFiClient client;
PubSubClient mqtt(client);
boolean mqttStatus = false;
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(), message, MQTT_RETAIN);
}
void mqttCallback(char* topic, byte* payload, unsigned int length) {
char buffer[length+1];
memcpy(buffer, payload, length);
buffer[length] = 0;
DEBUG_MSG("[MQTT] Received %s %s\n", topic, buffer);
// Action to perform
if ((char)payload[0] == '0') {
isCallbackMessage = true;
switchRelayOff();
}
if ((char)payload[0] == '1') {
isCallbackMessage = true;
switchRelayOn();
}
if ((char)payload[0] == '2') {
toggleRelay();
}
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());
if ((user != "") & (pass != "")) {
DEBUG_MSG(" as user %s: ", (char *) user.c_str());
mqtt.connect(getSetting("hostname", HOSTNAME).c_str(), user.c_str(), pass.c_str());
} else {
DEBUG_MSG(" anonymously: ");
mqtt.connect(getSetting("hostname", HOSTNAME).c_str());
}
if (mqtt.connected()) {
DEBUG_MSG("connected!\n");
buildTopics();
mqttStatus = true;
// Send status via webSocket
webSocketSend((char *) "{\"mqttStatus\": true}");
// 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 *) (digitalRead(RELAY_PIN) ? "1" : "0"));
// Subscribe to topic
DEBUG_MSG("[MQTT] Subscribing to %s\n", (char *) mqttTopic.c_str());
mqtt.subscribe(mqttTopic.c_str());
} else {
DEBUG_MSG("failed (rc=%d)\n", mqtt.state());
}
}
}
void mqttSetup() {
mqtt.setCallback(mqttCallback);
}
void mqttLoop() {
static unsigned long lastPeriod = 0;
if (WiFi.status() == WL_CONNECTED) {
if (!mqtt.connected()) {
if (mqttStatus) {
webSocketSend((char *) "{\"mqttStatus\": false}");
mqttStatus = false;
}
unsigned long currPeriod = millis() / MQTT_RECONNECT_DELAY;
if (currPeriod != lastPeriod) {
lastPeriod = currPeriod;
mqttConnect();
}
}
if (mqtt.connected()) mqtt.loop();
}
}