diff --git a/docs/integrate/home_assistant.md b/docs/integrate/home_assistant.md index 9cf317e..50457c4 100644 --- a/docs/integrate/home_assistant.md +++ b/docs/integrate/home_assistant.md @@ -168,6 +168,8 @@ sensor: ### MQTT Room Presence +The publication into presence topic needs to be activated [here is the command](../use/ble.md) + ```yaml sensor: - platform: mqtt_room diff --git a/docs/use/ble.md b/docs/use/ble.md index 69df7b1..4c9c860 100644 --- a/docs/use/ble.md +++ b/docs/use/ble.md @@ -133,6 +133,13 @@ If you want to change this characteristic: With Home Assistant, this command is directly avalaible through MQTT auto discovery as a switch into the HASS OpenMQTTGateway device entities list. ::: +## Setting if the gateway publish into Home Assistant Home presence topic + +If you want to publish to Home Assistant presence topic, you can activate this function by the HASS interface (this command is auto discovered), [here is a yaml example](../integrate/home_assistant.md#mqtt-room-presence). +Or by an MQTT command. + +`mosquitto_pub -t home/OpenMQTTGateway/commands/MQTTtoBT/config -m '{"hasspresence":true}'` + ## Setting the minimum RSSI accepted to publish device data If you want to change the minimum RSSI value accepted for a device to be published, you can change it by MQTT. For example if you want to set -80 diff --git a/main/ZgatewayBT.ino b/main/ZgatewayBT.ino index b76f499..cae1aee 100644 --- a/main/ZgatewayBT.ino +++ b/main/ZgatewayBT.ino @@ -98,8 +98,10 @@ void pubBTMainCore(JsonObject& data, bool haPresenceEnabled = true) { pub((char*)mactopic.c_str(), data); } if (haPresenceEnabled && data.containsKey("distance")) { - data.remove("servicedatauuid"); - data.remove("servicedata"); + if (data.containsKey("servicedatauuid")) + data.remove("servicedatauuid"); + if (data.containsKey("servicedata")) + data.remove("servicedata"); String topic = String(Base_Topic) + "home_presence/" + String(gateway_name); pub_custom_topic((char*)topic.c_str(), data, false); } @@ -168,6 +170,7 @@ void emptyBTQueue() { JsonBundle& bundle = jsonBTBufferQueue[next % BTQueueSize]; pubBTMainCore(*bundle.object, bundle.haPresence); atomic_store_explicit(&jsonBTBufferQueueNext, (next + 1) % (2 * BTQueueSize), ::memory_order_seq_cst); // use namespace std -> ambiguous error... + vTaskDelay(1); } } @@ -570,11 +573,9 @@ class MyAdvertisedDeviceCallbacks : public BLEAdvertisedDeviceCallbacks { BLEdata.set("rssi", (int)advertisedDevice->getRSSI()); if (advertisedDevice->haveTXPower()) BLEdata.set("txpower", (int8_t)advertisedDevice->getTXPower()); -# ifdef subjectHomePresence - if (advertisedDevice->haveRSSI() && !publishOnlySensors) { - haRoomPresence(BLEdata); // this device has an rssi and we don't want only sensors so in consequence we can use it for home assistant room presence component + if (advertisedDevice->haveRSSI() && !publishOnlySensors && hassPresence) { + hass_presence(BLEdata); // this device has an rssi and we don't want only sensors so in consequence we can use it for home assistant room presence component } -# endif if (advertisedDevice->haveServiceData()) { int serviceDataCount = advertisedDevice->getServiceDataCount(); Log.trace(F("Get services data number: %d" CR), serviceDataCount); @@ -966,10 +967,8 @@ bool BTtoMQTT() { return false; //if we have at least one white mac and this mac is not white we go out BLEdata.set("rssi", (int)rssi); -# ifdef subjectHomePresence - if (!publishOnlySensors) - haRoomPresence(BLEdata); // this device has an rssi and we don't want only sensors so in consequence we can use it for home assistant room presence component -# endif + if (!publishOnlySensors && hassPresence) + hass_presence(BLEdata); // this device has an rssi and we don't want only sensors so in consequence we can use it for home assistant room presence component Log.trace(F("Service data: %s" CR), restData.c_str()); BLEdata.set("servicedata", restData.c_str()); PublishDeviceData(BLEdata); @@ -1513,8 +1512,7 @@ JsonObject& process_inode_em(JsonObject& BLEdata) { return BLEdata; } -# ifdef subjectHomePresence -void haRoomPresence(JsonObject& HomePresence) { +void hass_presence(JsonObject& HomePresence) { int BLErssi = HomePresence["rssi"]; Log.trace(F("BLErssi %d" CR), BLErssi); int txPower = HomePresence["txpower"] | 0; @@ -1531,7 +1529,6 @@ void haRoomPresence(JsonObject& HomePresence) { HomePresence["distance"] = distance; Log.trace(F("Ble distance %D" CR), distance); } -# endif void BTforceScan() { if (!ProcessLock) { @@ -1604,6 +1601,9 @@ void MQTTtoBT(char* topicOri, JsonObject& BTdata) { // json object decoding bleConnect = (bool)BTdata["bleconnect"]; Log.notice(F("New value bleConnect: %T" CR), bleConnect); } + if (BTdata.containsKey("lowpowermode")) { + changelowpowermode((int)BTdata["lowpowermode"]); + } # endif // MinRSSI set if (BTdata.containsKey("minrssi")) { @@ -1613,11 +1613,14 @@ void MQTTtoBT(char* topicOri, JsonObject& BTdata) { // json object decoding minRssi = abs((int)BTdata["minrssi"]); Log.notice(F("New minrssi: %d" CR), minRssi); } -# ifdef ESP32 - if (BTdata.containsKey("lowpowermode")) { - changelowpowermode((int)BTdata["lowpowermode"]); + // Home Assistant presence message + if (BTdata.containsKey("hasspresence")) { + // storing Min RSSI for further use if needed + Log.trace(F("Previous hasspresence: %T" CR), hassPresence); + // set Min RSSI if present if not setting default value + hassPresence = (bool)BTdata["hasspresence"]; + Log.notice(F("New hasspresence: %T" CR), hassPresence); } -# endif } } #endif diff --git a/main/ZmqttDiscovery.ino b/main/ZmqttDiscovery.ino index 80478be..ce46503 100644 --- a/main/ZmqttDiscovery.ino +++ b/main/ZmqttDiscovery.ino @@ -700,6 +700,14 @@ void pubMqttDiscovery() { Gateway_AnnouncementMsg, will_Message, true, subjectMQTTtoBTset, //set,payload_avalaible,payload_not avalaible ,is a gateway entity, command topic "", "", "", "", true // device name, device manufacturer, device model, device mac, retain ); + createDiscovery("switch", //set Type + "", "BT: Publish HASS presence", (char*)getUniqueId("hasspresence", "").c_str(), //set state_topic,name,uniqueId + "", "", "", //set availability_topic,device_class,value_template, + "{\"hasspresence\":true}", "{\"hasspresence\":false}", "", //set,payload_on,payload_off,unit_of_meas, + 0, //set off_delay + Gateway_AnnouncementMsg, will_Message, true, subjectMQTTtoBTset, //set,payload_avalaible,payload_not avalaible ,is a gateway entity, command topic + "", "", "", "", true // device name, device manufacturer, device model, device mac, retain + ); # ifdef ESP32 createDiscovery("switch", //set Type "", "SYS: Low Power Mode command", (char*)getUniqueId("lowpowermode", "").c_str(), //set state_topic,name,uniqueId diff --git a/main/config_BT.h b/main/config_BT.h index 9a25bdf..aa2b98e 100644 --- a/main/config_BT.h +++ b/main/config_BT.h @@ -71,6 +71,9 @@ bool bleConnect = AttemptBLECOnnect; #ifndef PublishOnlySensors # define PublishOnlySensors false //false if we publish all BLE devices discovered or true only the identified sensors (like temperature sensors) #endif +#ifndef HassPresence +# define HassPresence false //false if we publish into Home Assistant presence topic +#endif #ifndef BTQueueSize # define BTQueueSize 4 // lockless queue size for multi core cases (ESP32 currently) @@ -92,6 +95,7 @@ unsigned int BLEinterval = TimeBtwRead; //time between 2 scans unsigned int BLEscanBeforeConnect = ScanBeforeConnect; //Number of BLE scans between connection cycles unsigned long scanCount = 0; bool publishOnlySensors = PublishOnlySensors; +bool hassPresence = HassPresence; #ifndef pubKnownBLEServiceData # define pubKnownBLEServiceData false // define true if you want to publish service data belonging to recognised sensors @@ -110,7 +114,6 @@ bool publishOnlySensors = PublishOnlySensors; #endif /*-------------------HOME ASSISTANT ROOM PRESENCE ----------------------*/ -// if not commented Home presence integration with HOME ASSISTANT is activated #define subjectHomePresence "home_presence/" // will send Home Assistant room presence message to this topic (first part is same for all rooms, second is room name) enum ble_sensor_model {