Skip to content

Commit b6c8b78

Browse files
authored
Add device storage sensor entities to Xbox (home-assistant#155657)
1 parent 78f26ed commit b6c8b78

File tree

10 files changed

+562
-28
lines changed

10 files changed

+562
-28
lines changed

homeassistant/components/xbox/__init__.py

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,12 @@
99
from homeassistant.helpers import config_validation as cv
1010

1111
from .const import DOMAIN
12-
from .coordinator import XboxConfigEntry, XboxUpdateCoordinator
12+
from .coordinator import (
13+
XboxConfigEntry,
14+
XboxConsolesCoordinator,
15+
XboxCoordinators,
16+
XboxUpdateCoordinator,
17+
)
1318

1419
_LOGGER = logging.getLogger(__name__)
1520

@@ -30,7 +35,9 @@ async def async_setup_entry(hass: HomeAssistant, entry: XboxConfigEntry) -> bool
3035
coordinator = XboxUpdateCoordinator(hass, entry)
3136
await coordinator.async_config_entry_first_refresh()
3237

33-
entry.runtime_data = coordinator
38+
consoles = XboxConsolesCoordinator(hass, entry, coordinator)
39+
40+
entry.runtime_data = XboxCoordinators(coordinator, consoles)
3441

3542
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
3643

@@ -53,16 +60,14 @@ async def async_migrate_unique_id(hass: HomeAssistant, entry: XboxConfigEntry) -
5360
if entry.version == 1 and entry.minor_version < 2:
5461
# Migrate unique_id from `xbox` to account xuid and
5562
# change generic entry name to user's gamertag
63+
coordinator = entry.runtime_data.status
64+
xuid = coordinator.client.xuid
65+
gamertag = coordinator.data.presence[xuid].gamertag
66+
5667
return hass.config_entries.async_update_entry(
5768
entry,
58-
unique_id=entry.runtime_data.client.xuid,
59-
title=(
60-
entry.runtime_data.data.presence[
61-
entry.runtime_data.client.xuid
62-
].gamertag
63-
if entry.title == "Home Assistant Cloud"
64-
else entry.title
65-
),
69+
unique_id=xuid,
70+
title=(gamertag if entry.title == "Home Assistant Cloud" else entry.title),
6671
minor_version=2,
6772
)
6873

homeassistant/components/xbox/binary_sensor.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ async def async_setup_entry(
111111
) -> None:
112112
"""Set up Xbox Live friends."""
113113
xuids_added: set[str] = set()
114-
coordinator = entry.runtime_data
114+
coordinator = entry.runtime_data.status
115115

116116
@callback
117117
def add_entities() -> None:

homeassistant/components/xbox/coordinator.py

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535

3636
_LOGGER = logging.getLogger(__name__)
3737

38-
type XboxConfigEntry = ConfigEntry[XboxUpdateCoordinator]
38+
type XboxConfigEntry = ConfigEntry[XboxCoordinators]
3939

4040

4141
@dataclass
@@ -55,6 +55,14 @@ class XboxData:
5555
title_info: dict[str, Title] = field(default_factory=dict)
5656

5757

58+
@dataclass
59+
class XboxCoordinators:
60+
"""Xbox coordinators."""
61+
62+
status: XboxUpdateCoordinator
63+
consoles: XboxConsolesCoordinator
64+
65+
5866
class XboxUpdateCoordinator(DataUpdateCoordinator[XboxData]):
5967
"""Store Xbox Console Status."""
6068

@@ -280,3 +288,43 @@ def configured_as_entry(self) -> set[str]:
280288
for entry in self.hass.config_entries.async_entries(DOMAIN)
281289
if entry.unique_id is not None
282290
}
291+
292+
293+
class XboxConsolesCoordinator(DataUpdateCoordinator[SmartglassConsoleList]):
294+
"""Update list of Xbox consoles."""
295+
296+
config_entry: XboxConfigEntry
297+
298+
def __init__(
299+
self,
300+
hass: HomeAssistant,
301+
config_entry: XboxConfigEntry,
302+
coordinator: XboxUpdateCoordinator,
303+
) -> None:
304+
"""Initialize."""
305+
super().__init__(
306+
hass,
307+
_LOGGER,
308+
config_entry=config_entry,
309+
name=DOMAIN,
310+
update_interval=timedelta(minutes=10),
311+
)
312+
self.client = coordinator.client
313+
self.async_set_updated_data(coordinator.consoles)
314+
315+
async def _async_update_data(self) -> SmartglassConsoleList:
316+
"""Fetch console data."""
317+
318+
try:
319+
return await self.client.smartglass.get_console_list()
320+
except TimeoutException as e:
321+
raise UpdateFailed(
322+
translation_domain=DOMAIN,
323+
translation_key="timeout_exception",
324+
) from e
325+
except (RequestError, HTTPStatusError) as e:
326+
_LOGGER.debug("Xbox exception:", exc_info=True)
327+
raise UpdateFailed(
328+
translation_domain=DOMAIN,
329+
translation_key="request_exception",
330+
) from e

homeassistant/components/xbox/image.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ async def async_setup_entry(
6464
) -> None:
6565
"""Set up Xbox images."""
6666

67-
coordinator = config_entry.runtime_data
67+
coordinator = config_entry.runtime_data.status
6868

6969
xuids_added: set[str] = set()
7070

homeassistant/components/xbox/media_player.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ async def async_setup_entry(
5656
) -> None:
5757
"""Set up Xbox media_player from a config entry."""
5858

59-
coordinator = entry.runtime_data
59+
coordinator = entry.runtime_data.status
6060

6161
async_add_entities(
6262
[

homeassistant/components/xbox/media_source.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ async def async_resolve_media(self, item: MediaSourceItem) -> PlayMedia:
112112
translation_key="account_not_configured",
113113
) from e
114114

115-
client = entry.runtime_data.client
115+
client = entry.runtime_data.status.client
116116

117117
if identifier.media_type in (ATTR_GAMECLIPS, ATTR_COMMUNITY_GAMECLIPS):
118118
try:
@@ -302,7 +302,7 @@ async def _build_game_library(self, entry: XboxConfigEntry) -> BrowseMediaSource
302302
async def _build_games(self, entry: XboxConfigEntry) -> list[BrowseMediaSource]:
303303
"""List Xbox games for the selected account."""
304304

305-
client = entry.runtime_data.client
305+
client = entry.runtime_data.status.client
306306
if TYPE_CHECKING:
307307
assert entry.unique_id
308308
fields = [
@@ -346,7 +346,7 @@ async def _build_game_title(
346346
self, entry: XboxConfigEntry, identifier: XboxMediaSourceIdentifier
347347
) -> BrowseMediaSource:
348348
"""Display game title."""
349-
client = entry.runtime_data.client
349+
client = entry.runtime_data.status.client
350350
try:
351351
game = (await client.titlehub.get_title_info(identifier.title_id)).titles[0]
352352
except TimeoutException as e:
@@ -402,7 +402,7 @@ async def _build_game_media(
402402
self, entry: XboxConfigEntry, identifier: XboxMediaSourceIdentifier
403403
) -> BrowseMediaSource:
404404
"""List game media."""
405-
client = entry.runtime_data.client
405+
client = entry.runtime_data.status.client
406406
try:
407407
game = (await client.titlehub.get_title_info(identifier.title_id)).titles[0]
408408
except TimeoutException as e:
@@ -439,7 +439,7 @@ async def _build_media_items_gameclips(
439439
self, entry: XboxConfigEntry, identifier: XboxMediaSourceIdentifier
440440
) -> list[BrowseMediaSource]:
441441
"""List media items."""
442-
client = entry.runtime_data.client
442+
client = entry.runtime_data.status.client
443443

444444
if identifier.media_type != ATTR_GAMECLIPS:
445445
return []
@@ -483,7 +483,7 @@ async def _build_media_items_community_gameclips(
483483
self, entry: XboxConfigEntry, identifier: XboxMediaSourceIdentifier
484484
) -> list[BrowseMediaSource]:
485485
"""List media items."""
486-
client = entry.runtime_data.client
486+
client = entry.runtime_data.status.client
487487

488488
if identifier.media_type != ATTR_COMMUNITY_GAMECLIPS:
489489
return []
@@ -527,7 +527,7 @@ async def _build_media_items_screenshots(
527527
self, entry: XboxConfigEntry, identifier: XboxMediaSourceIdentifier
528528
) -> list[BrowseMediaSource]:
529529
"""List media items."""
530-
client = entry.runtime_data.client
530+
client = entry.runtime_data.status.client
531531

532532
if identifier.media_type != ATTR_SCREENSHOTS:
533533
return []
@@ -571,7 +571,7 @@ async def _build_media_items_community_screenshots(
571571
self, entry: XboxConfigEntry, identifier: XboxMediaSourceIdentifier
572572
) -> list[BrowseMediaSource]:
573573
"""List media items."""
574-
client = entry.runtime_data.client
574+
client = entry.runtime_data.status.client
575575

576576
if identifier.media_type != ATTR_COMMUNITY_SCREENSHOTS:
577577
return []
@@ -640,7 +640,7 @@ def _build_media_items_promotional(
640640

641641
def gamerpic(config_entry: XboxConfigEntry) -> str | None:
642642
"""Return gamerpic."""
643-
coordinator = config_entry.runtime_data
643+
coordinator = config_entry.runtime_data.status
644644
if TYPE_CHECKING:
645645
assert config_entry.unique_id
646646
person = coordinator.data.presence[coordinator.client.xuid]

homeassistant/components/xbox/remote.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ async def async_setup_entry(
2727
async_add_entities: AddConfigEntryEntitiesCallback,
2828
) -> None:
2929
"""Set up Xbox media_player from a config entry."""
30-
coordinator = entry.runtime_data
30+
coordinator = entry.runtime_data.status
3131

3232
async_add_entities(
3333
[XboxRemote(console, coordinator) for console in coordinator.consoles.result]

0 commit comments

Comments
 (0)