mirror of
https://github.com/home-assistant/core.git
synced 2025-07-18 10:47:10 +00:00
Fix file sensor reading the whole file to get the last line (#73986)
This commit is contained in:
parent
ba64d9db64
commit
6ec6f0a835
@ -3,5 +3,6 @@
|
|||||||
"name": "File",
|
"name": "File",
|
||||||
"documentation": "https://www.home-assistant.io/integrations/file",
|
"documentation": "https://www.home-assistant.io/integrations/file",
|
||||||
"codeowners": ["@fabaff"],
|
"codeowners": ["@fabaff"],
|
||||||
"iot_class": "local_polling"
|
"iot_class": "local_polling",
|
||||||
|
"requirements": ["file-read-backwards==2.0.0"]
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ from __future__ import annotations
|
|||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
|
|
||||||
|
from file_read_backwards import FileReadBackwards
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
from homeassistant.components.sensor import PLATFORM_SCHEMA, SensorEntity
|
from homeassistant.components.sensor import PLATFORM_SCHEMA, SensorEntity
|
||||||
@ -77,9 +78,10 @@ class FileSensor(SensorEntity):
|
|||||||
def update(self):
|
def update(self):
|
||||||
"""Get the latest entry from a file and updates the state."""
|
"""Get the latest entry from a file and updates the state."""
|
||||||
try:
|
try:
|
||||||
with open(self._file_path, encoding="utf-8") as file_data:
|
with FileReadBackwards(self._file_path, encoding="utf-8") as file_data:
|
||||||
for line in file_data:
|
for line in file_data:
|
||||||
data = line
|
data = line
|
||||||
|
break
|
||||||
data = data.strip()
|
data = data.strip()
|
||||||
except (IndexError, FileNotFoundError, IsADirectoryError, UnboundLocalError):
|
except (IndexError, FileNotFoundError, IsADirectoryError, UnboundLocalError):
|
||||||
_LOGGER.warning(
|
_LOGGER.warning(
|
||||||
|
@ -637,6 +637,9 @@ feedparser==6.0.2
|
|||||||
# homeassistant.components.fibaro
|
# homeassistant.components.fibaro
|
||||||
fiblary3==0.1.8
|
fiblary3==0.1.8
|
||||||
|
|
||||||
|
# homeassistant.components.file
|
||||||
|
file-read-backwards==2.0.0
|
||||||
|
|
||||||
# homeassistant.components.fints
|
# homeassistant.components.fints
|
||||||
fints==3.1.0
|
fints==3.1.0
|
||||||
|
|
||||||
|
@ -455,6 +455,9 @@ feedparser==6.0.2
|
|||||||
# homeassistant.components.fibaro
|
# homeassistant.components.fibaro
|
||||||
fiblary3==0.1.8
|
fiblary3==0.1.8
|
||||||
|
|
||||||
|
# homeassistant.components.file
|
||||||
|
file-read-backwards==2.0.0
|
||||||
|
|
||||||
# homeassistant.components.fivem
|
# homeassistant.components.fivem
|
||||||
fivem-api==0.1.2
|
fivem-api==0.1.2
|
||||||
|
|
||||||
|
0
tests/components/file/fixtures/file_empty.txt
Normal file
0
tests/components/file/fixtures/file_empty.txt
Normal file
3
tests/components/file/fixtures/file_value.txt
Normal file
3
tests/components/file/fixtures/file_value.txt
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
43
|
||||||
|
45
|
||||||
|
21
|
2
tests/components/file/fixtures/file_value_template.txt
Normal file
2
tests/components/file/fixtures/file_value_template.txt
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
{"temperature": 29, "humidity": 31}
|
||||||
|
{"temperature": 26, "humidity": 36}
|
@ -1,5 +1,5 @@
|
|||||||
"""The tests for local file sensor platform."""
|
"""The tests for local file sensor platform."""
|
||||||
from unittest.mock import Mock, mock_open, patch
|
from unittest.mock import Mock, patch
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
@ -7,7 +7,7 @@ from homeassistant.const import STATE_UNKNOWN
|
|||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.setup import async_setup_component
|
from homeassistant.setup import async_setup_component
|
||||||
|
|
||||||
from tests.common import mock_registry
|
from tests.common import get_fixture_path, mock_registry
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
@ -21,13 +21,14 @@ def entity_reg(hass):
|
|||||||
async def test_file_value(hass: HomeAssistant) -> None:
|
async def test_file_value(hass: HomeAssistant) -> None:
|
||||||
"""Test the File sensor."""
|
"""Test the File sensor."""
|
||||||
config = {
|
config = {
|
||||||
"sensor": {"platform": "file", "name": "file1", "file_path": "mock.file1"}
|
"sensor": {
|
||||||
|
"platform": "file",
|
||||||
|
"name": "file1",
|
||||||
|
"file_path": get_fixture_path("file_value.txt", "file"),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_open = mock_open(read_data="43\n45\n21")
|
with patch.object(hass.config, "is_allowed_path", return_value=True):
|
||||||
with patch(
|
|
||||||
"homeassistant.components.file.sensor.open", m_open, create=True
|
|
||||||
), patch.object(hass.config, "is_allowed_path", return_value=True):
|
|
||||||
assert await async_setup_component(hass, "sensor", config)
|
assert await async_setup_component(hass, "sensor", config)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
@ -43,19 +44,12 @@ async def test_file_value_template(hass: HomeAssistant) -> None:
|
|||||||
"sensor": {
|
"sensor": {
|
||||||
"platform": "file",
|
"platform": "file",
|
||||||
"name": "file2",
|
"name": "file2",
|
||||||
"file_path": "mock.file2",
|
"file_path": get_fixture_path("file_value_template.txt", "file"),
|
||||||
"value_template": "{{ value_json.temperature }}",
|
"value_template": "{{ value_json.temperature }}",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
data = (
|
with patch.object(hass.config, "is_allowed_path", return_value=True):
|
||||||
'{"temperature": 29, "humidity": 31}\n' + '{"temperature": 26, "humidity": 36}'
|
|
||||||
)
|
|
||||||
|
|
||||||
m_open = mock_open(read_data=data)
|
|
||||||
with patch(
|
|
||||||
"homeassistant.components.file.sensor.open", m_open, create=True
|
|
||||||
), patch.object(hass.config, "is_allowed_path", return_value=True):
|
|
||||||
assert await async_setup_component(hass, "sensor", config)
|
assert await async_setup_component(hass, "sensor", config)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
@ -67,12 +61,15 @@ async def test_file_value_template(hass: HomeAssistant) -> None:
|
|||||||
@patch("os.access", Mock(return_value=True))
|
@patch("os.access", Mock(return_value=True))
|
||||||
async def test_file_empty(hass: HomeAssistant) -> None:
|
async def test_file_empty(hass: HomeAssistant) -> None:
|
||||||
"""Test the File sensor with an empty file."""
|
"""Test the File sensor with an empty file."""
|
||||||
config = {"sensor": {"platform": "file", "name": "file3", "file_path": "mock.file"}}
|
config = {
|
||||||
|
"sensor": {
|
||||||
|
"platform": "file",
|
||||||
|
"name": "file3",
|
||||||
|
"file_path": get_fixture_path("file_empty.txt", "file"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
m_open = mock_open(read_data="")
|
with patch.object(hass.config, "is_allowed_path", return_value=True):
|
||||||
with patch(
|
|
||||||
"homeassistant.components.file.sensor.open", m_open, create=True
|
|
||||||
), patch.object(hass.config, "is_allowed_path", return_value=True):
|
|
||||||
assert await async_setup_component(hass, "sensor", config)
|
assert await async_setup_component(hass, "sensor", config)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
@ -85,13 +82,14 @@ async def test_file_empty(hass: HomeAssistant) -> None:
|
|||||||
async def test_file_path_invalid(hass: HomeAssistant) -> None:
|
async def test_file_path_invalid(hass: HomeAssistant) -> None:
|
||||||
"""Test the File sensor with invalid path."""
|
"""Test the File sensor with invalid path."""
|
||||||
config = {
|
config = {
|
||||||
"sensor": {"platform": "file", "name": "file4", "file_path": "mock.file4"}
|
"sensor": {
|
||||||
|
"platform": "file",
|
||||||
|
"name": "file4",
|
||||||
|
"file_path": get_fixture_path("file_value.txt", "file"),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_open = mock_open(read_data="43\n45\n21")
|
with patch.object(hass.config, "is_allowed_path", return_value=False):
|
||||||
with patch(
|
|
||||||
"homeassistant.components.file.sensor.open", m_open, create=True
|
|
||||||
), patch.object(hass.config, "is_allowed_path", return_value=False):
|
|
||||||
assert await async_setup_component(hass, "sensor", config)
|
assert await async_setup_component(hass, "sensor", config)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user