mirror of
https://github.com/home-assistant/core.git
synced 2025-04-24 01:08:12 +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.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]]:
|
||||
@ -52,14 +59,14 @@ class SteamFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
||||
if res[0] is not None:
|
||||
name = str(res[0]["personaname"])
|
||||
else:
|
||||
errors = {"base": "invalid_account"}
|
||||
errors["base"] = "invalid_account"
|
||||
except (steam.api.HTTPError, steam.api.HTTPTimeoutError) as ex:
|
||||
errors = {"base": "cannot_connect"}
|
||||
errors["base"] = "cannot_connect"
|
||||
if "403" in str(ex):
|
||||
errors = {"base": "invalid_auth"}
|
||||
errors["base"] = "invalid_auth"
|
||||
except Exception as ex: # pylint:disable=broad-except
|
||||
LOGGER.exception("Unknown exception: %s", ex)
|
||||
errors = {"base": "unknown"}
|
||||
errors["base"] = "unknown"
|
||||
if not errors:
|
||||
entry = await self.async_set_unique_id(user_input[CONF_ACCOUNT])
|
||||
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:
|
||||
accounts_data = {
|
||||
CONF_ACCOUNTS: {
|
||||
acc["steamid"]: {
|
||||
"name": acc["personaname"],
|
||||
"enabled": True,
|
||||
}
|
||||
for acc in res
|
||||
acc["steamid"]: acc["personaname"] for acc in res
|
||||
}
|
||||
}
|
||||
user_input.pop(CONF_ACCOUNTS)
|
||||
else:
|
||||
accounts_data = {
|
||||
CONF_ACCOUNTS: {
|
||||
user_input[CONF_ACCOUNT]: {"name": name, "enabled": True}
|
||||
}
|
||||
}
|
||||
accounts_data = {CONF_ACCOUNTS: {user_input[CONF_ACCOUNT]: name}}
|
||||
return self.async_create_entry(
|
||||
title=name or DEFAULT_NAME,
|
||||
data=user_input,
|
||||
@ -103,6 +102,7 @@ class SteamFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
||||
}
|
||||
),
|
||||
errors=errors,
|
||||
description_placeholders=PLACEHOLDERS,
|
||||
)
|
||||
|
||||
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]:
|
||||
return self.async_abort(reason="already_configured")
|
||||
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"
|
||||
)
|
||||
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()
|
||||
|
||||
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):
|
||||
@ -148,56 +150,38 @@ class SteamOptionsFlowHandler(config_entries.OptionsFlow):
|
||||
"""Manage Steam options."""
|
||||
if user_input is not None:
|
||||
await self.hass.config_entries.async_unload(self.entry.entry_id)
|
||||
for k in self.options[CONF_ACCOUNTS]:
|
||||
if (
|
||||
self.options[CONF_ACCOUNTS][k]["enabled"]
|
||||
and k not in user_input[CONF_ACCOUNTS]
|
||||
and (
|
||||
entity_id := er.async_get(self.hass).async_get_entity_id(
|
||||
Platform.SENSOR, DOMAIN, f"sensor.steam_{k}"
|
||||
)
|
||||
for _id in self.options[CONF_ACCOUNTS]:
|
||||
if _id not in user_input[CONF_ACCOUNTS] and (
|
||||
entity_id := er.async_get(self.hass).async_get_entity_id(
|
||||
Platform.SENSOR, DOMAIN, f"sensor.steam_{_id}"
|
||||
)
|
||||
):
|
||||
er.async_get(self.hass).async_remove(entity_id)
|
||||
channel_data = {
|
||||
CONF_ACCOUNTS: {
|
||||
k: {
|
||||
"name": v["name"],
|
||||
"enabled": k in user_input[CONF_ACCOUNTS],
|
||||
}
|
||||
for k, v in self.options[CONF_ACCOUNTS].items()
|
||||
if k in user_input[CONF_ACCOUNTS]
|
||||
_id: name
|
||||
for _id, name in self.options[CONF_ACCOUNTS].items()
|
||||
if _id in user_input[CONF_ACCOUNTS]
|
||||
}
|
||||
}
|
||||
await self.hass.config_entries.async_reload(self.entry.entry_id)
|
||||
return self.async_create_entry(title="", data=channel_data)
|
||||
try:
|
||||
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)
|
||||
}
|
||||
|
||||
except steam.api.HTTPTimeoutError:
|
||||
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 = {
|
||||
vol.Required(
|
||||
CONF_ACCOUNTS,
|
||||
default={
|
||||
k
|
||||
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()}
|
||||
),
|
||||
default=set(self.options[CONF_ACCOUNTS]),
|
||||
): cv.multi_select(users | self.options[CONF_ACCOUNTS]),
|
||||
}
|
||||
self.options[CONF_ACCOUNTS] = users | self.options[CONF_ACCOUNTS]
|
||||
|
||||
return self.async_show_form(step_id="init", data_schema=vol.Schema(options))
|
||||
|
||||
@ -205,7 +189,6 @@ class SteamOptionsFlowHandler(config_entries.OptionsFlow):
|
||||
"""Get accounts."""
|
||||
interface = steam.api.interface("ISteamUser")
|
||||
friends = interface.GetFriendList(steamid=self.entry.data[CONF_ACCOUNT])
|
||||
friends = friends["friendslist"]["friends"]
|
||||
_users_str = [user["steamid"] for user in friends]
|
||||
_users_str = [user["steamid"] for user in friends["friendslist"]["friends"]]
|
||||
names = interface.GetPlayerSummaries(steamids=_users_str)
|
||||
return names["response"]["players"]["player"]
|
||||
|
@ -11,6 +11,11 @@ DOMAIN: Final = "steam_online"
|
||||
|
||||
LOGGER = logging.getLogger(__package__)
|
||||
|
||||
PLACEHOLDERS = {
|
||||
"api_key_url": "https://steamcommunity.com/dev/apikey",
|
||||
"account_id_url": "https://steamid.io",
|
||||
}
|
||||
|
||||
STATE_OFFLINE = "offline"
|
||||
STATE_ONLINE = "online"
|
||||
STATE_BUSY = "busy"
|
||||
@ -30,6 +35,4 @@ STEAM_STATUSES = {
|
||||
STEAM_API_URL = "https://steamcdn-a.akamaihd.net/steam/apps/"
|
||||
STEAM_HEADER_IMAGE_FILE = "header.jpg"
|
||||
STEAM_MAIN_IMAGE_FILE = "capsule_616x353.jpg"
|
||||
STEAM_ICON_URL = (
|
||||
"https://steamcdn-a.akamaihd.net/steamcommunity/public/images/apps/%d/%s.jpg"
|
||||
)
|
||||
STEAM_ICON_URL = "https://steamcdn-a.akamaihd.net/steamcommunity/public/images/apps/"
|
||||
|
@ -28,7 +28,7 @@ class SteamDataUpdateCoordinator(DataUpdateCoordinator):
|
||||
name=DOMAIN,
|
||||
update_interval=timedelta(seconds=30),
|
||||
)
|
||||
self.game_icons: dict = {}
|
||||
self.game_icons: dict[int, str] = {}
|
||||
self.player_interface: INTMethod = None
|
||||
self.user_interface: INTMethod = None
|
||||
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]]:
|
||||
"""Fetch data from API endpoint."""
|
||||
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:
|
||||
self.user_interface = steam.api.interface("ISteamUser")
|
||||
self.player_interface = steam.api.interface("IPlayerService")
|
||||
@ -46,7 +46,7 @@ class SteamDataUpdateCoordinator(DataUpdateCoordinator):
|
||||
steamid=_id, include_appinfo=1
|
||||
)["response"]
|
||||
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)
|
||||
players = {
|
||||
@ -56,8 +56,7 @@ class SteamDataUpdateCoordinator(DataUpdateCoordinator):
|
||||
}
|
||||
for k in players:
|
||||
data = self.player_interface.GetSteamLevel(steamid=players[k]["steamid"])
|
||||
data = data["response"]
|
||||
players[k]["level"] = data["player_level"]
|
||||
players[k]["level"] = data["response"]["player_level"]
|
||||
return players
|
||||
|
||||
async def _async_update_data(self) -> dict[str, dict[str, str | int]]:
|
||||
|
@ -65,7 +65,6 @@ async def async_setup_entry(
|
||||
async_add_entities(
|
||||
SteamSensor(hass.data[DOMAIN][entry.entry_id], account)
|
||||
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_main"] = f"{game_url}{STEAM_MAIN_IMAGE_FILE}"
|
||||
if info := self._get_game_icon(player):
|
||||
attrs["game_icon"] = STEAM_ICON_URL % (
|
||||
game_id,
|
||||
info,
|
||||
)
|
||||
attrs["game_icon"] = f"{STEAM_ICON_URL}{game_id}/{info}.jpg"
|
||||
self._attr_name = player["personaname"]
|
||||
self._attr_entity_picture = player["avatarmedium"]
|
||||
if last_online := player.get("lastlogoff"):
|
||||
|
@ -2,7 +2,7 @@
|
||||
"config": {
|
||||
"step": {
|
||||
"user": {
|
||||
"description": "Use https://steamid.io to find your Steam account ID",
|
||||
"description": "Use {account_id_url} to find your Steam account ID",
|
||||
"data": {
|
||||
"api_key": "[%key:common::config_flow::data::api_key%]",
|
||||
"account": "Steam account ID"
|
||||
@ -10,7 +10,7 @@
|
||||
},
|
||||
"reauth_confirm": {
|
||||
"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": {
|
||||
|
@ -12,7 +12,7 @@
|
||||
},
|
||||
"step": {
|
||||
"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"
|
||||
},
|
||||
"user": {
|
||||
@ -20,7 +20,7 @@
|
||||
"account": "Steam account ID",
|
||||
"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.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 tests.common import MockConfigEntry
|
||||
@ -19,38 +19,19 @@ CONF_DATA = {
|
||||
CONF_ACCOUNT: ACCOUNT_1,
|
||||
}
|
||||
|
||||
CONF_OPTIONS = {
|
||||
CONF_ACCOUNTS: {
|
||||
ACCOUNT_1: {
|
||||
CONF_NAME: ACCOUNT_NAME_1,
|
||||
"enabled": True,
|
||||
}
|
||||
}
|
||||
}
|
||||
CONF_OPTIONS = {CONF_ACCOUNTS: {ACCOUNT_1: ACCOUNT_NAME_1}}
|
||||
|
||||
CONF_OPTIONS_2 = {
|
||||
CONF_ACCOUNTS: {
|
||||
ACCOUNT_1: {
|
||||
CONF_NAME: ACCOUNT_NAME_1,
|
||||
"enabled": True,
|
||||
},
|
||||
ACCOUNT_2: {
|
||||
CONF_NAME: ACCOUNT_NAME_2,
|
||||
"enabled": True,
|
||||
},
|
||||
ACCOUNT_1: ACCOUNT_NAME_1,
|
||||
ACCOUNT_2: ACCOUNT_NAME_2,
|
||||
}
|
||||
}
|
||||
|
||||
CONF_IMPORT_OPTIONS = {
|
||||
CONF_ACCOUNTS: {
|
||||
ACCOUNT_1: {
|
||||
CONF_NAME: ACCOUNT_NAME_1,
|
||||
"enabled": True,
|
||||
},
|
||||
ACCOUNT_2: {
|
||||
CONF_NAME: ACCOUNT_NAME_2,
|
||||
"enabled": True,
|
||||
},
|
||||
ACCOUNT_1: ACCOUNT_NAME_1,
|
||||
ACCOUNT_2: ACCOUNT_NAME_2,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,6 @@
|
||||
"""Test Steam config flow."""
|
||||
from unittest.mock import patch
|
||||
|
||||
import steam
|
||||
|
||||
from homeassistant import data_entry_flow
|
||||
@ -25,7 +27,10 @@ from . import (
|
||||
|
||||
async def test_flow_user(hass: HomeAssistant) -> None:
|
||||
"""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(
|
||||
DOMAIN,
|
||||
context={"source": SOURCE_USER},
|
||||
|
Loading…
x
Reference in New Issue
Block a user