mirror of
https://github.com/home-assistant/core.git
synced 2025-07-25 14:17:45 +00:00
Store remote domain in Cloud preferences (#64532)
This commit is contained in:
parent
9f12612391
commit
3575009330
@ -157,10 +157,10 @@ def async_remote_ui_url(hass: HomeAssistant) -> str:
|
|||||||
if not hass.data[DOMAIN].client.prefs.remote_enabled:
|
if not hass.data[DOMAIN].client.prefs.remote_enabled:
|
||||||
raise CloudNotAvailable
|
raise CloudNotAvailable
|
||||||
|
|
||||||
if not hass.data[DOMAIN].remote.instance_domain:
|
if not (remote_domain := hass.data[DOMAIN].client.prefs.remote_domain):
|
||||||
raise CloudNotAvailable
|
raise CloudNotAvailable
|
||||||
|
|
||||||
return f"https://{hass.data[DOMAIN].remote.instance_domain}"
|
return f"https://{remote_domain}"
|
||||||
|
|
||||||
|
|
||||||
def is_cloudhook_request(request):
|
def is_cloudhook_request(request):
|
||||||
@ -235,7 +235,12 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
|
|||||||
Platform.TTS, DOMAIN, {}, config
|
Platform.TTS, DOMAIN, {}, config
|
||||||
)
|
)
|
||||||
|
|
||||||
|
async def _on_initialized():
|
||||||
|
"""Update preferences."""
|
||||||
|
await prefs.async_update(remote_domain=cloud.remote.instance_domain)
|
||||||
|
|
||||||
cloud.iot.register_on_connect(_on_connect)
|
cloud.iot.register_on_connect(_on_connect)
|
||||||
|
cloud.register_on_initialized(_on_initialized)
|
||||||
|
|
||||||
await cloud.initialize()
|
await cloud.initialize()
|
||||||
await http_api.async_setup(hass)
|
await http_api.async_setup(hass)
|
||||||
|
@ -18,6 +18,7 @@ PREF_ALIASES = "aliases"
|
|||||||
PREF_SHOULD_EXPOSE = "should_expose"
|
PREF_SHOULD_EXPOSE = "should_expose"
|
||||||
PREF_GOOGLE_LOCAL_WEBHOOK_ID = "google_local_webhook_id"
|
PREF_GOOGLE_LOCAL_WEBHOOK_ID = "google_local_webhook_id"
|
||||||
PREF_USERNAME = "username"
|
PREF_USERNAME = "username"
|
||||||
|
PREF_REMOTE_DOMAIN = "remote_domain"
|
||||||
PREF_ALEXA_DEFAULT_EXPOSE = "alexa_default_expose"
|
PREF_ALEXA_DEFAULT_EXPOSE = "alexa_default_expose"
|
||||||
PREF_GOOGLE_DEFAULT_EXPOSE = "google_default_expose"
|
PREF_GOOGLE_DEFAULT_EXPOSE = "google_default_expose"
|
||||||
PREF_TTS_DEFAULT_VOICE = "tts_default_voice"
|
PREF_TTS_DEFAULT_VOICE = "tts_default_voice"
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
"domain": "cloud",
|
"domain": "cloud",
|
||||||
"name": "Home Assistant Cloud",
|
"name": "Home Assistant Cloud",
|
||||||
"documentation": "https://www.home-assistant.io/integrations/cloud",
|
"documentation": "https://www.home-assistant.io/integrations/cloud",
|
||||||
"requirements": ["hass-nabucasa==0.51.0"],
|
"requirements": ["hass-nabucasa==0.52.0"],
|
||||||
"dependencies": ["http", "webhook"],
|
"dependencies": ["http", "webhook"],
|
||||||
"after_dependencies": ["google_assistant", "alexa"],
|
"after_dependencies": ["google_assistant", "alexa"],
|
||||||
"codeowners": ["@home-assistant/cloud"],
|
"codeowners": ["@home-assistant/cloud"],
|
||||||
|
@ -30,6 +30,7 @@ from .const import (
|
|||||||
PREF_GOOGLE_REPORT_STATE,
|
PREF_GOOGLE_REPORT_STATE,
|
||||||
PREF_GOOGLE_SECURE_DEVICES_PIN,
|
PREF_GOOGLE_SECURE_DEVICES_PIN,
|
||||||
PREF_OVERRIDE_NAME,
|
PREF_OVERRIDE_NAME,
|
||||||
|
PREF_REMOTE_DOMAIN,
|
||||||
PREF_SHOULD_EXPOSE,
|
PREF_SHOULD_EXPOSE,
|
||||||
PREF_TTS_DEFAULT_VOICE,
|
PREF_TTS_DEFAULT_VOICE,
|
||||||
PREF_USERNAME,
|
PREF_USERNAME,
|
||||||
@ -85,6 +86,7 @@ class CloudPreferences:
|
|||||||
alexa_default_expose=UNDEFINED,
|
alexa_default_expose=UNDEFINED,
|
||||||
google_default_expose=UNDEFINED,
|
google_default_expose=UNDEFINED,
|
||||||
tts_default_voice=UNDEFINED,
|
tts_default_voice=UNDEFINED,
|
||||||
|
remote_domain=UNDEFINED,
|
||||||
):
|
):
|
||||||
"""Update user preferences."""
|
"""Update user preferences."""
|
||||||
prefs = {**self._prefs}
|
prefs = {**self._prefs}
|
||||||
@ -103,6 +105,7 @@ class CloudPreferences:
|
|||||||
(PREF_ALEXA_DEFAULT_EXPOSE, alexa_default_expose),
|
(PREF_ALEXA_DEFAULT_EXPOSE, alexa_default_expose),
|
||||||
(PREF_GOOGLE_DEFAULT_EXPOSE, google_default_expose),
|
(PREF_GOOGLE_DEFAULT_EXPOSE, google_default_expose),
|
||||||
(PREF_TTS_DEFAULT_VOICE, tts_default_voice),
|
(PREF_TTS_DEFAULT_VOICE, tts_default_voice),
|
||||||
|
(PREF_REMOTE_DOMAIN, remote_domain),
|
||||||
):
|
):
|
||||||
if value is not UNDEFINED:
|
if value is not UNDEFINED:
|
||||||
prefs[key] = value
|
prefs[key] = value
|
||||||
@ -208,6 +211,11 @@ class CloudPreferences:
|
|||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
@property
|
||||||
|
def remote_domain(self):
|
||||||
|
"""Return remote domain."""
|
||||||
|
return self._prefs.get(PREF_REMOTE_DOMAIN)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def alexa_enabled(self):
|
def alexa_enabled(self):
|
||||||
"""Return if Alexa is enabled."""
|
"""Return if Alexa is enabled."""
|
||||||
@ -321,5 +329,6 @@ class CloudPreferences:
|
|||||||
PREF_GOOGLE_ENTITY_CONFIGS: {},
|
PREF_GOOGLE_ENTITY_CONFIGS: {},
|
||||||
PREF_GOOGLE_LOCAL_WEBHOOK_ID: webhook.async_generate_id(),
|
PREF_GOOGLE_LOCAL_WEBHOOK_ID: webhook.async_generate_id(),
|
||||||
PREF_GOOGLE_SECURE_DEVICES_PIN: None,
|
PREF_GOOGLE_SECURE_DEVICES_PIN: None,
|
||||||
|
PREF_REMOTE_DOMAIN: None,
|
||||||
PREF_USERNAME: username,
|
PREF_USERNAME: username,
|
||||||
}
|
}
|
||||||
|
@ -84,6 +84,8 @@ async def websocket_get_entity(hass, connection, msg):
|
|||||||
vol.Coerce(RegistryEntryDisabler), RegistryEntryDisabler.USER.value
|
vol.Coerce(RegistryEntryDisabler), RegistryEntryDisabler.USER.value
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
vol.Inclusive("options_domain", "entity_option"): str,
|
||||||
|
vol.Inclusive("options", "entity_option"): vol.Any(None, dict),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
async def websocket_update_entity(hass, connection, msg):
|
async def websocket_update_entity(hass, connection, msg):
|
||||||
@ -93,7 +95,8 @@ async def websocket_update_entity(hass, connection, msg):
|
|||||||
"""
|
"""
|
||||||
registry = await async_get_registry(hass)
|
registry = await async_get_registry(hass)
|
||||||
|
|
||||||
if msg["entity_id"] not in registry.entities:
|
entity_id = msg["entity_id"]
|
||||||
|
if entity_id not in registry.entities:
|
||||||
connection.send_message(
|
connection.send_message(
|
||||||
websocket_api.error_message(msg["id"], ERR_NOT_FOUND, "Entity not found")
|
websocket_api.error_message(msg["id"], ERR_NOT_FOUND, "Entity not found")
|
||||||
)
|
)
|
||||||
@ -105,7 +108,7 @@ async def websocket_update_entity(hass, connection, msg):
|
|||||||
if key in msg:
|
if key in msg:
|
||||||
changes[key] = msg[key]
|
changes[key] = msg[key]
|
||||||
|
|
||||||
if "new_entity_id" in msg and msg["new_entity_id"] != msg["entity_id"]:
|
if "new_entity_id" in msg and msg["new_entity_id"] != entity_id:
|
||||||
changes["new_entity_id"] = msg["new_entity_id"]
|
changes["new_entity_id"] = msg["new_entity_id"]
|
||||||
if hass.states.get(msg["new_entity_id"]) is not None:
|
if hass.states.get(msg["new_entity_id"]) is not None:
|
||||||
connection.send_message(
|
connection.send_message(
|
||||||
@ -118,7 +121,7 @@ async def websocket_update_entity(hass, connection, msg):
|
|||||||
return
|
return
|
||||||
|
|
||||||
if "disabled_by" in msg and msg["disabled_by"] is None:
|
if "disabled_by" in msg and msg["disabled_by"] is None:
|
||||||
entity = registry.entities[msg["entity_id"]]
|
entity = registry.entities[entity_id]
|
||||||
if entity.device_id:
|
if entity.device_id:
|
||||||
device_registry = await hass.helpers.device_registry.async_get_registry()
|
device_registry = await hass.helpers.device_registry.async_get_registry()
|
||||||
device = device_registry.async_get(entity.device_id)
|
device = device_registry.async_get(entity.device_id)
|
||||||
@ -132,12 +135,28 @@ async def websocket_update_entity(hass, connection, msg):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
if changes:
|
if changes:
|
||||||
entry = registry.async_update_entity(msg["entity_id"], **changes)
|
registry.async_update_entity(entity_id, **changes)
|
||||||
except ValueError as err:
|
except ValueError as err:
|
||||||
connection.send_message(
|
connection.send_message(
|
||||||
websocket_api.error_message(msg["id"], "invalid_info", str(err))
|
websocket_api.error_message(msg["id"], "invalid_info", str(err))
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
if "new_entity_id" in msg:
|
||||||
|
entity_id = msg["new_entity_id"]
|
||||||
|
|
||||||
|
try:
|
||||||
|
if "options_domain" in msg:
|
||||||
|
registry.async_update_entity_options(
|
||||||
|
entity_id, msg["options_domain"], msg["options"]
|
||||||
|
)
|
||||||
|
except ValueError as err:
|
||||||
|
connection.send_message(
|
||||||
|
websocket_api.error_message(msg["id"], "invalid_info", str(err))
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
|
entry = registry.async_get(entity_id)
|
||||||
result = {"entity_entry": _entry_ext_dict(entry)}
|
result = {"entity_entry": _entry_ext_dict(entry)}
|
||||||
if "disabled_by" in changes and changes["disabled_by"] is None:
|
if "disabled_by" in changes and changes["disabled_by"] is None:
|
||||||
config_entry = hass.config_entries.async_get_entry(entry.config_entry_id)
|
config_entry = hass.config_entries.async_get_entry(entry.config_entry_id)
|
||||||
@ -195,6 +214,7 @@ def _entry_ext_dict(entry):
|
|||||||
data = _entry_dict(entry)
|
data = _entry_dict(entry)
|
||||||
data["capabilities"] = entry.capabilities
|
data["capabilities"] = entry.capabilities
|
||||||
data["device_class"] = entry.device_class
|
data["device_class"] = entry.device_class
|
||||||
|
data["options"] = entry.options
|
||||||
data["original_device_class"] = entry.original_device_class
|
data["original_device_class"] = entry.original_device_class
|
||||||
data["original_icon"] = entry.original_icon
|
data["original_icon"] = entry.original_icon
|
||||||
data["original_name"] = entry.original_name
|
data["original_name"] = entry.original_name
|
||||||
|
@ -15,7 +15,7 @@ certifi>=2021.5.30
|
|||||||
ciso8601==2.2.0
|
ciso8601==2.2.0
|
||||||
cryptography==35.0.0
|
cryptography==35.0.0
|
||||||
emoji==1.5.0
|
emoji==1.5.0
|
||||||
hass-nabucasa==0.51.0
|
hass-nabucasa==0.52.0
|
||||||
home-assistant-frontend==20220118.0
|
home-assistant-frontend==20220118.0
|
||||||
httpx==0.21.0
|
httpx==0.21.0
|
||||||
ifaddr==0.1.7
|
ifaddr==0.1.7
|
||||||
|
@ -809,7 +809,7 @@ habitipy==0.2.0
|
|||||||
hangups==0.4.17
|
hangups==0.4.17
|
||||||
|
|
||||||
# homeassistant.components.cloud
|
# homeassistant.components.cloud
|
||||||
hass-nabucasa==0.51.0
|
hass-nabucasa==0.52.0
|
||||||
|
|
||||||
# homeassistant.components.splunk
|
# homeassistant.components.splunk
|
||||||
hass_splunk==0.1.1
|
hass_splunk==0.1.1
|
||||||
|
@ -522,7 +522,7 @@ habitipy==0.2.0
|
|||||||
hangups==0.4.17
|
hangups==0.4.17
|
||||||
|
|
||||||
# homeassistant.components.cloud
|
# homeassistant.components.cloud
|
||||||
hass-nabucasa==0.51.0
|
hass-nabucasa==0.52.0
|
||||||
|
|
||||||
# homeassistant.components.tasmota
|
# homeassistant.components.tasmota
|
||||||
hatasmota==0.3.1
|
hatasmota==0.3.1
|
||||||
|
@ -171,6 +171,7 @@ async def test_remote_ui_url(hass, mock_cloud_fixture):
|
|||||||
with pytest.raises(cloud.CloudNotAvailable):
|
with pytest.raises(cloud.CloudNotAvailable):
|
||||||
cloud.async_remote_ui_url(hass)
|
cloud.async_remote_ui_url(hass)
|
||||||
|
|
||||||
cl.remote._instance_domain = "example.com"
|
# Remote finished initializing
|
||||||
|
cl.client.prefs._prefs["remote_domain"] = "example.com"
|
||||||
|
|
||||||
assert cloud.async_remote_ui_url(hass) == "https://example.com"
|
assert cloud.async_remote_ui_url(hass) == "https://example.com"
|
||||||
|
@ -111,6 +111,7 @@ async def test_get_entity(hass, client):
|
|||||||
"entity_id": "test_domain.name",
|
"entity_id": "test_domain.name",
|
||||||
"icon": None,
|
"icon": None,
|
||||||
"name": "Hello World",
|
"name": "Hello World",
|
||||||
|
"options": {},
|
||||||
"original_device_class": None,
|
"original_device_class": None,
|
||||||
"original_icon": None,
|
"original_icon": None,
|
||||||
"original_name": None,
|
"original_name": None,
|
||||||
@ -138,6 +139,7 @@ async def test_get_entity(hass, client):
|
|||||||
"entity_id": "test_domain.no_name",
|
"entity_id": "test_domain.no_name",
|
||||||
"icon": None,
|
"icon": None,
|
||||||
"name": None,
|
"name": None,
|
||||||
|
"options": {},
|
||||||
"original_device_class": None,
|
"original_device_class": None,
|
||||||
"original_icon": None,
|
"original_icon": None,
|
||||||
"original_name": None,
|
"original_name": None,
|
||||||
@ -197,6 +199,7 @@ async def test_update_entity(hass, client):
|
|||||||
"entity_id": "test_domain.world",
|
"entity_id": "test_domain.world",
|
||||||
"icon": "icon:after update",
|
"icon": "icon:after update",
|
||||||
"name": "after update",
|
"name": "after update",
|
||||||
|
"options": {},
|
||||||
"original_device_class": None,
|
"original_device_class": None,
|
||||||
"original_icon": None,
|
"original_icon": None,
|
||||||
"original_name": None,
|
"original_name": None,
|
||||||
@ -250,6 +253,7 @@ async def test_update_entity(hass, client):
|
|||||||
"entity_id": "test_domain.world",
|
"entity_id": "test_domain.world",
|
||||||
"icon": "icon:after update",
|
"icon": "icon:after update",
|
||||||
"name": "after update",
|
"name": "after update",
|
||||||
|
"options": {},
|
||||||
"original_device_class": None,
|
"original_device_class": None,
|
||||||
"original_icon": None,
|
"original_icon": None,
|
||||||
"original_name": None,
|
"original_name": None,
|
||||||
@ -259,6 +263,40 @@ async def test_update_entity(hass, client):
|
|||||||
"reload_delay": 30,
|
"reload_delay": 30,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# UPDATE ENTITY OPTION
|
||||||
|
await client.send_json(
|
||||||
|
{
|
||||||
|
"id": 9,
|
||||||
|
"type": "config/entity_registry/update",
|
||||||
|
"entity_id": "test_domain.world",
|
||||||
|
"options_domain": "sensor",
|
||||||
|
"options": {"unit_of_measurement": "beard_second"},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
msg = await client.receive_json()
|
||||||
|
|
||||||
|
assert msg["result"] == {
|
||||||
|
"entity_entry": {
|
||||||
|
"area_id": "mock-area-id",
|
||||||
|
"capabilities": None,
|
||||||
|
"config_entry_id": None,
|
||||||
|
"device_class": "custom_device_class",
|
||||||
|
"device_id": None,
|
||||||
|
"disabled_by": None,
|
||||||
|
"entity_category": None,
|
||||||
|
"entity_id": "test_domain.world",
|
||||||
|
"icon": "icon:after update",
|
||||||
|
"name": "after update",
|
||||||
|
"options": {"sensor": {"unit_of_measurement": "beard_second"}},
|
||||||
|
"original_device_class": None,
|
||||||
|
"original_icon": None,
|
||||||
|
"original_name": None,
|
||||||
|
"platform": "test_platform",
|
||||||
|
"unique_id": "1234",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
async def test_update_entity_require_restart(hass, client):
|
async def test_update_entity_require_restart(hass, client):
|
||||||
"""Test updating entity."""
|
"""Test updating entity."""
|
||||||
@ -307,6 +345,7 @@ async def test_update_entity_require_restart(hass, client):
|
|||||||
"entity_id": "test_domain.world",
|
"entity_id": "test_domain.world",
|
||||||
"icon": None,
|
"icon": None,
|
||||||
"name": None,
|
"name": None,
|
||||||
|
"options": {},
|
||||||
"original_device_class": None,
|
"original_device_class": None,
|
||||||
"original_icon": None,
|
"original_icon": None,
|
||||||
"original_name": None,
|
"original_name": None,
|
||||||
@ -411,6 +450,7 @@ async def test_update_entity_no_changes(hass, client):
|
|||||||
"entity_id": "test_domain.world",
|
"entity_id": "test_domain.world",
|
||||||
"icon": None,
|
"icon": None,
|
||||||
"name": "name of entity",
|
"name": "name of entity",
|
||||||
|
"options": {},
|
||||||
"original_device_class": None,
|
"original_device_class": None,
|
||||||
"original_icon": None,
|
"original_icon": None,
|
||||||
"original_name": None,
|
"original_name": None,
|
||||||
@ -494,6 +534,7 @@ async def test_update_entity_id(hass, client):
|
|||||||
"entity_id": "test_domain.planet",
|
"entity_id": "test_domain.planet",
|
||||||
"icon": None,
|
"icon": None,
|
||||||
"name": None,
|
"name": None,
|
||||||
|
"options": {},
|
||||||
"original_device_class": None,
|
"original_device_class": None,
|
||||||
"original_icon": None,
|
"original_icon": None,
|
||||||
"original_name": None,
|
"original_name": None,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user