mirror of
https://github.com/home-assistant/core.git
synced 2025-07-14 16:57:10 +00:00
Clean up Steam integration (#71091)
* Clean up Steam * uno mas * uno mas * uno mas
This commit is contained in:
parent
00b5d30e24
commit
f14bc1cece
@ -13,7 +13,14 @@ from homeassistant.data_entry_flow import FlowResult
|
|||||||
from homeassistant.helpers import config_validation as cv, entity_registry as er
|
from homeassistant.helpers import config_validation as cv, entity_registry as er
|
||||||
from homeassistant.helpers.typing import ConfigType
|
from homeassistant.helpers.typing import ConfigType
|
||||||
|
|
||||||
from .const import CONF_ACCOUNT, CONF_ACCOUNTS, DEFAULT_NAME, DOMAIN, LOGGER
|
from .const import (
|
||||||
|
CONF_ACCOUNT,
|
||||||
|
CONF_ACCOUNTS,
|
||||||
|
DEFAULT_NAME,
|
||||||
|
DOMAIN,
|
||||||
|
LOGGER,
|
||||||
|
PLACEHOLDERS,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def validate_input(user_input: dict[str, str | int]) -> list[dict[str, str | int]]:
|
def validate_input(user_input: dict[str, str | int]) -> list[dict[str, str | int]]:
|
||||||
@ -52,14 +59,14 @@ class SteamFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
|||||||
if res[0] is not None:
|
if res[0] is not None:
|
||||||
name = str(res[0]["personaname"])
|
name = str(res[0]["personaname"])
|
||||||
else:
|
else:
|
||||||
errors = {"base": "invalid_account"}
|
errors["base"] = "invalid_account"
|
||||||
except (steam.api.HTTPError, steam.api.HTTPTimeoutError) as ex:
|
except (steam.api.HTTPError, steam.api.HTTPTimeoutError) as ex:
|
||||||
errors = {"base": "cannot_connect"}
|
errors["base"] = "cannot_connect"
|
||||||
if "403" in str(ex):
|
if "403" in str(ex):
|
||||||
errors = {"base": "invalid_auth"}
|
errors["base"] = "invalid_auth"
|
||||||
except Exception as ex: # pylint:disable=broad-except
|
except Exception as ex: # pylint:disable=broad-except
|
||||||
LOGGER.exception("Unknown exception: %s", ex)
|
LOGGER.exception("Unknown exception: %s", ex)
|
||||||
errors = {"base": "unknown"}
|
errors["base"] = "unknown"
|
||||||
if not errors:
|
if not errors:
|
||||||
entry = await self.async_set_unique_id(user_input[CONF_ACCOUNT])
|
entry = await self.async_set_unique_id(user_input[CONF_ACCOUNT])
|
||||||
if entry and self.source == config_entries.SOURCE_REAUTH:
|
if entry and self.source == config_entries.SOURCE_REAUTH:
|
||||||
@ -70,20 +77,12 @@ class SteamFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
|||||||
if self.source == config_entries.SOURCE_IMPORT:
|
if self.source == config_entries.SOURCE_IMPORT:
|
||||||
accounts_data = {
|
accounts_data = {
|
||||||
CONF_ACCOUNTS: {
|
CONF_ACCOUNTS: {
|
||||||
acc["steamid"]: {
|
acc["steamid"]: acc["personaname"] for acc in res
|
||||||
"name": acc["personaname"],
|
|
||||||
"enabled": True,
|
|
||||||
}
|
|
||||||
for acc in res
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
user_input.pop(CONF_ACCOUNTS)
|
user_input.pop(CONF_ACCOUNTS)
|
||||||
else:
|
else:
|
||||||
accounts_data = {
|
accounts_data = {CONF_ACCOUNTS: {user_input[CONF_ACCOUNT]: name}}
|
||||||
CONF_ACCOUNTS: {
|
|
||||||
user_input[CONF_ACCOUNT]: {"name": name, "enabled": True}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return self.async_create_entry(
|
return self.async_create_entry(
|
||||||
title=name or DEFAULT_NAME,
|
title=name or DEFAULT_NAME,
|
||||||
data=user_input,
|
data=user_input,
|
||||||
@ -103,6 +102,7 @@ class SteamFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
|||||||
}
|
}
|
||||||
),
|
),
|
||||||
errors=errors,
|
errors=errors,
|
||||||
|
description_placeholders=PLACEHOLDERS,
|
||||||
)
|
)
|
||||||
|
|
||||||
async def async_step_import(self, import_config: ConfigType) -> FlowResult:
|
async def async_step_import(self, import_config: ConfigType) -> FlowResult:
|
||||||
@ -111,7 +111,7 @@ class SteamFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
|||||||
if entry.data[CONF_API_KEY] == import_config[CONF_API_KEY]:
|
if entry.data[CONF_API_KEY] == import_config[CONF_API_KEY]:
|
||||||
return self.async_abort(reason="already_configured")
|
return self.async_abort(reason="already_configured")
|
||||||
LOGGER.warning(
|
LOGGER.warning(
|
||||||
"Steam yaml config in now deprecated and has been imported. "
|
"Steam yaml config is now deprecated and has been imported. "
|
||||||
"Please remove it from your config"
|
"Please remove it from your config"
|
||||||
)
|
)
|
||||||
import_config[CONF_ACCOUNT] = import_config[CONF_ACCOUNTS][0]
|
import_config[CONF_ACCOUNT] = import_config[CONF_ACCOUNTS][0]
|
||||||
@ -131,7 +131,9 @@ class SteamFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
|||||||
return await self.async_step_user()
|
return await self.async_step_user()
|
||||||
|
|
||||||
self._set_confirm_only()
|
self._set_confirm_only()
|
||||||
return self.async_show_form(step_id="reauth_confirm")
|
return self.async_show_form(
|
||||||
|
step_id="reauth_confirm", description_placeholders=PLACEHOLDERS
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class SteamOptionsFlowHandler(config_entries.OptionsFlow):
|
class SteamOptionsFlowHandler(config_entries.OptionsFlow):
|
||||||
@ -148,56 +150,38 @@ class SteamOptionsFlowHandler(config_entries.OptionsFlow):
|
|||||||
"""Manage Steam options."""
|
"""Manage Steam options."""
|
||||||
if user_input is not None:
|
if user_input is not None:
|
||||||
await self.hass.config_entries.async_unload(self.entry.entry_id)
|
await self.hass.config_entries.async_unload(self.entry.entry_id)
|
||||||
for k in self.options[CONF_ACCOUNTS]:
|
for _id in self.options[CONF_ACCOUNTS]:
|
||||||
if (
|
if _id not in user_input[CONF_ACCOUNTS] and (
|
||||||
self.options[CONF_ACCOUNTS][k]["enabled"]
|
entity_id := er.async_get(self.hass).async_get_entity_id(
|
||||||
and k not in user_input[CONF_ACCOUNTS]
|
Platform.SENSOR, DOMAIN, f"sensor.steam_{_id}"
|
||||||
and (
|
|
||||||
entity_id := er.async_get(self.hass).async_get_entity_id(
|
|
||||||
Platform.SENSOR, DOMAIN, f"sensor.steam_{k}"
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
):
|
):
|
||||||
er.async_get(self.hass).async_remove(entity_id)
|
er.async_get(self.hass).async_remove(entity_id)
|
||||||
channel_data = {
|
channel_data = {
|
||||||
CONF_ACCOUNTS: {
|
CONF_ACCOUNTS: {
|
||||||
k: {
|
_id: name
|
||||||
"name": v["name"],
|
for _id, name in self.options[CONF_ACCOUNTS].items()
|
||||||
"enabled": k in user_input[CONF_ACCOUNTS],
|
if _id in user_input[CONF_ACCOUNTS]
|
||||||
}
|
|
||||||
for k, v in self.options[CONF_ACCOUNTS].items()
|
|
||||||
if k in user_input[CONF_ACCOUNTS]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
await self.hass.config_entries.async_reload(self.entry.entry_id)
|
await self.hass.config_entries.async_reload(self.entry.entry_id)
|
||||||
return self.async_create_entry(title="", data=channel_data)
|
return self.async_create_entry(title="", data=channel_data)
|
||||||
try:
|
try:
|
||||||
users = {
|
users = {
|
||||||
name["steamid"]: {"name": name["personaname"], "enabled": False}
|
name["steamid"]: name["personaname"]
|
||||||
for name in await self.hass.async_add_executor_job(self.get_accounts)
|
for name in await self.hass.async_add_executor_job(self.get_accounts)
|
||||||
}
|
}
|
||||||
|
|
||||||
except steam.api.HTTPTimeoutError:
|
except steam.api.HTTPTimeoutError:
|
||||||
users = self.options[CONF_ACCOUNTS]
|
users = self.options[CONF_ACCOUNTS]
|
||||||
_users = users | self.options[CONF_ACCOUNTS]
|
|
||||||
self.options[CONF_ACCOUNTS] = {
|
|
||||||
k: v
|
|
||||||
for k, v in _users.items()
|
|
||||||
if k in users or self.options[CONF_ACCOUNTS][k]["enabled"]
|
|
||||||
}
|
|
||||||
|
|
||||||
options = {
|
options = {
|
||||||
vol.Required(
|
vol.Required(
|
||||||
CONF_ACCOUNTS,
|
CONF_ACCOUNTS,
|
||||||
default={
|
default=set(self.options[CONF_ACCOUNTS]),
|
||||||
k
|
): cv.multi_select(users | self.options[CONF_ACCOUNTS]),
|
||||||
for k in self.options[CONF_ACCOUNTS]
|
|
||||||
if self.options[CONF_ACCOUNTS][k]["enabled"]
|
|
||||||
},
|
|
||||||
): cv.multi_select(
|
|
||||||
{k: v["name"] for k, v in self.options[CONF_ACCOUNTS].items()}
|
|
||||||
),
|
|
||||||
}
|
}
|
||||||
|
self.options[CONF_ACCOUNTS] = users | self.options[CONF_ACCOUNTS]
|
||||||
|
|
||||||
return self.async_show_form(step_id="init", data_schema=vol.Schema(options))
|
return self.async_show_form(step_id="init", data_schema=vol.Schema(options))
|
||||||
|
|
||||||
@ -205,7 +189,6 @@ class SteamOptionsFlowHandler(config_entries.OptionsFlow):
|
|||||||
"""Get accounts."""
|
"""Get accounts."""
|
||||||
interface = steam.api.interface("ISteamUser")
|
interface = steam.api.interface("ISteamUser")
|
||||||
friends = interface.GetFriendList(steamid=self.entry.data[CONF_ACCOUNT])
|
friends = interface.GetFriendList(steamid=self.entry.data[CONF_ACCOUNT])
|
||||||
friends = friends["friendslist"]["friends"]
|
_users_str = [user["steamid"] for user in friends["friendslist"]["friends"]]
|
||||||
_users_str = [user["steamid"] for user in friends]
|
|
||||||
names = interface.GetPlayerSummaries(steamids=_users_str)
|
names = interface.GetPlayerSummaries(steamids=_users_str)
|
||||||
return names["response"]["players"]["player"]
|
return names["response"]["players"]["player"]
|
||||||
|
@ -11,6 +11,11 @@ DOMAIN: Final = "steam_online"
|
|||||||
|
|
||||||
LOGGER = logging.getLogger(__package__)
|
LOGGER = logging.getLogger(__package__)
|
||||||
|
|
||||||
|
PLACEHOLDERS = {
|
||||||
|
"api_key_url": "https://steamcommunity.com/dev/apikey",
|
||||||
|
"account_id_url": "https://steamid.io",
|
||||||
|
}
|
||||||
|
|
||||||
STATE_OFFLINE = "offline"
|
STATE_OFFLINE = "offline"
|
||||||
STATE_ONLINE = "online"
|
STATE_ONLINE = "online"
|
||||||
STATE_BUSY = "busy"
|
STATE_BUSY = "busy"
|
||||||
@ -30,6 +35,4 @@ STEAM_STATUSES = {
|
|||||||
STEAM_API_URL = "https://steamcdn-a.akamaihd.net/steam/apps/"
|
STEAM_API_URL = "https://steamcdn-a.akamaihd.net/steam/apps/"
|
||||||
STEAM_HEADER_IMAGE_FILE = "header.jpg"
|
STEAM_HEADER_IMAGE_FILE = "header.jpg"
|
||||||
STEAM_MAIN_IMAGE_FILE = "capsule_616x353.jpg"
|
STEAM_MAIN_IMAGE_FILE = "capsule_616x353.jpg"
|
||||||
STEAM_ICON_URL = (
|
STEAM_ICON_URL = "https://steamcdn-a.akamaihd.net/steamcommunity/public/images/apps/"
|
||||||
"https://steamcdn-a.akamaihd.net/steamcommunity/public/images/apps/%d/%s.jpg"
|
|
||||||
)
|
|
||||||
|
@ -28,7 +28,7 @@ class SteamDataUpdateCoordinator(DataUpdateCoordinator):
|
|||||||
name=DOMAIN,
|
name=DOMAIN,
|
||||||
update_interval=timedelta(seconds=30),
|
update_interval=timedelta(seconds=30),
|
||||||
)
|
)
|
||||||
self.game_icons: dict = {}
|
self.game_icons: dict[int, str] = {}
|
||||||
self.player_interface: INTMethod = None
|
self.player_interface: INTMethod = None
|
||||||
self.user_interface: INTMethod = None
|
self.user_interface: INTMethod = None
|
||||||
steam.api.key.set(self.config_entry.data[CONF_API_KEY])
|
steam.api.key.set(self.config_entry.data[CONF_API_KEY])
|
||||||
@ -36,7 +36,7 @@ class SteamDataUpdateCoordinator(DataUpdateCoordinator):
|
|||||||
def _update(self) -> dict[str, dict[str, str | int]]:
|
def _update(self) -> dict[str, dict[str, str | int]]:
|
||||||
"""Fetch data from API endpoint."""
|
"""Fetch data from API endpoint."""
|
||||||
accounts = self.config_entry.options[CONF_ACCOUNTS]
|
accounts = self.config_entry.options[CONF_ACCOUNTS]
|
||||||
_ids = [k for k in accounts if accounts[k]["enabled"]]
|
_ids = list(accounts)
|
||||||
if not self.user_interface or not self.player_interface:
|
if not self.user_interface or not self.player_interface:
|
||||||
self.user_interface = steam.api.interface("ISteamUser")
|
self.user_interface = steam.api.interface("ISteamUser")
|
||||||
self.player_interface = steam.api.interface("IPlayerService")
|
self.player_interface = steam.api.interface("IPlayerService")
|
||||||
@ -46,7 +46,7 @@ class SteamDataUpdateCoordinator(DataUpdateCoordinator):
|
|||||||
steamid=_id, include_appinfo=1
|
steamid=_id, include_appinfo=1
|
||||||
)["response"]
|
)["response"]
|
||||||
self.game_icons = self.game_icons | {
|
self.game_icons = self.game_icons | {
|
||||||
game["appid"]: game["img_icon_url"] for game in res.get("games", {})
|
game["appid"]: game["img_icon_url"] for game in res.get("games", [])
|
||||||
}
|
}
|
||||||
response = self.user_interface.GetPlayerSummaries(steamids=_ids)
|
response = self.user_interface.GetPlayerSummaries(steamids=_ids)
|
||||||
players = {
|
players = {
|
||||||
@ -56,8 +56,7 @@ class SteamDataUpdateCoordinator(DataUpdateCoordinator):
|
|||||||
}
|
}
|
||||||
for k in players:
|
for k in players:
|
||||||
data = self.player_interface.GetSteamLevel(steamid=players[k]["steamid"])
|
data = self.player_interface.GetSteamLevel(steamid=players[k]["steamid"])
|
||||||
data = data["response"]
|
players[k]["level"] = data["response"]["player_level"]
|
||||||
players[k]["level"] = data["player_level"]
|
|
||||||
return players
|
return players
|
||||||
|
|
||||||
async def _async_update_data(self) -> dict[str, dict[str, str | int]]:
|
async def _async_update_data(self) -> dict[str, dict[str, str | int]]:
|
||||||
|
@ -65,7 +65,6 @@ async def async_setup_entry(
|
|||||||
async_add_entities(
|
async_add_entities(
|
||||||
SteamSensor(hass.data[DOMAIN][entry.entry_id], account)
|
SteamSensor(hass.data[DOMAIN][entry.entry_id], account)
|
||||||
for account in entry.options[CONF_ACCOUNTS]
|
for account in entry.options[CONF_ACCOUNTS]
|
||||||
if entry.options[CONF_ACCOUNTS][account]["enabled"]
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -106,10 +105,7 @@ class SteamSensor(SteamEntity, SensorEntity):
|
|||||||
attrs["game_image_header"] = f"{game_url}{STEAM_HEADER_IMAGE_FILE}"
|
attrs["game_image_header"] = f"{game_url}{STEAM_HEADER_IMAGE_FILE}"
|
||||||
attrs["game_image_main"] = f"{game_url}{STEAM_MAIN_IMAGE_FILE}"
|
attrs["game_image_main"] = f"{game_url}{STEAM_MAIN_IMAGE_FILE}"
|
||||||
if info := self._get_game_icon(player):
|
if info := self._get_game_icon(player):
|
||||||
attrs["game_icon"] = STEAM_ICON_URL % (
|
attrs["game_icon"] = f"{STEAM_ICON_URL}{game_id}/{info}.jpg"
|
||||||
game_id,
|
|
||||||
info,
|
|
||||||
)
|
|
||||||
self._attr_name = player["personaname"]
|
self._attr_name = player["personaname"]
|
||||||
self._attr_entity_picture = player["avatarmedium"]
|
self._attr_entity_picture = player["avatarmedium"]
|
||||||
if last_online := player.get("lastlogoff"):
|
if last_online := player.get("lastlogoff"):
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
"config": {
|
"config": {
|
||||||
"step": {
|
"step": {
|
||||||
"user": {
|
"user": {
|
||||||
"description": "Use https://steamid.io to find your Steam account ID",
|
"description": "Use {account_id_url} to find your Steam account ID",
|
||||||
"data": {
|
"data": {
|
||||||
"api_key": "[%key:common::config_flow::data::api_key%]",
|
"api_key": "[%key:common::config_flow::data::api_key%]",
|
||||||
"account": "Steam account ID"
|
"account": "Steam account ID"
|
||||||
@ -10,7 +10,7 @@
|
|||||||
},
|
},
|
||||||
"reauth_confirm": {
|
"reauth_confirm": {
|
||||||
"title": "[%key:common::config_flow::title::reauth%]",
|
"title": "[%key:common::config_flow::title::reauth%]",
|
||||||
"description": "The Steam integration needs to be manually re-authenticated\n\nYou can find your key here: https://steamcommunity.com/dev/apikey"
|
"description": "The Steam integration needs to be manually re-authenticated\n\nYou can find your key here: {api_key_url}"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"error": {
|
"error": {
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
},
|
},
|
||||||
"step": {
|
"step": {
|
||||||
"reauth_confirm": {
|
"reauth_confirm": {
|
||||||
"description": "The Steam integration needs to be manually re-authenticated\n\nYou can find your key here: https://steamcommunity.com/dev/apikey",
|
"description": "The Steam integration needs to be manually re-authenticated\n\nYou can find your key here: {api_key_url}",
|
||||||
"title": "Reauthenticate Integration"
|
"title": "Reauthenticate Integration"
|
||||||
},
|
},
|
||||||
"user": {
|
"user": {
|
||||||
@ -20,7 +20,7 @@
|
|||||||
"account": "Steam account ID",
|
"account": "Steam account ID",
|
||||||
"api_key": "API Key"
|
"api_key": "API Key"
|
||||||
},
|
},
|
||||||
"description": "Use https://steamid.io to find your Steam account ID"
|
"description": "Use {account_id_url} to find your Steam account ID"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -3,7 +3,7 @@ from unittest.mock import patch
|
|||||||
|
|
||||||
from homeassistant.components.steam_online import DOMAIN
|
from homeassistant.components.steam_online import DOMAIN
|
||||||
from homeassistant.components.steam_online.const import CONF_ACCOUNT, CONF_ACCOUNTS
|
from homeassistant.components.steam_online.const import CONF_ACCOUNT, CONF_ACCOUNTS
|
||||||
from homeassistant.const import CONF_API_KEY, CONF_NAME
|
from homeassistant.const import CONF_API_KEY
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
|
|
||||||
from tests.common import MockConfigEntry
|
from tests.common import MockConfigEntry
|
||||||
@ -19,38 +19,19 @@ CONF_DATA = {
|
|||||||
CONF_ACCOUNT: ACCOUNT_1,
|
CONF_ACCOUNT: ACCOUNT_1,
|
||||||
}
|
}
|
||||||
|
|
||||||
CONF_OPTIONS = {
|
CONF_OPTIONS = {CONF_ACCOUNTS: {ACCOUNT_1: ACCOUNT_NAME_1}}
|
||||||
CONF_ACCOUNTS: {
|
|
||||||
ACCOUNT_1: {
|
|
||||||
CONF_NAME: ACCOUNT_NAME_1,
|
|
||||||
"enabled": True,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CONF_OPTIONS_2 = {
|
CONF_OPTIONS_2 = {
|
||||||
CONF_ACCOUNTS: {
|
CONF_ACCOUNTS: {
|
||||||
ACCOUNT_1: {
|
ACCOUNT_1: ACCOUNT_NAME_1,
|
||||||
CONF_NAME: ACCOUNT_NAME_1,
|
ACCOUNT_2: ACCOUNT_NAME_2,
|
||||||
"enabled": True,
|
|
||||||
},
|
|
||||||
ACCOUNT_2: {
|
|
||||||
CONF_NAME: ACCOUNT_NAME_2,
|
|
||||||
"enabled": True,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CONF_IMPORT_OPTIONS = {
|
CONF_IMPORT_OPTIONS = {
|
||||||
CONF_ACCOUNTS: {
|
CONF_ACCOUNTS: {
|
||||||
ACCOUNT_1: {
|
ACCOUNT_1: ACCOUNT_NAME_1,
|
||||||
CONF_NAME: ACCOUNT_NAME_1,
|
ACCOUNT_2: ACCOUNT_NAME_2,
|
||||||
"enabled": True,
|
|
||||||
},
|
|
||||||
ACCOUNT_2: {
|
|
||||||
CONF_NAME: ACCOUNT_NAME_2,
|
|
||||||
"enabled": True,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
"""Test Steam config flow."""
|
"""Test Steam config flow."""
|
||||||
|
from unittest.mock import patch
|
||||||
|
|
||||||
import steam
|
import steam
|
||||||
|
|
||||||
from homeassistant import data_entry_flow
|
from homeassistant import data_entry_flow
|
||||||
@ -25,7 +27,10 @@ from . import (
|
|||||||
|
|
||||||
async def test_flow_user(hass: HomeAssistant) -> None:
|
async def test_flow_user(hass: HomeAssistant) -> None:
|
||||||
"""Test user initialized flow."""
|
"""Test user initialized flow."""
|
||||||
with patch_interface():
|
with patch_interface(), patch(
|
||||||
|
"homeassistant.components.steam_online.async_setup_entry",
|
||||||
|
return_value=True,
|
||||||
|
):
|
||||||
result = await hass.config_entries.flow.async_init(
|
result = await hass.config_entries.flow.async_init(
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
context={"source": SOURCE_USER},
|
context={"source": SOURCE_USER},
|
||||||
|
Loading…
x
Reference in New Issue
Block a user