Skip to content

Commit

Permalink
Merge pull request #24465 from home-assistant/rc
Browse files Browse the repository at this point in the history
0.94.2
  • Loading branch information
balloob committed Jun 11, 2019
2 parents 282b4f4 + 6ea0575 commit c2218e8
Show file tree
Hide file tree
Showing 27 changed files with 373 additions and 137 deletions.
8 changes: 7 additions & 1 deletion homeassistant/components/axis/config_flow.py
Expand Up @@ -14,6 +14,8 @@
from .device import get_device
from .errors import AlreadyConfigured, AuthenticationRequired, CannotConnect

AXIS_OUI = {'00408C', 'ACCC8E', 'B8A44F'}

CONFIG_FILE = 'axis.conf'

EVENT_TYPES = ['motion', 'vmd3', 'pir', 'sound',
Expand Down Expand Up @@ -151,10 +153,14 @@ async def async_step_zeroconf(self, discovery_info):
This flow is triggered by the discovery component.
"""
serialnumber = discovery_info['properties']['macaddress']

if serialnumber[:6] not in AXIS_OUI:
return self.async_abort(reason='not_axis_device')

if discovery_info[CONF_HOST].startswith('169.254'):
return self.async_abort(reason='link_local_address')

serialnumber = discovery_info['properties']['macaddress']
# pylint: disable=unsupported-assignment-operation
self.context['macaddress'] = serialnumber

Expand Down
5 changes: 3 additions & 2 deletions homeassistant/components/axis/strings.json
Expand Up @@ -21,7 +21,8 @@
"abort": {
"already_configured": "Device is already configured",
"bad_config_file": "Bad data from config file",
"link_local_address": "Link local addresses are not supported"
"link_local_address": "Link local addresses are not supported",
"not_axis_device": "Discovered device not an Axis device"
}
}
}
}
2 changes: 1 addition & 1 deletion homeassistant/components/config/core.py
Expand Up @@ -56,7 +56,7 @@ async def websocket_update_config(hass, connection, msg):
data.pop('type')

try:
await hass.config.update(**data)
await hass.config.async_update(**data)
connection.send_result(msg['id'])
except ValueError as err:
connection.send_error(
Expand Down
4 changes: 3 additions & 1 deletion homeassistant/components/deconz/config_flow.py
Expand Up @@ -9,7 +9,6 @@
async_discovery, async_get_api_key, async_get_bridgeid)

from homeassistant import config_entries
from homeassistant.components.ssdp import ATTR_MANUFACTURERURL, ATTR_SERIAL
from homeassistant.const import CONF_API_KEY, CONF_HOST, CONF_PORT
from homeassistant.core import callback
from homeassistant.helpers import aiohttp_client
Expand Down Expand Up @@ -154,6 +153,9 @@ async def _update_entry(self, entry, host):

async def async_step_ssdp(self, discovery_info):
"""Handle a discovered deCONZ bridge."""
from homeassistant.components.ssdp import (
ATTR_MANUFACTURERURL, ATTR_SERIAL)

if discovery_info[ATTR_MANUFACTURERURL] != DECONZ_MANUFACTURERURL:
return self.async_abort(reason='not_deconz_bridge')

Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/deconz/manifest.json
Expand Up @@ -4,7 +4,7 @@
"config_flow": true,
"documentation": "https://www.home-assistant.io/components/deconz",
"requirements": [
"pydeconz==59"
"pydeconz==60"
],
"ssdp": {
"manufacturer": [
Expand Down
18 changes: 10 additions & 8 deletions homeassistant/components/gpslogger/__init__.py
Expand Up @@ -11,19 +11,21 @@
from homeassistant.helpers import config_entry_flow
from homeassistant.helpers.dispatcher import async_dispatcher_send
from homeassistant.components.device_tracker import DOMAIN as DEVICE_TRACKER
from .const import DOMAIN
from .const import (
DOMAIN,
ATTR_ALTITUDE,
ATTR_ACCURACY,
ATTR_ACTIVITY,
ATTR_DEVICE,
ATTR_DIRECTION,
ATTR_PROVIDER,
ATTR_SPEED,
)

_LOGGER = logging.getLogger(__name__)

TRACKER_UPDATE = '{}_tracker_update'.format(DOMAIN)

ATTR_ALTITUDE = 'altitude'
ATTR_ACCURACY = 'accuracy'
ATTR_ACTIVITY = 'activity'
ATTR_DEVICE = 'device'
ATTR_DIRECTION = 'direction'
ATTR_PROVIDER = 'provider'
ATTR_SPEED = 'speed'

DEFAULT_ACCURACY = 200
DEFAULT_BATTERY = -1
Expand Down
8 changes: 8 additions & 0 deletions homeassistant/components/gpslogger/const.py
@@ -1,3 +1,11 @@
"""Const for GPSLogger."""

DOMAIN = 'gpslogger'

ATTR_ALTITUDE = 'altitude'
ATTR_ACCURACY = 'accuracy'
ATTR_ACTIVITY = 'activity'
ATTR_DEVICE = 'device'
ATTR_DIRECTION = 'direction'
ATTR_PROVIDER = 'provider'
ATTR_SPEED = 'speed'
71 changes: 70 additions & 1 deletion homeassistant/components/gpslogger/device_tracker.py
Expand Up @@ -2,14 +2,29 @@
import logging

from homeassistant.core import callback
from homeassistant.const import (
ATTR_BATTERY_LEVEL,
ATTR_GPS_ACCURACY,
ATTR_LATITUDE,
ATTR_LONGITUDE,
)
from homeassistant.components.device_tracker import SOURCE_TYPE_GPS
from homeassistant.components.device_tracker.config_entry import (
DeviceTrackerEntity
)
from homeassistant.helpers import device_registry
from homeassistant.helpers.dispatcher import async_dispatcher_connect
from homeassistant.helpers.restore_state import RestoreEntity
from homeassistant.helpers.typing import HomeAssistantType

from . import DOMAIN as GPL_DOMAIN, TRACKER_UPDATE
from .const import (
ATTR_ACTIVITY,
ATTR_ALTITUDE,
ATTR_DIRECTION,
ATTR_PROVIDER,
ATTR_SPEED,
)

_LOGGER = logging.getLogger(__name__)

Expand All @@ -32,8 +47,27 @@ def _receive_data(device, gps, battery, accuracy, attrs):
hass.data[GPL_DOMAIN]['unsub_device_tracker'][entry.entry_id] = \
async_dispatcher_connect(hass, TRACKER_UPDATE, _receive_data)

# Restore previously loaded devices
dev_reg = await device_registry.async_get_registry(hass)
dev_ids = {
identifier[1]
for device in dev_reg.devices.values()
for identifier in device.identifiers
if identifier[0] == GPL_DOMAIN
}
if not dev_ids:
return

entities = []
for dev_id in dev_ids:
hass.data[GPL_DOMAIN]['devices'].add(dev_id)
entity = GPSLoggerEntity(dev_id, None, None, None, None)
entities.append(entity)

class GPSLoggerEntity(DeviceTrackerEntity):
async_add_entities(entities)


class GPSLoggerEntity(DeviceTrackerEntity, RestoreEntity):
"""Represent a tracked device."""

def __init__(
Expand Down Expand Up @@ -102,11 +136,46 @@ def source_type(self):

async def async_added_to_hass(self):
"""Register state update callback."""
await super().async_added_to_hass()
self._unsub_dispatcher = async_dispatcher_connect(
self.hass, TRACKER_UPDATE, self._async_receive_data)

# don't restore if we got created with data
if self._location is not None:
return

state = await self.async_get_last_state()
if state is None:
self._location = (None, None)
self._accuracy = None
self._attributes = {
ATTR_ALTITUDE: None,
ATTR_ACTIVITY: None,
ATTR_DIRECTION: None,
ATTR_PROVIDER: None,
ATTR_SPEED: None,
}
self._battery = None
return

attr = state.attributes
self._location = (
attr.get(ATTR_LATITUDE),
attr.get(ATTR_LONGITUDE),
)
self._accuracy = attr.get(ATTR_GPS_ACCURACY)
self._attributes = {
ATTR_ALTITUDE: attr.get(ATTR_ALTITUDE),
ATTR_ACTIVITY: attr.get(ATTR_ACTIVITY),
ATTR_DIRECTION: attr.get(ATTR_DIRECTION),
ATTR_PROVIDER: attr.get(ATTR_PROVIDER),
ATTR_SPEED: attr.get(ATTR_SPEED),
}
self._battery = attr.get(ATTR_BATTERY_LEVEL)

async def async_will_remove_from_hass(self):
"""Clean up after entity before removal."""
await super().async_will_remove_from_hass()
self._unsub_dispatcher()

@callback
Expand Down
12 changes: 9 additions & 3 deletions homeassistant/components/hassio/__init__.py
Expand Up @@ -9,7 +9,8 @@
from homeassistant.components.homeassistant import SERVICE_CHECK_CONFIG
import homeassistant.config as conf_util
from homeassistant.const import (
ATTR_NAME, SERVICE_HOMEASSISTANT_RESTART, SERVICE_HOMEASSISTANT_STOP)
ATTR_NAME, SERVICE_HOMEASSISTANT_RESTART, SERVICE_HOMEASSISTANT_STOP,
EVENT_CORE_CONFIG_UPDATE)
from homeassistant.core import DOMAIN as HASS_DOMAIN, callback
from homeassistant.exceptions import HomeAssistantError
import homeassistant.helpers.config_validation as cv
Expand Down Expand Up @@ -194,8 +195,13 @@ async def async_setup(hass, config):

await hassio.update_hass_api(config.get('http', {}), refresh_token.token)

if 'homeassistant' in config:
await hassio.update_hass_timezone(config['homeassistant'])
async def push_config(_):
"""Push core config to Hass.io."""
await hassio.update_hass_timezone(str(hass.config.time_zone))

hass.bus.async_listen(EVENT_CORE_CONFIG_UPDATE, push_config)

await push_config(None)

async def async_service_handler(service):
"""Handle service calls for Hass.io."""
Expand Down
6 changes: 3 additions & 3 deletions homeassistant/components/hassio/handler.py
Expand Up @@ -11,7 +11,7 @@
CONF_SERVER_PORT,
CONF_SSL_CERTIFICATE,
)
from homeassistant.const import CONF_TIME_ZONE, SERVER_PORT
from homeassistant.const import SERVER_PORT

from .const import X_HASSIO

Expand Down Expand Up @@ -140,13 +140,13 @@ async def update_hass_api(self, http_config, refresh_token):
payload=options)

@_api_bool
def update_hass_timezone(self, core_config):
def update_hass_timezone(self, timezone):
"""Update Home-Assistant timezone data on Hass.io.
This method return a coroutine.
"""
return self.send_command("/supervisor/options", payload={
'timezone': core_config.get(CONF_TIME_ZONE)
'timezone': timezone
})

async def send_command(self, command, method="post", payload=None,
Expand Down
3 changes: 2 additions & 1 deletion homeassistant/components/hue/config_flow.py
Expand Up @@ -8,7 +8,6 @@
import voluptuous as vol

from homeassistant import config_entries
from homeassistant.components.ssdp import ATTR_MANUFACTURERURL
from homeassistant.core import callback
from homeassistant.helpers import aiohttp_client

Expand Down Expand Up @@ -146,6 +145,8 @@ async def async_step_ssdp(self, discovery_info):
This flow is triggered by the SSDP component. It will check if the
host is already configured and delegate to the import step if not.
"""
from homeassistant.components.ssdp import ATTR_MANUFACTURERURL

if discovery_info[ATTR_MANUFACTURERURL] != HUE_MANUFACTURERURL:
return self.async_abort(reason='not_hue_bridge')

Expand Down
28 changes: 21 additions & 7 deletions homeassistant/components/zone/__init__.py
Expand Up @@ -3,10 +3,12 @@

import voluptuous as vol

from homeassistant.core import callback
from homeassistant.loader import bind_hass
import homeassistant.helpers.config_validation as cv
from homeassistant.const import (
CONF_NAME, CONF_LATITUDE, CONF_LONGITUDE, CONF_ICON, CONF_RADIUS)
CONF_NAME, CONF_LATITUDE, CONF_LONGITUDE, CONF_ICON, CONF_RADIUS,
EVENT_CORE_CONFIG_UPDATE)
from homeassistant.helpers import config_per_platform
from homeassistant.helpers.entity import async_generate_entity_id
from homeassistant.util import slugify
Expand Down Expand Up @@ -90,12 +92,24 @@ async def async_setup(hass, config):
hass.async_create_task(zone.async_update_ha_state())
entities.add(zone.entity_id)

if ENTITY_ID_HOME not in entities and HOME_ZONE not in zone_entries:
zone = Zone(hass, hass.config.location_name,
hass.config.latitude, hass.config.longitude,
DEFAULT_RADIUS, ICON_HOME, False)
zone.entity_id = ENTITY_ID_HOME
hass.async_create_task(zone.async_update_ha_state())
if ENTITY_ID_HOME in entities or HOME_ZONE in zone_entries:
return True

zone = Zone(hass, hass.config.location_name,
hass.config.latitude, hass.config.longitude,
DEFAULT_RADIUS, ICON_HOME, False)
zone.entity_id = ENTITY_ID_HOME
hass.async_create_task(zone.async_update_ha_state())

@callback
def core_config_updated(_):
"""Handle core config updated."""
zone.name = hass.config.location_name
zone.latitude = hass.config.latitude
zone.longitude = hass.config.longitude
zone.async_write_ha_state()

hass.bus.async_listen(EVENT_CORE_CONFIG_UPDATE, core_config_updated)

return True

Expand Down
17 changes: 7 additions & 10 deletions homeassistant/components/zone/zone.py
Expand Up @@ -23,21 +23,18 @@ def in_zone(zone, latitude, longitude, radius=0) -> bool:
class Zone(Entity):
"""Representation of a Zone."""

name = None

def __init__(self, hass, name, latitude, longitude, radius, icon, passive):
"""Initialize the zone."""
self.hass = hass
self._name = name
self._latitude = latitude
self._longitude = longitude
self.name = name
self.latitude = latitude
self.longitude = longitude
self._radius = radius
self._icon = icon
self._passive = passive

@property
def name(self):
"""Return the name of the zone."""
return self._name

@property
def state(self):
"""Return the state property really does nothing for a zone."""
Expand All @@ -53,8 +50,8 @@ def state_attributes(self):
"""Return the state attributes of the zone."""
data = {
ATTR_HIDDEN: True,
ATTR_LATITUDE: self._latitude,
ATTR_LONGITUDE: self._longitude,
ATTR_LATITUDE: self.latitude,
ATTR_LONGITUDE: self.longitude,
ATTR_RADIUS: self._radius,
}
if self._passive:
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/const.py
Expand Up @@ -2,7 +2,7 @@
"""Constants used by Home Assistant components."""
MAJOR_VERSION = 0
MINOR_VERSION = 94
PATCH_VERSION = '1'
PATCH_VERSION = '2'
__short_version__ = '{}.{}'.format(MAJOR_VERSION, MINOR_VERSION)
__version__ = '{}.{}'.format(__short_version__, PATCH_VERSION)
REQUIRED_PYTHON_VER = (3, 5, 3)
Expand Down

0 comments on commit c2218e8

Please sign in to comment.