mirror of
https://github.com/home-assistant/core.git
synced 2025-07-14 08:47:10 +00:00
Merge pull request #1314 from balloob/fix_own_tracks_mobile_beacon
Fix own tracks mobile beacon race condition
This commit is contained in:
commit
22b47ce9c6
@ -62,7 +62,7 @@ def setup_scanner(hass, config, see):
|
|||||||
see_beacons(dev_id, kwargs)
|
see_beacons(dev_id, kwargs)
|
||||||
|
|
||||||
def owntracks_event_update(topic, payload, qos):
|
def owntracks_event_update(topic, payload, qos):
|
||||||
# pylint: disable=too-many-branches
|
# pylint: disable=too-many-branches, too-many-statements
|
||||||
""" MQTT event (geofences) received. """
|
""" MQTT event (geofences) received. """
|
||||||
|
|
||||||
# Docs on available data:
|
# Docs on available data:
|
||||||
@ -92,7 +92,10 @@ def setup_scanner(hass, config, see):
|
|||||||
if zone is None:
|
if zone is None:
|
||||||
if data['t'] == 'b':
|
if data['t'] == 'b':
|
||||||
# Not a HA zone, and a beacon so assume mobile
|
# Not a HA zone, and a beacon so assume mobile
|
||||||
MOBILE_BEACONS_ACTIVE[dev_id].append(location)
|
beacons = MOBILE_BEACONS_ACTIVE[dev_id]
|
||||||
|
if location not in beacons:
|
||||||
|
beacons.append(location)
|
||||||
|
_LOGGER.info("Added beacon %s", location)
|
||||||
else:
|
else:
|
||||||
# Normal region
|
# Normal region
|
||||||
if not zone.attributes.get('passive'):
|
if not zone.attributes.get('passive'):
|
||||||
@ -108,28 +111,30 @@ def setup_scanner(hass, config, see):
|
|||||||
see_beacons(dev_id, kwargs)
|
see_beacons(dev_id, kwargs)
|
||||||
|
|
||||||
elif data['event'] == 'leave':
|
elif data['event'] == 'leave':
|
||||||
regions = REGIONS_ENTERED[dev_id]
|
with LOCK:
|
||||||
if location in regions:
|
regions = REGIONS_ENTERED[dev_id]
|
||||||
regions.remove(location)
|
if location in regions:
|
||||||
new_region = regions[-1] if regions else None
|
regions.remove(location)
|
||||||
|
new_region = regions[-1] if regions else None
|
||||||
|
|
||||||
if new_region:
|
if new_region:
|
||||||
# Exit to previous region
|
# Exit to previous region
|
||||||
zone = hass.states.get("zone.{}".format(new_region))
|
zone = hass.states.get("zone.{}".format(new_region))
|
||||||
if not zone.attributes.get('passive'):
|
if not zone.attributes.get('passive'):
|
||||||
kwargs['location_name'] = new_region
|
kwargs['location_name'] = new_region
|
||||||
_set_gps_from_zone(kwargs, zone)
|
_set_gps_from_zone(kwargs, zone)
|
||||||
_LOGGER.info("Exit from to %s", new_region)
|
_LOGGER.info("Exit to %s", new_region)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
_LOGGER.info("Exit to GPS")
|
_LOGGER.info("Exit to GPS")
|
||||||
|
|
||||||
see(**kwargs)
|
see(**kwargs)
|
||||||
see_beacons(dev_id, kwargs)
|
see_beacons(dev_id, kwargs)
|
||||||
|
|
||||||
beacons = MOBILE_BEACONS_ACTIVE[dev_id]
|
beacons = MOBILE_BEACONS_ACTIVE[dev_id]
|
||||||
if location in beacons:
|
if location in beacons:
|
||||||
beacons.remove(location)
|
beacons.remove(location)
|
||||||
|
_LOGGER.info("Remove beacon %s", location)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
_LOGGER.error(
|
_LOGGER.error(
|
||||||
@ -141,6 +146,8 @@ def setup_scanner(hass, config, see):
|
|||||||
""" Set active beacons to the current location """
|
""" Set active beacons to the current location """
|
||||||
|
|
||||||
kwargs = kwargs_param.copy()
|
kwargs = kwargs_param.copy()
|
||||||
|
# the battery state applies to the tracking device, not the beacon
|
||||||
|
kwargs.pop('battery', None)
|
||||||
for beacon in MOBILE_BEACONS_ACTIVE[dev_id]:
|
for beacon in MOBILE_BEACONS_ACTIVE[dev_id]:
|
||||||
kwargs['dev_id'] = "{}_{}".format(BEACON_DEV_ID, beacon)
|
kwargs['dev_id'] = "{}_{}".format(BEACON_DEV_ID, beacon)
|
||||||
kwargs['host_name'] = beacon
|
kwargs['host_name'] = beacon
|
||||||
|
@ -379,3 +379,36 @@ class TestDeviceTrackerOwnTracks(unittest.TestCase):
|
|||||||
message['lat'] = "4.0"
|
message['lat'] = "4.0"
|
||||||
self.send_message(LOCATION_TOPIC, LOCATION_MESSAGE)
|
self.send_message(LOCATION_TOPIC, LOCATION_MESSAGE)
|
||||||
self.assert_tracker_latitude(3.0)
|
self.assert_tracker_latitude(3.0)
|
||||||
|
|
||||||
|
def test_mobile_multiple_async_enter_exit(self):
|
||||||
|
# Test race condition
|
||||||
|
enter_message = REGION_ENTER_MESSAGE.copy()
|
||||||
|
enter_message['desc'] = IBEACON_DEVICE
|
||||||
|
exit_message = REGION_LEAVE_MESSAGE.copy()
|
||||||
|
exit_message['desc'] = IBEACON_DEVICE
|
||||||
|
|
||||||
|
for i in range(0, 20):
|
||||||
|
fire_mqtt_message(
|
||||||
|
self.hass, EVENT_TOPIC, json.dumps(enter_message))
|
||||||
|
fire_mqtt_message(
|
||||||
|
self.hass, EVENT_TOPIC, json.dumps(exit_message))
|
||||||
|
|
||||||
|
fire_mqtt_message(
|
||||||
|
self.hass, EVENT_TOPIC, json.dumps(enter_message))
|
||||||
|
|
||||||
|
self.hass.pool.block_till_done()
|
||||||
|
self.send_message(EVENT_TOPIC, exit_message)
|
||||||
|
self.assertEqual(owntracks.MOBILE_BEACONS_ACTIVE['greg_phone'], [])
|
||||||
|
|
||||||
|
def test_mobile_multiple_enter_exit(self):
|
||||||
|
# Should only happen if the iphone dies
|
||||||
|
enter_message = REGION_ENTER_MESSAGE.copy()
|
||||||
|
enter_message['desc'] = IBEACON_DEVICE
|
||||||
|
exit_message = REGION_LEAVE_MESSAGE.copy()
|
||||||
|
exit_message['desc'] = IBEACON_DEVICE
|
||||||
|
|
||||||
|
self.send_message(EVENT_TOPIC, enter_message)
|
||||||
|
self.send_message(EVENT_TOPIC, enter_message)
|
||||||
|
self.send_message(EVENT_TOPIC, exit_message)
|
||||||
|
|
||||||
|
self.assertEqual(owntracks.MOBILE_BEACONS_ACTIVE['greg_phone'], [])
|
||||||
|
Loading…
x
Reference in New Issue
Block a user