commit
98c6e56ea4
2 changed files with 898 additions and 0 deletions
282
homeassistant/components/proximity.py
Normal file
282
homeassistant/components/proximity.py
Normal file
|
@ -0,0 +1,282 @@
|
|||
"""
|
||||
custom_components.proximity
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Component to monitor the proximity of devices to a particular zone and the
|
||||
direction of travel. The result is an entity created in HA which maintains
|
||||
the proximity data
|
||||
|
||||
This component is useful to reduce the number of automation rules required
|
||||
when wanting to perform automations based on locations outside a particular
|
||||
zone. The standard HA zone and state based triggers allow similar control
|
||||
but the number of rules grows exponentially when factors such as direction
|
||||
of travel need to be taken into account. Some examples of its use include:
|
||||
- Increase thermostat temperature as you near home
|
||||
- Decrease temperature the further away from home you travel
|
||||
|
||||
The Proximity entity which is created has the following values:
|
||||
state = distance from the monitored zone (in km)
|
||||
dir_of_travel = direction of the closest device to the monitoed zone. Values
|
||||
are:
|
||||
'not set'
|
||||
'arrived'
|
||||
'towards'
|
||||
'away_from'
|
||||
'unknown'
|
||||
'stationary'
|
||||
dist_to_zone = distance from the monitored zone (in km)
|
||||
|
||||
Use configuration.yaml to enable the user to easily tune a number of settings:
|
||||
- Zone: the zone to which this component is measuring the distance to. Default
|
||||
is the home zone
|
||||
- Ignored Zones: where proximity is not calculated for a device (either the
|
||||
device being monitored or ones being compared (e.g. work or school)
|
||||
- Devices: a list of devices to compare location against to check closeness to
|
||||
the configured zone
|
||||
- Tolerance: the tolerance used to calculate the direction of travel in metres
|
||||
(to filter out small GPS co-ordinate changes
|
||||
|
||||
Logging levels debug, info and error are in use
|
||||
|
||||
Example configuration.yaml entry:
|
||||
proximity:
|
||||
zone: home
|
||||
ignored_zones:
|
||||
- twork
|
||||
- elschool
|
||||
devices:
|
||||
- device_tracker.nwaring_nickmobile
|
||||
- device_tracker.eleanorsiphone
|
||||
- device_tracker.tsiphone
|
||||
tolerance: 50
|
||||
"""
|
||||
|
||||
import logging
|
||||
from homeassistant.helpers.event import track_state_change
|
||||
from homeassistant.helpers.entity import Entity
|
||||
from homeassistant.util.location import distance
|
||||
|
||||
DEPENDENCIES = ['zone', 'device_tracker']
|
||||
|
||||
# domain for the component
|
||||
DOMAIN = 'proximity'
|
||||
|
||||
# default tolerance
|
||||
DEFAULT_TOLERANCE = 1
|
||||
|
||||
# default zone
|
||||
DEFAULT_PROXIMITY_ZONE = 'home'
|
||||
|
||||
# entity attributes
|
||||
ATTR_DIST_FROM = 'dist_to_zone'
|
||||
ATTR_DIR_OF_TRAVEL = 'dir_of_travel'
|
||||
ATTR_NEAREST = 'nearest'
|
||||
ATTR_FRIENDLY_NAME = 'friendly_name'
|
||||
|
||||
# Shortcut for the logger
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def setup(hass, config): # pylint: disable=too-many-locals,too-many-statements
|
||||
""" get the zones and offsets from configuration.yaml"""
|
||||
ignored_zones = []
|
||||
if 'ignored_zones' in config[DOMAIN]:
|
||||
for variable in config[DOMAIN]['ignored_zones']:
|
||||
ignored_zones.append(variable)
|
||||
|
||||
# get the devices from configuration.yaml
|
||||
if 'devices' not in config[DOMAIN]:
|
||||
_LOGGER.error('devices not found in config')
|
||||
return False
|
||||
|
||||
proximity_devices = []
|
||||
for variable in config[DOMAIN]['devices']:
|
||||
proximity_devices.append(variable)
|
||||
|
||||
# get the direction of travel tolerance from configuration.yaml
|
||||
tolerance = config[DOMAIN].get('tolerance', DEFAULT_TOLERANCE)
|
||||
|
||||
# get the zone to monitor proximity to from configuration.yaml
|
||||
proximity_zone = config[DOMAIN].get('zone', DEFAULT_PROXIMITY_ZONE)
|
||||
|
||||
entity_id = DOMAIN + '.' + proximity_zone
|
||||
proximity_zone = 'zone.' + proximity_zone
|
||||
|
||||
state = hass.states.get(proximity_zone)
|
||||
zone_friendly_name = (state.name).lower()
|
||||
|
||||
# set the default values
|
||||
dist_to_zone = 'not set'
|
||||
dir_of_travel = 'not set'
|
||||
nearest = 'not set'
|
||||
|
||||
proximity = Proximity(hass, zone_friendly_name, dist_to_zone,
|
||||
dir_of_travel, nearest, ignored_zones,
|
||||
proximity_devices, tolerance, proximity_zone)
|
||||
proximity.entity_id = entity_id
|
||||
|
||||
proximity.update_ha_state()
|
||||
|
||||
# main command to monitor proximity of devices
|
||||
track_state_change(hass, proximity_devices,
|
||||
proximity.check_proximity_state_change)
|
||||
|
||||
# Tells the bootstrapper that the component was successfully initialized
|
||||
return True
|
||||
|
||||
|
||||
class Proximity(Entity): # pylint: disable=too-many-instance-attributes
|
||||
""" Represents a Proximity in Home Assistant. """
|
||||
def __init__(self, hass, zone_friendly_name, dist_to, dir_of_travel,
|
||||
nearest, ignored_zones, proximity_devices, tolerance,
|
||||
proximity_zone):
|
||||
# pylint: disable=too-many-arguments
|
||||
self.hass = hass
|
||||
self.friendly_name = zone_friendly_name
|
||||
self.dist_to = dist_to
|
||||
self.dir_of_travel = dir_of_travel
|
||||
self.nearest = nearest
|
||||
self.ignored_zones = ignored_zones
|
||||
self.proximity_devices = proximity_devices
|
||||
self.tolerance = tolerance
|
||||
self.proximity_zone = proximity_zone
|
||||
|
||||
@property
|
||||
def state(self):
|
||||
return self.dist_to
|
||||
|
||||
@property
|
||||
def unit_of_measurement(self):
|
||||
""" Unit of measurement of this entity """
|
||||
return "km"
|
||||
|
||||
@property
|
||||
def state_attributes(self):
|
||||
return {
|
||||
ATTR_DIR_OF_TRAVEL: self.dir_of_travel,
|
||||
ATTR_NEAREST: self.nearest,
|
||||
ATTR_FRIENDLY_NAME: self.friendly_name
|
||||
}
|
||||
|
||||
def check_proximity_state_change(self, entity, old_state, new_state):
|
||||
# pylint: disable=too-many-branches,too-many-statements,too-many-locals
|
||||
""" Function to perform the proximity checking """
|
||||
entity_name = new_state.name
|
||||
devices_to_calculate = False
|
||||
devices_in_zone = ''
|
||||
|
||||
zone_state = self.hass.states.get(self.proximity_zone)
|
||||
proximity_latitude = zone_state.attributes.get('latitude')
|
||||
proximity_longitude = zone_state.attributes.get('longitude')
|
||||
|
||||
# check for devices in the monitored zone
|
||||
for device in self.proximity_devices:
|
||||
device_state = self.hass.states.get(device)
|
||||
|
||||
if device_state.state not in self.ignored_zones:
|
||||
devices_to_calculate = True
|
||||
|
||||
# check the location of all devices
|
||||
if (device_state.state).lower() == (self.friendly_name).lower():
|
||||
device_friendly = device_state.name
|
||||
if devices_in_zone != '':
|
||||
devices_in_zone = devices_in_zone + ', '
|
||||
devices_in_zone = devices_in_zone + device_friendly
|
||||
|
||||
# no-one to track so reset the entity
|
||||
if not devices_to_calculate:
|
||||
self.dist_to = 'not set'
|
||||
self.dir_of_travel = 'not set'
|
||||
self.nearest = 'not set'
|
||||
self.update_ha_state()
|
||||
return
|
||||
|
||||
# at least one device is in the monitored zone so update the entity
|
||||
if devices_in_zone != '':
|
||||
self.dist_to = 0
|
||||
self.dir_of_travel = 'arrived'
|
||||
self.nearest = devices_in_zone
|
||||
self.update_ha_state()
|
||||
return
|
||||
|
||||
# we can't check proximity because latitude and longitude don't exist
|
||||
if 'latitude' not in new_state.attributes:
|
||||
return
|
||||
|
||||
# collect distances to the zone for all devices
|
||||
distances_to_zone = {}
|
||||
for device in self.proximity_devices:
|
||||
# ignore devices in an ignored zone
|
||||
device_state = self.hass.states.get(device)
|
||||
if device_state.state in self.ignored_zones:
|
||||
continue
|
||||
|
||||
# ignore devices if proximity cannot be calculated
|
||||
if 'latitude' not in device_state.attributes:
|
||||
continue
|
||||
|
||||
# calculate the distance to the proximity zone
|
||||
dist_to_zone = distance(proximity_latitude,
|
||||
proximity_longitude,
|
||||
device_state.attributes['latitude'],
|
||||
device_state.attributes['longitude'])
|
||||
|
||||
# add the device and distance to a dictionary
|
||||
distances_to_zone[device] = round(dist_to_zone / 1000, 1)
|
||||
|
||||
# loop through each of the distances collected and work out the closest
|
||||
closest_device = ''
|
||||
dist_to_zone = 1000000
|
||||
|
||||
for device in distances_to_zone:
|
||||
if distances_to_zone[device] < dist_to_zone:
|
||||
closest_device = device
|
||||
dist_to_zone = distances_to_zone[device]
|
||||
|
||||
# if the closest device is one of the other devices
|
||||
if closest_device != entity:
|
||||
self.dist_to = round(distances_to_zone[closest_device])
|
||||
self.dir_of_travel = 'unknown'
|
||||
device_state = self.hass.states.get(closest_device)
|
||||
self.nearest = device_state.name
|
||||
self.update_ha_state()
|
||||
return
|
||||
|
||||
# stop if we cannot calculate the direction of travel (i.e. we don't
|
||||
# have a previous state and a current LAT and LONG)
|
||||
if old_state is None or 'latitude' not in old_state.attributes:
|
||||
self.dist_to = round(distances_to_zone[entity])
|
||||
self.dir_of_travel = 'unknown'
|
||||
self.nearest = entity_name
|
||||
self.update_ha_state()
|
||||
return
|
||||
|
||||
# reset the variables
|
||||
distance_travelled = 0
|
||||
|
||||
# calculate the distance travelled
|
||||
old_distance = distance(proximity_latitude, proximity_longitude,
|
||||
old_state.attributes['latitude'],
|
||||
old_state.attributes['longitude'])
|
||||
new_distance = distance(proximity_latitude, proximity_longitude,
|
||||
new_state.attributes['latitude'],
|
||||
new_state.attributes['longitude'])
|
||||
distance_travelled = round(new_distance - old_distance, 1)
|
||||
|
||||
# check for tolerance
|
||||
if distance_travelled < self.tolerance * -1:
|
||||
direction_of_travel = 'towards'
|
||||
elif distance_travelled > self.tolerance:
|
||||
direction_of_travel = 'away_from'
|
||||
else:
|
||||
direction_of_travel = 'stationary'
|
||||
|
||||
# update the proximity entity
|
||||
self.dist_to = round(dist_to_zone)
|
||||
self.dir_of_travel = direction_of_travel
|
||||
self.nearest = entity_name
|
||||
self.update_ha_state()
|
||||
_LOGGER.debug('proximity.%s update entity: distance=%s: direction=%s: '
|
||||
'device=%s', self.friendly_name, round(dist_to_zone),
|
||||
direction_of_travel, entity_name)
|
||||
|
||||
_LOGGER.info('%s: proximity calculation complete', entity_name)
|
616
tests/components/test_proximity.py
Normal file
616
tests/components/test_proximity.py
Normal file
|
@ -0,0 +1,616 @@
|
|||
"""
|
||||
tests.components.proximity
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Tests proximity component.
|
||||
"""
|
||||
|
||||
import homeassistant.core as ha
|
||||
from homeassistant.components import proximity
|
||||
|
||||
class TestProximity:
|
||||
""" Test the Proximity component. """
|
||||
|
||||
def setup_method(self, method):
|
||||
self.hass = ha.HomeAssistant()
|
||||
self.hass.states.set(
|
||||
'zone.home', 'zoning',
|
||||
{
|
||||
'name': 'home',
|
||||
'latitude': 2.1,
|
||||
'longitude': 1.1,
|
||||
'radius': 10
|
||||
})
|
||||
|
||||
def teardown_method(self, method):
|
||||
""" Stop down stuff we started. """
|
||||
self.hass.stop()
|
||||
|
||||
def test_proximity(self):
|
||||
assert proximity.setup(self.hass, {
|
||||
'proximity': {
|
||||
'zone': 'home',
|
||||
'ignored_zones': {
|
||||
'work'
|
||||
},
|
||||
'devices': {
|
||||
'device_tracker.test1',
|
||||
'device_tracker.test2'
|
||||
},
|
||||
'tolerance': '1'
|
||||
}
|
||||
})
|
||||
|
||||
state = self.hass.states.get('proximity.home')
|
||||
assert state.state == 'not set'
|
||||
assert state.attributes.get('nearest') == 'not set'
|
||||
assert state.attributes.get('dir_of_travel') == 'not set'
|
||||
|
||||
self.hass.states.set('proximity.home', '0')
|
||||
self.hass.pool.block_till_done()
|
||||
state = self.hass.states.get('proximity.home')
|
||||
assert state.state == '0'
|
||||
|
||||
def test_no_devices_in_config(self):
|
||||
assert not proximity.setup(self.hass, {
|
||||
'proximity': {
|
||||
'zone': 'home',
|
||||
'ignored_zones': {
|
||||
'work'
|
||||
},
|
||||
'tolerance': '1'
|
||||
}
|
||||
})
|
||||
|
||||
def test_no_tolerance_in_config(self):
|
||||
assert proximity.setup(self.hass, {
|
||||
'proximity': {
|
||||
'zone': 'home',
|
||||
'ignored_zones': {
|
||||
'work'
|
||||
},
|
||||
'devices': {
|
||||
'device_tracker.test1',
|
||||
'device_tracker.test2'
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
def test_no_ignored_zones_in_config(self):
|
||||
assert proximity.setup(self.hass, {
|
||||
'proximity': {
|
||||
'zone': 'home',
|
||||
'devices': {
|
||||
'device_tracker.test1',
|
||||
'device_tracker.test2'
|
||||
},
|
||||
'tolerance': '1'
|
||||
}
|
||||
})
|
||||
|
||||
def test_no_zone_in_config(self):
|
||||
assert proximity.setup(self.hass, {
|
||||
'proximity': {
|
||||
'ignored_zones': {
|
||||
'work'
|
||||
},
|
||||
'devices': {
|
||||
'device_tracker.test1',
|
||||
'device_tracker.test2'
|
||||
},
|
||||
'tolerance': '1'
|
||||
}
|
||||
})
|
||||
|
||||
def test_device_tracker_test1_in_zone(self):
|
||||
assert proximity.setup(self.hass, {
|
||||
'proximity': {
|
||||
'zone': 'home',
|
||||
'ignored_zones': {
|
||||
'work'
|
||||
},
|
||||
'devices': {
|
||||
'device_tracker.test1'
|
||||
},
|
||||
'tolerance': '1'
|
||||
}
|
||||
})
|
||||
|
||||
self.hass.states.set(
|
||||
'device_tracker.test1', 'home',
|
||||
{
|
||||
'friendly_name': 'test1',
|
||||
'latitude': 2.1,
|
||||
'longitude': 1.1
|
||||
})
|
||||
self.hass.pool.block_till_done()
|
||||
state = self.hass.states.get('proximity.home')
|
||||
assert state.state == '0'
|
||||
assert state.attributes.get('nearest') == 'test1'
|
||||
assert state.attributes.get('dir_of_travel') == 'arrived'
|
||||
|
||||
def test_device_trackers_in_zone(self):
|
||||
assert proximity.setup(self.hass, {
|
||||
'proximity': {
|
||||
'zone': 'home',
|
||||
'ignored_zones': {
|
||||
'work'
|
||||
},
|
||||
'devices': {
|
||||
'device_tracker.test1',
|
||||
'device_tracker.test2'
|
||||
},
|
||||
'tolerance': '1'
|
||||
}
|
||||
})
|
||||
|
||||
self.hass.states.set(
|
||||
'device_tracker.test1', 'home',
|
||||
{
|
||||
'friendly_name': 'test1',
|
||||
'latitude': 2.1,
|
||||
'longitude': 1.1
|
||||
})
|
||||
self.hass.pool.block_till_done()
|
||||
self.hass.states.set(
|
||||
'device_tracker.test2', 'home',
|
||||
{
|
||||
'friendly_name': 'test2',
|
||||
'latitude': 2.1,
|
||||
'longitude': 1.1
|
||||
})
|
||||
self.hass.pool.block_till_done()
|
||||
state = self.hass.states.get('proximity.home')
|
||||
assert state.state == '0'
|
||||
assert (state.attributes.get('nearest') == 'test1, test2') or (state.attributes.get('nearest') == 'test2, test1')
|
||||
assert state.attributes.get('dir_of_travel') == 'arrived'
|
||||
|
||||
def test_device_tracker_test1_away(self):
|
||||
assert proximity.setup(self.hass, {
|
||||
'proximity': {
|
||||
'zone': 'home',
|
||||
'ignored_zones': {
|
||||
'work'
|
||||
},
|
||||
'devices': {
|
||||
'device_tracker.test1'
|
||||
},
|
||||
'tolerance': '1'
|
||||
}
|
||||
})
|
||||
|
||||
self.hass.states.set(
|
||||
'device_tracker.test1', 'not_home',
|
||||
{
|
||||
'friendly_name': 'test1',
|
||||
'latitude': 20.1,
|
||||
'longitude': 10.1
|
||||
})
|
||||
self.hass.pool.block_till_done()
|
||||
state = self.hass.states.get('proximity.home')
|
||||
assert state.attributes.get('nearest') == 'test1'
|
||||
assert state.attributes.get('dir_of_travel') == 'unknown'
|
||||
|
||||
def test_device_tracker_test1_awayfurther(self):
|
||||
assert proximity.setup(self.hass, {
|
||||
'proximity': {
|
||||
'zone': 'home',
|
||||
'ignored_zones': {
|
||||
'work'
|
||||
},
|
||||
'devices': {
|
||||
'device_tracker.test1'
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
self.hass.states.set(
|
||||
'device_tracker.test1', 'not_home',
|
||||
{
|
||||
'friendly_name': 'test1',
|
||||
'latitude': 20.1,
|
||||
'longitude': 10.1
|
||||
})
|
||||
self.hass.pool.block_till_done()
|
||||
state = self.hass.states.get('proximity.home')
|
||||
assert state.attributes.get('nearest') == 'test1'
|
||||
assert state.attributes.get('dir_of_travel') == 'unknown'
|
||||
self.hass.states.set(
|
||||
'device_tracker.test1', 'not_home',
|
||||
{
|
||||
'friendly_name': 'test1',
|
||||
'latitude': 40.1,
|
||||
'longitude': 20.1
|
||||
})
|
||||
self.hass.pool.block_till_done()
|
||||
state = self.hass.states.get('proximity.home')
|
||||
assert state.attributes.get('nearest') == 'test1'
|
||||
assert state.attributes.get('dir_of_travel') == 'away_from'
|
||||
|
||||
def test_device_tracker_test1_awaycloser(self):
|
||||
assert proximity.setup(self.hass, {
|
||||
'proximity': {
|
||||
'zone': 'home',
|
||||
'ignored_zones': {
|
||||
'work'
|
||||
},
|
||||
'devices': {
|
||||
'device_tracker.test1'
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
self.hass.states.set(
|
||||
'device_tracker.test1', 'not_home',
|
||||
{
|
||||
'friendly_name': 'test1',
|
||||
'latitude': 40.1,
|
||||
'longitude': 20.1
|
||||
})
|
||||
self.hass.pool.block_till_done()
|
||||
state = self.hass.states.get('proximity.home')
|
||||
assert state.attributes.get('nearest') == 'test1'
|
||||
assert state.attributes.get('dir_of_travel') == 'unknown'
|
||||
self.hass.states.set(
|
||||
'device_tracker.test1', 'not_home',
|
||||
{
|
||||
'friendly_name': 'test1',
|
||||
'latitude': 20.1,
|
||||
'longitude': 10.1
|
||||
})
|
||||
self.hass.pool.block_till_done()
|
||||
state = self.hass.states.get('proximity.home')
|
||||
assert state.attributes.get('nearest') == 'test1'
|
||||
assert state.attributes.get('dir_of_travel') == 'towards'
|
||||
|
||||
def test_all_device_trackers_in_ignored_zone(self):
|
||||
assert proximity.setup(self.hass, {
|
||||
'proximity': {
|
||||
'zone': 'home',
|
||||
'ignored_zones': {
|
||||
'work'
|
||||
},
|
||||
'devices': {
|
||||
'device_tracker.test1'
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
self.hass.states.set(
|
||||
'device_tracker.test1', 'work',
|
||||
{
|
||||
'friendly_name': 'test1'
|
||||
})
|
||||
self.hass.pool.block_till_done()
|
||||
state = self.hass.states.get('proximity.home')
|
||||
assert state.state == 'not set'
|
||||
assert state.attributes.get('nearest') == 'not set'
|
||||
assert state.attributes.get('dir_of_travel') == 'not set'
|
||||
|
||||
def test_device_tracker_test1_no_coordinates(self):
|
||||
assert proximity.setup(self.hass, {
|
||||
'proximity': {
|
||||
'zone': 'home',
|
||||
'ignored_zones': {
|
||||
'work'
|
||||
},
|
||||
'devices': {
|
||||
'device_tracker.test1'
|
||||
},
|
||||
'tolerance': '1'
|
||||
}
|
||||
})
|
||||
|
||||
self.hass.states.set(
|
||||
'device_tracker.test1', 'not_home',
|
||||
{
|
||||
'friendly_name': 'test1'
|
||||
})
|
||||
self.hass.pool.block_till_done()
|
||||
state = self.hass.states.get('proximity.home')
|
||||
assert state.attributes.get('nearest') == 'not set'
|
||||
assert state.attributes.get('dir_of_travel') == 'not set'
|
||||
|
||||
def test_device_tracker_test1_awayfurther_than_test2_first_test1(self):
|
||||
self.hass.states.set(
|
||||
'device_tracker.test1', 'not_home',
|
||||
{
|
||||
'friendly_name': 'test1'
|
||||
})
|
||||
self.hass.pool.block_till_done()
|
||||
self.hass.states.set(
|
||||
'device_tracker.test2', 'not_home',
|
||||
{
|
||||
'friendly_name': 'test2'
|
||||
})
|
||||
self.hass.pool.block_till_done()
|
||||
assert proximity.setup(self.hass, {
|
||||
'proximity': {
|
||||
'zone': 'home',
|
||||
'ignored_zones': {
|
||||
'work'
|
||||
},
|
||||
'devices': {
|
||||
'device_tracker.test1',
|
||||
'device_tracker.test2'
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
self.hass.states.set(
|
||||
'device_tracker.test1', 'not_home',
|
||||
{
|
||||
'friendly_name': 'test1',
|
||||
'latitude': 20.1,
|
||||
'longitude': 10.1
|
||||
})
|
||||
self.hass.pool.block_till_done()
|
||||
state = self.hass.states.get('proximity.home')
|
||||
assert state.attributes.get('nearest') == 'test1'
|
||||
assert state.attributes.get('dir_of_travel') == 'unknown'
|
||||
self.hass.states.set(
|
||||
'device_tracker.test2', 'not_home',
|
||||
{
|
||||
'friendly_name': 'test2',
|
||||
'latitude': 40.1,
|
||||
'longitude': 20.1
|
||||
})
|
||||
self.hass.pool.block_till_done()
|
||||
state = self.hass.states.get('proximity.home')
|
||||
assert state.attributes.get('nearest') == 'test1'
|
||||
assert state.attributes.get('dir_of_travel') == 'unknown'
|
||||
|
||||
def test_device_tracker_test1_awayfurther_than_test2_first_test2(self):
|
||||
self.hass.states.set(
|
||||
'device_tracker.test1', 'not_home',
|
||||
{
|
||||
'friendly_name': 'test1'
|
||||
})
|
||||
self.hass.pool.block_till_done()
|
||||
self.hass.states.set(
|
||||
'device_tracker.test2', 'not_home',
|
||||
{
|
||||
'friendly_name': 'test2'
|
||||
})
|
||||
self.hass.pool.block_till_done()
|
||||
assert proximity.setup(self.hass, {
|
||||
'proximity': {
|
||||
'zone': 'home',
|
||||
'ignored_zones': {
|
||||
'work'
|
||||
},
|
||||
'devices': {
|
||||
'device_tracker.test1',
|
||||
'device_tracker.test2'
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
self.hass.states.set(
|
||||
'device_tracker.test2', 'not_home',
|
||||
{
|
||||
'friendly_name': 'test2',
|
||||
'latitude': 40.1,
|
||||
'longitude': 20.1
|
||||
})
|
||||
self.hass.pool.block_till_done()
|
||||
state = self.hass.states.get('proximity.home')
|
||||
assert state.attributes.get('nearest') == 'test2'
|
||||
assert state.attributes.get('dir_of_travel') == 'unknown'
|
||||
self.hass.states.set(
|
||||
'device_tracker.test1', 'not_home',
|
||||
{
|
||||
'friendly_name': 'test1',
|
||||
'latitude': 20.1,
|
||||
'longitude': 10.1
|
||||
})
|
||||
self.hass.pool.block_till_done()
|
||||
state = self.hass.states.get('proximity.home')
|
||||
assert state.attributes.get('nearest') == 'test1'
|
||||
assert state.attributes.get('dir_of_travel') == 'unknown'
|
||||
|
||||
def test_device_tracker_test1_awayfurther_test2_in_ignored_zone(self):
|
||||
self.hass.states.set(
|
||||
'device_tracker.test1', 'not_home',
|
||||
{
|
||||
'friendly_name': 'test1'
|
||||
})
|
||||
self.hass.pool.block_till_done()
|
||||
self.hass.states.set(
|
||||
'device_tracker.test2', 'work',
|
||||
{
|
||||
'friendly_name': 'test2'
|
||||
})
|
||||
self.hass.pool.block_till_done()
|
||||
assert proximity.setup(self.hass, {
|
||||
'proximity': {
|
||||
'zone': 'home',
|
||||
'ignored_zones': {
|
||||
'work'
|
||||
},
|
||||
'devices': {
|
||||
'device_tracker.test1',
|
||||
'device_tracker.test2'
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
self.hass.states.set(
|
||||
'device_tracker.test1', 'not_home',
|
||||
{
|
||||
'friendly_name': 'test1',
|
||||
'latitude': 20.1,
|
||||
'longitude': 10.1
|
||||
})
|
||||
self.hass.pool.block_till_done()
|
||||
state = self.hass.states.get('proximity.home')
|
||||
assert state.attributes.get('nearest') == 'test1'
|
||||
assert state.attributes.get('dir_of_travel') == 'unknown'
|
||||
|
||||
def test_device_tracker_test1_awayfurther_than_test2_first_test1_than_test2_than_test1(self):
|
||||
self.hass.states.set(
|
||||
'device_tracker.test1', 'not_home',
|
||||
{
|
||||
'friendly_name': 'test1'
|
||||
})
|
||||
self.hass.pool.block_till_done()
|
||||
self.hass.states.set(
|
||||
'device_tracker.test2', 'not_home',
|
||||
{
|
||||
'friendly_name': 'test2'
|
||||
})
|
||||
self.hass.pool.block_till_done()
|
||||
assert proximity.setup(self.hass, {
|
||||
'proximity': {
|
||||
'zone': 'home',
|
||||
'ignored_zones': {
|
||||
'work'
|
||||
},
|
||||
'devices': {
|
||||
'device_tracker.test1',
|
||||
'device_tracker.test2'
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
self.hass.states.set(
|
||||
'device_tracker.test1', 'not_home',
|
||||
{
|
||||
'friendly_name': 'test1',
|
||||
'latitude': 10.1,
|
||||
'longitude': 5.1
|
||||
})
|
||||
self.hass.pool.block_till_done()
|
||||
|
||||
self.hass.states.set(
|
||||
'device_tracker.test2', 'not_home',
|
||||
{
|
||||
'friendly_name': 'test2',
|
||||
'latitude': 20.1,
|
||||
'longitude': 10.1
|
||||
})
|
||||
self.hass.pool.block_till_done()
|
||||
self.hass.states.set(
|
||||
'device_tracker.test1', 'not_home',
|
||||
{
|
||||
'friendly_name': 'test1',
|
||||
'latitude': 40.1,
|
||||
'longitude': 20.1
|
||||
})
|
||||
self.hass.pool.block_till_done()
|
||||
self.hass.states.set(
|
||||
'device_tracker.test1', 'not_home',
|
||||
{
|
||||
'friendly_name': 'test1',
|
||||
'latitude': 35.1,
|
||||
'longitude': 15.1
|
||||
})
|
||||
self.hass.pool.block_till_done()
|
||||
self.hass.states.set(
|
||||
'device_tracker.test1', 'work',
|
||||
{
|
||||
'friendly_name': 'test1'
|
||||
})
|
||||
self.hass.pool.block_till_done()
|
||||
state = self.hass.states.get('proximity.home')
|
||||
assert state.attributes.get('nearest') == 'test2'
|
||||
assert state.attributes.get('dir_of_travel') == 'unknown'
|
||||
|
||||
def test_device_tracker_test1_awayfurther_a_bit(self):
|
||||
assert proximity.setup(self.hass, {
|
||||
'proximity': {
|
||||
'zone': 'home',
|
||||
'ignored_zones': {
|
||||
'work'
|
||||
},
|
||||
'devices': {
|
||||
'device_tracker.test1'
|
||||
},
|
||||
'tolerance': 1000
|
||||
}
|
||||
})
|
||||
|
||||
self.hass.states.set(
|
||||
'device_tracker.test1', 'not_home',
|
||||
{
|
||||
'friendly_name': 'test1',
|
||||
'latitude': 20.1000001,
|
||||
'longitude': 10.1000001
|
||||
})
|
||||
self.hass.pool.block_till_done()
|
||||
state = self.hass.states.get('proximity.home')
|
||||
assert state.attributes.get('nearest') == 'test1'
|
||||
assert state.attributes.get('dir_of_travel') == 'unknown'
|
||||
self.hass.states.set(
|
||||
'device_tracker.test1', 'not_home',
|
||||
{
|
||||
'friendly_name': 'test1',
|
||||
'latitude': 20.1000002,
|
||||
'longitude': 10.1000002
|
||||
})
|
||||
self.hass.pool.block_till_done()
|
||||
state = self.hass.states.get('proximity.home')
|
||||
assert state.attributes.get('nearest') == 'test1'
|
||||
assert state.attributes.get('dir_of_travel') == 'stationary'
|
||||
|
||||
def test_device_tracker_test1_nearest_after_test2_in_ignored_zone(self):
|
||||
self.hass.states.set(
|
||||
'device_tracker.test1', 'not_home',
|
||||
{
|
||||
'friendly_name': 'test1'
|
||||
})
|
||||
self.hass.pool.block_till_done()
|
||||
self.hass.states.set(
|
||||
'device_tracker.test2', 'not_home',
|
||||
{
|
||||
'friendly_name': 'test2'
|
||||
})
|
||||
self.hass.pool.block_till_done()
|
||||
assert proximity.setup(self.hass, {
|
||||
'proximity': {
|
||||
'zone': 'home',
|
||||
'ignored_zones': {
|
||||
'work'
|
||||
},
|
||||
'devices': {
|
||||
'device_tracker.test1',
|
||||
'device_tracker.test2'
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
self.hass.states.set(
|
||||
'device_tracker.test1', 'not_home',
|
||||
{
|
||||
'friendly_name': 'test1',
|
||||
'latitude': 20.1,
|
||||
'longitude': 10.1
|
||||
})
|
||||
self.hass.pool.block_till_done()
|
||||
state = self.hass.states.get('proximity.home')
|
||||
assert state.attributes.get('nearest') == 'test1'
|
||||
assert state.attributes.get('dir_of_travel') == 'unknown'
|
||||
|
||||
self.hass.states.set(
|
||||
'device_tracker.test2', 'not_home',
|
||||
{
|
||||
'friendly_name': 'test2',
|
||||
'latitude': 10.1,
|
||||
'longitude': 5.1
|
||||
})
|
||||
self.hass.pool.block_till_done()
|
||||
state = self.hass.states.get('proximity.home')
|
||||
assert state.attributes.get('nearest') == 'test2'
|
||||
assert state.attributes.get('dir_of_travel') == 'unknown'
|
||||
|
||||
self.hass.states.set(
|
||||
'device_tracker.test2', 'work',
|
||||
{
|
||||
'friendly_name': 'test2',
|
||||
'latitude': 12.6,
|
||||
'longitude': 7.6
|
||||
})
|
||||
self.hass.pool.block_till_done()
|
||||
state = self.hass.states.get('proximity.home')
|
||||
assert state.attributes.get('nearest') == 'test1'
|
||||
assert state.attributes.get('dir_of_travel') == 'unknown'
|
Loading…
Add table
Add a link
Reference in a new issue