mirror of
https://github.com/home-assistant/core.git
synced 2025-07-20 03:37:07 +00:00
commit
fbc53a886f
@ -77,6 +77,12 @@ class CloudGoogleConfig(AbstractConfig):
|
|||||||
"""Return Cloud User account."""
|
"""Return Cloud User account."""
|
||||||
return self._user
|
return self._user
|
||||||
|
|
||||||
|
async def async_initialize(self):
|
||||||
|
"""Perform async initialization of config."""
|
||||||
|
await super().async_initialize()
|
||||||
|
# Remove bad data that was there until 0.103.6 - Jan 6, 2020
|
||||||
|
self._store.pop_agent_user_id(self._user)
|
||||||
|
|
||||||
def should_expose(self, state):
|
def should_expose(self, state):
|
||||||
"""If a state object should be exposed."""
|
"""If a state object should be exposed."""
|
||||||
return self._should_expose_entity_id(state.entity_id)
|
return self._should_expose_entity_id(state.entity_id)
|
||||||
@ -93,6 +99,15 @@ class CloudGoogleConfig(AbstractConfig):
|
|||||||
entity_config = entity_configs.get(entity_id, {})
|
entity_config = entity_configs.get(entity_id, {})
|
||||||
return entity_config.get(PREF_SHOULD_EXPOSE, DEFAULT_SHOULD_EXPOSE)
|
return entity_config.get(PREF_SHOULD_EXPOSE, DEFAULT_SHOULD_EXPOSE)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def agent_user_id(self):
|
||||||
|
"""Return Agent User Id to use for query responses."""
|
||||||
|
return self._cloud.username
|
||||||
|
|
||||||
|
def get_agent_user_id(self, context):
|
||||||
|
"""Get agent user ID making request."""
|
||||||
|
return self.agent_user_id
|
||||||
|
|
||||||
def should_2fa(self, state):
|
def should_2fa(self, state):
|
||||||
"""If an entity should be checked for 2FA."""
|
"""If an entity should be checked for 2FA."""
|
||||||
entity_configs = self._prefs.google_entity_configs
|
entity_configs = self._prefs.google_entity_configs
|
||||||
|
@ -175,7 +175,7 @@ class GoogleActionsSyncView(HomeAssistantView):
|
|||||||
hass = request.app["hass"]
|
hass = request.app["hass"]
|
||||||
cloud: Cloud = hass.data[DOMAIN]
|
cloud: Cloud = hass.data[DOMAIN]
|
||||||
gconf = await cloud.client.get_google_config()
|
gconf = await cloud.client.get_google_config()
|
||||||
status = await gconf.async_sync_entities(gconf.cloud_user)
|
status = await gconf.async_sync_entities(gconf.agent_user_id)
|
||||||
return self.json({}, status_code=status)
|
return self.json({}, status_code=status)
|
||||||
|
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
"name": "Environment Canada",
|
"name": "Environment Canada",
|
||||||
"documentation": "https://www.home-assistant.io/integrations/environment_canada",
|
"documentation": "https://www.home-assistant.io/integrations/environment_canada",
|
||||||
"requirements": [
|
"requirements": [
|
||||||
"env_canada==0.0.30"
|
"env_canada==0.0.31"
|
||||||
],
|
],
|
||||||
"dependencies": [],
|
"dependencies": [],
|
||||||
"codeowners": [
|
"codeowners": [
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
"""Helper classes for Google Assistant integration."""
|
"""Helper classes for Google Assistant integration."""
|
||||||
|
from abc import ABC, abstractmethod
|
||||||
from asyncio import gather
|
from asyncio import gather
|
||||||
from collections.abc import Mapping
|
from collections.abc import Mapping
|
||||||
import logging
|
import logging
|
||||||
@ -35,7 +36,7 @@ SYNC_DELAY = 15
|
|||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class AbstractConfig:
|
class AbstractConfig(ABC):
|
||||||
"""Hold the configuration for Google Assistant."""
|
"""Hold the configuration for Google Assistant."""
|
||||||
|
|
||||||
_unsub_report_state = None
|
_unsub_report_state = None
|
||||||
@ -95,9 +96,13 @@ class AbstractConfig:
|
|||||||
"""Return the user ID to be used for actions received via the local SDK."""
|
"""Return the user ID to be used for actions received via the local SDK."""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def get_agent_user_id(self, context):
|
||||||
|
"""Get agent user ID from context."""
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
def should_expose(self, state) -> bool:
|
def should_expose(self, state) -> bool:
|
||||||
"""Return if entity should be exposed."""
|
"""Return if entity should be exposed."""
|
||||||
raise NotImplementedError
|
|
||||||
|
|
||||||
def should_2fa(self, state):
|
def should_2fa(self, state):
|
||||||
"""If an entity should have 2FA checked."""
|
"""If an entity should have 2FA checked."""
|
||||||
|
@ -121,6 +121,10 @@ class GoogleConfig(AbstractConfig):
|
|||||||
|
|
||||||
return is_default_exposed or explicit_expose
|
return is_default_exposed or explicit_expose
|
||||||
|
|
||||||
|
def get_agent_user_id(self, context):
|
||||||
|
"""Get agent user ID making request."""
|
||||||
|
return context.user_id
|
||||||
|
|
||||||
def should_2fa(self, state):
|
def should_2fa(self, state):
|
||||||
"""If an entity should have 2FA checked."""
|
"""If an entity should have 2FA checked."""
|
||||||
return True
|
return True
|
||||||
|
@ -79,7 +79,7 @@ async def async_devices_sync(hass, data, payload):
|
|||||||
EVENT_SYNC_RECEIVED, {"request_id": data.request_id}, context=data.context
|
EVENT_SYNC_RECEIVED, {"request_id": data.request_id}, context=data.context
|
||||||
)
|
)
|
||||||
|
|
||||||
agent_user_id = data.context.user_id
|
agent_user_id = data.config.get_agent_user_id(data.context)
|
||||||
|
|
||||||
devices = await asyncio.gather(
|
devices = await asyncio.gather(
|
||||||
*(
|
*(
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
"name": "Smartthings",
|
"name": "Smartthings",
|
||||||
"config_flow": true,
|
"config_flow": true,
|
||||||
"documentation": "https://www.home-assistant.io/integrations/smartthings",
|
"documentation": "https://www.home-assistant.io/integrations/smartthings",
|
||||||
"requirements": ["pysmartapp==0.3.2", "pysmartthings==0.6.9"],
|
"requirements": ["pysmartapp==0.3.2", "pysmartthings==0.7.0"],
|
||||||
"dependencies": ["webhook"],
|
"dependencies": ["webhook"],
|
||||||
"after_dependencies": ["cloud"],
|
"after_dependencies": ["cloud"],
|
||||||
"codeowners": ["@andrewsayre"]
|
"codeowners": ["@andrewsayre"]
|
||||||
|
@ -131,6 +131,9 @@ class UniFiClientTracker(ScannerEntity):
|
|||||||
self.is_wired = self.client.mac not in controller.wireless_clients
|
self.is_wired = self.client.mac not in controller.wireless_clients
|
||||||
self.wired_bug = None
|
self.wired_bug = None
|
||||||
|
|
||||||
|
if self.is_wired != self.client.is_wired:
|
||||||
|
self.wired_bug = dt_util.utcnow() - self.controller.option_detection_time
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def entity_registry_enabled_default(self):
|
def entity_registry_enabled_default(self):
|
||||||
"""Return if the entity should be enabled when first added to the entity registry."""
|
"""Return if the entity should be enabled when first added to the entity registry."""
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
"""Constants used by Home Assistant components."""
|
"""Constants used by Home Assistant components."""
|
||||||
MAJOR_VERSION = 0
|
MAJOR_VERSION = 0
|
||||||
MINOR_VERSION = 103
|
MINOR_VERSION = 103
|
||||||
PATCH_VERSION = "5"
|
PATCH_VERSION = "6"
|
||||||
__short_version__ = "{}.{}".format(MAJOR_VERSION, MINOR_VERSION)
|
__short_version__ = "{}.{}".format(MAJOR_VERSION, MINOR_VERSION)
|
||||||
__version__ = "{}.{}".format(__short_version__, PATCH_VERSION)
|
__version__ = "{}.{}".format(__short_version__, PATCH_VERSION)
|
||||||
REQUIRED_PYTHON_VER = (3, 6, 1)
|
REQUIRED_PYTHON_VER = (3, 6, 1)
|
||||||
|
@ -475,7 +475,7 @@ enocean==0.50
|
|||||||
enturclient==0.2.1
|
enturclient==0.2.1
|
||||||
|
|
||||||
# homeassistant.components.environment_canada
|
# homeassistant.components.environment_canada
|
||||||
env_canada==0.0.30
|
env_canada==0.0.31
|
||||||
|
|
||||||
# homeassistant.components.envirophat
|
# homeassistant.components.envirophat
|
||||||
# envirophat==0.0.6
|
# envirophat==0.0.6
|
||||||
@ -1485,7 +1485,7 @@ pysma==0.3.4
|
|||||||
pysmartapp==0.3.2
|
pysmartapp==0.3.2
|
||||||
|
|
||||||
# homeassistant.components.smartthings
|
# homeassistant.components.smartthings
|
||||||
pysmartthings==0.6.9
|
pysmartthings==0.7.0
|
||||||
|
|
||||||
# homeassistant.components.smarty
|
# homeassistant.components.smarty
|
||||||
pysmarty==0.8
|
pysmarty==0.8
|
||||||
|
@ -490,7 +490,7 @@ pysma==0.3.4
|
|||||||
pysmartapp==0.3.2
|
pysmartapp==0.3.2
|
||||||
|
|
||||||
# homeassistant.components.smartthings
|
# homeassistant.components.smartthings
|
||||||
pysmartthings==0.6.9
|
pysmartthings==0.7.0
|
||||||
|
|
||||||
# homeassistant.components.soma
|
# homeassistant.components.soma
|
||||||
pysoma==0.0.10
|
pysoma==0.0.10
|
||||||
|
@ -102,13 +102,17 @@ async def test_handler_google_actions(hass):
|
|||||||
reqid = "5711642932632160983"
|
reqid = "5711642932632160983"
|
||||||
data = {"requestId": reqid, "inputs": [{"intent": "action.devices.SYNC"}]}
|
data = {"requestId": reqid, "inputs": [{"intent": "action.devices.SYNC"}]}
|
||||||
|
|
||||||
config = await cloud.client.get_google_config()
|
with patch(
|
||||||
resp = await cloud.client.async_google_message(data)
|
"hass_nabucasa.Cloud._decode_claims",
|
||||||
|
return_value={"cognito:username": "myUserName"},
|
||||||
|
):
|
||||||
|
await cloud.client.get_google_config()
|
||||||
|
resp = await cloud.client.async_google_message(data)
|
||||||
|
|
||||||
assert resp["requestId"] == reqid
|
assert resp["requestId"] == reqid
|
||||||
payload = resp["payload"]
|
payload = resp["payload"]
|
||||||
|
|
||||||
assert payload["agentUserId"] == config.cloud_user
|
assert payload["agentUserId"] == "myUserName"
|
||||||
|
|
||||||
devices = payload["devices"]
|
devices = payload["devices"]
|
||||||
assert len(devices) == 1
|
assert len(devices) == 1
|
||||||
|
@ -63,6 +63,10 @@ class MockConfig(helpers.AbstractConfig):
|
|||||||
"""Return local SDK webhook id."""
|
"""Return local SDK webhook id."""
|
||||||
return self._local_sdk_user_id
|
return self._local_sdk_user_id
|
||||||
|
|
||||||
|
def get_agent_user_id(self, context):
|
||||||
|
"""Get agent user ID making request."""
|
||||||
|
return context.user_id
|
||||||
|
|
||||||
def should_expose(self, state):
|
def should_expose(self, state):
|
||||||
"""Expose it all."""
|
"""Expose it all."""
|
||||||
return self._should_expose is None or self._should_expose(state)
|
return self._should_expose is None or self._should_expose(state)
|
||||||
|
@ -60,6 +60,7 @@ async def setup_unifi_integration(
|
|||||||
clients_response,
|
clients_response,
|
||||||
devices_response,
|
devices_response,
|
||||||
clients_all_response,
|
clients_all_response,
|
||||||
|
known_wireless_clients=None,
|
||||||
):
|
):
|
||||||
"""Create the UniFi controller."""
|
"""Create the UniFi controller."""
|
||||||
if UNIFI_CONFIG not in hass.data:
|
if UNIFI_CONFIG not in hass.data:
|
||||||
@ -77,6 +78,11 @@ async def setup_unifi_integration(
|
|||||||
entry_id=1,
|
entry_id=1,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if known_wireless_clients:
|
||||||
|
hass.data[UNIFI_WIRELESS_CLIENTS].update_data(
|
||||||
|
known_wireless_clients, config_entry
|
||||||
|
)
|
||||||
|
|
||||||
mock_client_responses = deque()
|
mock_client_responses = deque()
|
||||||
mock_client_responses.append(clients_response)
|
mock_client_responses.append(clients_response)
|
||||||
|
|
||||||
|
@ -44,6 +44,14 @@ CLIENT_3 = {
|
|||||||
"last_seen": 1562600145,
|
"last_seen": 1562600145,
|
||||||
"mac": "00:00:00:00:00:03",
|
"mac": "00:00:00:00:00:03",
|
||||||
}
|
}
|
||||||
|
CLIENT_4 = {
|
||||||
|
"essid": "ssid",
|
||||||
|
"hostname": "client_4",
|
||||||
|
"ip": "10.0.0.4",
|
||||||
|
"is_wired": True,
|
||||||
|
"last_seen": 1562600145,
|
||||||
|
"mac": "00:00:00:00:00:04",
|
||||||
|
}
|
||||||
|
|
||||||
DEVICE_1 = {
|
DEVICE_1 = {
|
||||||
"board_rev": 3,
|
"board_rev": 3,
|
||||||
@ -103,16 +111,20 @@ async def test_no_clients(hass):
|
|||||||
|
|
||||||
async def test_tracked_devices(hass):
|
async def test_tracked_devices(hass):
|
||||||
"""Test the update_items function with some clients."""
|
"""Test the update_items function with some clients."""
|
||||||
|
client_4_copy = copy(CLIENT_4)
|
||||||
|
client_4_copy["last_seen"] = dt_util.as_timestamp(dt_util.utcnow())
|
||||||
|
|
||||||
controller = await setup_unifi_integration(
|
controller = await setup_unifi_integration(
|
||||||
hass,
|
hass,
|
||||||
ENTRY_CONFIG,
|
ENTRY_CONFIG,
|
||||||
options={CONF_SSID_FILTER: ["ssid"]},
|
options={CONF_SSID_FILTER: ["ssid"]},
|
||||||
sites=SITES,
|
sites=SITES,
|
||||||
clients_response=[CLIENT_1, CLIENT_2, CLIENT_3],
|
clients_response=[CLIENT_1, CLIENT_2, CLIENT_3, client_4_copy],
|
||||||
devices_response=[DEVICE_1, DEVICE_2],
|
devices_response=[DEVICE_1, DEVICE_2],
|
||||||
clients_all_response={},
|
clients_all_response={},
|
||||||
|
known_wireless_clients=(CLIENT_4["mac"],),
|
||||||
)
|
)
|
||||||
assert len(hass.states.async_all()) == 5
|
assert len(hass.states.async_all()) == 6
|
||||||
|
|
||||||
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
|
||||||
@ -125,6 +137,11 @@ async def test_tracked_devices(hass):
|
|||||||
client_3 = hass.states.get("device_tracker.client_3")
|
client_3 = hass.states.get("device_tracker.client_3")
|
||||||
assert client_3 is None
|
assert client_3 is None
|
||||||
|
|
||||||
|
# Wireless client with wired bug, if bug active on restart mark device away
|
||||||
|
client_4 = hass.states.get("device_tracker.client_4")
|
||||||
|
assert client_4 is not None
|
||||||
|
assert client_4.state == "not_home"
|
||||||
|
|
||||||
device_1 = hass.states.get("device_tracker.device_1")
|
device_1 = hass.states.get("device_tracker.device_1")
|
||||||
assert device_1 is not None
|
assert device_1 is not None
|
||||||
assert device_1.state == "not_home"
|
assert device_1.state == "not_home"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user