mirror of
https://github.com/home-assistant/core.git
synced 2026-05-08 17:49:37 +01:00
Add device storage sensor entities to Xbox (#155657)
This commit is contained in:
@@ -9,7 +9,12 @@ from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers import config_validation as cv
|
||||
|
||||
from .const import DOMAIN
|
||||
from .coordinator import XboxConfigEntry, XboxUpdateCoordinator
|
||||
from .coordinator import (
|
||||
XboxConfigEntry,
|
||||
XboxConsolesCoordinator,
|
||||
XboxCoordinators,
|
||||
XboxUpdateCoordinator,
|
||||
)
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
@@ -30,7 +35,9 @@ async def async_setup_entry(hass: HomeAssistant, entry: XboxConfigEntry) -> bool
|
||||
coordinator = XboxUpdateCoordinator(hass, entry)
|
||||
await coordinator.async_config_entry_first_refresh()
|
||||
|
||||
entry.runtime_data = coordinator
|
||||
consoles = XboxConsolesCoordinator(hass, entry, coordinator)
|
||||
|
||||
entry.runtime_data = XboxCoordinators(coordinator, consoles)
|
||||
|
||||
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
|
||||
|
||||
@@ -53,16 +60,14 @@ async def async_migrate_unique_id(hass: HomeAssistant, entry: XboxConfigEntry) -
|
||||
if entry.version == 1 and entry.minor_version < 2:
|
||||
# Migrate unique_id from `xbox` to account xuid and
|
||||
# change generic entry name to user's gamertag
|
||||
coordinator = entry.runtime_data.status
|
||||
xuid = coordinator.client.xuid
|
||||
gamertag = coordinator.data.presence[xuid].gamertag
|
||||
|
||||
return hass.config_entries.async_update_entry(
|
||||
entry,
|
||||
unique_id=entry.runtime_data.client.xuid,
|
||||
title=(
|
||||
entry.runtime_data.data.presence[
|
||||
entry.runtime_data.client.xuid
|
||||
].gamertag
|
||||
if entry.title == "Home Assistant Cloud"
|
||||
else entry.title
|
||||
),
|
||||
unique_id=xuid,
|
||||
title=(gamertag if entry.title == "Home Assistant Cloud" else entry.title),
|
||||
minor_version=2,
|
||||
)
|
||||
|
||||
|
||||
@@ -111,7 +111,7 @@ async def async_setup_entry(
|
||||
) -> None:
|
||||
"""Set up Xbox Live friends."""
|
||||
xuids_added: set[str] = set()
|
||||
coordinator = entry.runtime_data
|
||||
coordinator = entry.runtime_data.status
|
||||
|
||||
@callback
|
||||
def add_entities() -> None:
|
||||
|
||||
@@ -35,7 +35,7 @@ from .const import DOMAIN
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
type XboxConfigEntry = ConfigEntry[XboxUpdateCoordinator]
|
||||
type XboxConfigEntry = ConfigEntry[XboxCoordinators]
|
||||
|
||||
|
||||
@dataclass
|
||||
@@ -55,6 +55,14 @@ class XboxData:
|
||||
title_info: dict[str, Title] = field(default_factory=dict)
|
||||
|
||||
|
||||
@dataclass
|
||||
class XboxCoordinators:
|
||||
"""Xbox coordinators."""
|
||||
|
||||
status: XboxUpdateCoordinator
|
||||
consoles: XboxConsolesCoordinator
|
||||
|
||||
|
||||
class XboxUpdateCoordinator(DataUpdateCoordinator[XboxData]):
|
||||
"""Store Xbox Console Status."""
|
||||
|
||||
@@ -280,3 +288,43 @@ class XboxUpdateCoordinator(DataUpdateCoordinator[XboxData]):
|
||||
for entry in self.hass.config_entries.async_entries(DOMAIN)
|
||||
if entry.unique_id is not None
|
||||
}
|
||||
|
||||
|
||||
class XboxConsolesCoordinator(DataUpdateCoordinator[SmartglassConsoleList]):
|
||||
"""Update list of Xbox consoles."""
|
||||
|
||||
config_entry: XboxConfigEntry
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
hass: HomeAssistant,
|
||||
config_entry: XboxConfigEntry,
|
||||
coordinator: XboxUpdateCoordinator,
|
||||
) -> None:
|
||||
"""Initialize."""
|
||||
super().__init__(
|
||||
hass,
|
||||
_LOGGER,
|
||||
config_entry=config_entry,
|
||||
name=DOMAIN,
|
||||
update_interval=timedelta(minutes=10),
|
||||
)
|
||||
self.client = coordinator.client
|
||||
self.async_set_updated_data(coordinator.consoles)
|
||||
|
||||
async def _async_update_data(self) -> SmartglassConsoleList:
|
||||
"""Fetch console data."""
|
||||
|
||||
try:
|
||||
return await self.client.smartglass.get_console_list()
|
||||
except TimeoutException as e:
|
||||
raise UpdateFailed(
|
||||
translation_domain=DOMAIN,
|
||||
translation_key="timeout_exception",
|
||||
) from e
|
||||
except (RequestError, HTTPStatusError) as e:
|
||||
_LOGGER.debug("Xbox exception:", exc_info=True)
|
||||
raise UpdateFailed(
|
||||
translation_domain=DOMAIN,
|
||||
translation_key="request_exception",
|
||||
) from e
|
||||
|
||||
@@ -64,7 +64,7 @@ async def async_setup_entry(
|
||||
) -> None:
|
||||
"""Set up Xbox images."""
|
||||
|
||||
coordinator = config_entry.runtime_data
|
||||
coordinator = config_entry.runtime_data.status
|
||||
|
||||
xuids_added: set[str] = set()
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ async def async_setup_entry(
|
||||
) -> None:
|
||||
"""Set up Xbox media_player from a config entry."""
|
||||
|
||||
coordinator = entry.runtime_data
|
||||
coordinator = entry.runtime_data.status
|
||||
|
||||
async_add_entities(
|
||||
[
|
||||
|
||||
@@ -112,7 +112,7 @@ class XboxSource(MediaSource):
|
||||
translation_key="account_not_configured",
|
||||
) from e
|
||||
|
||||
client = entry.runtime_data.client
|
||||
client = entry.runtime_data.status.client
|
||||
|
||||
if identifier.media_type in (ATTR_GAMECLIPS, ATTR_COMMUNITY_GAMECLIPS):
|
||||
try:
|
||||
@@ -302,7 +302,7 @@ class XboxSource(MediaSource):
|
||||
async def _build_games(self, entry: XboxConfigEntry) -> list[BrowseMediaSource]:
|
||||
"""List Xbox games for the selected account."""
|
||||
|
||||
client = entry.runtime_data.client
|
||||
client = entry.runtime_data.status.client
|
||||
if TYPE_CHECKING:
|
||||
assert entry.unique_id
|
||||
fields = [
|
||||
@@ -346,7 +346,7 @@ class XboxSource(MediaSource):
|
||||
self, entry: XboxConfigEntry, identifier: XboxMediaSourceIdentifier
|
||||
) -> BrowseMediaSource:
|
||||
"""Display game title."""
|
||||
client = entry.runtime_data.client
|
||||
client = entry.runtime_data.status.client
|
||||
try:
|
||||
game = (await client.titlehub.get_title_info(identifier.title_id)).titles[0]
|
||||
except TimeoutException as e:
|
||||
@@ -402,7 +402,7 @@ class XboxSource(MediaSource):
|
||||
self, entry: XboxConfigEntry, identifier: XboxMediaSourceIdentifier
|
||||
) -> BrowseMediaSource:
|
||||
"""List game media."""
|
||||
client = entry.runtime_data.client
|
||||
client = entry.runtime_data.status.client
|
||||
try:
|
||||
game = (await client.titlehub.get_title_info(identifier.title_id)).titles[0]
|
||||
except TimeoutException as e:
|
||||
@@ -439,7 +439,7 @@ class XboxSource(MediaSource):
|
||||
self, entry: XboxConfigEntry, identifier: XboxMediaSourceIdentifier
|
||||
) -> list[BrowseMediaSource]:
|
||||
"""List media items."""
|
||||
client = entry.runtime_data.client
|
||||
client = entry.runtime_data.status.client
|
||||
|
||||
if identifier.media_type != ATTR_GAMECLIPS:
|
||||
return []
|
||||
@@ -483,7 +483,7 @@ class XboxSource(MediaSource):
|
||||
self, entry: XboxConfigEntry, identifier: XboxMediaSourceIdentifier
|
||||
) -> list[BrowseMediaSource]:
|
||||
"""List media items."""
|
||||
client = entry.runtime_data.client
|
||||
client = entry.runtime_data.status.client
|
||||
|
||||
if identifier.media_type != ATTR_COMMUNITY_GAMECLIPS:
|
||||
return []
|
||||
@@ -527,7 +527,7 @@ class XboxSource(MediaSource):
|
||||
self, entry: XboxConfigEntry, identifier: XboxMediaSourceIdentifier
|
||||
) -> list[BrowseMediaSource]:
|
||||
"""List media items."""
|
||||
client = entry.runtime_data.client
|
||||
client = entry.runtime_data.status.client
|
||||
|
||||
if identifier.media_type != ATTR_SCREENSHOTS:
|
||||
return []
|
||||
@@ -571,7 +571,7 @@ class XboxSource(MediaSource):
|
||||
self, entry: XboxConfigEntry, identifier: XboxMediaSourceIdentifier
|
||||
) -> list[BrowseMediaSource]:
|
||||
"""List media items."""
|
||||
client = entry.runtime_data.client
|
||||
client = entry.runtime_data.status.client
|
||||
|
||||
if identifier.media_type != ATTR_COMMUNITY_SCREENSHOTS:
|
||||
return []
|
||||
@@ -640,7 +640,7 @@ class XboxSource(MediaSource):
|
||||
|
||||
def gamerpic(config_entry: XboxConfigEntry) -> str | None:
|
||||
"""Return gamerpic."""
|
||||
coordinator = config_entry.runtime_data
|
||||
coordinator = config_entry.runtime_data.status
|
||||
if TYPE_CHECKING:
|
||||
assert config_entry.unique_id
|
||||
person = coordinator.data.presence[coordinator.client.xuid]
|
||||
|
||||
@@ -27,7 +27,7 @@ async def async_setup_entry(
|
||||
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up Xbox media_player from a config entry."""
|
||||
coordinator = entry.runtime_data
|
||||
coordinator = entry.runtime_data.status
|
||||
|
||||
async_add_entities(
|
||||
[XboxRemote(console, coordinator) for console in coordinator.consoles.result]
|
||||
|
||||
@@ -9,20 +9,32 @@ from enum import StrEnum
|
||||
from typing import Any
|
||||
|
||||
from pythonxbox.api.provider.people.models import Person
|
||||
from pythonxbox.api.provider.smartglass.models import SmartglassConsole, StorageDevice
|
||||
from pythonxbox.api.provider.titlehub.models import Title
|
||||
|
||||
from homeassistant.components.sensor import (
|
||||
DOMAIN as SENSOR_DOMAIN,
|
||||
EntityCategory,
|
||||
SensorDeviceClass,
|
||||
SensorEntity,
|
||||
SensorEntityDescription,
|
||||
SensorStateClass,
|
||||
)
|
||||
from homeassistant.const import CONF_NAME, UnitOfInformation
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.helpers.device_registry import DeviceInfo
|
||||
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
||||
from homeassistant.helpers.typing import StateType
|
||||
from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
||||
|
||||
from .coordinator import XboxConfigEntry
|
||||
from .entity import XboxBaseEntity, XboxBaseEntityDescription, check_deprecated_entity
|
||||
from .const import DOMAIN
|
||||
from .coordinator import XboxConfigEntry, XboxConsolesCoordinator
|
||||
from .entity import (
|
||||
MAP_MODEL,
|
||||
XboxBaseEntity,
|
||||
XboxBaseEntityDescription,
|
||||
check_deprecated_entity,
|
||||
)
|
||||
|
||||
MAP_JOIN_RESTRICTIONS = {
|
||||
"local": "invite_only",
|
||||
@@ -44,6 +56,8 @@ class XboxSensor(StrEnum):
|
||||
FRIENDS = "friends"
|
||||
IN_PARTY = "in_party"
|
||||
JOIN_RESTRICTIONS = "join_restrictions"
|
||||
TOTAL_STORAGE = "total_storage"
|
||||
FREE_STORAGE = "free_storage"
|
||||
|
||||
|
||||
@dataclass(kw_only=True, frozen=True)
|
||||
@@ -53,6 +67,15 @@ class XboxSensorEntityDescription(XboxBaseEntityDescription, SensorEntityDescrip
|
||||
value_fn: Callable[[Person, Title | None], StateType | datetime]
|
||||
|
||||
|
||||
@dataclass(kw_only=True, frozen=True)
|
||||
class XboxStorageDeviceSensorEntityDescription(
|
||||
XboxBaseEntityDescription, SensorEntityDescription
|
||||
):
|
||||
"""Xbox console sensor description."""
|
||||
|
||||
value_fn: Callable[[StorageDevice], StateType]
|
||||
|
||||
|
||||
def now_playing_attributes(_: Person, title: Title | None) -> dict[str, Any]:
|
||||
"""Attributes of the currently played title."""
|
||||
attributes: dict[str, Any] = {
|
||||
@@ -195,6 +218,31 @@ SENSOR_DESCRIPTIONS: tuple[XboxSensorEntityDescription, ...] = (
|
||||
),
|
||||
)
|
||||
|
||||
STORAGE_SENSOR_DESCRIPTIONS: tuple[XboxStorageDeviceSensorEntityDescription, ...] = (
|
||||
XboxStorageDeviceSensorEntityDescription(
|
||||
key=XboxSensor.TOTAL_STORAGE,
|
||||
translation_key=XboxSensor.TOTAL_STORAGE,
|
||||
value_fn=lambda x: x.total_space_bytes,
|
||||
device_class=SensorDeviceClass.DATA_SIZE,
|
||||
native_unit_of_measurement=UnitOfInformation.BYTES,
|
||||
suggested_unit_of_measurement=UnitOfInformation.GIBIBYTES,
|
||||
suggested_display_precision=0,
|
||||
entity_category=EntityCategory.DIAGNOSTIC,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
),
|
||||
XboxStorageDeviceSensorEntityDescription(
|
||||
key=XboxSensor.FREE_STORAGE,
|
||||
translation_key=XboxSensor.FREE_STORAGE,
|
||||
value_fn=lambda x: x.free_space_bytes,
|
||||
device_class=SensorDeviceClass.DATA_SIZE,
|
||||
native_unit_of_measurement=UnitOfInformation.BYTES,
|
||||
suggested_unit_of_measurement=UnitOfInformation.GIBIBYTES,
|
||||
suggested_display_precision=0,
|
||||
entity_category=EntityCategory.DIAGNOSTIC,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
@@ -203,7 +251,7 @@ async def async_setup_entry(
|
||||
) -> None:
|
||||
"""Set up Xbox Live friends."""
|
||||
xuids_added: set[str] = set()
|
||||
coordinator = config_entry.runtime_data
|
||||
coordinator = config_entry.runtime_data.status
|
||||
|
||||
@callback
|
||||
def add_entities() -> None:
|
||||
@@ -225,6 +273,20 @@ async def async_setup_entry(
|
||||
coordinator.async_add_listener(add_entities)
|
||||
add_entities()
|
||||
|
||||
consoles_coordinator = config_entry.runtime_data.consoles
|
||||
|
||||
async_add_entities(
|
||||
[
|
||||
XboxStorageDeviceSensorEntity(
|
||||
console, storage_device, consoles_coordinator, description
|
||||
)
|
||||
for description in STORAGE_SENSOR_DESCRIPTIONS
|
||||
for console in coordinator.consoles.result
|
||||
if console.storage_devices
|
||||
for storage_device in console.storage_devices
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
class XboxSensorEntity(XboxBaseEntity, SensorEntity):
|
||||
"""Representation of a Xbox presence state."""
|
||||
@@ -235,3 +297,62 @@ class XboxSensorEntity(XboxBaseEntity, SensorEntity):
|
||||
def native_value(self) -> StateType | datetime:
|
||||
"""Return the state of the requested attribute."""
|
||||
return self.entity_description.value_fn(self.data, self.title_info)
|
||||
|
||||
|
||||
class XboxStorageDeviceSensorEntity(
|
||||
CoordinatorEntity[XboxConsolesCoordinator], SensorEntity
|
||||
):
|
||||
"""Console storage device entity for the Xbox integration."""
|
||||
|
||||
_attr_has_entity_name = True
|
||||
entity_description: XboxStorageDeviceSensorEntityDescription
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
console: SmartglassConsole,
|
||||
storage_device: StorageDevice,
|
||||
coordinator: XboxConsolesCoordinator,
|
||||
entity_description: XboxStorageDeviceSensorEntityDescription,
|
||||
) -> None:
|
||||
"""Initialize the Xbox Console entity."""
|
||||
super().__init__(coordinator)
|
||||
self.entity_description = entity_description
|
||||
self.client = coordinator.client
|
||||
self._console = console
|
||||
self._storage_device = storage_device
|
||||
self._attr_unique_id = (
|
||||
f"{console.id}_{storage_device.storage_device_id}_{entity_description.key}"
|
||||
)
|
||||
self._attr_translation_placeholders = {
|
||||
CONF_NAME: storage_device.storage_device_name
|
||||
}
|
||||
|
||||
self._attr_device_info = DeviceInfo(
|
||||
identifiers={(DOMAIN, console.id)},
|
||||
manufacturer="Microsoft",
|
||||
model=MAP_MODEL.get(self._console.console_type, "Unknown"),
|
||||
name=console.name,
|
||||
)
|
||||
|
||||
@property
|
||||
def data(self):
|
||||
"""Storage device data."""
|
||||
consoles = self.coordinator.data.result
|
||||
console = next((c for c in consoles if c.id == self._console.id), None)
|
||||
if not console or not console.storage_devices:
|
||||
return None
|
||||
|
||||
return next(
|
||||
(
|
||||
d
|
||||
for d in console.storage_devices
|
||||
if d.storage_device_id == self._storage_device.storage_device_id
|
||||
),
|
||||
None,
|
||||
)
|
||||
|
||||
@property
|
||||
def native_value(self) -> StateType:
|
||||
"""Return the state of the requested attribute."""
|
||||
|
||||
return self.entity_description.value_fn(self.data) if self.data else None
|
||||
|
||||
@@ -65,6 +65,9 @@
|
||||
"name": "Following",
|
||||
"unit_of_measurement": "people"
|
||||
},
|
||||
"free_storage": {
|
||||
"name": "Free space - {name}"
|
||||
},
|
||||
"friends": {
|
||||
"name": "Friends",
|
||||
"unit_of_measurement": "[%key:component::xbox::entity::sensor::following::unit_of_measurement%]"
|
||||
@@ -105,6 +108,9 @@
|
||||
},
|
||||
"status": {
|
||||
"name": "Status"
|
||||
},
|
||||
"total_storage": {
|
||||
"name": "Total space - {name}"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -1371,3 +1371,357 @@
|
||||
'state': 'Offline',
|
||||
})
|
||||
# ---
|
||||
# name: test_sensors[sensor.xone_free_space_external-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'sensor',
|
||||
'entity_category': <EntityCategory.DIAGNOSTIC: 'diagnostic'>,
|
||||
'entity_id': 'sensor.xone_free_space_external',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
'sensor': dict({
|
||||
'suggested_display_precision': 0,
|
||||
}),
|
||||
'sensor.private': dict({
|
||||
'suggested_unit_of_measurement': <UnitOfInformation.GIBIBYTES: 'GiB'>,
|
||||
}),
|
||||
}),
|
||||
'original_device_class': <SensorDeviceClass.DATA_SIZE: 'data_size'>,
|
||||
'original_icon': None,
|
||||
'original_name': 'Free space - External',
|
||||
'platform': 'xbox',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': <XboxSensor.FREE_STORAGE: 'free_storage'>,
|
||||
'unique_id': 'HIJKLMN_3_free_storage',
|
||||
'unit_of_measurement': <UnitOfInformation.GIBIBYTES: 'GiB'>,
|
||||
})
|
||||
# ---
|
||||
# name: test_sensors[sensor.xone_free_space_external-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'data_size',
|
||||
'friendly_name': 'XONE Free space - External',
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
'unit_of_measurement': <UnitOfInformation.GIBIBYTES: 'GiB'>,
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.xone_free_space_external',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': '2980.89726638794',
|
||||
})
|
||||
# ---
|
||||
# name: test_sensors[sensor.xone_free_space_internal-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'sensor',
|
||||
'entity_category': <EntityCategory.DIAGNOSTIC: 'diagnostic'>,
|
||||
'entity_id': 'sensor.xone_free_space_internal',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
'sensor': dict({
|
||||
'suggested_display_precision': 0,
|
||||
}),
|
||||
'sensor.private': dict({
|
||||
'suggested_unit_of_measurement': <UnitOfInformation.GIBIBYTES: 'GiB'>,
|
||||
}),
|
||||
}),
|
||||
'original_device_class': <SensorDeviceClass.DATA_SIZE: 'data_size'>,
|
||||
'original_icon': None,
|
||||
'original_name': 'Free space - Internal',
|
||||
'platform': 'xbox',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': <XboxSensor.FREE_STORAGE: 'free_storage'>,
|
||||
'unique_id': 'HIJKLMN_2_free_storage',
|
||||
'unit_of_measurement': <UnitOfInformation.GIBIBYTES: 'GiB'>,
|
||||
})
|
||||
# ---
|
||||
# name: test_sensors[sensor.xone_free_space_internal-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'data_size',
|
||||
'friendly_name': 'XONE Free space - Internal',
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
'unit_of_measurement': <UnitOfInformation.GIBIBYTES: 'GiB'>,
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.xone_free_space_internal',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': '137.056728363037',
|
||||
})
|
||||
# ---
|
||||
# name: test_sensors[sensor.xone_total_space_external-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'sensor',
|
||||
'entity_category': <EntityCategory.DIAGNOSTIC: 'diagnostic'>,
|
||||
'entity_id': 'sensor.xone_total_space_external',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
'sensor': dict({
|
||||
'suggested_display_precision': 0,
|
||||
}),
|
||||
'sensor.private': dict({
|
||||
'suggested_unit_of_measurement': <UnitOfInformation.GIBIBYTES: 'GiB'>,
|
||||
}),
|
||||
}),
|
||||
'original_device_class': <SensorDeviceClass.DATA_SIZE: 'data_size'>,
|
||||
'original_icon': None,
|
||||
'original_name': 'Total space - External',
|
||||
'platform': 'xbox',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': <XboxSensor.TOTAL_STORAGE: 'total_storage'>,
|
||||
'unique_id': 'HIJKLMN_3_total_storage',
|
||||
'unit_of_measurement': <UnitOfInformation.GIBIBYTES: 'GiB'>,
|
||||
})
|
||||
# ---
|
||||
# name: test_sensors[sensor.xone_total_space_external-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'data_size',
|
||||
'friendly_name': 'XONE Total space - External',
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
'unit_of_measurement': <UnitOfInformation.GIBIBYTES: 'GiB'>,
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.xone_total_space_external',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': '3726.02327680588',
|
||||
})
|
||||
# ---
|
||||
# name: test_sensors[sensor.xone_total_space_internal-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'sensor',
|
||||
'entity_category': <EntityCategory.DIAGNOSTIC: 'diagnostic'>,
|
||||
'entity_id': 'sensor.xone_total_space_internal',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
'sensor': dict({
|
||||
'suggested_display_precision': 0,
|
||||
}),
|
||||
'sensor.private': dict({
|
||||
'suggested_unit_of_measurement': <UnitOfInformation.GIBIBYTES: 'GiB'>,
|
||||
}),
|
||||
}),
|
||||
'original_device_class': <SensorDeviceClass.DATA_SIZE: 'data_size'>,
|
||||
'original_icon': None,
|
||||
'original_name': 'Total space - Internal',
|
||||
'platform': 'xbox',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': <XboxSensor.TOTAL_STORAGE: 'total_storage'>,
|
||||
'unique_id': 'HIJKLMN_2_total_storage',
|
||||
'unit_of_measurement': <UnitOfInformation.GIBIBYTES: 'GiB'>,
|
||||
})
|
||||
# ---
|
||||
# name: test_sensors[sensor.xone_total_space_internal-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'data_size',
|
||||
'friendly_name': 'XONE Total space - Internal',
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
'unit_of_measurement': <UnitOfInformation.GIBIBYTES: 'GiB'>,
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.xone_total_space_internal',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': '364.999996185303',
|
||||
})
|
||||
# ---
|
||||
# name: test_sensors[sensor.xonex_free_space_internal-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'sensor',
|
||||
'entity_category': <EntityCategory.DIAGNOSTIC: 'diagnostic'>,
|
||||
'entity_id': 'sensor.xonex_free_space_internal',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
'sensor': dict({
|
||||
'suggested_display_precision': 0,
|
||||
}),
|
||||
'sensor.private': dict({
|
||||
'suggested_unit_of_measurement': <UnitOfInformation.GIBIBYTES: 'GiB'>,
|
||||
}),
|
||||
}),
|
||||
'original_device_class': <SensorDeviceClass.DATA_SIZE: 'data_size'>,
|
||||
'original_icon': None,
|
||||
'original_name': 'Free space - Internal',
|
||||
'platform': 'xbox',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': <XboxSensor.FREE_STORAGE: 'free_storage'>,
|
||||
'unique_id': 'ABCDEFG_1_free_storage',
|
||||
'unit_of_measurement': <UnitOfInformation.GIBIBYTES: 'GiB'>,
|
||||
})
|
||||
# ---
|
||||
# name: test_sensors[sensor.xonex_free_space_internal-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'data_size',
|
||||
'friendly_name': 'XONEX Free space - Internal',
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
'unit_of_measurement': <UnitOfInformation.GIBIBYTES: 'GiB'>,
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.xonex_free_space_internal',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': '220.041568756104',
|
||||
})
|
||||
# ---
|
||||
# name: test_sensors[sensor.xonex_total_space_internal-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'sensor',
|
||||
'entity_category': <EntityCategory.DIAGNOSTIC: 'diagnostic'>,
|
||||
'entity_id': 'sensor.xonex_total_space_internal',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
'sensor': dict({
|
||||
'suggested_display_precision': 0,
|
||||
}),
|
||||
'sensor.private': dict({
|
||||
'suggested_unit_of_measurement': <UnitOfInformation.GIBIBYTES: 'GiB'>,
|
||||
}),
|
||||
}),
|
||||
'original_device_class': <SensorDeviceClass.DATA_SIZE: 'data_size'>,
|
||||
'original_icon': None,
|
||||
'original_name': 'Total space - Internal',
|
||||
'platform': 'xbox',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': <XboxSensor.TOTAL_STORAGE: 'total_storage'>,
|
||||
'unique_id': 'ABCDEFG_1_total_storage',
|
||||
'unit_of_measurement': <UnitOfInformation.GIBIBYTES: 'GiB'>,
|
||||
})
|
||||
# ---
|
||||
# name: test_sensors[sensor.xonex_total_space_internal-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'data_size',
|
||||
'friendly_name': 'XONEX Total space - Internal',
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
'unit_of_measurement': <UnitOfInformation.GIBIBYTES: 'GiB'>,
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.xonex_total_space_internal',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': '780.999996185303',
|
||||
})
|
||||
# ---
|
||||
|
||||
Reference in New Issue
Block a user