Fix device tracker deadlock after exception in scanner

This commit is contained in:
Paulus Schoutsen 2015-06-02 21:39:33 -07:00
parent 73dab5a398
commit 644a3058de
2 changed files with 58 additions and 57 deletions

View File

@ -17,7 +17,7 @@ import homeassistant.util.dt as dt_util
from homeassistant.const import ( from homeassistant.const import (
STATE_HOME, STATE_NOT_HOME, ATTR_ENTITY_PICTURE, ATTR_FRIENDLY_NAME, STATE_HOME, STATE_NOT_HOME, ATTR_ENTITY_PICTURE, ATTR_FRIENDLY_NAME,
CONF_PLATFORM) CONF_PLATFORM, DEVICE_DEFAULT_NAME)
from homeassistant.components import group from homeassistant.components import group
DOMAIN = "device_tracker" DOMAIN = "device_tracker"
@ -169,66 +169,28 @@ class DeviceTracker(object):
if not self.lock.acquire(False): if not self.lock.acquire(False):
return return
found_devices = set(dev.upper() for dev in try:
self.device_scanner.scan_devices()) found_devices = set(dev.upper() for dev in
self.device_scanner.scan_devices())
for device in self.tracked: for device in self.tracked:
is_home = device in found_devices is_home = device in found_devices
self._update_state(now, device, is_home) self._update_state(now, device, is_home)
if is_home: if is_home:
found_devices.remove(device) found_devices.remove(device)
# Did we find any devices that we didn't know about yet? # Did we find any devices that we didn't know about yet?
new_devices = found_devices - self.untracked_devices new_devices = found_devices - self.untracked_devices
if new_devices: if new_devices:
if not self.track_new_devices: if not self.track_new_devices:
self.untracked_devices.update(new_devices) self.untracked_devices.update(new_devices)
# Write new devices to known devices file self._update_known_devices_file(new_devices)
if not self.invalid_known_devices_file: finally:
self.lock.release()
known_dev_path = self.hass.config.path(KNOWN_DEVICES_FILE)
try:
# If file does not exist we will write the header too
is_new_file = not os.path.isfile(known_dev_path)
with open(known_dev_path, 'a') as outp:
_LOGGER.info(
"Found %d new devices, updating %s",
len(new_devices), known_dev_path)
writer = csv.writer(outp)
if is_new_file:
writer.writerow((
"device", "name", "track", "picture"))
for device in new_devices:
# See if the device scanner knows the name
# else defaults to unknown device
dname = self.device_scanner.get_device_name(device)
name = dname or "unknown device"
track = 0
if self.track_new_devices:
self._track_device(device, name)
track = 1
writer.writerow((device, name, track, ""))
if self.track_new_devices:
self._generate_entity_ids(new_devices)
except IOError:
_LOGGER.exception(
"Error updating %s with %d new devices",
known_dev_path, len(new_devices))
self.lock.release()
# pylint: disable=too-many-branches # pylint: disable=too-many-branches
def _read_known_devices_file(self): def _read_known_devices_file(self):
@ -309,6 +271,44 @@ class DeviceTracker(object):
finally: finally:
self.lock.release() self.lock.release()
def _update_known_devices_file(self, new_devices):
""" Add new devices to known devices file. """
if not self.invalid_known_devices_file:
known_dev_path = self.hass.config.path(KNOWN_DEVICES_FILE)
try:
# If file does not exist we will write the header too
is_new_file = not os.path.isfile(known_dev_path)
with open(known_dev_path, 'a') as outp:
_LOGGER.info("Found %d new devices, updating %s",
len(new_devices), known_dev_path)
writer = csv.writer(outp)
if is_new_file:
writer.writerow(("device", "name", "track", "picture"))
for device in new_devices:
# See if the device scanner knows the name
# else defaults to unknown device
name = self.device_scanner.get_device_name(device) or \
DEVICE_DEFAULT_NAME
track = 0
if self.track_new_devices:
self._track_device(device, name)
track = 1
writer.writerow((device, name, track, ""))
if self.track_new_devices:
self._generate_entity_ids(new_devices)
except IOError:
_LOGGER.exception("Error updating %s with %d new devices",
known_dev_path, len(new_devices))
def _track_device(self, device, name): def _track_device(self, device, name):
""" """
Add a device to the list of tracked devices. Add a device to the list of tracked devices.

View File

@ -14,7 +14,8 @@ import homeassistant as ha
import homeassistant.loader as loader import homeassistant.loader as loader
import homeassistant.util.dt as dt_util import homeassistant.util.dt as dt_util
from homeassistant.const import ( from homeassistant.const import (
STATE_HOME, STATE_NOT_HOME, ATTR_ENTITY_PICTURE, CONF_PLATFORM) STATE_HOME, STATE_NOT_HOME, ATTR_ENTITY_PICTURE, CONF_PLATFORM,
DEVICE_DEFAULT_NAME)
import homeassistant.components.device_tracker as device_tracker import homeassistant.components.device_tracker as device_tracker
from helpers import get_test_home_assistant from helpers import get_test_home_assistant
@ -96,7 +97,7 @@ class TestComponentsDeviceTracker(unittest.TestCase):
# To ensure all the three expected lines are there, we sort the file # To ensure all the three expected lines are there, we sort the file
with open(self.known_dev_path) as fil: with open(self.known_dev_path) as fil:
self.assertEqual( self.assertEqual(
['DEV1,unknown device,0,\n', 'DEV2,dev2,0,\n', ['DEV1,{},0,\n'.format(DEVICE_DEFAULT_NAME), 'DEV2,dev2,0,\n',
'device,name,track,picture\n'], 'device,name,track,picture\n'],
sorted(fil)) sorted(fil))