diff --git a/homeassistant/auth/__init__.py b/homeassistant/auth/__init__.py index 7d8ef13d2bb..49f01211e5a 100644 --- a/homeassistant/auth/__init__.py +++ b/homeassistant/auth/__init__.py @@ -190,6 +190,7 @@ class AuthManager: credentials=credentials, name=info.name, is_active=info.is_active, + group_ids=[GROUP_ID_ADMIN], ) self.hass.bus.async_fire(EVENT_USER_ADDED, { diff --git a/homeassistant/components/asuswrt.py b/homeassistant/components/asuswrt.py index c653c1d03fd..719e857c751 100644 --- a/homeassistant/components/asuswrt.py +++ b/homeassistant/components/asuswrt.py @@ -14,7 +14,7 @@ from homeassistant.const import ( from homeassistant.helpers import config_validation as cv from homeassistant.helpers.discovery import async_load_platform -REQUIREMENTS = ['aioasuswrt==1.1.11'] +REQUIREMENTS = ['aioasuswrt==1.1.13'] _LOGGER = logging.getLogger(__name__) diff --git a/homeassistant/components/cloud/__init__.py b/homeassistant/components/cloud/__init__.py index 4f4b0c582fc..ba5621b1f8d 100644 --- a/homeassistant/components/cloud/__init__.py +++ b/homeassistant/components/cloud/__init__.py @@ -186,9 +186,9 @@ class Cloud: self._gactions_config = ga_h.Config( should_expose=should_expose, + allow_unlock=self.prefs.google_allow_unlock, agent_user_id=self.claims['cognito:username'], entity_config=conf.get(CONF_ENTITY_CONFIG), - allow_unlock=self.prefs.google_allow_unlock, ) return self._gactions_config diff --git a/homeassistant/components/device_tracker/googlehome.py b/homeassistant/components/device_tracker/googlehome.py index 575d9688493..dabb92a0751 100644 --- a/homeassistant/components/device_tracker/googlehome.py +++ b/homeassistant/components/device_tracker/googlehome.py @@ -14,7 +14,7 @@ from homeassistant.components.device_tracker import ( DOMAIN, PLATFORM_SCHEMA, DeviceScanner) from homeassistant.const import CONF_HOST -REQUIREMENTS = ['ghlocalapi==0.1.0'] +REQUIREMENTS = ['ghlocalapi==0.3.5'] _LOGGER = logging.getLogger(__name__) @@ -89,4 +89,5 @@ class GoogleHomeDeviceScanner(DeviceScanner): devices[uuid]['btle_mac_address'] = device['mac_address'] devices[uuid]['ghname'] = ghname devices[uuid]['source_type'] = 'bluetooth' + await self.scanner.clear_scan_result() self.last_results = devices diff --git a/homeassistant/components/google_assistant/helpers.py b/homeassistant/components/google_assistant/helpers.py index e71756d9fee..f20a4106a16 100644 --- a/homeassistant/components/google_assistant/helpers.py +++ b/homeassistant/components/google_assistant/helpers.py @@ -16,8 +16,8 @@ class SmartHomeError(Exception): class Config: """Hold the configuration for Google Assistant.""" - def __init__(self, should_expose, agent_user_id, entity_config=None, - allow_unlock=False): + def __init__(self, should_expose, allow_unlock, agent_user_id, + entity_config=None): """Initialize the configuration.""" self.should_expose = should_expose self.agent_user_id = agent_user_id diff --git a/homeassistant/components/google_assistant/http.py b/homeassistant/components/google_assistant/http.py index f29e8bbae12..d688491fe89 100644 --- a/homeassistant/components/google_assistant/http.py +++ b/homeassistant/components/google_assistant/http.py @@ -15,6 +15,7 @@ from homeassistant.const import CLOUD_NEVER_EXPOSED_ENTITIES from .const import ( GOOGLE_ASSISTANT_API_ENDPOINT, + CONF_ALLOW_UNLOCK, CONF_EXPOSE_BY_DEFAULT, CONF_EXPOSED_DOMAINS, CONF_ENTITY_CONFIG, @@ -32,6 +33,7 @@ def async_register_http(hass, cfg): expose_by_default = cfg.get(CONF_EXPOSE_BY_DEFAULT) exposed_domains = cfg.get(CONF_EXPOSED_DOMAINS) entity_config = cfg.get(CONF_ENTITY_CONFIG) or {} + allow_unlock = cfg.get(CONF_ALLOW_UNLOCK, False) def is_exposed(entity) -> bool: """Determine if an entity should be exposed to Google Assistant.""" @@ -57,7 +59,7 @@ def async_register_http(hass, cfg): return is_default_exposed or explicit_expose hass.http.register_view( - GoogleAssistantView(is_exposed, entity_config)) + GoogleAssistantView(is_exposed, entity_config, allow_unlock)) class GoogleAssistantView(HomeAssistantView): @@ -67,15 +69,17 @@ class GoogleAssistantView(HomeAssistantView): name = 'api:google_assistant' requires_auth = True - def __init__(self, is_exposed, entity_config): + def __init__(self, is_exposed, entity_config, allow_unlock): """Initialize the Google Assistant request handler.""" self.is_exposed = is_exposed self.entity_config = entity_config + self.allow_unlock = allow_unlock async def post(self, request: Request) -> Response: """Handle Google Assistant requests.""" message = await request.json() # type: dict config = Config(self.is_exposed, + self.allow_unlock, request['hass_user'].id, self.entity_config) result = await async_handle_message( diff --git a/homeassistant/components/sensor/asuswrt.py b/homeassistant/components/sensor/asuswrt.py index 4ca088fb1e2..876f0dfd559 100644 --- a/homeassistant/components/sensor/asuswrt.py +++ b/homeassistant/components/sensor/asuswrt.py @@ -68,7 +68,7 @@ class AsuswrtRXSensor(AsuswrtSensor): async def async_update(self): """Fetch new state data for the sensor.""" await super().async_update() - if self._speed is not None: + if self._speed: self._state = round(self._speed[0] / 125000, 2) @@ -86,7 +86,7 @@ class AsuswrtTXSensor(AsuswrtSensor): async def async_update(self): """Fetch new state data for the sensor.""" await super().async_update() - if self._speed is not None: + if self._speed: self._state = round(self._speed[1] / 125000, 2) @@ -104,7 +104,7 @@ class AsuswrtTotalRXSensor(AsuswrtSensor): async def async_update(self): """Fetch new state data for the sensor.""" await super().async_update() - if self._rates is not None: + if self._rates: self._state = round(self._rates[0] / 1000000000, 1) @@ -122,5 +122,5 @@ class AsuswrtTotalTXSensor(AsuswrtSensor): async def async_update(self): """Fetch new state data for the sensor.""" await super().async_update() - if self._rates is not None: + if self._rates: self._state = round(self._rates[1] / 1000000000, 1) diff --git a/homeassistant/components/sensor/tautulli.py b/homeassistant/components/sensor/tautulli.py index 7b0d8e491d2..f47f0e5c382 100644 --- a/homeassistant/components/sensor/tautulli.py +++ b/homeassistant/components/sensor/tautulli.py @@ -19,7 +19,7 @@ import homeassistant.helpers.config_validation as cv from homeassistant.helpers.entity import Entity from homeassistant.util import Throttle -REQUIREMENTS = ['pytautulli==0.4.0'] +REQUIREMENTS = ['pytautulli==0.4.1'] _LOGGER = logging.getLogger(__name__) @@ -90,9 +90,9 @@ class TautulliSensor(Entity): await self.tautulli.async_update() self.home = self.tautulli.api.home_data self.sessions = self.tautulli.api.session_data - self._attributes['Top Movie'] = self.home[0]['rows'][0]['title'] - self._attributes['Top TV Show'] = self.home[3]['rows'][0]['title'] - self._attributes['Top User'] = self.home[7]['rows'][0]['user'] + self._attributes['Top Movie'] = self.home.get('movie') + self._attributes['Top TV Show'] = self.home.get('tv') + self._attributes['Top User'] = self.home.get('user') for key in self.sessions: if 'sessions' not in key: self._attributes[key] = self.sessions[key] diff --git a/homeassistant/components/wink/__init__.py b/homeassistant/components/wink/__init__.py index a94f8c3bdf2..c4cefa2c2d1 100644 --- a/homeassistant/components/wink/__init__.py +++ b/homeassistant/components/wink/__init__.py @@ -690,6 +690,10 @@ class WinkDevice(Entity): @property def unique_id(self): """Return the unique id of the Wink device.""" + if hasattr(self.wink, 'capability') and \ + self.wink.capability() is not None: + return "{}_{}".format(self.wink.object_id(), + self.wink.capability()) return self.wink.object_id() @property diff --git a/homeassistant/const.py b/homeassistant/const.py index 1a1d45396f0..63d4e9f00f5 100644 --- a/homeassistant/const.py +++ b/homeassistant/const.py @@ -2,7 +2,7 @@ """Constants used by Home Assistant components.""" MAJOR_VERSION = 0 MINOR_VERSION = 83 -PATCH_VERSION = '2' +PATCH_VERSION = '3' __short_version__ = '{}.{}'.format(MAJOR_VERSION, MINOR_VERSION) __version__ = '{}.{}'.format(__short_version__, PATCH_VERSION) REQUIRED_PYTHON_VER = (3, 5, 3) diff --git a/requirements_all.txt b/requirements_all.txt index e4020ca41e7..169c54aa713 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -86,7 +86,7 @@ abodepy==0.14.0 afsapi==0.0.4 # homeassistant.components.asuswrt -aioasuswrt==1.1.11 +aioasuswrt==1.1.13 # homeassistant.components.device_tracker.automatic aioautomatic==0.6.5 @@ -422,7 +422,7 @@ geojson_client==0.3 georss_client==0.4 # homeassistant.components.device_tracker.googlehome -ghlocalapi==0.1.0 +ghlocalapi==0.3.5 # homeassistant.components.sensor.gitter gitterpy==0.1.7 @@ -1154,7 +1154,7 @@ pystride==0.1.7 pysyncthru==0.3.1 # homeassistant.components.sensor.tautulli -pytautulli==0.4.0 +pytautulli==0.4.1 # homeassistant.components.media_player.liveboxplaytv pyteleloisirs==3.4 diff --git a/tests/auth/test_init.py b/tests/auth/test_init.py index 4357ba1b1de..e950230f10a 100644 --- a/tests/auth/test_init.py +++ b/tests/auth/test_init.py @@ -870,3 +870,28 @@ async def test_async_remove_user(hass): await hass.async_block_till_done() assert len(events) == 1 assert events[0].data['user_id'] == user.id + + +async def test_new_users_admin(mock_hass): + """Test newly created users are admin.""" + manager = await auth.auth_manager_from_config(mock_hass, [{ + 'type': 'insecure_example', + 'users': [{ + 'username': 'test-user', + 'password': 'test-pass', + 'name': 'Test Name' + }] + }], []) + ensure_auth_manager_loaded(manager) + + user = await manager.async_create_user('Hello') + assert user.is_admin + + user_cred = await manager.async_get_or_create_user(auth_models.Credentials( + id='mock-id', + auth_provider_type='insecure_example', + auth_provider_id=None, + data={'username': 'test-user'}, + is_new=True, + )) + assert user_cred.is_admin diff --git a/tests/components/google_assistant/test_smart_home.py b/tests/components/google_assistant/test_smart_home.py index 66e7747e06a..36971224f92 100644 --- a/tests/components/google_assistant/test_smart_home.py +++ b/tests/components/google_assistant/test_smart_home.py @@ -11,6 +11,7 @@ from homeassistant.components.light.demo import DemoLight BASIC_CONFIG = helpers.Config( should_expose=lambda state: True, + allow_unlock=False, agent_user_id='test-agent', ) REQ_ID = 'ff36a3cc-ec34-11e6-b1a0-64510650abcf' @@ -35,6 +36,7 @@ async def test_sync_message(hass): config = helpers.Config( should_expose=lambda state: state.entity_id != 'light.not_expose', + allow_unlock=False, agent_user_id='test-agent', entity_config={ 'light.demo_light': { diff --git a/tests/components/google_assistant/test_trait.py b/tests/components/google_assistant/test_trait.py index 42af1230eed..616c43464a6 100644 --- a/tests/components/google_assistant/test_trait.py +++ b/tests/components/google_assistant/test_trait.py @@ -25,6 +25,7 @@ from tests.common import async_mock_service BASIC_CONFIG = helpers.Config( should_expose=lambda state: True, + allow_unlock=False, agent_user_id='test-agent', )