Add created sensor in filesize (#131108)

This commit is contained in:
G Johansson 2024-11-21 08:31:50 +01:00 committed by GitHub
parent 5529cfda09
commit e7fedef651
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 267 additions and 5 deletions

View File

@ -60,12 +60,14 @@ class FileSizeCoordinator(DataUpdateCoordinator[dict[str, int | float | datetime
statinfo = await self.hass.async_add_executor_job(self._update)
size = statinfo.st_size
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)
data: dict[str, int | float | datetime] = {
"file": round(size / 1e6, 2),
"bytes": size,
"last_updated": last_updated,
"created": created,
}
return data

View File

@ -9,6 +9,9 @@
},
"last_updated": {
"default": "mdi:file"
},
"created": {
"default": "mdi:file"
}
}
}

View File

@ -47,6 +47,13 @@ SENSOR_TYPES = (
device_class=SensorDeviceClass.TIMESTAMP,
entity_category=EntityCategory.DIAGNOSTIC,
),
SensorEntityDescription(
key="created",
translation_key="created",
entity_registry_enabled_default=False,
device_class=SensorDeviceClass.TIMESTAMP,
entity_category=EntityCategory.DIAGNOSTIC,
),
)

View File

@ -26,6 +26,9 @@
},
"last_updated": {
"name": "Last updated"
},
"created": {
"name": "Created"
}
}
}

View File

@ -8,21 +8,30 @@ from unittest.mock import patch
import pytest
from homeassistant.components.filesize.const import DOMAIN
from homeassistant.const import CONF_FILE_PATH
from homeassistant.components.filesize.const import DOMAIN, PLATFORMS
from homeassistant.const import CONF_FILE_PATH, Platform
from . import TEST_FILE_NAME
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
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."""
test_file = str(tmp_path.joinpath(TEST_FILE_NAME))
return MockConfigEntry(
title=TEST_FILE_NAME,
domain=DOMAIN,
entry_id="01JD5CTQMH9FKEFQKZJ8MMBQ3X",
data={CONF_FILE_PATH: test_file},
unique_id=test_file,
)

View 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',
})
# ---

View File

@ -2,14 +2,55 @@
import os
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.helpers import entity_registry as er
from homeassistant.helpers.entity_component import async_update_entity
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(