Merge pull request #32964 from home-assistant/rc

0.107.1
This commit is contained in:
Paulus Schoutsen 2020-03-18 22:14:25 -07:00 committed by GitHub
commit 88e3e73bb4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 76 additions and 54 deletions

View File

@ -3,8 +3,8 @@
"name": "Device Tracker", "name": "Device Tracker",
"documentation": "https://www.home-assistant.io/integrations/device_tracker", "documentation": "https://www.home-assistant.io/integrations/device_tracker",
"requirements": [], "requirements": [],
"dependencies": [], "dependencies": ["zone"],
"after_dependencies": ["zone"], "after_dependencies": [],
"codeowners": [], "codeowners": [],
"quality_scale": "internal" "quality_scale": "internal"
} }

View File

@ -3,11 +3,12 @@
"name": "Home Assistant Frontend", "name": "Home Assistant Frontend",
"documentation": "https://www.home-assistant.io/integrations/frontend", "documentation": "https://www.home-assistant.io/integrations/frontend",
"requirements": [ "requirements": [
"home-assistant-frontend==20200318.0" "home-assistant-frontend==20200318.1"
], ],
"dependencies": [ "dependencies": [
"api", "api",
"auth", "auth",
"device_automation",
"http", "http",
"lovelace", "lovelace",
"onboarding", "onboarding",
@ -19,4 +20,4 @@
"@home-assistant/frontend" "@home-assistant/frontend"
], ],
"quality_scale": "internal" "quality_scale": "internal"
} }

View File

@ -1,6 +1,6 @@
"""Support for the definition of zones.""" """Support for the definition of zones."""
import logging import logging
from typing import Dict, Optional, cast from typing import Any, Dict, Optional, cast
import voluptuous as vol import voluptuous as vol
@ -18,6 +18,7 @@ from homeassistant.const import (
CONF_RADIUS, CONF_RADIUS,
EVENT_CORE_CONFIG_UPDATE, EVENT_CORE_CONFIG_UPDATE,
SERVICE_RELOAD, SERVICE_RELOAD,
STATE_UNAVAILABLE,
) )
from homeassistant.core import Event, HomeAssistant, ServiceCall, State, callback from homeassistant.core import Event, HomeAssistant, ServiceCall, State, callback
from homeassistant.helpers import ( from homeassistant.helpers import (
@ -65,8 +66,20 @@ UPDATE_FIELDS = {
} }
def empty_value(value: Any) -> Any:
"""Test if the user has the default config value from adding "zone:"."""
if isinstance(value, dict) and len(value) == 0:
return []
raise vol.Invalid("Not a default value")
CONFIG_SCHEMA = vol.Schema( CONFIG_SCHEMA = vol.Schema(
{vol.Optional(DOMAIN): vol.All(cv.ensure_list, [vol.Schema(CREATE_FIELDS)])}, {
vol.Optional(DOMAIN, default=[]): vol.Any(
vol.All(cv.ensure_list, [vol.Schema(CREATE_FIELDS)]), empty_value,
)
},
extra=vol.ALLOW_EXTRA, extra=vol.ALLOW_EXTRA,
) )
@ -93,7 +106,7 @@ def async_active_zone(
closest = None closest = None
for zone in zones: for zone in zones:
if zone.attributes.get(ATTR_PASSIVE): if zone.state == STATE_UNAVAILABLE or zone.attributes.get(ATTR_PASSIVE):
continue continue
zone_dist = distance( zone_dist = distance(
@ -126,6 +139,9 @@ def in_zone(zone: State, latitude: float, longitude: float, radius: float = 0) -
Async friendly. Async friendly.
""" """
if zone.state == STATE_UNAVAILABLE:
return False
zone_dist = distance( zone_dist = distance(
latitude, latitude,
longitude, longitude,
@ -180,7 +196,7 @@ async def async_setup(hass: HomeAssistant, config: Dict) -> bool:
component, storage_collection, lambda conf: Zone(conf, True) component, storage_collection, lambda conf: Zone(conf, True)
) )
if DOMAIN in config: if config[DOMAIN]:
await yaml_collection.async_load(config[DOMAIN]) await yaml_collection.async_load(config[DOMAIN])
await storage_collection.async_load() await storage_collection.async_load()
@ -206,7 +222,7 @@ async def async_setup(hass: HomeAssistant, config: Dict) -> bool:
conf = await component.async_prepare_reload(skip_reset=True) conf = await component.async_prepare_reload(skip_reset=True)
if conf is None: if conf is None:
return return
await yaml_collection.async_load(conf.get(DOMAIN, [])) await yaml_collection.async_load(conf[DOMAIN])
service.async_register_admin_service( service.async_register_admin_service(
hass, hass,

View File

@ -1,7 +1,7 @@
"""Constants used by Home Assistant components.""" """Constants used by Home Assistant components."""
MAJOR_VERSION = 0 MAJOR_VERSION = 0
MINOR_VERSION = 107 MINOR_VERSION = 107
PATCH_VERSION = "0" PATCH_VERSION = "1"
__short_version__ = f"{MAJOR_VERSION}.{MINOR_VERSION}" __short_version__ = f"{MAJOR_VERSION}.{MINOR_VERSION}"
__version__ = f"{__short_version__}.{PATCH_VERSION}" __version__ = f"{__short_version__}.{PATCH_VERSION}"
REQUIRED_PYTHON_VER = (3, 7, 0) REQUIRED_PYTHON_VER = (3, 7, 0)

View File

@ -12,7 +12,7 @@ cryptography==2.8
defusedxml==0.6.0 defusedxml==0.6.0
distro==1.4.0 distro==1.4.0
hass-nabucasa==0.32.2 hass-nabucasa==0.32.2
home-assistant-frontend==20200318.0 home-assistant-frontend==20200318.1
importlib-metadata==1.5.0 importlib-metadata==1.5.0
jinja2>=2.10.3 jinja2>=2.10.3
netdisco==2.6.0 netdisco==2.6.0

View File

@ -696,7 +696,7 @@ hole==0.5.0
holidays==0.10.1 holidays==0.10.1
# homeassistant.components.frontend # homeassistant.components.frontend
home-assistant-frontend==20200318.0 home-assistant-frontend==20200318.1
# homeassistant.components.zwave # homeassistant.components.zwave
homeassistant-pyozw==0.1.9 homeassistant-pyozw==0.1.9

View File

@ -263,7 +263,7 @@ hole==0.5.0
holidays==0.10.1 holidays==0.10.1
# homeassistant.components.frontend # homeassistant.components.frontend
home-assistant-frontend==20200318.0 home-assistant-frontend==20200318.1
# homeassistant.components.zwave # homeassistant.components.zwave
homeassistant-pyozw==0.1.9 homeassistant-pyozw==0.1.9

View File

@ -140,16 +140,7 @@ async def test_webhook_update_registration(webhook_client, authed_api_client):
async def test_webhook_handle_get_zones(hass, create_registrations, webhook_client): async def test_webhook_handle_get_zones(hass, create_registrations, webhook_client):
"""Test that we can get zones properly.""" """Test that we can get zones properly."""
await async_setup_component( await async_setup_component(
hass, hass, ZONE_DOMAIN, {ZONE_DOMAIN: {}},
ZONE_DOMAIN,
{
ZONE_DOMAIN: {
"name": "test",
"latitude": 32.880837,
"longitude": -117.237561,
"radius": 250,
}
},
) )
resp = await webhook_client.post( resp = await webhook_client.post(
@ -160,10 +151,9 @@ async def test_webhook_handle_get_zones(hass, create_registrations, webhook_clie
assert resp.status == 200 assert resp.status == 200
json = await resp.json() json = await resp.json()
assert len(json) == 2 assert len(json) == 1
zones = sorted(json, key=lambda entry: entry["entity_id"]) zones = sorted(json, key=lambda entry: entry["entity_id"])
assert zones[0]["entity_id"] == "zone.home" assert zones[0]["entity_id"] == "zone.home"
assert zones[1]["entity_id"] == "zone.test"
async def test_webhook_handle_get_config(hass, create_registrations, webhook_client): async def test_webhook_handle_get_config(hass, create_registrations, webhook_client):

View File

@ -108,7 +108,7 @@ async def test_no_clients(hass):
"""Test the update_clients function when no clients are found.""" """Test the update_clients function when no clients are found."""
await setup_unifi_integration(hass) await setup_unifi_integration(hass)
assert len(hass.states.async_all()) == 0 assert len(hass.states.async_entity_ids("device_tracker")) == 0
async def test_tracked_devices(hass): async def test_tracked_devices(hass):
@ -123,7 +123,7 @@ async def test_tracked_devices(hass):
devices_response=[DEVICE_1, DEVICE_2], devices_response=[DEVICE_1, DEVICE_2],
known_wireless_clients=(CLIENT_4["mac"],), known_wireless_clients=(CLIENT_4["mac"],),
) )
assert len(hass.states.async_all()) == 6 assert len(hass.states.async_entity_ids("device_tracker")) == 5
client_1 = hass.states.get("device_tracker.client_1") client_1 = hass.states.get("device_tracker.client_1")
assert client_1 is not None assert client_1 is not None
@ -184,7 +184,7 @@ async def test_controller_state_change(hass):
controller = await setup_unifi_integration( controller = await setup_unifi_integration(
hass, clients_response=[CLIENT_1], devices_response=[DEVICE_1], hass, clients_response=[CLIENT_1], devices_response=[DEVICE_1],
) )
assert len(hass.states.async_all()) == 2 assert len(hass.states.async_entity_ids("device_tracker")) == 2
# Controller unavailable # Controller unavailable
controller.async_unifi_signalling_callback( controller.async_unifi_signalling_callback(
@ -214,7 +214,7 @@ async def test_option_track_clients(hass):
controller = await setup_unifi_integration( controller = await setup_unifi_integration(
hass, clients_response=[CLIENT_1, CLIENT_2], devices_response=[DEVICE_1], hass, clients_response=[CLIENT_1, CLIENT_2], devices_response=[DEVICE_1],
) )
assert len(hass.states.async_all()) == 3 assert len(hass.states.async_entity_ids("device_tracker")) == 3
client_1 = hass.states.get("device_tracker.client_1") client_1 = hass.states.get("device_tracker.client_1")
assert client_1 is not None assert client_1 is not None
@ -259,7 +259,7 @@ async def test_option_track_wired_clients(hass):
controller = await setup_unifi_integration( controller = await setup_unifi_integration(
hass, clients_response=[CLIENT_1, CLIENT_2], devices_response=[DEVICE_1], hass, clients_response=[CLIENT_1, CLIENT_2], devices_response=[DEVICE_1],
) )
assert len(hass.states.async_all()) == 3 assert len(hass.states.async_entity_ids("device_tracker")) == 3
client_1 = hass.states.get("device_tracker.client_1") client_1 = hass.states.get("device_tracker.client_1")
assert client_1 is not None assert client_1 is not None
@ -304,7 +304,7 @@ async def test_option_track_devices(hass):
controller = await setup_unifi_integration( controller = await setup_unifi_integration(
hass, clients_response=[CLIENT_1, CLIENT_2], devices_response=[DEVICE_1], hass, clients_response=[CLIENT_1, CLIENT_2], devices_response=[DEVICE_1],
) )
assert len(hass.states.async_all()) == 3 assert len(hass.states.async_entity_ids("device_tracker")) == 3
client_1 = hass.states.get("device_tracker.client_1") client_1 = hass.states.get("device_tracker.client_1")
assert client_1 is not None assert client_1 is not None
@ -349,7 +349,7 @@ async def test_option_ssid_filter(hass):
controller = await setup_unifi_integration( controller = await setup_unifi_integration(
hass, options={CONF_SSID_FILTER: ["ssid"]}, clients_response=[CLIENT_3], hass, options={CONF_SSID_FILTER: ["ssid"]}, clients_response=[CLIENT_3],
) )
assert len(hass.states.async_all()) == 1 assert len(hass.states.async_entity_ids("device_tracker")) == 0
# SSID filter active # SSID filter active
client_3 = hass.states.get("device_tracker.client_3") client_3 = hass.states.get("device_tracker.client_3")
@ -387,7 +387,7 @@ async def test_wireless_client_go_wired_issue(hass):
client_1_client["last_seen"] = dt_util.as_timestamp(dt_util.utcnow()) client_1_client["last_seen"] = dt_util.as_timestamp(dt_util.utcnow())
controller = await setup_unifi_integration(hass, clients_response=[client_1_client]) controller = await setup_unifi_integration(hass, clients_response=[client_1_client])
assert len(hass.states.async_all()) == 1 assert len(hass.states.async_entity_ids("device_tracker")) == 1
client_1 = hass.states.get("device_tracker.client_1") client_1 = hass.states.get("device_tracker.client_1")
assert client_1 is not None assert client_1 is not None
@ -460,7 +460,7 @@ async def test_restoring_client(hass):
clients_response=[CLIENT_2], clients_response=[CLIENT_2],
clients_all_response=[CLIENT_1], clients_all_response=[CLIENT_1],
) )
assert len(hass.states.async_all()) == 2 assert len(hass.states.async_entity_ids("device_tracker")) == 2
device_1 = hass.states.get("device_tracker.client_1") device_1 = hass.states.get("device_tracker.client_1")
assert device_1 is not None assert device_1 is not None
@ -474,7 +474,7 @@ async def test_dont_track_clients(hass):
clients_response=[CLIENT_1], clients_response=[CLIENT_1],
devices_response=[DEVICE_1], devices_response=[DEVICE_1],
) )
assert len(hass.states.async_all()) == 1 assert len(hass.states.async_entity_ids("device_tracker")) == 1
client_1 = hass.states.get("device_tracker.client_1") client_1 = hass.states.get("device_tracker.client_1")
assert client_1 is None assert client_1 is None
@ -492,7 +492,7 @@ async def test_dont_track_devices(hass):
clients_response=[CLIENT_1], clients_response=[CLIENT_1],
devices_response=[DEVICE_1], devices_response=[DEVICE_1],
) )
assert len(hass.states.async_all()) == 1 assert len(hass.states.async_entity_ids("device_tracker")) == 1
client_1 = hass.states.get("device_tracker.client_1") client_1 = hass.states.get("device_tracker.client_1")
assert client_1 is not None assert client_1 is not None
@ -509,7 +509,7 @@ async def test_dont_track_wired_clients(hass):
options={unifi.controller.CONF_TRACK_WIRED_CLIENTS: False}, options={unifi.controller.CONF_TRACK_WIRED_CLIENTS: False},
clients_response=[CLIENT_1, CLIENT_2], clients_response=[CLIENT_1, CLIENT_2],
) )
assert len(hass.states.async_all()) == 1 assert len(hass.states.async_entity_ids("device_tracker")) == 1
client_1 = hass.states.get("device_tracker.client_1") client_1 = hass.states.get("device_tracker.client_1")
assert client_1 is not None assert client_1 is not None

View File

@ -55,7 +55,7 @@ async def test_no_clients(hass):
) )
assert len(controller.mock_requests) == 4 assert len(controller.mock_requests) == 4
assert len(hass.states.async_all()) == 0 assert len(hass.states.async_entity_ids("sensor")) == 0
async def test_sensors(hass): async def test_sensors(hass):
@ -71,7 +71,7 @@ async def test_sensors(hass):
) )
assert len(controller.mock_requests) == 4 assert len(controller.mock_requests) == 4
assert len(hass.states.async_all()) == 4 assert len(hass.states.async_entity_ids("sensor")) == 4
wired_client_rx = hass.states.get("sensor.wired_client_name_rx") wired_client_rx = hass.states.get("sensor.wired_client_name_rx")
assert wired_client_rx.state == "1234.0" assert wired_client_rx.state == "1234.0"

View File

@ -209,7 +209,7 @@ async def test_no_clients(hass):
) )
assert len(controller.mock_requests) == 4 assert len(controller.mock_requests) == 4
assert len(hass.states.async_all()) == 0 assert len(hass.states.async_entity_ids("switch")) == 0
async def test_controller_not_client(hass): async def test_controller_not_client(hass):
@ -222,7 +222,7 @@ async def test_controller_not_client(hass):
) )
assert len(controller.mock_requests) == 4 assert len(controller.mock_requests) == 4
assert len(hass.states.async_all()) == 0 assert len(hass.states.async_entity_ids("switch")) == 0
cloudkey = hass.states.get("switch.cloud_key") cloudkey = hass.states.get("switch.cloud_key")
assert cloudkey is None assert cloudkey is None
@ -240,7 +240,7 @@ async def test_not_admin(hass):
) )
assert len(controller.mock_requests) == 4 assert len(controller.mock_requests) == 4
assert len(hass.states.async_all()) == 0 assert len(hass.states.async_entity_ids("switch")) == 0
async def test_switches(hass): async def test_switches(hass):
@ -258,7 +258,7 @@ async def test_switches(hass):
) )
assert len(controller.mock_requests) == 4 assert len(controller.mock_requests) == 4
assert len(hass.states.async_all()) == 3 assert len(hass.states.async_entity_ids("switch")) == 3
switch_1 = hass.states.get("switch.poe_client_1") switch_1 = hass.states.get("switch.poe_client_1")
assert switch_1 is not None assert switch_1 is not None
@ -312,7 +312,7 @@ async def test_new_client_discovered_on_block_control(hass):
) )
assert len(controller.mock_requests) == 4 assert len(controller.mock_requests) == 4
assert len(hass.states.async_all()) == 0 assert len(hass.states.async_entity_ids("switch")) == 0
blocked = hass.states.get("switch.block_client_1") blocked = hass.states.get("switch.block_client_1")
assert blocked is None assert blocked is None
@ -324,7 +324,7 @@ async def test_new_client_discovered_on_block_control(hass):
controller.api.session_handler("data") controller.api.session_handler("data")
await hass.async_block_till_done() await hass.async_block_till_done()
assert len(hass.states.async_all()) == 1 assert len(hass.states.async_entity_ids("switch")) == 1
blocked = hass.states.get("switch.block_client_1") blocked = hass.states.get("switch.block_client_1")
assert blocked is not None assert blocked is not None
@ -336,7 +336,7 @@ async def test_option_block_clients(hass):
options={CONF_BLOCK_CLIENT: [BLOCKED["mac"]]}, options={CONF_BLOCK_CLIENT: [BLOCKED["mac"]]},
clients_all_response=[BLOCKED, UNBLOCKED], clients_all_response=[BLOCKED, UNBLOCKED],
) )
assert len(hass.states.async_all()) == 1 assert len(hass.states.async_entity_ids("switch")) == 1
# Add a second switch # Add a second switch
hass.config_entries.async_update_entry( hass.config_entries.async_update_entry(
@ -344,28 +344,28 @@ async def test_option_block_clients(hass):
options={CONF_BLOCK_CLIENT: [BLOCKED["mac"], UNBLOCKED["mac"]]}, options={CONF_BLOCK_CLIENT: [BLOCKED["mac"], UNBLOCKED["mac"]]},
) )
await hass.async_block_till_done() await hass.async_block_till_done()
assert len(hass.states.async_all()) == 2 assert len(hass.states.async_entity_ids("switch")) == 2
# Remove the second switch again # Remove the second switch again
hass.config_entries.async_update_entry( hass.config_entries.async_update_entry(
controller.config_entry, options={CONF_BLOCK_CLIENT: [BLOCKED["mac"]]}, controller.config_entry, options={CONF_BLOCK_CLIENT: [BLOCKED["mac"]]},
) )
await hass.async_block_till_done() await hass.async_block_till_done()
assert len(hass.states.async_all()) == 1 assert len(hass.states.async_entity_ids("switch")) == 1
# Enable one and remove another one # Enable one and remove another one
hass.config_entries.async_update_entry( hass.config_entries.async_update_entry(
controller.config_entry, options={CONF_BLOCK_CLIENT: [UNBLOCKED["mac"]]}, controller.config_entry, options={CONF_BLOCK_CLIENT: [UNBLOCKED["mac"]]},
) )
await hass.async_block_till_done() await hass.async_block_till_done()
assert len(hass.states.async_all()) == 1 assert len(hass.states.async_entity_ids("switch")) == 1
# Remove one # Remove one
hass.config_entries.async_update_entry( hass.config_entries.async_update_entry(
controller.config_entry, options={CONF_BLOCK_CLIENT: []}, controller.config_entry, options={CONF_BLOCK_CLIENT: []},
) )
await hass.async_block_till_done() await hass.async_block_till_done()
assert len(hass.states.async_all()) == 0 assert len(hass.states.async_entity_ids("switch")) == 0
async def test_new_client_discovered_on_poe_control(hass): async def test_new_client_discovered_on_poe_control(hass):
@ -378,7 +378,7 @@ async def test_new_client_discovered_on_poe_control(hass):
) )
assert len(controller.mock_requests) == 4 assert len(controller.mock_requests) == 4
assert len(hass.states.async_all()) == 1 assert len(hass.states.async_entity_ids("switch")) == 1
controller.api.websocket._data = { controller.api.websocket._data = {
"meta": {"message": "sta:sync"}, "meta": {"message": "sta:sync"},
@ -391,7 +391,7 @@ async def test_new_client_discovered_on_poe_control(hass):
"switch", "turn_off", {"entity_id": "switch.poe_client_1"}, blocking=True "switch", "turn_off", {"entity_id": "switch.poe_client_1"}, blocking=True
) )
assert len(controller.mock_requests) == 5 assert len(controller.mock_requests) == 5
assert len(hass.states.async_all()) == 2 assert len(hass.states.async_entity_ids("switch")) == 2
assert controller.mock_requests[4] == { assert controller.mock_requests[4] == {
"json": { "json": {
"port_overrides": [{"port_idx": 1, "portconf_id": "1a1", "poe_mode": "off"}] "port_overrides": [{"port_idx": 1, "portconf_id": "1a1", "poe_mode": "off"}]
@ -430,7 +430,7 @@ async def test_ignore_multiple_poe_clients_on_same_port(hass):
) )
assert len(controller.mock_requests) == 4 assert len(controller.mock_requests) == 4
assert len(hass.states.async_all()) == 3 assert len(hass.states.async_entity_ids("device_tracker")) == 3
switch_1 = hass.states.get("switch.poe_client_1") switch_1 = hass.states.get("switch.poe_client_1")
switch_2 = hass.states.get("switch.poe_client_2") switch_2 = hass.states.get("switch.poe_client_2")
@ -481,7 +481,7 @@ async def test_restoring_client(hass):
) )
assert len(controller.mock_requests) == 4 assert len(controller.mock_requests) == 4
assert len(hass.states.async_all()) == 2 assert len(hass.states.async_entity_ids("switch")) == 2
device_1 = hass.states.get("switch.client_1") device_1 = hass.states.get("switch.client_1")
assert device_1 is not None assert device_1 is not None

View File

@ -487,3 +487,18 @@ async def test_import_config_entry(hass):
assert state.attributes[zone.ATTR_RADIUS] == 3 assert state.attributes[zone.ATTR_RADIUS] == 3
assert state.attributes[zone.ATTR_PASSIVE] is False assert state.attributes[zone.ATTR_PASSIVE] is False
assert state.attributes[ATTR_ICON] == "mdi:from-config-entry" assert state.attributes[ATTR_ICON] == "mdi:from-config-entry"
async def test_zone_empty_setup(hass):
"""Set up zone with empty config."""
assert await setup.async_setup_component(hass, DOMAIN, {"zone": {}})
async def test_unavailable_zone(hass):
"""Test active zone with unavailable zones."""
assert await setup.async_setup_component(hass, DOMAIN, {"zone": {}})
hass.states.async_set("zone.bla", "unavailable", {"restored": True})
assert zone.async_active_zone(hass, 0.0, 0.01) is None
assert zone.in_zone(hass.states.get("zone.bla"), 0, 0) is False