BLE custom component

I was able to reproduce your error @molodax, check your github issue.

@luca-angemi
Have you got any ideas how you could exclude the random private addresses from being added?
https://blog.bluetooth.com/bluetooth-technology-protecting-your-privacy Looking at https://devzone.nordicsemi.com/f/nordic-q-a/27012/how-to-distinguish-between-random-and-public-gap-addresses it appears there should be a way of working them out - my Pixel 2 generates a new random device about every 60 seconds which pollutes Home Assistant somewhat if you have ``track_new_devices```turned on (which can be useful).

For my purposes Iā€™ve coped the release code to be a custom component and amended as follows (to ignore unnamed devices, which nearly all appear to be random addresses)

                if name is None:
                    return
                else:
                    if new_devices[address] >= MIN_SEEN_NEW:
                        _LOGGER.debug("Adding %s to tracked devices", address)
                        devs_to_track.append(address)
                    else:
                        return```

Hi!

Did you configure in your configuration.yaml the parameter

track_new_devices: false

?

If you do that it doesnā€™t add the useful stuff with fixed addresses. Itā€™s only the random private addresses addresses which could do with being excluded - e.g. my Android phone (which changes every minute or so) and TV (which changes every time you turn it on) - still allows Home Assistant to find the Smart Watch and other useful devices.

If thatā€™s not possible to work out from the MAC Address (which appears to be the case https://stackoverflow.com/questions/23471364/private-vs-public-addresses-in-bluetooth-low-energy-on-android also canā€™t find any hcitool switches to do the same), then the easiest changes would be a list of names to ignore (e.g. my TV) and a flag to ignore unnamed devicesā€¦

Will have to try and work out how to pass config options from configuration.yaml to the custom_component

Oh sorry I didnā€™t understand.
If the mac keeps changing I donā€™t really know how you could discriminate unless as you mentioned you exclude from the devices names.

Took a bit longer than I expected but Iā€™ve got a fork that works for me (I copied the base from the Home Assistant Repo)

So Iā€™ve added three new options:-

  • hci_device - Allows you to override the Bluetooth Dongle used - I was suffering from the Bluetooth scanning falling over when the webcam was accessed (seemingly a common issue on the Pi3B) and the ā€œfixā€ is to use a USB Dongle - So need to override that
  • hide_unnamed - If itā€™s got no name I donā€™t care, so hide it - In my case all these unnamed devices had random mac addresses anyway or were unidentified Windows machines
  • blacklist_names - Ignore devices with the following names - My TV generating a new device every time I turned it on got boarding really fast as were new Tileā€™s being frequently added (either my Neighbour has one and it generates random addresses or a lot of people walking down the street have them)
  - platform: bluetooth_le_tracker
    track_new_devices: true
    interval_seconds: 15
    hci_device: 'hci1'
    hide_unnamed: true
    blacklist_names:
      - "Kev's LG TV"
      - 'Tile'
      - 'Kitchen Radio'
      - 'Bedroom Radio'

(Note - Worth adding any Chromecasts to this too - if they lose internet youā€™ll get a new device every 15 minutes or so - they only have a BLE Name when they are disconnected from WiFi - woke up to about 30 Push Bullet notifications this morning as my Kitchen Chromecast fell off the WiFi :scream: )

Most of the code changes were to fix the blank names causing errors (discussed up thread) or to support these options, but there was also one addition to work around the scanning breaking after a few hours (File I/O Error in the logs when trying to access the BLE Dongle):-

except pygatt.exceptions.BLEError as error:
            _LOGGER.error("BLEError during Bluetooth LE scan: %s", error)
            return {}

This allows that run to gracefully fail (rather than throw an exception), but for future runs to happen

This is giving me stable runs without constantly getting new devices added :slight_smile:

4 Likes

Thanks @kevjs1982 it seems to be running a lot better now. Iā€™m at about 24 hours now. The official component fails after a number of hours as youā€™ve mentioned. Hopefully, it gets merged to the main repo

Iā€™ve added your custom component in my setup (docker in my synology NAS).

In the last 24 no device were added (while regular bt works fine).

Interesting - what settings for platform: bluetooth_le_tracker have you got in configuration.yaml?

My hunch is youā€™ve added hci_device: 'hci1' which is only needed if you have a second Bluetooth Dongle you want to use (i.e. for most uses ignore it). Does home-assistant.log show anything - also do any already detected devices show as being at home?

Iā€™m getting this error when I try itā€¦ I am using a docker on ubuntu

2018-11-21 09:12:26 ERROR (SyncWorker_9) [pygatt.backends.gatttool.gatttool] Unexpected error when scanning: Invalid device: Operation not permitted

2018-11-21 09:12:26 ERROR (SyncWorker_9) [custom_components.device_tracker.bluetooth_le_tracker] BLEError during Bluetooth LE scan: Unexpected error when scanning: Invalid device: Operation not permitted

any idea please?

If I run hcitool it works but doesnā€™t find my android 8 phone

mark@HomeAssistant ~ $ sudo hcitool lescan
LE Scan ...
4C:56:1A:D1:F2:E2 (unknown)
4C:56:1A:D1:F2:E2 (unknown)

Cheers
Mark

I upgradet to 82.1 and then I SEE NOW A LOT OF ERRORS! LOL

BLEError during Bluetooth LE scan: BLE adapter requires reset after a scan as root- call adapter.reset()

BLE adapter requires reset after a scan as root- call adapter.reset()

I see in the log every second.

Hereā€™s my setup:

  - platform: bluetooth_le_tracker
    track_new_devices: yes
    interval_seconds: 15
    #hci_device: 'hci1'
    #consider_home: 2000
    #scan_duration: 15
    hide_unnamed: true

As told before Iā€™m running Home Assistant inside a docker in my synology nas.

The container has access to BT dongle.

Ah, Iā€™ve seen that one before (with the standard component) if you restart hass while itā€™s in the middle of scanning. Sometimes simply restarting hass again fixes it. See Wim_Lā€™s reply BLE custom component

Iā€™ve ended up adding sudo hciconfig hci0 reset to the bash file which I use to restart hass

#!/bin/bash
sudo systemctl stop [email protected]
sleep 2
sudo hciconfig hci0 reset
sudo hciconfig hci1 reset
sleep 2
sudo systemctl start [email protected]

Iā€™ve tried rebooting HA and his docker. Nothing changed!

Iā€™m running HA in docker so i canā€™t run this script. Can you please support me to create it for docker environment?

Sorry, never used Docker myself.

" > BLEError during Bluetooth LE scan: BLE adapter requires reset after a scan as root- call adapter.reset()" means something else has used the Bluetooth Adapter.

sudo hciconfig hci0 reset
Needs to be run to clear that.

Would suggest reverting to the standard component, does the problem still exist. Does rebooting the PC running Docker fix it?

I fixed the ble scanning in a different way: my main/first device tracker is my router and has the
track_new_devices as false. I just add ā€œtrueā€ in the know_device I want to track. With the ble tracker I had to explicit track_new_devices as true, then the component is loaded correctly and ble devices added in know_devices. At this point the BLE_ devices are not tracked still, then I changed ā€œtrueā€ to the tracking option inside know_devices and BOOM. Now the component is loaded and working: it ignores every new devices and tracks only the device I want.

Hi @kevjs1982

Iā€™m trying to use your component, and it looks like in the beginning it starts tracking existing BLE devices correctly but very soon I get the following errors and it stops working:

ERROR (SyncWorker_12) [pygatt.backends.gatttool.gatttool] Unexpected error when scanning: Set scan parameters failed: I/O error

2018-12-12 15:25:14 ERROR (SyncWorker_12) [custom_components.device_tracker.ble] BLEError during Bluetooth LE scan: Unexpected error when scanning: Set scan parameters failed: I/O error

2018-12-12 15:25:29 ERROR (SyncWorker_2) [pygatt.backends.gatttool.gatttool] Unexpected error when scanning: LE Scan ...
CC:B1:1A:A1:96:15 (unknown)
56:51:B1:CA:A3:BE (unknown)
28:A2:63:97:9F:A9 (unknown)
54:46:32:B0:B1:5B (unknown)
40:16:3B:E4:6F:4F (unknown)
C4:7C:8D:62:1C:F7 (unknown)
68:D9:3C:91:E9:81 (unknown)
75:2A:F4:90:56:46 (unknown)
7A:AD:06:1A:5D:D8 (unknown)
56:51:B1:CA:A3:BE (unknown)
C4:7C:8D:62:7A:D9 (unknown)
C4:7C:8D:62:7A:D9 Flower care
04:69:F8:B3:BE:DC (unknown)
38:23:6F:08:76:0F (unknown)
FC:8F:90:2E:28:6E (unknown)
C4:7C:8D:62:79:E5 (unknown)
75:2A:F4:90:56:46 (unknown)
77:E3:29:F2:77:26 (unknown)
DC:56:E7:42:F8:FE (unknown)
C4:7C:8D:62:1C:F7 Flower care
68:4A:9B:69:97:49 (unknown)
08:66:98:89:B0:27 (unknown)

2018-12-12 15:25:29 ERROR (SyncWorker_2) [custom_components.device_tracker.ble] BLEError during Bluetooth LE scan: Unexpected error when scanning: LE Scan ...
CC:B1:1A:A1:96:15 (unknown)
56:51:B1:CA:A3:BE (unknown)
28:A2:63:97:9F:A9 (unknown)
54:46:32:B0:B1:5B (unknown)
40:16:3B:E4:6F:4F (unknown)
C4:7C:8D:62:1C:F7 (unknown)
68:D9:3C:91:E9:81 (unknown)
75:2A:F4:90:56:46 (unknown)
7A:AD:06:1A:5D:D8 (unknown)
56:51:B1:CA:A3:BE (unknown)
C4:7C:8D:62:7A:D9 (unknown)
C4:7C:8D:62:7A:D9 Flower care
04:69:F8:B3:BE:DC (unknown)
38:23:6F:08:76:0F (unknown)
FC:8F:90:2E:28:6E (unknown)
C4:7C:8D:62:79:E5 (unknown)
75:2A:F4:90:56:46 (unknown)
77:E3:29:F2:77:26 (unknown)
DC:56:E7:42:F8:FE (unknown)
C4:7C:8D:62:1C:F7 Flower care
68:4A:9B:69:97:49 (unknown)
08:66:98:89:B0:27 (unknown)

2018-12-12 15:25:52 ERROR (MainThread) [homeassistant.core] Error doing job: Future exception was never retrieved
Traceback (most recent call last):
  File "/usr/local/lib/python3.6/concurrent/futures/thread.py", line 56, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/config/custom_components/device_tracker/ble.py", line 139, in update_ble
    see_device(address, devs[address], new_device=True)
  File "/config/custom_components/device_tracker/ble.py", line 58, in see_device
    elif name in config.get(CONF_BLACKLIST):
TypeError: argument of type 'NoneType' is not iterable

Any ideas what can cause it and how to fix it?

Odd, itā€™s a very naĆÆve change to the official component, simply when it errors it tries to carry on so you might see the odd error about it failing to scan - this is normal. The official component dies, this should try again.

The bottom error TypeError: argument of type 'NoneType' is not iterable should be getting caught

Could you try adding :-

blacklist_names:
  - "anything that is not a real device"

to the configuration? Looks like it might not be correctly coping with an empty blacklist

Thank you, it did helped when I added blacklist_names to the configuration. It looks like lack of this option in my initial configuration rather than which names listed was a problem in my case, i.e. blacklist_names appeared required option even if I included some fake names of inexisted devices.
Would you consider to update the official ble tracker since it seems working quite reliable?

Thanks for this. I finally have a working ble tracker :slight_smile:

Previously I was using nmap on an iphone. Which proved to be quite reliable when changing states from not_home to home. But was pretty bad for the reverse.
Bluetooth works perfectly for both state changes on amazfit pace.

1 Like