diff --git a/OpenMQTTGateway.ino b/OpenMQTTGateway.ino index 33019ae..9a370db 100644 --- a/OpenMQTTGateway.ino +++ b/OpenMQTTGateway.ino @@ -133,6 +133,9 @@ #ifdef ZsensorGPIOKeyCode #include "config_GPIOKeyCode.h" #endif +#ifdef ZmqttDiscovery + #include "config_mqttDiscovery.h" +#endif /*------------------------------------------------------------------------*/ @@ -193,7 +196,7 @@ void saveConfigCallback () { } boolean reconnect() { - + // Loop until we're reconnected while (!client.connected()) { trc(F("MQTT connection...")); //F function enable to decrease sram usage @@ -204,6 +207,11 @@ boolean reconnect() { pub(will_Topic,Gateway_AnnouncementMsg,will_Retain); // publish version pub(version_Topic,OMG_VERSION,will_Retain); + //home assistant discovery + #ifdef ZmqttDiscovery + pubMqttDiscovery(); + #endif + //Subscribing to topic if (client.subscribe(subjectMQTTtoX)) { #ifdef ZgatewayRF @@ -783,6 +791,9 @@ void stateMeasures(){ #ifdef ZsensorGPIOKeyCode modules = modules + ZsensorGPIOKeyCode; #endif + #ifdef ZmqttDiscovery + modules = modules + ZmqttDiscovery; + #endif SYSdata["modules"] = modules; trc(modules); char JSONmessageBuffer[100]; diff --git a/User_config.h b/User_config.h index 5c8a7d6..1850d93 100644 --- a/User_config.h +++ b/User_config.h @@ -95,6 +95,7 @@ char mqtt_port[6] = "1883"; //#define ZgatewayRFM69 "RFM69" //ESP8266, Arduino, ESP32 //#define ZsensorGPIOKeyCode "GPIOKeyCode" //ESP8266, Arduino, ESP32 //#define ZsensorGPIOInput "GPIOInput" //ESP8266, Arduino, ESP32 +#define ZmqttDiscovery "HADiscovery"//ESP8266, Arduino, EPS32, Sonoff RF Bridge /*-------------DEFINE YOUR ADVANCED NETWORK PARAMETERS BELOW----------------*/ //#define MDNS_SD //uncomment if you want to use mdns for discovering automatically your ip server, please note that MDNS with ESP32 can cause the BLE to not work @@ -116,13 +117,13 @@ const byte subnet[] = { 255, 255, 255, 0 }; //ip adress #define will_Topic Base_Topic Gateway_Name "/LWT" #define will_QoS 0 #define will_Retain true -#define will_Message "Offline" -#define Gateway_AnnouncementMsg "Online" +#define will_Message "offline" +#define Gateway_AnnouncementMsg "online" #define jsonPublishing true //comment if you don't want to use Json publishing (one topic for all the parameters) //example home/OpenMQTTGateway_ESP32_DEVKIT/BTtoMQTT/4XXXXXXXXXX4 {"rssi":-63,"servicedata":"fe0000000000000000000000000000000000000000"} -#define simplePublishing true //comment if you don't want to use simple publishing (one topic for one parameter) +//#define simplePublishing true //comment if you don't want to use simple publishing (one topic for one parameter) //example // home/OpenMQTTGateway_ESP32_DEVKIT/BTtoMQTT/4XXXXXXXXXX4/rssi -63.0 // home/OpenMQTTGateway_ESP32_DEVKIT/BTtoMQTT/4XXXXXXXXXX4/servicedata fe0000000000000000000000000000000000000000 @@ -162,7 +163,7 @@ const byte subnet[] = { 255, 255, 255, 0 }; //ip adress #define multiCore //comment to don't use multicore function of ESP32 for BLE #endif -#define JSON_MSG_BUFFER 256 // Json message max buffer size, don't put 1024 or higher it is causing unexpected behaviour on ESP8266 +#define JSON_MSG_BUFFER 512 // Json message max buffer size, don't put 1024 or higher it is causing unexpected behaviour on ESP8266 #define TimeBetweenReadingSYS 120000 // time between system readings (like memory) #define subjectSYStoMQTT Base_Topic Gateway_Name "/SYStoMQTT" diff --git a/ZmqttDiscovery.ino b/ZmqttDiscovery.ino new file mode 100644 index 0000000..cbd18b0 --- /dev/null +++ b/ZmqttDiscovery.ino @@ -0,0 +1,166 @@ +/* + OpenMQTTGateway Addon - ESP8266 or Arduino program for home automation + + Act as a wifi or ethernet gateway between your 433mhz/infrared IR signal and a MQTT broker + Send and receiving command by MQTT + + This is the Home Assistant mqtt Discovery addon. + + Copyright: (c) Rafal Herok + + This file is part of OpenMQTTGateway. + + OpenMQTTGateway is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenMQTTGateway is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifdef ZmqttDiscovery + +void pubMqttDiscovery() +{ +#ifdef omgStatus + trc(F("omgStatusDiscovery")); + createDiscovery("binary_sensor", //set sensorType + will_Topic, DEVICENAME, getUniqueId("omg", "status"), //set state_topic,name,uniqueId + "", "connectivity", "", //set availability_topic,device_class,value_template, + Gateway_AnnouncementMsg, will_Message, "", //set,payload_on,payload_off,unit_of_meas, + true, false, 0); //set optimistic,retain, off_delay +#endif +#ifdef discBme280 + trc(F("bme280Discovery")); + createDiscovery("sensor", + BME, "tempc", getUniqueId("bme", "tempc"), + will_Topic, "temperature", "{{ value_json.tempc }}", + "", "", "°C", + true, false, 0); + createDiscovery("sensor", + BME, "tempf", getUniqueId("bme", "tempf"), + will_Topic, "temperature", "{{ value_json.tempf }}", + "", "", "°F", + true, false, 0); + createDiscovery("sensor", + BME, "pa", getUniqueId("bme", "pa"), + will_Topic, "pressure", "{{ float(value_json.pa) * 0.01 }}", + "", "", "hPa", + true, false, 0); + createDiscovery("sensor", + BME, "hum", getUniqueId("bme", "hum"), + will_Topic, "humidity", "{{ value_json.hum }}", + "", "", "%", + true, false, 0); + createDiscovery("sensor", + BME, "altim", getUniqueId("bme", "altim"), + will_Topic, "", "{{ value_json.altim }}", + "", "", "m", + true, false, 0); + createDiscovery("sensor", + BME, "altift", getUniqueId("bme", "altift"), + will_Topic, "", "{{ value_json.altift }}", + "", "", "ft", + true, false, 0); +#endif +} + +void createDiscovery(String sensor_type, + String state_topic, String name, String unique_id, + String availability_topic, String device_class, String value_template, + String payload_on, String payload_off, String unit_of_meas, + bool optimistic, bool retain, int off_delay) +{ + StaticJsonBuffer jsonBuffer3; + JsonObject &sensor = jsonBuffer3.createObject(); + sensor.set("stat_t", state_topic); //state_topic + sensor.set("name", name); //name + sensor.set("uniq_id", unique_id); //unique_id + if (availability_topic != "") + { + sensor.set("avty_t", availability_topic); //availability_topic + } + if (device_class != "") + { + sensor.set("dev_cla", device_class); //device_class + } + if (value_template != "") + { + sensor.set("val_tpl", value_template); //value_template + } + if (payload_on != "") + { + sensor.set("pl_on", payload_on); // payload_on + } + if (payload_off != "") + { + sensor.set("pl_off", payload_off); //payload_off + } + if (unit_of_meas != "") + { + sensor.set("unit_of_meas", unit_of_meas); //unit_of_measurement + } + if (optimistic != true) + { + sensor.set("opt", optimistic); //optimistic + } + if (retain != false) + { + sensor.set("ret", retain); //retain + } + if (off_delay > 0) + { + sensor.set("off_delay", off_delay); //off_delay + } + + char JSONmessageBuffer[JSON_MSG_BUFFER]; + StaticJsonBuffer jsonDeviceBuffer; + JsonObject &device = jsonDeviceBuffer.createObject(); + device.set("name", DEVICENAME); + device.set("manufacturer", DEVICEMANUFACTURER); + device.set("sw_version", OMG_VERSION); + JsonArray &identifiers = device.createNestedArray("identifiers"); + identifiers.add(getMacAddress()); + + sensor.set("device", device); //device sensor is connected to + + String topic = (String)discovery_Topic + "/" + sensor_type + "/" + unique_id + "/config"; + pubDiscovery(topic, sensor); +} + +void pubDiscovery(String topicori, JsonObject &data) +{ + char JSONmessageBuffer[JSON_MSG_BUFFER]; + trc(F("Pub json into:")); + trc(topicori); + data.printTo(JSONmessageBuffer, sizeof(JSONmessageBuffer)); + trc(JSONmessageBuffer); + client.publish((char *)topicori.c_str(), JSONmessageBuffer, true); +} + +String getMacAddress() +{ + uint8_t baseMac[6]; +#ifdef ESP8266 + WiFi.macAddress(baseMac); +#else + esp_read_mac(baseMac, ESP_MAC_WIFI_STA); +#endif + char baseMacChr[13] = {0}; + sprintf(baseMacChr, "%02X%02X%02X%02X%02X%02X", baseMac[0], baseMac[1], baseMac[2], baseMac[3], baseMac[4], baseMac[5]); + return String(baseMacChr); +} + +String getUniqueId(String name, String sufix) +{ + String uniqueId = (String)getMacAddress() + name + sufix; + return String(uniqueId); +} + +#endif diff --git a/config_mqttDiscovery.h b/config_mqttDiscovery.h new file mode 100644 index 0000000..7d257a2 --- /dev/null +++ b/config_mqttDiscovery.h @@ -0,0 +1,32 @@ +/* + OpenMQTTGateway - ESP8266 or Arduino program for home automation + + Act as a wifi or ethernet gateway between your 433mhz/infrared IR signal and a MQTT broker + Send and receiving command by MQTT + + This files enables to set your parameter for the Home assistant mqtt Discovery + + Copyright: (c) Rafal Herok + + This file is part of OpenMQTTGateway. + + OpenMQTTGateway is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenMQTTGateway is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +*/ +#define discovery_Topic "homeassistant" +#define omgStatus //uncomment to create OMG status sensor +#define discBme280 //uncomment to enable bme280 sensors + +#define DEVICENAME "OpenMQTTGateway " Gateway_Name +#define DEVICEMANUFACTURER "AnimaVitis" diff --git a/tests/Test_config.h b/tests/Test_config.h index 9850bf1..76d513c 100644 --- a/tests/Test_config.h +++ b/tests/Test_config.h @@ -129,6 +129,7 @@ const byte subnet[] = { 255, 255, 255, 0 }; //ip adress #define ZgatewayRFM69 "RFM69"// If you uncomment this you can't use RF and BT due to the fact that RF use also D8 and BT use also D6/D7 #define ZsensorGPIOInput "GPIOInput" #define ZsensorGPIOKeyCode "GPIOKeyCode" + #define ZmqttDiscovery "HADiscovery"//ESP8266, Arduino, EPS32, Sonoff RF Bridge #define jsonPublishing true #define simplePublishing true #elif ESP32 @@ -149,6 +150,7 @@ const byte subnet[] = { 255, 255, 255, 0 }; //ip adress #define ZgatewayRFM69 "RFM69" #define ZsensorGPIOInput "GPIOInput" #define ZsensorGPIOKeyCode "GPIOKeyCode" + #define ZmqttDiscovery "HADiscovery"//ESP8266, Arduino, EPS32, Sonoff RF Bridge #define jsonPublishing true #define simplePublishing true #elif defined(__AVR_ATmega1280__) @@ -171,6 +173,7 @@ const byte subnet[] = { 255, 255, 255, 0 }; //ip adress #define ZgatewayRFM69 "RFM69"// If you uncomment this you can't use RF and BT due to the fact that RF use also D8 and BT use also D6/D7 #define ZsensorGPIOInput "GPIOInput" #define ZsensorGPIOKeyCode "GPIOKeyCode" + #define ZmqttDiscovery "HADiscovery"//ESP8266, Arduino, EPS32, Sonoff RF Bridge #define jsonPublishing true #define simplePublishing true #else // for arduino Uno