Preserve new BLE tracker item name if seen before adding discovery (#30318)

* Preserve new BLE device name if one seen before the last scan but not on it

* Save an indented else block

* Use async_fire_time_changed and mock_device_tracker_conf in tests
This commit is contained in:
Ville Skyttä 2020-01-05 23:13:54 +02:00 committed by GitHub
parent fffc5a5fbb
commit f400b77837
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 78 additions and 15 deletions

View File

@ -84,7 +84,6 @@ omit =
homeassistant/components/blockchain/sensor.py
homeassistant/components/bloomsky/*
homeassistant/components/bluesound/*
homeassistant/components/bluetooth_le_tracker/device_tracker.py
homeassistant/components/bluetooth_tracker/*
homeassistant/components/bme280/sensor.py
homeassistant/components/bme680/sensor.py

View File

@ -44,23 +44,26 @@ def setup_scanner(hass, config, see, discovery_info=None):
def see_device(address, name, new_device=False):
"""Mark a device as seen."""
if new_device:
if address in new_devices:
new_devices[address] += 1
_LOGGER.debug("Seen %s %s times", address, new_devices[address])
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")
if new_device:
if address in new_devices:
new_devices[address]["seen"] += 1
if name:
new_devices[address]["name"] = name
else:
name = new_devices[address]["name"]
_LOGGER.debug("Seen %s %s times", address, new_devices[address]["seen"])
if new_devices[address]["seen"] < MIN_SEEN_NEW:
return
_LOGGER.debug("Adding %s to tracked devices", address)
devs_to_track.append(address)
else:
_LOGGER.debug("Seen %s for the first time", address)
new_devices[address] = {"seen": 1, "name": name}
return
see(
mac=BLE_PREFIX + address,
host_name=name,

View File

@ -428,6 +428,10 @@ pyfritzhome==0.4.0
# homeassistant.components.ifttt
pyfttt==0.3
# homeassistant.components.bluetooth_le_tracker
# homeassistant.components.skybeacon
pygatt[GATTTOOL]==4.0.5
# homeassistant.components.version
pyhaversion==3.1.0

View File

@ -0,0 +1 @@
"""Tests for the Bluetooth LE tracker component."""

View File

@ -0,0 +1,56 @@
"""Test Bluetooth LE device tracker."""
from datetime import timedelta
from unittest.mock import patch
from homeassistant.components.bluetooth_le_tracker import device_tracker
from homeassistant.components.device_tracker.const import (
CONF_SCAN_INTERVAL,
CONF_TRACK_NEW,
DOMAIN,
)
from homeassistant.const import CONF_PLATFORM
from homeassistant.setup import async_setup_component
from homeassistant.util import dt as dt_util, slugify
from tests.common import async_fire_time_changed
async def test_preserve_new_tracked_device_name(hass, mock_device_tracker_conf):
"""Test preserving tracked device name across new seens."""
address = "DE:AD:BE:EF:13:37"
name = "Mock device name"
entity_id = f"{DOMAIN}.{slugify(name)}"
with patch(
"homeassistant.components."
"bluetooth_le_tracker.device_tracker.pygatt.GATTToolBackend"
) as mock_backend, patch.object(device_tracker, "MIN_SEEN_NEW", 3):
# Return with name when seen first time
device = {"address": address, "name": name}
mock_backend.return_value.scan.return_value = [device]
config = {
CONF_PLATFORM: "bluetooth_le_tracker",
CONF_SCAN_INTERVAL: timedelta(minutes=1),
CONF_TRACK_NEW: True,
}
result = await async_setup_component(hass, DOMAIN, {DOMAIN: config})
assert result
# Seen once here; return without name when seen subsequent times
device["name"] = None
# Tick until device seen enough times for to be registered for tracking
for _ in range(device_tracker.MIN_SEEN_NEW - 1):
async_fire_time_changed(
hass,
dt_util.utcnow() + config[CONF_SCAN_INTERVAL] + timedelta(seconds=1),
)
await hass.async_block_till_done()
state = hass.states.get(entity_id)
assert state
assert state.name == name