ESPHome component for ESPresense-like room tracking

Also, the home assistant app can do background iBeacons, at least on Android. probably iPhones too. Nevermind, it seems Apple has some limitations that prevent that, which is why room assistant is doing it that way.

Do you possibly have an example yaml of adding a 2nd device? I did another addtracker line but it doesn’t seem to be working. So far it works great with just the one device! Thanks!!!

was a typo in ibeacon uuid. Working great now! Thanks again!!!

1 Like

Hi,

I created a feature request outlining a way to solve this problem, if you’re like to look at Apple Devices Presence using ESPHome BLE Proxy (ESPresense alternative)

Thanks

Dan

2 Likes

Thanks for this project! I managed to successfully flash it on an olimex board and had it debug all BLE UUIDs as a test.

There are however a lot of them :slight_smile: Do you know an easy way to find the UUD for an iOS device (iPhone)?

unfortunately this little bit of code doesn’t support iOS. iOS has some security limitations that prevents identifying iBeacons by UUID. ESPresense has a workaround, but I didn’t port them because I don’t have any apple devices to test with. I’m open to a PR if you can hack it in though.

For MAC tracking and HA companion app tracking I made integration + ESPHome component. It does use MQTT, but not with discovery - for convenience, all beacons are created in integration, and have device_tracker, as well as current room sensor with raw data for all RSSI in arguments, and some settings for calibration.

GitHub - formatBCE/ESP32_BLE_presense: ESP32 firmware for Home Assistant Format BLE Tracker integration https://github.com/formatBCE/Format-BLE-Tracker. - ESPHome part
GitHub - formatBCE/Format-BLE-Tracker: BLE tracker integration, which works with ESP32 firmware https://github.com/formatBCE/ESP32_BLE_presense - HA integration

P.S.

  1. It doesn’t use ESPHome BLE stack, since that’s too laggy.
  2. Kalman filtering is used in integration to reduce RSSI noise.
  3. Usually changing room takes around 10-15 seconds. There’s room for improvement still.
1 Like

I notice this hasn’t been updated since last year. IN the example ESPhome YAML ‘add this section 2’ I take it we DONT add the custom_component section at the bottom given what is stated in the readme?

Looks good, but does it work in conjunction with the bt_proxy in active mode?
Thanks.

I doubt it’ll work with BT proxy. Scanning takes whole available radio time - it’s it’s main purpose.
All non-bluetooth tasks are working fine though (like GPIO sensors, UART etc.)

You want to add custom_component - it’s main config section.
Did readme confuse you?

P.S. it wasn’t updated because it works flawlessly for me.
However, I made some changes locally recently to HA integration, and testing them now. If it works better, will publish shortly.

Yes a little bit simply because of “Custom firmware (deprecated, use ESPHome instead)” sounds like we should not include that last section of ESPhome YAML:

custom_component:
- lambda: |-
    auto my_node = new BleNodeComponent("room_name"); # TODO replace rooom_name with your room name
    return {my_node};

…but I guess it’s that I was confusing “custom firmware” with “custom component”.

1 Like

Very nice project, added this to a few esp32 running esphome used as rgb fairy lights i have in a few rooms. I added my Android phone and my galaxy watch 4 and both were picked up just fine.

But my wife is using apple devices, do you plan to add apple presense detection? As i understand, this is quite tricky because of the way apple handles the uuid/MAC.

Thanks, I’m glad it works for you!

Regarding Apple - it’s harder to do because I don’t have any :slight_smile:

If you’re ready to test, I’d try to add support. :wink:

Sure, testing would be no problem. :+1:
We have an Iphone and an apple watch at home.

I am surprised that this is not used more often. For me this is very interesting because all of my Esp32 i already have and flashed with esphome can be used with your integration without much effort.

That’s exactly why I wanted to develop it: I put it basically on every ESP32 I have, which isn’t using Bluetooth yet, and it works in parallel with main functionality. Also I wanted it to be proper device_tracker to use with Person integration (almost everyone else is just using binary_sensor), idk if that makes sense to anybody except myself tho.

BTW, did you try with HA companion app on iPhone? It should have that UUID for tracking purposes, I guess?

1 Like

I just had a look at the iPhone App and there is no uuid mentioned or toggable. As far as i know the beacon in Apple devices ist Always on, but to follows it with Espresense you need to extract an irk value.

I have about a dozen M5stack-Atom-Lites around the house. Some of them run LD2420 radars, some run older LD1115H radars, and all of them are BT proxy modules for HA. I thought - why there’s no integration with HA’s mqtt_room?! So, I started investigating, and no luck. But I came across this piece of code:

There aren’t many things in life I hate as passionately as C++. I never fully understood the code, and it wasn’t very useful as-is - the distance calculation when using HA android app (beacon) is crap.

But I learned from it and created a lambda that gets RSSI, negates it, and uses MQTT to send it to mqtt_room (instead of calculating the distance).

Unfortunately, there’s no HA API for mqtt_room, so I had to use MQTT proper. Anyway, my code is crap, I haven’t worked as a programmer since mid-90s :wink:, but it works, and if you want to make it better - have fun and let me know!

P.S. Ooops, I forgot - you need the include files from the project I shamelessly plagiarized.

1 Like

Awesome job man! I had a quick look at your code, and the simplicity makes it genius. I have been stalling the setup of a room presence system using esp devices as I hoped there would be something released like a decent espresense integration in esphome.

Your solution is not the final answer, but the idea is really nice. I will have a go on this on some of my devices. If there’s anything I can improve, I’ll be happy to create a PR.

1 Like

Turns out, there’s a MUCH better way, I was almost there but missed it :man_facepalming:

You just define your iBeacon as ble_rssi, and perform on_value. And call a script :slight_smile: Works both for iBeacons and for devices with a fixed MAC addresses.

UPD: you need sanity check, ESPhome sends large numbers for unavailable iBeacons.

mqtt:
  id: mqtt_client
  broker: ${mqtt_host}
  client_id: ${name}
  discovery: false
  topic_prefix: null
  log_topic: null
  idf_send_async: true

script:
  - id: report_ble_rooms
    parameters:
      device: string
      rssi: int
    then:
      - lambda: |-
          id(mqtt_client).publish_json(
            (std::string)"${mqtt_topic}/" + device + "/$LOCATION",
            [=](JsonObject root)
            {
              root["id"] = device;
              root["name"] = "Fancy name for " + device;
              root["distance"] = 0 - rssi - 30;
            }
          );

sensor:
############################### iBeacons
  - platform: ble_rssi
    ibeacon_uuid: !secret ble_uuid_z_flip_4
    name:         ${ble_name_z_flip_4}
    on_value:
      then:
        - lambda: id(report_ble_rooms)->execute("${ble_name_z_flip_4}", x);
  - platform: ble_rssi
    ibeacon_uuid: !secret ble_uuid_pixel_5a
    name:         ${ble_name_pixel_5a}
    on_value:
      then:
        - lambda: id(report_ble_rooms)->execute("${ble_name_pixel_5a}", x);
  - platform: ble_rssi
    ibeacon_uuid: !secret ble_uuid_pixel_4a
    name:         ${ble_name_pixel_4a}
    on_value:
      then:
        - lambda: id(report_ble_rooms)->execute("${ble_name_pixel_4a}", x);

############################### MAC addresses (fixed)
  - platform: ble_rssi
    mac_address:  !secret ble_mac_huawei_nina
    name:         ${ble_name_huawei_nina}
    on_value:
      then:
        - lambda: id(report_ble_rooms)->execute("${ble_name_huawei_nina}", x);
  - platform: ble_rssi
    mac_address:  !secret ble_mac_huawei_chuck
    name:         ${ble_name_huawei_chuck}
    on_value:
      then:
        - lambda: id(report_ble_rooms)->execute("${ble_name_huawei_chuck}", x);
1 Like