From 394a2b188569ad31a03511d905d084fb9a709ddf Mon Sep 17 00:00:00 2001 From: Krzysztof Malisiewicz Date: Sat, 5 Jun 2021 12:12:49 +0200 Subject: [PATCH] Add Home Assistant MQTT discovery. (#467) * Add Home Assistant MQTT discovery. * Add Home Assistant MQTT discovery. * Add Home Assistant MQTT discovery. * Add Home Assistant MQTT discovery - better performance. * Add Home Assistant MQTT discovery - better topic name. * Add Home Assistant MQTT discovery - add disable HA MQTT discovery. * Add Home Assistant MQTT discovery - lint format. Co-authored-by: Krzysztof Malisiewicz Co-authored-by: Samuel Lang --- pio/lib/Globals/Globals.h | 1 + pio/lib/Sender/Sender.cpp | 61 +++++++++++++++++++++++---- pio/lib/Sender/Sender.h | 6 +++ pio/lib/WiFiManagerKT/WiFiManagerKT.h | 38 +++++++++-------- pio/src/iSpindel.cpp | 43 ++++++++++++++++++- 5 files changed, 123 insertions(+), 26 deletions(-) diff --git a/pio/lib/Globals/Globals.h b/pio/lib/Globals/Globals.h index d0ee350c..a032a90f 100644 --- a/pio/lib/Globals/Globals.h +++ b/pio/lib/Globals/Globals.h @@ -32,6 +32,7 @@ extern Ticker flasher; #define API_THINGSPEAK true #define API_BLYNK true #define API_BREWBLOX true +#define API_MQTT_HASSIO true #define API_AWSIOTMQTT true //AWS //#define BLYNK_DEBUG diff --git a/pio/lib/Sender/Sender.cpp b/pio/lib/Sender/Sender.cpp index 7e66792f..4855e8fd 100644 --- a/pio/lib/Sender/Sender.cpp +++ b/pio/lib/Sender/Sender.cpp @@ -164,6 +164,51 @@ bool SenderClass::mqttConnect(const String &server, uint16_t port, const String return false; } +#ifdef API_MQTT_HASSIO +bool SenderClass::enableHassioDiscovery(String server, uint16_t port, String username, String password, String name, String unit) +{ + bool response = mqttConnect(server, port, name, username, password); + if (response) + { + _mqttClient.setBufferSize(512); + auto chipid = String(ESP.getChipId(), HEX); + String device = "\"dev\": { \"name\": \"" + name + "\",\"mdl\": \"ispindel\",\"sw\": \"" + FIRMWAREVERSION + "\",\"mf\": \"iSpindel\",\"ids\": [\"" + chipid + "\"]}"; + String topic = "homeassistant/sensor/iSpindel_" + chipid + "/"; + _mqttClient.publish((topic + "temperature/config").c_str(), ("{ \"uniq_id\": \"" + chipid + "_temp\", \"dev_cla\": \"temperature\", \"name\": \"Temperature\", \"unit_of_meas\": \"°" + unit + "\", \"val_tpl\": \"{{ value_json }}\", \"stat_t\": \"ispindel/" + name + "/temperature\"," + device + "}").c_str(), true); + _mqttClient.publish((topic + "tilt/config").c_str(), ("{ \"uniq_id\": \"" + chipid + "_tilt\", \"name\": \"Tilt\", \"val_tpl\": \"{{ value_json }}\", \"stat_t\": \"ispindel/" + name + "/tilt\"," + device + "}").c_str(), true); + _mqttClient.publish((topic + "battery/config").c_str(), ("{ \"uniq_id\": \"" + chipid + "_battery\", \"dev_cla\": \"voltage\", \"name\": \"Battery voltage\", \"unit_of_meas\": \"V\", \"val_tpl\": \"{{ value_json }}\", \"stat_t\": \"ispindel/" + name + "/battery\"," + device + "}").c_str(), true); + _mqttClient.publish((topic + "rssi/config").c_str(), ("{ \"uniq_id\": \"" + chipid + "_rssi\", \"dev_cla\": \"signal_strength\", \"name\": \"Signal Strength\", \"unit_of_meas\": \"dB\", \"val_tpl\": \"{{ value_json }}\", \"stat_t\": \"ispindel/" + name + "/RSSI\"," + device + "}").c_str(), true); + _mqttClient.publish((topic + "gravity/config").c_str(), ("{ \"uniq_id\": \"" + chipid + "_gravity\", \"name\": \"Gravity\", \"unit_of_meas\": \"°P\", \"val_tpl\": \"{{ value_json }}\", \"stat_t\": \"ispindel/" + name + "/gravity\"," + device + "}").c_str(), true); + _mqttClient.loop(); + } + + CONSOLELN(F("Closing MQTT connection")); + _mqttClient.disconnect(); + stopclient(); + return response; +} + +bool SenderClass::disableHassioDiscovery(String server, uint16_t port, String username, String password, String name) +{ + bool response = mqttConnect(server, port, name, username, password); + if (response) + { + auto chipid = String(ESP.getChipId(), HEX); + String topic = "homeassistant/sensor/iSpindel_" + chipid + "/"; + _mqttClient.publish((topic + "temperature/config").c_str(), ""); + _mqttClient.publish((topic + "tilt/config").c_str(), ""); + _mqttClient.publish((topic + "battery/config").c_str(), ""); + _mqttClient.publish((topic + "rssi/config").c_str(), ""); + _mqttClient.publish((topic + "gravity/config").c_str(), ""); + _mqttClient.loop(); + } + CONSOLELN(F("Closing MQTT connection")); + _mqttClient.disconnect(); + stopclient(); + return response; +} +#endif + bool SenderClass::sendMQTT(String server, uint16_t port, String username, String password, String name) { bool response = mqttConnect(server, port, name, username, password); @@ -248,20 +293,20 @@ String SenderClass::sendTCP(String server, uint16_t port) bool SenderClass::sendThingSpeak(String token, long Channel) { int field = 0; - unsigned long channelNumber = Channel; + unsigned long channelNumber = Channel; const char * writeAPIKey = token.c_str(); - + serializeJson(_doc, Serial); ThingSpeak.begin(_client); CONSOLELN(F("\nSender: ThingSpeak posting")); - + for (const auto &kv : _doc.as()) - { - field++; + { + field++; ThingSpeak.setField(field, kv.value().as()); } - // write to the ThingSpeak channel + // write to the ThingSpeak channel int x = ThingSpeak.writeFields(channelNumber, writeAPIKey); if(x == 200){ @@ -639,7 +684,7 @@ bool SenderClass::sendBlynk(char* token) i++; delay(50); } - + if (Blynk.connected()) { CONSOLELN(F("\nConnected to the Blynk server, sending data")); @@ -656,7 +701,7 @@ bool SenderClass::sendBlynk(char* token) CONSOLELN(F("\nFailed to connect to Blynk, going to sleep")); return false; } - + delay(150); //delay to allow last value to be sent; return true; } diff --git a/pio/lib/Sender/Sender.h b/pio/lib/Sender/Sender.h index a1d2380f..14d01f4e 100644 --- a/pio/lib/Sender/Sender.h +++ b/pio/lib/Sender/Sender.h @@ -8,6 +8,8 @@ #ifndef _SENDER_H_ #define _SENDER_H_ +#include "Globals.h" + #include #include #include @@ -30,6 +32,10 @@ class SenderClass bool sendTCONTROL(String server, uint16_t port); bool sendBlynk(char* token); bool sendBrewblox(String server, uint16_t port, String topic, String username, String password, String name); +#ifdef API_MQTT_HASSIO + bool enableHassioDiscovery(String server, uint16_t port, String username, String password, String name, String unit); + bool disableHassioDiscovery(String server, uint16_t port, String username, String password, String name); +#endif bool sendSecureMQTT(char CACert[], char deviceCert[], char deviceKey[], String server, uint16_t port, String name, String topic); //AWS void add(String id, float value); void add(String id, String value); diff --git a/pio/lib/WiFiManagerKT/WiFiManagerKT.h b/pio/lib/WiFiManagerKT/WiFiManagerKT.h index 6ddcf813..3735a4d5 100644 --- a/pio/lib/WiFiManagerKT/WiFiManagerKT.h +++ b/pio/lib/WiFiManagerKT/WiFiManagerKT.h @@ -36,27 +36,29 @@ const char HTTP_ISPINDEL_IMG[] PROGMEM = "{v}"; -const char HTTP_STYLE[] PROGMEM = ""; +const char HTTP_STYLE[] PROGMEM = ""; const char HTTP_SCRIPT[] PROGMEM = R"V0G0N(