Fix file sensor reading the whole file to get the last line (#73986)

This commit is contained in:
J. Nick Koston 2022-06-25 21:02:50 -05:00 committed by GitHub
parent ba64d9db64
commit 6ec6f0a835
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 40 additions and 28 deletions

View File

@ -3,5 +3,6 @@
"name": "File",
"documentation": "https://www.home-assistant.io/integrations/file",
"codeowners": ["@fabaff"],
"iot_class": "local_polling"
"iot_class": "local_polling",
"requirements": ["file-read-backwards==2.0.0"]
}

View File

@ -4,6 +4,7 @@ from __future__ import annotations
import logging
import os
from file_read_backwards import FileReadBackwards
import voluptuous as vol
from homeassistant.components.sensor import PLATFORM_SCHEMA, SensorEntity
@ -77,9 +78,10 @@ class FileSensor(SensorEntity):
def update(self):
"""Get the latest entry from a file and updates the state."""
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:
data = line
break
data = data.strip()
except (IndexError, FileNotFoundError, IsADirectoryError, UnboundLocalError):
_LOGGER.warning(

View File

@ -637,6 +637,9 @@ feedparser==6.0.2
# homeassistant.components.fibaro
fiblary3==0.1.8
# homeassistant.components.file
file-read-backwards==2.0.0
# homeassistant.components.fints
fints==3.1.0

View File

@ -455,6 +455,9 @@ feedparser==6.0.2
# homeassistant.components.fibaro
fiblary3==0.1.8
# homeassistant.components.file
file-read-backwards==2.0.0
# homeassistant.components.fivem
fivem-api==0.1.2

View File

@ -0,0 +1,3 @@
43
45
21

View File

@ -0,0 +1,2 @@
{"temperature": 29, "humidity": 31}
{"temperature": 26, "humidity": 36}

View File

@ -1,5 +1,5 @@
"""The tests for local file sensor platform."""
from unittest.mock import Mock, mock_open, patch
from unittest.mock import Mock, patch
import pytest
@ -7,7 +7,7 @@ from homeassistant.const import STATE_UNKNOWN
from homeassistant.core import HomeAssistant
from homeassistant.setup import async_setup_component
from tests.common import mock_registry
from tests.common import get_fixture_path, mock_registry
@pytest.fixture
@ -21,13 +21,14 @@ def entity_reg(hass):
async def test_file_value(hass: HomeAssistant) -> None:
"""Test the File sensor."""
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(
"homeassistant.components.file.sensor.open", m_open, create=True
), patch.object(hass.config, "is_allowed_path", return_value=True):
with patch.object(hass.config, "is_allowed_path", return_value=True):
assert await async_setup_component(hass, "sensor", config)
await hass.async_block_till_done()
@ -43,19 +44,12 @@ async def test_file_value_template(hass: HomeAssistant) -> None:
"sensor": {
"platform": "file",
"name": "file2",
"file_path": "mock.file2",
"file_path": get_fixture_path("file_value_template.txt", "file"),
"value_template": "{{ value_json.temperature }}",
}
}
data = (
'{"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):
with patch.object(hass.config, "is_allowed_path", return_value=True):
assert await async_setup_component(hass, "sensor", config)
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))
async def test_file_empty(hass: HomeAssistant) -> None:
"""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(
"homeassistant.components.file.sensor.open", m_open, create=True
), patch.object(hass.config, "is_allowed_path", return_value=True):
with patch.object(hass.config, "is_allowed_path", return_value=True):
assert await async_setup_component(hass, "sensor", config)
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:
"""Test the File sensor with invalid path."""
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(
"homeassistant.components.file.sensor.open", m_open, create=True
), patch.object(hass.config, "is_allowed_path", return_value=False):
with patch.object(hass.config, "is_allowed_path", return_value=False):
assert await async_setup_component(hass, "sensor", config)
await hass.async_block_till_done()