core: Bluetooth tracker LE setting up error

Home Assistant release with the issue:

0.78.0

Last working Home Assistant release (if known):

Operating environment (Hass.io/Docker/Windows/etc.):

hassio (HassOS 1.10) rpi 3

Component/platform:

Bluetooth tracker LE https://www.home-assistant.io/components/device_tracker.bluetooth_le_tracker/

Description of problem: Error in setting up the platform.

Problem-relevant configuration.yaml entries and (fill out even if it seems unimportant):

device_tracker:
  - platform: bluetooth_le_tracker

Traceback (if applicable):

2018-09-18 19:57:05 WARNING (SyncWorker_13) [homeassistant.components.device_tracker.bluetooth_le_tracker] No Bluetooth LE devices to track!
2018-09-18 19:57:05 ERROR (MainThread) [homeassistant.components.device_tracker] Error setting up platform bluetooth_le_tracker

Additional information: Nothing more in log. I also have Mi Flora Plant component that works with Bluetooth LE.

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 8
  • Comments: 119 (27 by maintainers)

Most upvoted comments

Traceback (if applicable):

2018-09-18 19:57:05 WARNING (SyncWorker_13) [homeassistant.components.device_tracker.bluetooth_le_tracker] No Bluetooth LE devices to track!
2018-09-18 19:57:05 ERROR (MainThread) [homeassistant.components.device_tracker] Error setting up platform bluetooth_le_tracker

There is a problem with setting the default track_new_devices, you have to activate it yourself:

device_tracker:
  - platform: bluetooth_le_tracker
    track_new_devices: True

Now works for me.

Error during Bluetooth LE scan: Unexpected error when scanning: Set scan parameters failed: I/O error

in Home Assistant 0.106.5

Was able to reproduce the error by restarting home assistant while it was scanning.

When HA gets restarted while a scan is being done, the HCI0 interface is not being disconnected gracefully:

2018-09-23 13:27:17 DEBUG (Thread-14) [homeassistant.components.device_tracker.bluetooth_le_tracker] Discovering Bluetooth LE devices 2018-09-23 13:27:17 INFO (Thread-14) [pygatt.backends.gatttool.gatttool] Starting BLE scan 2018-09-23 13:27:18 ERROR (Thread-14) [pygatt.backends.gatttool.gatttool] Unexpected error when scanning: LE Scan … 14:BB:6E:D3:3F:C2 (unknown) 14:BB:6E:D3:3F:C2 [TV] Samsung 6 Series (40) 7C:2F:80:CE:F0:D6 (unknown) 7C:2F:80:CE:F0:D6 Gigaset G-tag

The interface is left in a dirty state, on start or restart a ‘hciconfig hci0 reset’ should be called to clean the interface.

Could @boosik and @Molodax test this by stopping HA, call ‘hciconfig hci0 reset’ and start HA again to see if it runs?

2 other issues are apparent on a fresh install:

  1. It doesn’t create known_devices.yaml. It errors out saying it’s not there:

EDIT: This is default behavior that can be fixed by adding: (ty @qubik)

device_tracker:
  - platform: ble
    track_new_devices: True

  1. the python ‘pexpect’ library needs to be manually installed, HA seems to forget installing it.

fixed via #75013 in 2022.8.0 (unreleased)

Me too, Home Assistant 0.113.0, hassio install on rpi3 2020-07-24 18:54:33 ERROR (SyncWorker_0) [pygatt.backends.gatttool.gatttool] Unexpected error when scanning: Set scan parameters failed: I/O error 2020-07-24 18:54:33 ERROR (SyncWorker_0) [homeassistant.components.bluetooth_le_tracker.device_tracker] Error during Bluetooth LE scan: Unexpected error when scanning: Set scan parameters failed: I/O error `device_tracker:

  • platform: bluetooth_le_tracker track_new_devices: true track_battery: true interval_seconds: 300 `

Hi, how do you get that far.

i’m stuck in the logs, home assistant saying :

FileNotFoundError: [Errno 2] No such file or directory: 'sudo'

i’m using hass.io on rpi 3b+ and i don’t understand how, from docker containers to leave access to bluetooth device, even when reading this doc: https://www.home-assistant.io/integrations/bluetooth_le_tracker/#rootless-setup

Logger: homeassistant
Source: components/bluetooth_le_tracker/device_tracker.py:189
First occurred: 0:47:02 (1 occurrences)
Last logged: 0:47:02

Error doing job: Future exception was never retrieved
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/components/bluetooth_le_tracker/device_tracker.py", line 172, in update_ble
    adapter.start(reset_on_start=True)
  File "/usr/local/lib/python3.8/site-packages/pygatt/backends/gatttool/gatttool.py", line 264, in start
    self.reset()
  File "/usr/local/lib/python3.8/site-packages/pygatt/backends/gatttool/gatttool.py", line 631, in reset
    subprocess.Popen(["sudo", "systemctl", "restart", "bluetooth"]).wait()
  File "/usr/local/lib/python3.8/subprocess.py", line 854, in __init__
    self._execute_child(args, executable, preexec_fn, close_fds,
  File "/usr/local/lib/python3.8/subprocess.py", line 1702, in _execute_child
    raise child_exception_type(errno_num, err_msg, err_filename)
FileNotFoundError: [Errno 2] No such file or directory: 'sudo'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/local/lib/python3.8/concurrent/futures/thread.py", line 57, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/usr/src/homeassistant/homeassistant/components/bluetooth_le_tracker/device_tracker.py", line 189, in update_ble
    adapter.stop()
  File "/usr/local/lib/python3.8/site-packages/pygatt/backends/gatttool/gatttool.py", line 308, in stop
    self.disconnect(self._connected_device)
  File "/usr/local/lib/python3.8/site-packages/pygatt/backends/gatttool/gatttool.py", line 50, in wrapper
    return func(self, *args, **kwargs)
  File "/usr/local/lib/python3.8/site-packages/pygatt/backends/gatttool/gatttool.py", line 486, in disconnect
    if not self._receiver.is_set("disconnected"):
AttributeError: 'NoneType' object has no attribute 'is_set'

I have the same setup and the same error. Did you solve the problem @xvolte ?

Same issue. Worked reliably for months on RPi4 till update to 21.3.3 or thereabouts. Now my tile BLE trackers are changing everyone to ‘away’ every few minutes.

[pygatt.backends.gatttool.gatttool] Unexpected error when scanning: Set scan parameters failed: I/O error [homeassistant.components.bluetooth_le_tracker.device_tracker] Error during Bluetooth LE scan: Unexpected error when scanning: Set scan parameters failed: I/O error

Me too, Home Assistant 0.113.0, hassio install on rpi3 `2020-07-24 18:54:33 ERROR (SyncWorker_0) [pygatt.backends.gatttool.gatttool] Unexpected error when scanning: Set scan parameters failed: I/O error

2020-07-24 18:54:33 ERROR (SyncWorker_0) [homeassistant.components.bluetooth_le_tracker.device_tracker] Error during Bluetooth LE scan: Unexpected error when scanning: Set scan parameters failed: I/O error device_tracker:

  • platform: bluetooth_le_tracker track_new_devices: true track_battery: true interval_seconds: 300 `

Hi, how do you get that far.

i’m stuck in the logs, home assistant saying :

FileNotFoundError: [Errno 2] No such file or directory: 'sudo'

i’m using hass.io on rpi 3b+ and i don’t understand how, from docker containers to leave access to bluetooth device, even when reading this doc: https://www.home-assistant.io/integrations/bluetooth_le_tracker/#rootless-setup

Logger: homeassistant
Source: components/bluetooth_le_tracker/device_tracker.py:189
First occurred: 0:47:02 (1 occurrences)
Last logged: 0:47:02

Error doing job: Future exception was never retrieved
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/components/bluetooth_le_tracker/device_tracker.py", line 172, in update_ble
    adapter.start(reset_on_start=True)
  File "/usr/local/lib/python3.8/site-packages/pygatt/backends/gatttool/gatttool.py", line 264, in start
    self.reset()
  File "/usr/local/lib/python3.8/site-packages/pygatt/backends/gatttool/gatttool.py", line 631, in reset
    subprocess.Popen(["sudo", "systemctl", "restart", "bluetooth"]).wait()
  File "/usr/local/lib/python3.8/subprocess.py", line 854, in __init__
    self._execute_child(args, executable, preexec_fn, close_fds,
  File "/usr/local/lib/python3.8/subprocess.py", line 1702, in _execute_child
    raise child_exception_type(errno_num, err_msg, err_filename)
FileNotFoundError: [Errno 2] No such file or directory: 'sudo'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/local/lib/python3.8/concurrent/futures/thread.py", line 57, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/usr/src/homeassistant/homeassistant/components/bluetooth_le_tracker/device_tracker.py", line 189, in update_ble
    adapter.stop()
  File "/usr/local/lib/python3.8/site-packages/pygatt/backends/gatttool/gatttool.py", line 308, in stop
    self.disconnect(self._connected_device)
  File "/usr/local/lib/python3.8/site-packages/pygatt/backends/gatttool/gatttool.py", line 50, in wrapper
    return func(self, *args, **kwargs)
  File "/usr/local/lib/python3.8/site-packages/pygatt/backends/gatttool/gatttool.py", line 486, in disconnect
    if not self._receiver.is_set("disconnected"):
AttributeError: 'NoneType' object has no attribute 'is_set'

Home Assistant release with the issue:

0.78.0

Last working Home Assistant release (if known):

Operating environment (Hass.io/Docker/Windows/etc.):

Docker on Ubuntu Server 18.04

Component/platform:

Bluetooth tracker LE https://www.home-assistant.io/components/device_tracker.bluetooth_le_tracker/

Description of problem: Error in setting up the platform. Classic Bluetooth (not LE) is working well on the same instance in the same Docker container. hcitool lescan works well in the container. hcitool dev show device hci0 up and running.

Problem-relevant configuration.yaml entries and (fill out even if it seems unimportant):

device_tracker:
  - platform: bluetooth_le_tracker

Traceback (if applicable):

2018-09-19 08:27:58 WARNING (SyncWorker_11) [homeassistant.components.device_tracker.bluetooth_le_tracker] No Bluetooth LE devices to track!
2018-09-19 08:27:58 ERROR (MainThread) [homeassistant.components.device_tracker] Error setting up platform bluetooth_le_tracker

I discovered today that only 531 user installation uses bluetooth LE, indeed we are a niche.

That is low. It might be higher if it were more reliable 😀

Hi all, I wrote a watchdog daemon for who are running HA as supervised like me. If you are interested to try it is here: https://github.com/mcanteri/home-assistant-bluetooth-LE-watchdog

Is this for me if I’m running HAS OS on a pi4, or is this for docker container-esque setups?

Hi all, I wrote a watchdog daemon for who are running HA as supervised like me. If you are interested to try it is here: https://github.com/mcanteri/home-assistant-bluetooth-LE-watchdog

Same problem on Hass.io 0.107.7. I dont have Miflora. I tried many diffirent variants of device_tracker config but this is what i see everytime.

2020-04-01 23:06:20 WARNING (SyncWorker_18) [homeassistant.components.bluetooth_le_tracker.device_tracker] No Bluetooth LE devices to track!
2020-04-01 23:06:21 ERROR (MainThread) [homeassistant.components.device_tracker] Error setting up platform legacy

HASS 0.107.4 Logger: homeassistant.components.bluetooth_le_tracker.device_tracker Source: components/bluetooth_le_tracker/device_tracker.py:119 Integration: bluetooth_le_tracker (documentation, issues) First occurred: 10:44:42 PM (27 occurrences) Last logged: 10:54:27 PM

Error during Bluetooth LE scan: Unexpected error when scanning: LE Scan

I was having this issue too, and I did notice now that> track_new_devices: false cause the issue, while if I set track_new_devices: true

It is working fine.

Will some one test this? https://github.com/home-assistant/home-assistant/blob/ble_v2/homeassistant/components/device_tracker/bluetooth_le_tracker.py

@pvizeli, I tried your v2 component. Initially I had the same problem that @Molodax had (“Unable to install package pygattlib==0.0.4”).

I found that some libraries and packages where required:

sudo apt-get install libglib2.0-dev
sudo apt-get install libboost-python-dev
sudo apt-get install libboost-thread-dev
pip3 install boost

After installing those requisites, the component started working like a charm, detecting BLE devices and storing them in the known_devices.yaml

I have a Mi Flora, I´ll try to use both components to see if there are problems

The problem is that Bluetooth and python are not the best friends. Most of exists library are very old I don’t work with our fast moving.

The old gatttlib library was to broken. I port it to a library they use the cmd line tool like Miflora. Look like that’s difficult that two library use the same command line tool.

I try to port this platform to https://github.com/pybluez/pygattlib. Maybe some one will help on it instead to workaround it 😉

fixed via #75013 in 2022.8.0 (unreleased)

i have same issue Home Assistant 2022.9.1

Logger: homeassistant.components.device_tracker
Source: components/device_tracker/legacy.py:313
Integration: Device tracker ([documentation](https://www.home-assistant.io/integrations/device_tracker), [issues](https://github.com/home-assistant/home-assistant/issues?q=is%3Aissue+is%3Aopen+label%3A%22integration%3A+device_tracker%22))
First occurred: 3:07:56 PM (1 occurrences)
Last logged: 3:07:56 PM

Error setting up platform legacy bluetooth_le_tracker
Logger: homeassistant.components.bluetooth_le_tracker.device_tracker
Source: components/bluetooth_le_tracker/device_tracker.py:133
Integration: bluetooth_le_tracker ([documentation](https://www.home-assistant.io/integrations/bluetooth_le_tracker), [issues](https://github.com/home-assistant/home-assistant/issues?q=is%3Aissue+is%3Aopen+label%3A%22integration%3A+bluetooth_le_tracker%22))
First occurred: 3:07:56 PM (1 occurrences)
Last logged: 3:07:56 PM

No Bluetooth LE devices to track!

any debug info that i can provide to help investigate?

Hardware is raspberry pi 4 with in built bluetooth

Hi all, I wrote a watchdog daemon for who are running HA as supervised like me. If you are interested to try it is here: https://github.com/mcanteri/home-assistant-bluetooth-LE-watchdog

Wow, this patches the home assistant container. Clever, but scary 😀

I’ve had problems with Bluetooth (Mi Flora and Xiaomi BLE temp sensor) since v0.9x something. It seems they finally fixed this on the RPi3 in HassOS 3.13 that just came out. You might want tio try that. It certainly solved my problems at least…

https://github.com/home-assistant/operating-system/releases

For all those still encountering this BLEError issue I have created a workaround ble_tracker.py which may work for you (works fine for me). All it simply does is correctly intercept the problematic BLEError and basically ignores it. Seems to work because each time because the ble_device_tracker module invokes a new pygatt backend instance from scratch every time it polls for new BLE devices… So if you get an error in a single poll, who cares try again next time. this tracker module seems pretty crude (which is exactly how I would have coded it lol).

Install into custom_components/device_tracker/ble_tracker.py

"""
Tracking for bluetooth low energy devices.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/device_tracker.bluetooth_le_tracker/
"""
import logging

from homeassistant.helpers.event import track_point_in_utc_time
from homeassistant.components.device_tracker import (
    YAML_DEVICES, CONF_TRACK_NEW, CONF_SCAN_INTERVAL, DEFAULT_SCAN_INTERVAL,
    load_config, SOURCE_TYPE_BLUETOOTH_LE
)
import homeassistant.util.dt as dt_util

_LOGGER = logging.getLogger(__name__)

REQUIREMENTS = ['pygatt==3.2.0']

BLE_PREFIX = 'BLE_'
MIN_SEEN_NEW = 5


def setup_scanner(hass, config, see, discovery_info=None):
    """Set up the Bluetooth LE Scanner."""
    # pylint: disable=import-error
    import pygatt
    from pygatt.exceptions import BLEError
    new_devices = {}

    def see_device(address, name, new_device=False):
        """Mark a device as seen."""
        if new_device:
            if address in new_devices:
                _LOGGER.debug(
                    "Seen %s %s times", address, new_devices[address])
                new_devices[address] += 1
                if new_devices[address] >= MIN_SEEN_NEW:
                    _LOGGER.debug("Adding %s to tracked devices", address)
                    devs_to_track.append(address)
                else:
                    return
            else:
                _LOGGER.debug("Seen %s for the first time", address)
                new_devices[address] = 1
                return

        if name is not None:
            name = name.strip("\x00")

        see(mac=BLE_PREFIX + address, host_name=name,
            source_type=SOURCE_TYPE_BLUETOOTH_LE)

    def discover_ble_devices():
        """Discover Bluetooth LE devices."""
        _LOGGER.debug("Discovering Bluetooth LE devices")
        try:
            adapter = pygatt.GATTToolBackend()
            devs = adapter.scan()

            devices = {x['address']: x['name'] for x in devs}
            _LOGGER.debug("Bluetooth LE devices discovered = %s", devices)
        except BLEError as error:
            _LOGGER.error("Caught pygatt BLE Error: %s - will try again later", error)
            return {}
        except RuntimeError as error:
            _LOGGER.error("Error during Bluetooth LE scan: %s", error)
            return {}
        return devices

    yaml_path = hass.config.path(YAML_DEVICES)
    devs_to_track = []
    devs_donot_track = []

    # Load all known devices.
    # We just need the devices so set consider_home and home range
    # to 0
    for device in load_config(yaml_path, hass, 0):
        # check if device is a valid bluetooth device
        if device.mac and device.mac[:4].upper() == BLE_PREFIX:
            if device.track:
                _LOGGER.debug("Adding %s to BLE tracker", device.mac)
                devs_to_track.append(device.mac[4:])
            else:
                _LOGGER.debug("Adding %s to BLE do not track", device.mac)
                devs_donot_track.append(device.mac[4:])

    # if track new devices is true discover new devices
    # on every scan.
    track_new = config.get(CONF_TRACK_NEW)

    if not devs_to_track and not track_new:
        _LOGGER.warning("No Bluetooth LE devices to track!")
        return False

    interval = config.get(CONF_SCAN_INTERVAL, DEFAULT_SCAN_INTERVAL)

    def update_ble(now):
        """Lookup Bluetooth LE devices and update status."""
        devs = discover_ble_devices()
        for mac in devs_to_track:
            if mac not in devs:
                continue

            if devs[mac] is None:
                devs[mac] = mac
            see_device(mac, devs[mac])

        if track_new:
            for address in devs:
                if address not in devs_to_track and \
                        address not in devs_donot_track:
                    _LOGGER.info("Discovered Bluetooth LE device %s", address)
                    see_device(address, devs[address], new_device=True)

        track_point_in_utc_time(hass, update_ble, dt_util.utcnow() + interval)

    update_ble(dt_util.utcnow())
    return True

My config is:

device_tracker:
  - platform: bluetooth_tracker
  - platform: ble_tracker

will this work on the homeassistant docker container? That thing seems to run a stripped down (Alpine?) Linux which doesn’t have any of these libraries in it’s repositories. libboost etc.

It seems that this configuration is now (0.79.3) working (docker on linux) :

   - platform: bluetooth_le_tracker
     device_id: hci0
     scan_interval: 60
     track_new_devices: True

I’ve managed to workaround the issue. Create a file “/config/custom_components/device_tracker/ble.py” Paste following code to that file (only change is None check near line 47):

"""
Tracking for bluetooth low energy devices.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/device_tracker.bluetooth_le_tracker/
"""
import logging

from homeassistant.helpers.event import track_point_in_utc_time
from homeassistant.components.device_tracker import (
    YAML_DEVICES, CONF_TRACK_NEW, CONF_SCAN_INTERVAL, DEFAULT_SCAN_INTERVAL,
    load_config, SOURCE_TYPE_BLUETOOTH_LE
)
import homeassistant.util.dt as dt_util

_LOGGER = logging.getLogger(__name__)

REQUIREMENTS = ['pygatt==3.2.0']

BLE_PREFIX = 'BLE_'
MIN_SEEN_NEW = 5


def setup_scanner(hass, config, see, discovery_info=None):
    """Set up the Bluetooth LE Scanner."""
    # pylint: disable=import-error
    import pygatt
    new_devices = {}

    def see_device(address, name, new_device=False):
        """Mark a device as seen."""
        if new_device:
            if address in new_devices:
                _LOGGER.debug(
                    "Seen %s %s times", address, new_devices[address])
                new_devices[address] += 1
                if new_devices[address] >= MIN_SEEN_NEW:
                    _LOGGER.debug("Adding %s to tracked devices", address)
                    devs_to_track.append(address)
                else:
                    return
            else:
                _LOGGER.debug("Seen %s for the first time", address)
                new_devices[address] = 1
                return
        
        if name is None:
            see(mac=BLE_PREFIX + address, host_name=BLE_PREFIX + address,
                source_type=SOURCE_TYPE_BLUETOOTH_LE)
        else:
            see(mac=BLE_PREFIX + address, host_name=name.strip("\x00"),
                source_type=SOURCE_TYPE_BLUETOOTH_LE)

    def discover_ble_devices():
        """Discover Bluetooth LE devices."""
        _LOGGER.debug("Discovering Bluetooth LE devices")
        try:
            adapter = pygatt.GATTToolBackend()
            devs = adapter.scan()

            devices = {x['address']: x['name'] for x in devs}
            _LOGGER.debug("Bluetooth LE devices discovered = %s", devices)
        except RuntimeError as error:
            _LOGGER.error("Error during Bluetooth LE scan: %s", error)
            return {}
        return devices

    yaml_path = hass.config.path(YAML_DEVICES)
    devs_to_track = []
    devs_donot_track = []

    # Load all known devices.
    # We just need the devices so set consider_home and home range
    # to 0
    for device in load_config(yaml_path, hass, 0):
        # check if device is a valid bluetooth device
        if device.mac and device.mac[:4].upper() == BLE_PREFIX:
            if device.track:
                _LOGGER.debug("Adding %s to BLE tracker", device.mac)
                devs_to_track.append(device.mac[4:])
            else:
                _LOGGER.debug("Adding %s to BLE do not track", device.mac)
                devs_donot_track.append(device.mac[4:])

    # if track new devices is true discover new devices
    # on every scan.
    track_new = config.get(CONF_TRACK_NEW)

    if not devs_to_track and not track_new:
        _LOGGER.warning("No Bluetooth LE devices to track!")
        return False

    interval = config.get(CONF_SCAN_INTERVAL, DEFAULT_SCAN_INTERVAL)

    def update_ble(now):
        """Lookup Bluetooth LE devices and update status."""
        devs = discover_ble_devices()
        for mac in devs_to_track:
            if mac not in devs:
                continue

            if devs[mac] is None:
                devs[mac] = mac
            see_device(mac, devs[mac])

        if track_new:
            for address in devs:
                if address not in devs_to_track and \
                        address not in devs_donot_track:
                    _LOGGER.info("Discovered Bluetooth LE device %s", address)
                    see_device(address, devs[address], new_device=True)

        track_point_in_utc_time(hass, update_ble, dt_util.utcnow() + interval)

    update_ble(dt_util.utcnow())
    return True

Now use this configuration.yaml:

device_tracker:
  - platform: ble
    track_new_devices: True

I have not tested it with miflora component because I have zero miflora devices.

@gubiq nice find! I’m now getting new devices in known_devices.yaml But I have found new problem.

Looks like some devices doesn’t have names and component throws exception when that happens, because it is trying to strip some symbols from it.

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 "/usr/local/lib/python3.6/site-packages/homeassistant/components/device_tracker/bluetooth_le_tracker.py", line 107, in update_ble
    see_device(address, devs[address], new_device=True)
  File "/usr/local/lib/python3.6/site-packages/homeassistant/components/device_tracker/bluetooth_le_tracker.py", line 47, in see_device
    see(mac=BLE_PREFIX + address, host_name=name.strip("\x00"),
AttributeError: 'NoneType' object has no attribute 'strip'