mirror of
https://github.com/home-assistant/core.git
synced 2025-07-17 02:07:09 +00:00
Add created sensor in filesize (#131108)
This commit is contained in:
parent
5529cfda09
commit
e7fedef651
@ -60,12 +60,14 @@ class FileSizeCoordinator(DataUpdateCoordinator[dict[str, int | float | datetime
|
|||||||
statinfo = await self.hass.async_add_executor_job(self._update)
|
statinfo = await self.hass.async_add_executor_job(self._update)
|
||||||
size = statinfo.st_size
|
size = statinfo.st_size
|
||||||
last_updated = dt_util.utc_from_timestamp(statinfo.st_mtime)
|
last_updated = dt_util.utc_from_timestamp(statinfo.st_mtime)
|
||||||
|
created = dt_util.utc_from_timestamp(statinfo.st_ctime)
|
||||||
|
|
||||||
_LOGGER.debug("size %s, last updated %s", size, last_updated)
|
_LOGGER.debug("size %s, last updated %s", size, last_updated)
|
||||||
data: dict[str, int | float | datetime] = {
|
data: dict[str, int | float | datetime] = {
|
||||||
"file": round(size / 1e6, 2),
|
"file": round(size / 1e6, 2),
|
||||||
"bytes": size,
|
"bytes": size,
|
||||||
"last_updated": last_updated,
|
"last_updated": last_updated,
|
||||||
|
"created": created,
|
||||||
}
|
}
|
||||||
|
|
||||||
return data
|
return data
|
||||||
|
@ -9,6 +9,9 @@
|
|||||||
},
|
},
|
||||||
"last_updated": {
|
"last_updated": {
|
||||||
"default": "mdi:file"
|
"default": "mdi:file"
|
||||||
|
},
|
||||||
|
"created": {
|
||||||
|
"default": "mdi:file"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -47,6 +47,13 @@ SENSOR_TYPES = (
|
|||||||
device_class=SensorDeviceClass.TIMESTAMP,
|
device_class=SensorDeviceClass.TIMESTAMP,
|
||||||
entity_category=EntityCategory.DIAGNOSTIC,
|
entity_category=EntityCategory.DIAGNOSTIC,
|
||||||
),
|
),
|
||||||
|
SensorEntityDescription(
|
||||||
|
key="created",
|
||||||
|
translation_key="created",
|
||||||
|
entity_registry_enabled_default=False,
|
||||||
|
device_class=SensorDeviceClass.TIMESTAMP,
|
||||||
|
entity_category=EntityCategory.DIAGNOSTIC,
|
||||||
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -26,6 +26,9 @@
|
|||||||
},
|
},
|
||||||
"last_updated": {
|
"last_updated": {
|
||||||
"name": "Last updated"
|
"name": "Last updated"
|
||||||
|
},
|
||||||
|
"created": {
|
||||||
|
"name": "Created"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,21 +8,30 @@ from unittest.mock import patch
|
|||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from homeassistant.components.filesize.const import DOMAIN
|
from homeassistant.components.filesize.const import DOMAIN, PLATFORMS
|
||||||
from homeassistant.const import CONF_FILE_PATH
|
from homeassistant.const import CONF_FILE_PATH, Platform
|
||||||
|
|
||||||
from . import TEST_FILE_NAME
|
from . import TEST_FILE_NAME
|
||||||
|
|
||||||
from tests.common import MockConfigEntry
|
from tests.common import MockConfigEntry
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(name="load_platforms")
|
||||||
|
async def patch_platform_constant() -> list[Platform]:
|
||||||
|
"""Return list of platforms to load."""
|
||||||
|
return PLATFORMS
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def mock_config_entry(tmp_path: Path) -> MockConfigEntry:
|
def mock_config_entry(
|
||||||
|
tmp_path: Path, load_platforms: list[Platform]
|
||||||
|
) -> MockConfigEntry:
|
||||||
"""Return the default mocked config entry."""
|
"""Return the default mocked config entry."""
|
||||||
test_file = str(tmp_path.joinpath(TEST_FILE_NAME))
|
test_file = str(tmp_path.joinpath(TEST_FILE_NAME))
|
||||||
return MockConfigEntry(
|
return MockConfigEntry(
|
||||||
title=TEST_FILE_NAME,
|
title=TEST_FILE_NAME,
|
||||||
domain=DOMAIN,
|
domain=DOMAIN,
|
||||||
|
entry_id="01JD5CTQMH9FKEFQKZJ8MMBQ3X",
|
||||||
data={CONF_FILE_PATH: test_file},
|
data={CONF_FILE_PATH: test_file},
|
||||||
unique_id=test_file,
|
unique_id=test_file,
|
||||||
)
|
)
|
||||||
|
197
tests/components/filesize/snapshots/test_sensor.ambr
Normal file
197
tests/components/filesize/snapshots/test_sensor.ambr
Normal file
@ -0,0 +1,197 @@
|
|||||||
|
# serializer version: 1
|
||||||
|
# name: test_sensors[load_platforms0][sensor.file_txt_created-entry]
|
||||||
|
EntityRegistryEntrySnapshot({
|
||||||
|
'aliases': set({
|
||||||
|
}),
|
||||||
|
'area_id': None,
|
||||||
|
'capabilities': None,
|
||||||
|
'config_entry_id': <ANY>,
|
||||||
|
'device_class': None,
|
||||||
|
'device_id': <ANY>,
|
||||||
|
'disabled_by': None,
|
||||||
|
'domain': 'sensor',
|
||||||
|
'entity_category': <EntityCategory.DIAGNOSTIC: 'diagnostic'>,
|
||||||
|
'entity_id': 'sensor.file_txt_created',
|
||||||
|
'has_entity_name': True,
|
||||||
|
'hidden_by': None,
|
||||||
|
'icon': None,
|
||||||
|
'id': <ANY>,
|
||||||
|
'labels': set({
|
||||||
|
}),
|
||||||
|
'name': None,
|
||||||
|
'options': dict({
|
||||||
|
}),
|
||||||
|
'original_device_class': <SensorDeviceClass.TIMESTAMP: 'timestamp'>,
|
||||||
|
'original_icon': None,
|
||||||
|
'original_name': 'Created',
|
||||||
|
'platform': 'filesize',
|
||||||
|
'previous_unique_id': None,
|
||||||
|
'supported_features': 0,
|
||||||
|
'translation_key': 'created',
|
||||||
|
'unique_id': '01JD5CTQMH9FKEFQKZJ8MMBQ3X-created',
|
||||||
|
'unit_of_measurement': None,
|
||||||
|
})
|
||||||
|
# ---
|
||||||
|
# name: test_sensors[load_platforms0][sensor.file_txt_created-state]
|
||||||
|
StateSnapshot({
|
||||||
|
'attributes': ReadOnlyDict({
|
||||||
|
'device_class': 'timestamp',
|
||||||
|
'friendly_name': 'file.txt Created',
|
||||||
|
}),
|
||||||
|
'context': <ANY>,
|
||||||
|
'entity_id': 'sensor.file_txt_created',
|
||||||
|
'last_changed': <ANY>,
|
||||||
|
'last_reported': <ANY>,
|
||||||
|
'last_updated': <ANY>,
|
||||||
|
'state': '2024-11-20T18:19:04+00:00',
|
||||||
|
})
|
||||||
|
# ---
|
||||||
|
# name: test_sensors[load_platforms0][sensor.file_txt_last_updated-entry]
|
||||||
|
EntityRegistryEntrySnapshot({
|
||||||
|
'aliases': set({
|
||||||
|
}),
|
||||||
|
'area_id': None,
|
||||||
|
'capabilities': None,
|
||||||
|
'config_entry_id': <ANY>,
|
||||||
|
'device_class': None,
|
||||||
|
'device_id': <ANY>,
|
||||||
|
'disabled_by': None,
|
||||||
|
'domain': 'sensor',
|
||||||
|
'entity_category': <EntityCategory.DIAGNOSTIC: 'diagnostic'>,
|
||||||
|
'entity_id': 'sensor.file_txt_last_updated',
|
||||||
|
'has_entity_name': True,
|
||||||
|
'hidden_by': None,
|
||||||
|
'icon': None,
|
||||||
|
'id': <ANY>,
|
||||||
|
'labels': set({
|
||||||
|
}),
|
||||||
|
'name': None,
|
||||||
|
'options': dict({
|
||||||
|
}),
|
||||||
|
'original_device_class': <SensorDeviceClass.TIMESTAMP: 'timestamp'>,
|
||||||
|
'original_icon': None,
|
||||||
|
'original_name': 'Last updated',
|
||||||
|
'platform': 'filesize',
|
||||||
|
'previous_unique_id': None,
|
||||||
|
'supported_features': 0,
|
||||||
|
'translation_key': 'last_updated',
|
||||||
|
'unique_id': '01JD5CTQMH9FKEFQKZJ8MMBQ3X-last_updated',
|
||||||
|
'unit_of_measurement': None,
|
||||||
|
})
|
||||||
|
# ---
|
||||||
|
# name: test_sensors[load_platforms0][sensor.file_txt_last_updated-state]
|
||||||
|
StateSnapshot({
|
||||||
|
'attributes': ReadOnlyDict({
|
||||||
|
'device_class': 'timestamp',
|
||||||
|
'friendly_name': 'file.txt Last updated',
|
||||||
|
}),
|
||||||
|
'context': <ANY>,
|
||||||
|
'entity_id': 'sensor.file_txt_last_updated',
|
||||||
|
'last_changed': <ANY>,
|
||||||
|
'last_reported': <ANY>,
|
||||||
|
'last_updated': <ANY>,
|
||||||
|
'state': '2024-11-20T18:19:24+00:00',
|
||||||
|
})
|
||||||
|
# ---
|
||||||
|
# name: test_sensors[load_platforms0][sensor.file_txt_size-entry]
|
||||||
|
EntityRegistryEntrySnapshot({
|
||||||
|
'aliases': set({
|
||||||
|
}),
|
||||||
|
'area_id': None,
|
||||||
|
'capabilities': dict({
|
||||||
|
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||||
|
}),
|
||||||
|
'config_entry_id': <ANY>,
|
||||||
|
'device_class': None,
|
||||||
|
'device_id': <ANY>,
|
||||||
|
'disabled_by': None,
|
||||||
|
'domain': 'sensor',
|
||||||
|
'entity_category': None,
|
||||||
|
'entity_id': 'sensor.file_txt_size',
|
||||||
|
'has_entity_name': True,
|
||||||
|
'hidden_by': None,
|
||||||
|
'icon': None,
|
||||||
|
'id': <ANY>,
|
||||||
|
'labels': set({
|
||||||
|
}),
|
||||||
|
'name': None,
|
||||||
|
'options': dict({
|
||||||
|
}),
|
||||||
|
'original_device_class': <SensorDeviceClass.DATA_SIZE: 'data_size'>,
|
||||||
|
'original_icon': None,
|
||||||
|
'original_name': 'Size',
|
||||||
|
'platform': 'filesize',
|
||||||
|
'previous_unique_id': None,
|
||||||
|
'supported_features': 0,
|
||||||
|
'translation_key': 'size',
|
||||||
|
'unique_id': '01JD5CTQMH9FKEFQKZJ8MMBQ3X',
|
||||||
|
'unit_of_measurement': <UnitOfInformation.MEGABYTES: 'MB'>,
|
||||||
|
})
|
||||||
|
# ---
|
||||||
|
# name: test_sensors[load_platforms0][sensor.file_txt_size-state]
|
||||||
|
StateSnapshot({
|
||||||
|
'attributes': ReadOnlyDict({
|
||||||
|
'device_class': 'data_size',
|
||||||
|
'friendly_name': 'file.txt Size',
|
||||||
|
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||||
|
'unit_of_measurement': <UnitOfInformation.MEGABYTES: 'MB'>,
|
||||||
|
}),
|
||||||
|
'context': <ANY>,
|
||||||
|
'entity_id': 'sensor.file_txt_size',
|
||||||
|
'last_changed': <ANY>,
|
||||||
|
'last_reported': <ANY>,
|
||||||
|
'last_updated': <ANY>,
|
||||||
|
'state': '0.0',
|
||||||
|
})
|
||||||
|
# ---
|
||||||
|
# name: test_sensors[load_platforms0][sensor.file_txt_size_in_bytes-entry]
|
||||||
|
EntityRegistryEntrySnapshot({
|
||||||
|
'aliases': set({
|
||||||
|
}),
|
||||||
|
'area_id': None,
|
||||||
|
'capabilities': dict({
|
||||||
|
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||||
|
}),
|
||||||
|
'config_entry_id': <ANY>,
|
||||||
|
'device_class': None,
|
||||||
|
'device_id': <ANY>,
|
||||||
|
'disabled_by': None,
|
||||||
|
'domain': 'sensor',
|
||||||
|
'entity_category': <EntityCategory.DIAGNOSTIC: 'diagnostic'>,
|
||||||
|
'entity_id': 'sensor.file_txt_size_in_bytes',
|
||||||
|
'has_entity_name': True,
|
||||||
|
'hidden_by': None,
|
||||||
|
'icon': None,
|
||||||
|
'id': <ANY>,
|
||||||
|
'labels': set({
|
||||||
|
}),
|
||||||
|
'name': None,
|
||||||
|
'options': dict({
|
||||||
|
}),
|
||||||
|
'original_device_class': <SensorDeviceClass.DATA_SIZE: 'data_size'>,
|
||||||
|
'original_icon': None,
|
||||||
|
'original_name': 'Size in bytes',
|
||||||
|
'platform': 'filesize',
|
||||||
|
'previous_unique_id': None,
|
||||||
|
'supported_features': 0,
|
||||||
|
'translation_key': 'size_bytes',
|
||||||
|
'unique_id': '01JD5CTQMH9FKEFQKZJ8MMBQ3X-bytes',
|
||||||
|
'unit_of_measurement': <UnitOfInformation.BYTES: 'B'>,
|
||||||
|
})
|
||||||
|
# ---
|
||||||
|
# name: test_sensors[load_platforms0][sensor.file_txt_size_in_bytes-state]
|
||||||
|
StateSnapshot({
|
||||||
|
'attributes': ReadOnlyDict({
|
||||||
|
'device_class': 'data_size',
|
||||||
|
'friendly_name': 'file.txt Size in bytes',
|
||||||
|
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||||
|
'unit_of_measurement': <UnitOfInformation.BYTES: 'B'>,
|
||||||
|
}),
|
||||||
|
'context': <ANY>,
|
||||||
|
'entity_id': 'sensor.file_txt_size_in_bytes',
|
||||||
|
'last_changed': <ANY>,
|
||||||
|
'last_reported': <ANY>,
|
||||||
|
'last_updated': <ANY>,
|
||||||
|
'state': '4',
|
||||||
|
})
|
||||||
|
# ---
|
@ -2,14 +2,55 @@
|
|||||||
|
|
||||||
import os
|
import os
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
from unittest.mock import patch
|
||||||
|
|
||||||
from homeassistant.const import CONF_FILE_PATH, STATE_UNAVAILABLE
|
import pytest
|
||||||
|
from syrupy.assertion import SnapshotAssertion
|
||||||
|
|
||||||
|
from homeassistant.const import CONF_FILE_PATH, STATE_UNAVAILABLE, Platform
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
|
from homeassistant.helpers import entity_registry as er
|
||||||
from homeassistant.helpers.entity_component import async_update_entity
|
from homeassistant.helpers.entity_component import async_update_entity
|
||||||
|
|
||||||
from . import TEST_FILE_NAME, async_create_file
|
from . import TEST_FILE_NAME, async_create_file
|
||||||
|
|
||||||
from tests.common import MockConfigEntry
|
from tests.common import MockConfigEntry, snapshot_platform
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"load_platforms",
|
||||||
|
[[Platform.SENSOR]],
|
||||||
|
)
|
||||||
|
@pytest.mark.usefixtures("entity_registry_enabled_by_default")
|
||||||
|
async def test_sensors(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
mock_config_entry: MockConfigEntry,
|
||||||
|
tmp_path: Path,
|
||||||
|
entity_registry: er.EntityRegistry,
|
||||||
|
snapshot: SnapshotAssertion,
|
||||||
|
) -> None:
|
||||||
|
"""Test that an invalid path is caught."""
|
||||||
|
testfile = str(tmp_path.joinpath("file.txt"))
|
||||||
|
await async_create_file(hass, testfile)
|
||||||
|
hass.config.allowlist_external_dirs = {tmp_path}
|
||||||
|
mock_config_entry.add_to_hass(hass)
|
||||||
|
hass.config_entries.async_update_entry(
|
||||||
|
mock_config_entry, data={CONF_FILE_PATH: testfile}
|
||||||
|
)
|
||||||
|
with (
|
||||||
|
patch(
|
||||||
|
"os.stat_result.st_mtime",
|
||||||
|
1732126764.780758,
|
||||||
|
),
|
||||||
|
patch(
|
||||||
|
"os.stat_result.st_ctime",
|
||||||
|
1732126744.780758,
|
||||||
|
),
|
||||||
|
):
|
||||||
|
await hass.config_entries.async_setup(mock_config_entry.entry_id)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
await snapshot_platform(hass, entity_registry, snapshot, mock_config_entry.entry_id)
|
||||||
|
|
||||||
|
|
||||||
async def test_invalid_path(
|
async def test_invalid_path(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user