Skip to content

Commit

Permalink
Merge pull request #24396 from home-assistant/rc
Browse files Browse the repository at this point in the history
0.94.1
  • Loading branch information
balloob authored Jun 8, 2019
2 parents 09292d5 + b68a796 commit 282b4f4
Show file tree
Hide file tree
Showing 38 changed files with 388 additions and 109 deletions.
71 changes: 42 additions & 29 deletions homeassistant/components/automation/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,7 @@ def __init__(self, automation_id, name, async_attach_triggers, cond_func,
self._last_triggered = None
self._hidden = hidden
self._initial_state = initial_state
self._is_enabled = False

@property
def name(self):
Expand All @@ -216,7 +217,8 @@ def hidden(self) -> bool:
@property
def is_on(self) -> bool:
"""Return True if entity is on."""
return self._async_detach_triggers is not None
return (self._async_detach_triggers is not None or
self._is_enabled)

async def async_added_to_hass(self) -> None:
"""Startup with initial state or previous state."""
Expand All @@ -239,37 +241,16 @@ async def async_added_to_hass(self) -> None:
"initial state", self.entity_id,
enable_automation)

if not enable_automation:
return

# HomeAssistant is starting up
if self.hass.state == CoreState.not_running:
async def async_enable_automation(event):
"""Start automation on startup."""
await self.async_enable()

self.hass.bus.async_listen_once(
EVENT_HOMEASSISTANT_START, async_enable_automation)

# HomeAssistant is running
else:
if enable_automation:
await self.async_enable()

async def async_turn_on(self, **kwargs) -> None:
"""Turn the entity on and update the state."""
if self.is_on:
return

await self.async_enable()

async def async_turn_off(self, **kwargs) -> None:
"""Turn the entity off."""
if not self.is_on:
return

self._async_detach_triggers()
self._async_detach_triggers = None
await self.async_update_ha_state()
await self.async_disable()

async def async_trigger(self, variables, skip_condition=False,
context=None):
Expand All @@ -296,19 +277,51 @@ async def async_trigger(self, variables, skip_condition=False,
async def async_will_remove_from_hass(self):
"""Remove listeners when removing automation from HASS."""
await super().async_will_remove_from_hass()
await self.async_turn_off()
await self.async_disable()

async def async_enable(self):
"""Enable this automation entity.
This method is a coroutine.
"""
if self.is_on:
if self._is_enabled:
return

self._async_detach_triggers = await self._async_attach_triggers(
self.async_trigger)
await self.async_update_ha_state()
self._is_enabled = True

# HomeAssistant is starting up
if self.hass.state != CoreState.not_running:
self._async_detach_triggers = await self._async_attach_triggers(
self.async_trigger)
self.async_write_ha_state()
return

async def async_enable_automation(event):
"""Start automation on startup."""
# Don't do anything if no longer enabled or already attached
if (not self._is_enabled or
self._async_detach_triggers is not None):
return

self._async_detach_triggers = await self._async_attach_triggers(
self.async_trigger)

self.hass.bus.async_listen_once(
EVENT_HOMEASSISTANT_START, async_enable_automation)
self.async_write_ha_state()

async def async_disable(self):
"""Disable the automation entity."""
if not self._is_enabled:
return

self._is_enabled = False

if self._async_detach_triggers is not None:
self._async_detach_triggers()
self._async_detach_triggers = None

self.async_write_ha_state()

@property
def device_state_attributes(self):
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/axis/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"name": "Axis",
"config_flow": true,
"documentation": "https://www.home-assistant.io/components/axis",
"requirements": ["axis==24"],
"requirements": ["axis==25"],
"dependencies": [],
"zeroconf": ["_axis-video._tcp.local."],
"codeowners": ["@kane610"]
Expand Down
4 changes: 4 additions & 0 deletions homeassistant/components/cloud/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,7 @@

class InvalidTrustedNetworks(Exception):
"""Raised when invalid trusted networks config."""


class InvalidTrustedProxies(Exception):
"""Raised when invalid trusted proxies config."""
8 changes: 6 additions & 2 deletions homeassistant/components/cloud/http_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@

from .const import (
DOMAIN, REQUEST_TIMEOUT, PREF_ENABLE_ALEXA, PREF_ENABLE_GOOGLE,
PREF_GOOGLE_SECURE_DEVICES_PIN, InvalidTrustedNetworks)
PREF_GOOGLE_SECURE_DEVICES_PIN, InvalidTrustedNetworks,
InvalidTrustedProxies)

_LOGGER = logging.getLogger(__name__)

Expand Down Expand Up @@ -52,7 +53,10 @@
_CLOUD_ERRORS = {
InvalidTrustedNetworks:
(500, 'Remote UI not compatible with 127.0.0.1/::1'
' as a trusted network.')
' as a trusted network.'),
InvalidTrustedProxies:
(500, 'Remote UI not compatible with 127.0.0.1/::1'
' as trusted proxies.'),
}


Expand Down
22 changes: 20 additions & 2 deletions homeassistant/components/cloud/prefs.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
PREF_GOOGLE_SECURE_DEVICES_PIN, PREF_CLOUDHOOKS, PREF_CLOUD_USER,
PREF_GOOGLE_ENTITY_CONFIGS, PREF_OVERRIDE_NAME, PREF_DISABLE_2FA,
PREF_ALIASES, PREF_SHOULD_EXPOSE,
InvalidTrustedNetworks)
InvalidTrustedNetworks, InvalidTrustedProxies)

STORAGE_KEY = DOMAIN
STORAGE_VERSION = 1
Expand Down Expand Up @@ -59,6 +59,9 @@ async def async_update(self, *, google_enabled=_UNDEF,
if remote_enabled is True and self._has_local_trusted_network:
raise InvalidTrustedNetworks

if remote_enabled is True and self._has_local_trusted_proxies:
raise InvalidTrustedProxies

await self._store.async_save(self._prefs)

async def async_update_google_entity_config(
Expand Down Expand Up @@ -112,7 +115,7 @@ def remote_enabled(self):
if not enabled:
return False

if self._has_local_trusted_network:
if self._has_local_trusted_network or self._has_local_trusted_proxies:
return False

return True
Expand Down Expand Up @@ -162,3 +165,18 @@ def _has_local_trusted_network(self) -> bool:
return True

return False

@property
def _has_local_trusted_proxies(self) -> bool:
"""Return if we allow localhost to be a proxy and use its data."""
if not hasattr(self._hass, 'http'):
return False

local4 = ip_address('127.0.0.1')
local6 = ip_address('::1')

if any(local4 in nwk or local6 in nwk
for nwk in self._hass.http.trusted_proxies):
return True

return False
22 changes: 13 additions & 9 deletions homeassistant/components/deconz/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

DECONZ_MANUFACTURERURL = 'http://www.dresden-elektronik.de'
CONF_SERIAL = 'serial'
ATTR_UUID = 'udn'


@callback
Expand Down Expand Up @@ -156,25 +157,28 @@ async def async_step_ssdp(self, discovery_info):
if discovery_info[ATTR_MANUFACTURERURL] != DECONZ_MANUFACTURERURL:
return self.async_abort(reason='not_deconz_bridge')

bridgeid = discovery_info[ATTR_SERIAL]
gateway_entries = configured_gateways(self.hass)
uuid = discovery_info[ATTR_UUID].replace('uuid:', '')
gateways = {
gateway.api.config.uuid: gateway
for gateway in self.hass.data.get(DOMAIN, {}).values()
}

if bridgeid in gateway_entries:
entry = gateway_entries[bridgeid]
if uuid in gateways:
entry = gateways[uuid].config_entry
await self._update_entry(entry, discovery_info[CONF_HOST])
return self.async_abort(reason='updated_instance')

# pylint: disable=unsupported-assignment-operation
self.context[ATTR_SERIAL] = bridgeid

if any(bridgeid == flow['context'][ATTR_SERIAL]
bridgeid = discovery_info[ATTR_SERIAL]
if any(bridgeid == flow['context'][CONF_BRIDGEID]
for flow in self._async_in_progress()):
return self.async_abort(reason='already_in_progress')

# pylint: disable=unsupported-assignment-operation
self.context[CONF_BRIDGEID] = bridgeid

deconz_config = {
CONF_HOST: discovery_info[CONF_HOST],
CONF_PORT: discovery_info[CONF_PORT],
CONF_BRIDGEID: bridgeid
}

return await self.async_step_import(deconz_config)
Expand Down
22 changes: 11 additions & 11 deletions homeassistant/components/discovery/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@
SERVICE_MOBILE_APP: ('mobile_app', None),
SERVICE_HASS_IOS_APP: ('ios', None),
SERVICE_NETGEAR: ('device_tracker', None),
SERVICE_WEMO: ('wemo', None),
SERVICE_HASSIO: ('hassio', None),
SERVICE_APPLE_TV: ('apple_tv', None),
SERVICE_ENIGMA2: ('media_player', 'enigma2'),
Expand Down Expand Up @@ -94,19 +93,20 @@
SERVICE_DLNA_DMR: ('media_player', 'dlna_dmr'),
}

MIGRATED_SERVICE_HANDLERS = {
'axis': None,
'deconz': None,
'esphome': None,
'ikea_tradfri': None,
'homekit': None,
'philips_hue': None
}
MIGRATED_SERVICE_HANDLERS = [
'axis',
'deconz',
'esphome',
'ikea_tradfri',
'homekit',
'philips_hue',
SERVICE_WEMO,
]

DEFAULT_ENABLED = list(CONFIG_ENTRY_HANDLERS) + list(SERVICE_HANDLERS) + \
list(MIGRATED_SERVICE_HANDLERS)
MIGRATED_SERVICE_HANDLERS
DEFAULT_DISABLED = list(OPTIONAL_SERVICE_HANDLERS) + \
list(MIGRATED_SERVICE_HANDLERS)
MIGRATED_SERVICE_HANDLERS

CONF_IGNORE = 'ignore'
CONF_ENABLE = 'enable'
Expand Down
2 changes: 0 additions & 2 deletions homeassistant/components/homekit_controller/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,7 @@


HOMEKIT_IGNORE = [
'BSB002',
'Home Assistant Bridge',
'TRADFRI gateway',
]
HOMEKIT_DIR = '.homekit'
PAIRING_FILE = 'pairing.json'
Expand Down
1 change: 1 addition & 0 deletions homeassistant/components/http/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,7 @@ def __init__(self, hass,
self.ssl_key = ssl_key
self.server_host = server_host
self.server_port = server_port
self.trusted_proxies = trusted_proxies
self.is_ban_enabled = is_ban_enabled
self.ssl_profile = ssl_profile
self._handler = None
Expand Down
16 changes: 16 additions & 0 deletions homeassistant/components/hue/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,22 @@ async def async_step_ssdp(self, discovery_info):
'path': 'phue-{}.conf'.format(serial)
})

async def async_step_homekit(self, homekit_info):
"""Handle HomeKit discovery."""
# pylint: disable=unsupported-assignment-operation
host = self.context['host'] = homekit_info.get('host')

if any(host == flow['context']['host']
for flow in self._async_in_progress()):
return self.async_abort(reason='already_in_progress')

if host in configured_hosts(self.hass):
return self.async_abort(reason='already_configured')

return await self.async_step_import({
'host': host,
})

async def async_step_import(self, import_info):
"""Import a new bridge as a config entry.
Expand Down
5 changes: 5 additions & 0 deletions homeassistant/components/hue/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@
"Royal Philips Electronics"
]
},
"homekit": {
"models": [
"BSB002"
]
},
"dependencies": [],
"codeowners": [
"@balloob"
Expand Down
21 changes: 14 additions & 7 deletions homeassistant/components/sun/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
from datetime import timedelta

from homeassistant.const import (
CONF_ELEVATION, SUN_EVENT_SUNRISE, SUN_EVENT_SUNSET)
CONF_ELEVATION, SUN_EVENT_SUNRISE, SUN_EVENT_SUNSET,
EVENT_CORE_CONFIG_UPDATE)
from homeassistant.core import callback
from homeassistant.helpers.entity import Entity
from homeassistant.helpers.event import async_track_point_in_utc_time
Expand Down Expand Up @@ -70,7 +71,7 @@ async def async_setup(hass, config):
_LOGGER.warning(
"Elevation is now configured in home assistant core. "
"See https://home-assistant.io/docs/configuration/basic/")
Sun(hass, get_astral_location(hass))
Sun(hass)
return True


Expand All @@ -79,18 +80,23 @@ class Sun(Entity):

entity_id = ENTITY_ID

def __init__(self, hass, location):
def __init__(self, hass):
"""Initialize the sun."""
self.hass = hass
self.location = location
self.location = None
self._state = self.next_rising = self.next_setting = None
self.next_dawn = self.next_dusk = None
self.next_midnight = self.next_noon = None
self.solar_elevation = self.solar_azimuth = None
self.rising = self.phase = None

self._next_change = None
self.update_events(dt_util.utcnow())

def update_location(event):
self.location = get_astral_location(self.hass)
self.update_events(dt_util.utcnow())
update_location(None)
self.hass.bus.async_listen(
EVENT_CORE_CONFIG_UPDATE, update_location)

@property
def name(self):
Expand All @@ -100,7 +106,8 @@ def name(self):
@property
def state(self):
"""Return the state of the sun."""
if self.next_rising > self.next_setting:
# 0.8333 is the same value as astral uses
if self.solar_elevation > -0.833:
return STATE_ABOVE_HORIZON

return STATE_BELOW_HORIZON
Expand Down
Loading

0 comments on commit 282b4f4

Please sign in to comment.