mirror of
https://github.com/home-assistant/core.git
synced 2025-07-25 06:07:17 +00:00
Migrate geofency over to the Webhook component (#18951)
* Migrate geofency over to the Webhook component * Return web.Response correctly * Fix test * Lint * Fix error that tests caught
This commit is contained in:
parent
23382ab199
commit
2bdbf6955d
18
homeassistant/components/geofency/.translations/en.json
Normal file
18
homeassistant/components/geofency/.translations/en.json
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"config": {
|
||||||
|
"title": "Geofency Webhook",
|
||||||
|
"step": {
|
||||||
|
"user": {
|
||||||
|
"title": "Set up the Geofency Webhook",
|
||||||
|
"description": "Are you sure you want to set up the Geofency Webhook?"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"abort": {
|
||||||
|
"one_instance_allowed": "Only a single instance is necessary.",
|
||||||
|
"not_internet_accessible": "Your Home Assistant instance needs to be accessible from the internet to receive messages from Geofency."
|
||||||
|
},
|
||||||
|
"create_entry": {
|
||||||
|
"default": "To send events to Home Assistant, you will need to setup the webhook feature in Geofency.\n\nFill in the following info:\n\n- URL: `{webhook_url}`\n- Method: POST\n\nSee [the documentation]({docs_url}) for further details."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -7,11 +7,12 @@ https://home-assistant.io/components/geofency/
|
|||||||
import logging
|
import logging
|
||||||
|
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
from aiohttp import web
|
||||||
|
|
||||||
import homeassistant.helpers.config_validation as cv
|
import homeassistant.helpers.config_validation as cv
|
||||||
from homeassistant.components.http import HomeAssistantView
|
|
||||||
from homeassistant.const import HTTP_UNPROCESSABLE_ENTITY, STATE_NOT_HOME, \
|
from homeassistant.const import HTTP_UNPROCESSABLE_ENTITY, STATE_NOT_HOME, \
|
||||||
ATTR_LATITUDE, ATTR_LONGITUDE
|
ATTR_LATITUDE, ATTR_LONGITUDE, CONF_WEBHOOK_ID, HTTP_OK
|
||||||
|
from homeassistant.helpers import config_entry_flow
|
||||||
from homeassistant.helpers.discovery import async_load_platform
|
from homeassistant.helpers.discovery import async_load_platform
|
||||||
from homeassistant.helpers.dispatcher import async_dispatcher_send
|
from homeassistant.helpers.dispatcher import async_dispatcher_send
|
||||||
from homeassistant.util import slugify
|
from homeassistant.util import slugify
|
||||||
@ -19,7 +20,7 @@ from homeassistant.util import slugify
|
|||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
DOMAIN = 'geofency'
|
DOMAIN = 'geofency'
|
||||||
DEPENDENCIES = ['http']
|
DEPENDENCIES = ['webhook']
|
||||||
|
|
||||||
CONF_MOBILE_BEACONS = 'mobile_beacons'
|
CONF_MOBILE_BEACONS = 'mobile_beacons'
|
||||||
|
|
||||||
@ -40,8 +41,6 @@ BEACON_DEV_PREFIX = 'beacon'
|
|||||||
LOCATION_ENTRY = '1'
|
LOCATION_ENTRY = '1'
|
||||||
LOCATION_EXIT = '0'
|
LOCATION_EXIT = '0'
|
||||||
|
|
||||||
URL = '/api/geofency'
|
|
||||||
|
|
||||||
TRACKER_UPDATE = '{}_tracker_update'.format(DOMAIN)
|
TRACKER_UPDATE = '{}_tracker_update'.format(DOMAIN)
|
||||||
|
|
||||||
|
|
||||||
@ -50,7 +49,6 @@ async def async_setup(hass, hass_config):
|
|||||||
config = hass_config[DOMAIN]
|
config = hass_config[DOMAIN]
|
||||||
mobile_beacons = config[CONF_MOBILE_BEACONS]
|
mobile_beacons = config[CONF_MOBILE_BEACONS]
|
||||||
hass.data[DOMAIN] = [slugify(beacon) for beacon in mobile_beacons]
|
hass.data[DOMAIN] = [slugify(beacon) for beacon in mobile_beacons]
|
||||||
hass.http.register_view(GeofencyView(hass.data[DOMAIN]))
|
|
||||||
|
|
||||||
hass.async_create_task(
|
hass.async_create_task(
|
||||||
async_load_platform(hass, 'device_tracker', DOMAIN, {}, hass_config)
|
async_load_platform(hass, 'device_tracker', DOMAIN, {}, hass_config)
|
||||||
@ -58,89 +56,106 @@ async def async_setup(hass, hass_config):
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
class GeofencyView(HomeAssistantView):
|
async def handle_webhook(hass, webhook_id, request):
|
||||||
"""View to handle Geofency requests."""
|
"""Handle incoming webhook with Mailgun inbound messages."""
|
||||||
|
data = _validate_data(await request.post())
|
||||||
|
|
||||||
url = URL
|
if not data:
|
||||||
name = 'api:geofency'
|
return web.Response(
|
||||||
|
body="Invalid data",
|
||||||
def __init__(self, mobile_beacons):
|
status=HTTP_UNPROCESSABLE_ENTITY
|
||||||
"""Initialize Geofency url endpoints."""
|
|
||||||
self.mobile_beacons = mobile_beacons
|
|
||||||
|
|
||||||
async def post(self, request):
|
|
||||||
"""Handle Geofency requests."""
|
|
||||||
data = await request.post()
|
|
||||||
hass = request.app['hass']
|
|
||||||
|
|
||||||
data = self._validate_data(data)
|
|
||||||
if not data:
|
|
||||||
return "Invalid data", HTTP_UNPROCESSABLE_ENTITY
|
|
||||||
|
|
||||||
if self._is_mobile_beacon(data):
|
|
||||||
return await self._set_location(hass, data, None)
|
|
||||||
if data['entry'] == LOCATION_ENTRY:
|
|
||||||
location_name = data['name']
|
|
||||||
else:
|
|
||||||
location_name = STATE_NOT_HOME
|
|
||||||
if ATTR_CURRENT_LATITUDE in data:
|
|
||||||
data[ATTR_LATITUDE] = data[ATTR_CURRENT_LATITUDE]
|
|
||||||
data[ATTR_LONGITUDE] = data[ATTR_CURRENT_LONGITUDE]
|
|
||||||
|
|
||||||
return await self._set_location(hass, data, location_name)
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def _validate_data(data):
|
|
||||||
"""Validate POST payload."""
|
|
||||||
data = data.copy()
|
|
||||||
|
|
||||||
required_attributes = ['address', 'device', 'entry',
|
|
||||||
'latitude', 'longitude', 'name']
|
|
||||||
|
|
||||||
valid = True
|
|
||||||
for attribute in required_attributes:
|
|
||||||
if attribute not in data:
|
|
||||||
valid = False
|
|
||||||
_LOGGER.error("'%s' not specified in message", attribute)
|
|
||||||
|
|
||||||
if not valid:
|
|
||||||
return {}
|
|
||||||
|
|
||||||
data['address'] = data['address'].replace('\n', ' ')
|
|
||||||
data['device'] = slugify(data['device'])
|
|
||||||
data['name'] = slugify(data['name'])
|
|
||||||
|
|
||||||
gps_attributes = [ATTR_LATITUDE, ATTR_LONGITUDE,
|
|
||||||
ATTR_CURRENT_LATITUDE, ATTR_CURRENT_LONGITUDE]
|
|
||||||
|
|
||||||
for attribute in gps_attributes:
|
|
||||||
if attribute in data:
|
|
||||||
data[attribute] = float(data[attribute])
|
|
||||||
|
|
||||||
return data
|
|
||||||
|
|
||||||
def _is_mobile_beacon(self, data):
|
|
||||||
"""Check if we have a mobile beacon."""
|
|
||||||
return 'beaconUUID' in data and data['name'] in self.mobile_beacons
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def _device_name(data):
|
|
||||||
"""Return name of device tracker."""
|
|
||||||
if 'beaconUUID' in data:
|
|
||||||
return "{}_{}".format(BEACON_DEV_PREFIX, data['name'])
|
|
||||||
return data['device']
|
|
||||||
|
|
||||||
async def _set_location(self, hass, data, location_name):
|
|
||||||
"""Fire HA event to set location."""
|
|
||||||
device = self._device_name(data)
|
|
||||||
|
|
||||||
async_dispatcher_send(
|
|
||||||
hass,
|
|
||||||
TRACKER_UPDATE,
|
|
||||||
device,
|
|
||||||
(data[ATTR_LATITUDE], data[ATTR_LONGITUDE]),
|
|
||||||
location_name,
|
|
||||||
data
|
|
||||||
)
|
)
|
||||||
|
|
||||||
return "Setting location for {}".format(device)
|
if _is_mobile_beacon(data, hass.data[DOMAIN]):
|
||||||
|
return _set_location(hass, data, None)
|
||||||
|
if data['entry'] == LOCATION_ENTRY:
|
||||||
|
location_name = data['name']
|
||||||
|
else:
|
||||||
|
location_name = STATE_NOT_HOME
|
||||||
|
if ATTR_CURRENT_LATITUDE in data:
|
||||||
|
data[ATTR_LATITUDE] = data[ATTR_CURRENT_LATITUDE]
|
||||||
|
data[ATTR_LONGITUDE] = data[ATTR_CURRENT_LONGITUDE]
|
||||||
|
|
||||||
|
return _set_location(hass, data, location_name)
|
||||||
|
|
||||||
|
|
||||||
|
def _validate_data(data):
|
||||||
|
"""Validate POST payload."""
|
||||||
|
data = data.copy()
|
||||||
|
|
||||||
|
required_attributes = ['address', 'device', 'entry',
|
||||||
|
'latitude', 'longitude', 'name']
|
||||||
|
|
||||||
|
valid = True
|
||||||
|
for attribute in required_attributes:
|
||||||
|
if attribute not in data:
|
||||||
|
valid = False
|
||||||
|
_LOGGER.error("'%s' not specified in message", attribute)
|
||||||
|
|
||||||
|
if not valid:
|
||||||
|
return {}
|
||||||
|
|
||||||
|
data['address'] = data['address'].replace('\n', ' ')
|
||||||
|
data['device'] = slugify(data['device'])
|
||||||
|
data['name'] = slugify(data['name'])
|
||||||
|
|
||||||
|
gps_attributes = [ATTR_LATITUDE, ATTR_LONGITUDE,
|
||||||
|
ATTR_CURRENT_LATITUDE, ATTR_CURRENT_LONGITUDE]
|
||||||
|
|
||||||
|
for attribute in gps_attributes:
|
||||||
|
if attribute in data:
|
||||||
|
data[attribute] = float(data[attribute])
|
||||||
|
|
||||||
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
def _is_mobile_beacon(data, mobile_beacons):
|
||||||
|
"""Check if we have a mobile beacon."""
|
||||||
|
return 'beaconUUID' in data and data['name'] in mobile_beacons
|
||||||
|
|
||||||
|
|
||||||
|
def _device_name(data):
|
||||||
|
"""Return name of device tracker."""
|
||||||
|
if 'beaconUUID' in data:
|
||||||
|
return "{}_{}".format(BEACON_DEV_PREFIX, data['name'])
|
||||||
|
return data['device']
|
||||||
|
|
||||||
|
|
||||||
|
def _set_location(hass, data, location_name):
|
||||||
|
"""Fire HA event to set location."""
|
||||||
|
device = _device_name(data)
|
||||||
|
|
||||||
|
async_dispatcher_send(
|
||||||
|
hass,
|
||||||
|
TRACKER_UPDATE,
|
||||||
|
device,
|
||||||
|
(data[ATTR_LATITUDE], data[ATTR_LONGITUDE]),
|
||||||
|
location_name,
|
||||||
|
data
|
||||||
|
)
|
||||||
|
|
||||||
|
return web.Response(
|
||||||
|
body="Setting location for {}".format(device),
|
||||||
|
status=HTTP_OK
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
async def async_setup_entry(hass, entry):
|
||||||
|
"""Configure based on config entry."""
|
||||||
|
hass.components.webhook.async_register(
|
||||||
|
DOMAIN, 'Geofency', entry.data[CONF_WEBHOOK_ID], handle_webhook)
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
async def async_unload_entry(hass, entry):
|
||||||
|
"""Unload a config entry."""
|
||||||
|
hass.components.webhook.async_unregister(entry.data[CONF_WEBHOOK_ID])
|
||||||
|
return True
|
||||||
|
|
||||||
|
config_entry_flow.register_webhook_flow(
|
||||||
|
DOMAIN,
|
||||||
|
'Geofency Webhook',
|
||||||
|
{
|
||||||
|
'docs_url': 'https://www.home-assistant.io/components/geofency/'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
18
homeassistant/components/geofency/strings.json
Normal file
18
homeassistant/components/geofency/strings.json
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"config": {
|
||||||
|
"title": "Geofency Webhook",
|
||||||
|
"step": {
|
||||||
|
"user": {
|
||||||
|
"title": "Set up the Geofency Webhook",
|
||||||
|
"description": "Are you sure you want to set up the Geofency Webhook?"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"abort": {
|
||||||
|
"one_instance_allowed": "Only a single instance is necessary.",
|
||||||
|
"not_internet_accessible": "Your Home Assistant instance needs to be accessible from the internet to receive messages from Geofency."
|
||||||
|
},
|
||||||
|
"create_entry": {
|
||||||
|
"default": "To send events to Home Assistant, you will need to setup the webhook feature in Geofency.\n\nFill in the following info:\n\n- URL: `{webhook_url}`\n- Method: POST\n\nSee [the documentation]({docs_url}) for further details."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -140,6 +140,7 @@ FLOWS = [
|
|||||||
'deconz',
|
'deconz',
|
||||||
'dialogflow',
|
'dialogflow',
|
||||||
'esphome',
|
'esphome',
|
||||||
|
'geofency',
|
||||||
'hangouts',
|
'hangouts',
|
||||||
'homematicip_cloud',
|
'homematicip_cloud',
|
||||||
'hue',
|
'hue',
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
"""The tests for the Geofency device tracker platform."""
|
"""The tests for the Geofency device tracker platform."""
|
||||||
# pylint: disable=redefined-outer-name
|
# pylint: disable=redefined-outer-name
|
||||||
from unittest.mock import patch
|
from unittest.mock import patch, Mock
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
|
from homeassistant import data_entry_flow
|
||||||
from homeassistant.components import zone
|
from homeassistant.components import zone
|
||||||
from homeassistant.components.geofency import (
|
from homeassistant.components.geofency import (
|
||||||
CONF_MOBILE_BEACONS, URL, DOMAIN)
|
CONF_MOBILE_BEACONS, DOMAIN)
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
HTTP_OK, HTTP_UNPROCESSABLE_ENTITY, STATE_HOME,
|
HTTP_OK, HTTP_UNPROCESSABLE_ENTITY, STATE_HOME,
|
||||||
STATE_NOT_HOME)
|
STATE_NOT_HOME)
|
||||||
@ -113,6 +114,9 @@ def mock_dev_track(mock_device_tracker_conf):
|
|||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def geofency_client(loop, hass, hass_client):
|
def geofency_client(loop, hass, hass_client):
|
||||||
"""Geofency mock client."""
|
"""Geofency mock client."""
|
||||||
|
assert loop.run_until_complete(async_setup_component(
|
||||||
|
hass, 'persistent_notification', {}))
|
||||||
|
|
||||||
assert loop.run_until_complete(async_setup_component(
|
assert loop.run_until_complete(async_setup_component(
|
||||||
hass, DOMAIN, {
|
hass, DOMAIN, {
|
||||||
DOMAIN: {
|
DOMAIN: {
|
||||||
@ -138,10 +142,28 @@ def setup_zones(loop, hass):
|
|||||||
}}))
|
}}))
|
||||||
|
|
||||||
|
|
||||||
async def test_data_validation(geofency_client):
|
@pytest.fixture
|
||||||
|
async def webhook_id(hass, geofency_client):
|
||||||
|
"""Initialize the Geofency component and get the webhook_id."""
|
||||||
|
hass.config.api = Mock(base_url='http://example.com')
|
||||||
|
result = await hass.config_entries.flow.async_init('geofency', context={
|
||||||
|
'source': 'user'
|
||||||
|
})
|
||||||
|
assert result['type'] == data_entry_flow.RESULT_TYPE_FORM, result
|
||||||
|
|
||||||
|
result = await hass.config_entries.flow.async_configure(
|
||||||
|
result['flow_id'], {})
|
||||||
|
assert result['type'] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
|
||||||
|
|
||||||
|
return result['result'].data['webhook_id']
|
||||||
|
|
||||||
|
|
||||||
|
async def test_data_validation(geofency_client, webhook_id):
|
||||||
"""Test data validation."""
|
"""Test data validation."""
|
||||||
|
url = '/api/webhook/{}'.format(webhook_id)
|
||||||
|
|
||||||
# No data
|
# No data
|
||||||
req = await geofency_client.post(URL)
|
req = await geofency_client.post(url)
|
||||||
assert req.status == HTTP_UNPROCESSABLE_ENTITY
|
assert req.status == HTTP_UNPROCESSABLE_ENTITY
|
||||||
|
|
||||||
missing_attributes = ['address', 'device',
|
missing_attributes = ['address', 'device',
|
||||||
@ -151,14 +173,16 @@ async def test_data_validation(geofency_client):
|
|||||||
for attribute in missing_attributes:
|
for attribute in missing_attributes:
|
||||||
copy = GPS_ENTER_HOME.copy()
|
copy = GPS_ENTER_HOME.copy()
|
||||||
del copy[attribute]
|
del copy[attribute]
|
||||||
req = await geofency_client.post(URL, data=copy)
|
req = await geofency_client.post(url, data=copy)
|
||||||
assert req.status == HTTP_UNPROCESSABLE_ENTITY
|
assert req.status == HTTP_UNPROCESSABLE_ENTITY
|
||||||
|
|
||||||
|
|
||||||
async def test_gps_enter_and_exit_home(hass, geofency_client):
|
async def test_gps_enter_and_exit_home(hass, geofency_client, webhook_id):
|
||||||
"""Test GPS based zone enter and exit."""
|
"""Test GPS based zone enter and exit."""
|
||||||
|
url = '/api/webhook/{}'.format(webhook_id)
|
||||||
|
|
||||||
# Enter the Home zone
|
# Enter the Home zone
|
||||||
req = await geofency_client.post(URL, data=GPS_ENTER_HOME)
|
req = await geofency_client.post(url, data=GPS_ENTER_HOME)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
assert req.status == HTTP_OK
|
assert req.status == HTTP_OK
|
||||||
device_name = slugify(GPS_ENTER_HOME['device'])
|
device_name = slugify(GPS_ENTER_HOME['device'])
|
||||||
@ -167,7 +191,7 @@ async def test_gps_enter_and_exit_home(hass, geofency_client):
|
|||||||
assert STATE_HOME == state_name
|
assert STATE_HOME == state_name
|
||||||
|
|
||||||
# Exit the Home zone
|
# Exit the Home zone
|
||||||
req = await geofency_client.post(URL, data=GPS_EXIT_HOME)
|
req = await geofency_client.post(url, data=GPS_EXIT_HOME)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
assert req.status == HTTP_OK
|
assert req.status == HTTP_OK
|
||||||
device_name = slugify(GPS_EXIT_HOME['device'])
|
device_name = slugify(GPS_EXIT_HOME['device'])
|
||||||
@ -180,7 +204,7 @@ async def test_gps_enter_and_exit_home(hass, geofency_client):
|
|||||||
data['currentLatitude'] = NOT_HOME_LATITUDE
|
data['currentLatitude'] = NOT_HOME_LATITUDE
|
||||||
data['currentLongitude'] = NOT_HOME_LONGITUDE
|
data['currentLongitude'] = NOT_HOME_LONGITUDE
|
||||||
|
|
||||||
req = await geofency_client.post(URL, data=data)
|
req = await geofency_client.post(url, data=data)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
assert req.status == HTTP_OK
|
assert req.status == HTTP_OK
|
||||||
device_name = slugify(GPS_EXIT_HOME['device'])
|
device_name = slugify(GPS_EXIT_HOME['device'])
|
||||||
@ -192,10 +216,12 @@ async def test_gps_enter_and_exit_home(hass, geofency_client):
|
|||||||
assert NOT_HOME_LONGITUDE == current_longitude
|
assert NOT_HOME_LONGITUDE == current_longitude
|
||||||
|
|
||||||
|
|
||||||
async def test_beacon_enter_and_exit_home(hass, geofency_client):
|
async def test_beacon_enter_and_exit_home(hass, geofency_client, webhook_id):
|
||||||
"""Test iBeacon based zone enter and exit - a.k.a stationary iBeacon."""
|
"""Test iBeacon based zone enter and exit - a.k.a stationary iBeacon."""
|
||||||
|
url = '/api/webhook/{}'.format(webhook_id)
|
||||||
|
|
||||||
# Enter the Home zone
|
# Enter the Home zone
|
||||||
req = await geofency_client.post(URL, data=BEACON_ENTER_HOME)
|
req = await geofency_client.post(url, data=BEACON_ENTER_HOME)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
assert req.status == HTTP_OK
|
assert req.status == HTTP_OK
|
||||||
device_name = slugify("beacon_{}".format(BEACON_ENTER_HOME['name']))
|
device_name = slugify("beacon_{}".format(BEACON_ENTER_HOME['name']))
|
||||||
@ -204,7 +230,7 @@ async def test_beacon_enter_and_exit_home(hass, geofency_client):
|
|||||||
assert STATE_HOME == state_name
|
assert STATE_HOME == state_name
|
||||||
|
|
||||||
# Exit the Home zone
|
# Exit the Home zone
|
||||||
req = await geofency_client.post(URL, data=BEACON_EXIT_HOME)
|
req = await geofency_client.post(url, data=BEACON_EXIT_HOME)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
assert req.status == HTTP_OK
|
assert req.status == HTTP_OK
|
||||||
device_name = slugify("beacon_{}".format(BEACON_ENTER_HOME['name']))
|
device_name = slugify("beacon_{}".format(BEACON_ENTER_HOME['name']))
|
||||||
@ -213,10 +239,12 @@ async def test_beacon_enter_and_exit_home(hass, geofency_client):
|
|||||||
assert STATE_NOT_HOME == state_name
|
assert STATE_NOT_HOME == state_name
|
||||||
|
|
||||||
|
|
||||||
async def test_beacon_enter_and_exit_car(hass, geofency_client):
|
async def test_beacon_enter_and_exit_car(hass, geofency_client, webhook_id):
|
||||||
"""Test use of mobile iBeacon."""
|
"""Test use of mobile iBeacon."""
|
||||||
|
url = '/api/webhook/{}'.format(webhook_id)
|
||||||
|
|
||||||
# Enter the Car away from Home zone
|
# Enter the Car away from Home zone
|
||||||
req = await geofency_client.post(URL, data=BEACON_ENTER_CAR)
|
req = await geofency_client.post(url, data=BEACON_ENTER_CAR)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
assert req.status == HTTP_OK
|
assert req.status == HTTP_OK
|
||||||
device_name = slugify("beacon_{}".format(BEACON_ENTER_CAR['name']))
|
device_name = slugify("beacon_{}".format(BEACON_ENTER_CAR['name']))
|
||||||
@ -225,7 +253,7 @@ async def test_beacon_enter_and_exit_car(hass, geofency_client):
|
|||||||
assert STATE_NOT_HOME == state_name
|
assert STATE_NOT_HOME == state_name
|
||||||
|
|
||||||
# Exit the Car away from Home zone
|
# Exit the Car away from Home zone
|
||||||
req = await geofency_client.post(URL, data=BEACON_EXIT_CAR)
|
req = await geofency_client.post(url, data=BEACON_EXIT_CAR)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
assert req.status == HTTP_OK
|
assert req.status == HTTP_OK
|
||||||
device_name = slugify("beacon_{}".format(BEACON_ENTER_CAR['name']))
|
device_name = slugify("beacon_{}".format(BEACON_ENTER_CAR['name']))
|
||||||
@ -237,7 +265,7 @@ async def test_beacon_enter_and_exit_car(hass, geofency_client):
|
|||||||
data = BEACON_ENTER_CAR.copy()
|
data = BEACON_ENTER_CAR.copy()
|
||||||
data['latitude'] = HOME_LATITUDE
|
data['latitude'] = HOME_LATITUDE
|
||||||
data['longitude'] = HOME_LONGITUDE
|
data['longitude'] = HOME_LONGITUDE
|
||||||
req = await geofency_client.post(URL, data=data)
|
req = await geofency_client.post(url, data=data)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
assert req.status == HTTP_OK
|
assert req.status == HTTP_OK
|
||||||
device_name = slugify("beacon_{}".format(data['name']))
|
device_name = slugify("beacon_{}".format(data['name']))
|
||||||
@ -246,7 +274,7 @@ async def test_beacon_enter_and_exit_car(hass, geofency_client):
|
|||||||
assert STATE_HOME == state_name
|
assert STATE_HOME == state_name
|
||||||
|
|
||||||
# Exit the Car in the Home zone
|
# Exit the Car in the Home zone
|
||||||
req = await geofency_client.post(URL, data=data)
|
req = await geofency_client.post(url, data=data)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
assert req.status == HTTP_OK
|
assert req.status == HTTP_OK
|
||||||
device_name = slugify("beacon_{}".format(data['name']))
|
device_name = slugify("beacon_{}".format(data['name']))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user