114 lines
3.3 KiB
C++
114 lines
3.3 KiB
C++
#include <PubSubClient.h>
|
|
#include <Arduino.h>
|
|
#include <ESP8266WiFi.h>
|
|
#include <ArduinoJson.h>
|
|
|
|
class MQTTHelper {
|
|
private:
|
|
String _group = "homedevice";
|
|
String _identifier = "garagesensor";
|
|
const char* _user = "homedevice";
|
|
const char* _password = "WNzAb4VazNFUPlpkn0ED";
|
|
|
|
WiFiClient _espClient;
|
|
PubSubClient _mqttClient;
|
|
String _will_topic;
|
|
|
|
void reconnect(int delayMillis = 5000);
|
|
bool connect();
|
|
void announce();
|
|
void callback(char* topic, byte* payload, unsigned int length);
|
|
public:
|
|
MQTTHelper() : _espClient(), _mqttClient(_espClient) {
|
|
auto deviceMac = WiFi.macAddress();
|
|
deviceMac.replace(":","");
|
|
_identifier = "etxean-"+deviceMac.substring(6);
|
|
_will_topic = getTopic("online");
|
|
_mqttClient.setCallback([this] (char* topic, byte* payload, unsigned int length) { this->callback(topic, payload, length); });
|
|
}
|
|
|
|
String getIdentifier() { return _identifier; }
|
|
|
|
String getTopic(String node) {
|
|
return _group + "/" + _identifier + "/" + node;
|
|
}
|
|
|
|
void Configure(IPAddress server, uint16 port) {
|
|
Serial.println("Configuring MQTT connection to: "+server.toString()+":"+String(port));
|
|
_mqttClient.setServer(server, port);
|
|
if (_mqttClient.connected()) {
|
|
connect();
|
|
}
|
|
}
|
|
|
|
void loop() {
|
|
static unsigned long lastWill;
|
|
if (!_mqttClient.connected()) {
|
|
reconnect();
|
|
}
|
|
_mqttClient.loop();
|
|
|
|
auto now = millis();
|
|
if ((now - lastWill) > 1000)
|
|
{
|
|
lastWill = now;
|
|
_mqttClient.publish(_will_topic.c_str(), "true");
|
|
}
|
|
}
|
|
|
|
template<class T>
|
|
void publish(String sensor, T payload, bool retained = false) {
|
|
_mqttClient.publish(getTopic(sensor).c_str(), String(payload).c_str(), retained);
|
|
}
|
|
};
|
|
|
|
void MQTTHelper::callback(char* topic, byte* payload, unsigned int length) {
|
|
Serial.print("Message arrived:");
|
|
Serial.print(topic);
|
|
Serial.print(" = ");
|
|
for (unsigned int i=0; i<length; i++) {
|
|
Serial.print((char)payload[i]);
|
|
}
|
|
Serial.println();
|
|
}
|
|
|
|
void MQTTHelper::reconnect(int delayMillis) {
|
|
// Loop until we're reconnected
|
|
while (!_mqttClient.connected()) {
|
|
Serial.print("Attempting MQTT connection...");
|
|
if (connect()) {
|
|
Serial.println("connected");
|
|
} else {
|
|
auto reconnectSeconds = (int)round(delayMillis/1000.0);
|
|
Serial.print("failed, rc=");
|
|
Serial.print(_mqttClient.state());
|
|
Serial.println(" try again in "+String(reconnectSeconds)+" seconds");
|
|
// Wait 5 seconds before retrying
|
|
delay(delayMillis);
|
|
}
|
|
}
|
|
}
|
|
|
|
void MQTTHelper::announce() {
|
|
DynamicJsonDocument doc(1024);
|
|
doc["id"] = _identifier;
|
|
doc["ip"] = WiFi.localIP().toString();
|
|
doc["mac"] = WiFi.macAddress();
|
|
String payload;
|
|
serializeJson(doc,payload);
|
|
publish("settings",payload);
|
|
}
|
|
|
|
bool MQTTHelper::connect() {
|
|
// If you do not want to use a username and password, change next line to
|
|
// if (_mqttClient.connect(_identifier.c_str()) {
|
|
if (_mqttClient.connect(_identifier.c_str(), _user, _password, _will_topic.c_str(), 2, false, "false")) {
|
|
_mqttClient.subscribe((getTopic("settings")+"/get").c_str());
|
|
announce();
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|