Advertising intervals for BLE beacon

I’m trying to build a BLE sensor beacon to detect how often my Rivian’s headlights turn themselves on unexpectedly in the middle of the night. I programmed an Adafruit Feather Sense, transmitting data to Home Assistant using the BTHome integration. To start with, I set it to advertise for 1 second, then sleep for 1 second. It works, but it doesn’t capture brief changes properly. For example, if the headlights turn on for 30 seconds, the HA history shows it was on for 3 minutes.

I’m wondering if maybe HA is missing some of the broadcasts. Maybe I need to increase the advertising time, or decrease the interval between advertisements. Not sure what is common for other beacons like this. If it does miss a broadcast, is there some mechanism whereby HA would keep the last value for awhile before switching to “no data”?

I’m also trying to figure out what resolution Home Assistant can record in the history. I’m hoping it can record and display one sample per second, but so far I haven’t been able to find this info.

I added a counter sensor which just increments a number every second, so I’ve learned that the HA history view can show resolution with single second precision.

Sometimes the history view shows a flat line instead of a gap, which makes me think HA is holding on to stale values when it shouldn’t.

Why not just put a $1.00 light dependant resistor (LDR) connected to ESPHome in front of the car?

ESPhome could poll that many thousands of times a second and only report the on/off states to home assistant.

Or if you don’t know how to build it, a $10 zigbee light sensor.

I’m new to microcontrollers and I’m doing this for fun and education. I like that the Feather Sense has many different sensors built in so I think I’ll be able to find other uses for it in the future. And I think BLE has better battery life than Wifi.

Putting the light detection logic on the board is a good idea, that might do a better job catching quick changes. I’m doing that now (using CircuitPython), but HA still shows the same problem, where the monotonic counter is sometimes flatlining.

Is there a way to make HA log the raw bytes of every BLE packet received? I couldn’t find that in the debug loggers.

What are you using to receive the Bluetooth packets?

Is the Bluetooth radio sharing an antenna with a wifi radio?

If so then it can’t receive all the time. Some time has to be spent doing wifi.

There’s some advice here for ESPHome about this but it may also be relevant to you: Bluetooth Proxy - ESPHome - Smart Home Made Simple

In short it is recommended to use a BLE proxy that connects vial wired LAN rather than Wifi so the antenna can be dedicated to Bluetooth.

Um, I’d probably be focusing my energies on why the headlights are turning on unexpedectedly rather than inventing a sophisticated system to measure how often. Can you just set up a cheap security camera and check the video recording later for timestamps? You could repurpose it later for… a security camera!

Yes, you will most likely become an expert on BlueTooth going down the path you have chosen, trying to get it to work, but your headlights will still be blinking…

Solve the actual problem.

1 Like

I’m receiving the packets on my Home Assistant server, a Raspberry Pi 4. It’s connected via Ethernet so I don’t think Wifi should interfere. Just to make sure, today I disabled Wifi at the hardware level using the config.txt overlay and that didn’t change the results.

Looking closer at the history graph, I realized it does show the exact timestamps for each data point when you hover the mouse on the line, so I can confirm these flat lines represent missing samples. After a while, the line disappears and the entity becomes unavailable, but I’m not sure exactly how long that takes.

I’ve tried various different advertising intervals (i.e. 1000ms on, 4000ms off) and in each case, Home Assistant occasionally misses some samples. I’m not sure if this is a limitation of the BT hardware, or something in Home Assistant software. I suppose HA is not really designed for high frequency data like this, so it would make sense to skip samples if the CPU is busy doing other tasks.

I’m interested to see if a Wifi sensor like ESP32 would work any better.

Don’t use integer multiples.

See: BC04P Beacon – Deep Dive into the Configuration Screens – Blue Charm Beacons

Quirky intervals have a purpose: When beacons are being scanned by smartphones, there is the possibility that the scanning window of the phone and the broadcast of the beacon will not line up exactly. In that case, the broadcast will be missed by the phone. To reduce the chance of this happening, the smart people at Apple recommend that you set your advertising interval to one of these odd-looking numbers: 152.5 ms, 211.25 ms, 318.75 ms, 417.5 ms, 546.25 ms, 760 ms, 852.5 ms, 1022.5 ms, or 1285 ms. It is a bit complicated to explain this in detail, but suffice it to say, these intervals work better. This BC04P beacon has been designed with this in mind, and as far as I know, Blue Charm beacons are one of the only brands of beacons on the market that allow the user to input these precise optimal interval numbers.

Interesting! It looks like the source of that recommendation is here: Technical Q&A QA1931: Using the correct Bluetooth LE Advertising and Connection Parameters for a stable connection

That page makes it sound like they’re only talking about “connectable” peripherals, and only when connecting to Apple devices. So I’m not sure if that’s relevant for Home Assistant? In a separate document, Apple says iBeacons must use 100ms advertising interval.

Anyway, I’ll try this. It doesn’t say how long each advertisement should last, so I assume it should be as short as possible to maximize battery life. So I’ll try advertising for 20ms (the minimum allowed) and then sleeping 1002.5ms.