-
-
Save kmdm/c01c0693b1380d826af200a3e9b2a656 to your computer and use it in GitHub Desktop.
# MQTT broker configuration | |
mqtt: | |
broker: !secret mqtt_broker | |
username: !secret mqtt_username | |
password: !secret mqtt_password | |
discovery: False # Only if you use the HA API usually | |
id: mqtt_client | |
# Define the room for this ESP32 node | |
substitutions: | |
room_name: bedroom | |
# Push the room name into a global | |
globals: | |
- id: room_topic | |
type: std::string | |
initial_value: '"room_presence/${room_name}"' | |
# Configure the esp32_ble_tracker to push beacon advertisements to MQTT | |
esp32_ble_tracker: | |
on_ble_advertise: | |
- then: | |
- lambda: |- | |
if (x.get_ibeacon().has_value()) { | |
std::string uuid; | |
esp_bt_uuid_t raw_uuid = x.get_ibeacon().value().get_uuid().get_uuid(); | |
char sbuf[64]; | |
char *bpos = sbuf; | |
switch (raw_uuid.len) { | |
case ESP_UUID_LEN_128: | |
for (int8_t i = 0; i <= 15; i++) { | |
sprintf(bpos, "%02x", raw_uuid.uuid.uuid128[i]); | |
bpos += 2; | |
if (i == 6 || i == 8 || i == 10 || i == 12) | |
sprintf(bpos++, "-"); | |
} | |
sbuf[47] = '\0'; | |
uuid.assign(sbuf); | |
break; | |
default: | |
uuid = x.get_ibeacon().value().get_uuid().to_string(); | |
std::transform(uuid.begin(), uuid.end(), uuid.begin(), [](unsigned char c){ return std::tolower(c); }); | |
break; | |
} | |
char mbuf[32] = {0}; | |
sprintf(mbuf, "-%hu-%hu", x.get_ibeacon().value().get_major(), x.get_ibeacon().value().get_minor()); | |
uuid.append(mbuf); | |
int8_t tx_power = x.get_ibeacon().value().get_signal_power(); | |
if (tx_power >= 100) { | |
tx_power = -69; | |
} | |
float dist = pow(10, (float)(tx_power - x.get_rssi()) / (10 * 2)); | |
if (dist < 50) { | |
ESP_LOGD("ble_adv", "Sending MQTT room update for '%s' (%s): %.03fm (%d rssi, %d sigpow)", | |
x.get_name().c_str(), uuid.c_str(), dist, x.get_rssi(), tx_power); | |
id(mqtt_client).publish_json(id(room_topic), [=](JsonObject root) { | |
root["id"] = uuid; | |
root["name"] = x.get_name(); | |
root["distance"] = dist; | |
root["rssi"] = x.get_rssi(); | |
root["tx_power"] = tx_power; | |
}); | |
} else { | |
ESP_LOGD("ble_adv", "Skipping MQTT room update for '%s' (%s): %.03fm (%d rssi, %d sigpow)", | |
x.get_name().c_str(), uuid.c_str(), dist, x.get_rssi(), tx_power); | |
} | |
} |
# Configure the sensors in Home Assistant as normal: | |
sensor: | |
- platform: mqtt_room | |
name: Test beacon 1 | |
device_id: aabbccdd-eeff-1122-3344-5566778899aa-0001-0002 | |
state_topic: room_presence |
@greghesp I've updated the gist to include a better calculation for distance using the signal power reported by the BLE beacon. I've added a dist filter but just hardcoded it at 50.
(In the HA companion app you can set what this value is)
The check for a tx_power of 100 is for some weird beacons I have which appear to set the transmit power to 100 so it's just badly fixed back to the default I was using before, it could be unnecessary for you but you can monitor the rssi/tx_power values on the esp32 logs and also the MQTT broker since I've added those values there as well (although any dist >= 50 won't be on MQTT obviously).
@kmdm What is the dist value measured in? Im assuming its not meters?
Thank you so much for sharing it.
modify the max_distance and remove almost all false positives. Is there any other parameter that you recommend me to change?
Thanks again
@kmdm Would it be possible to specify only certain UUIDs?
@mihsu81 you can do this on the HA side. It'll just ignore the rest that's sent
Whoops! Bit sleepy still. I'm also not sure if
5
is a correct float.As for the distance. I've not got presence sensors in every room, so I may go into 1 room and it reports to HA that I'm in room X when I'm not even in a room with a sensor. This way, HA would just report that I'm home, rather than in a room im not
The bottom of this post gives a good example:
https://www.reddit.com/r/homeassistant/comments/ma02pv/how_to_fine_tune_room_assistant_ble/?utm_medium=android_app&utm_source=share