Skip to content

Commit 277241c

Browse files
Adjust ManualTriggerSensorEntity to handle timestamp device classes (home-assistant#145909)
1 parent 17034f4 commit 277241c

File tree

7 files changed

+65
-42
lines changed

7 files changed

+65
-42
lines changed

homeassistant/components/command_line/sensor.py

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@
1010

1111
from jsonpath import jsonpath
1212

13-
from homeassistant.components.sensor import SensorDeviceClass
14-
from homeassistant.components.sensor.helpers import async_parse_date_datetime
1513
from homeassistant.const import (
1614
CONF_COMMAND,
1715
CONF_NAME,
@@ -188,16 +186,7 @@ async def _async_update(self) -> None:
188186
self.entity_id, variables, None
189187
)
190188

191-
if self.device_class not in {
192-
SensorDeviceClass.DATE,
193-
SensorDeviceClass.TIMESTAMP,
194-
}:
195-
self._attr_native_value = value
196-
elif value is not None:
197-
self._attr_native_value = async_parse_date_datetime(
198-
value, self.entity_id, self.device_class
199-
)
200-
189+
self._set_native_value_with_possible_timestamp(value)
201190
self._process_manual_data(variables)
202191
self.async_write_ha_state()
203192

homeassistant/components/rest/sensor.py

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,7 @@
1313
CONF_STATE_CLASS,
1414
DOMAIN as SENSOR_DOMAIN,
1515
PLATFORM_SCHEMA as SENSOR_PLATFORM_SCHEMA,
16-
SensorDeviceClass,
1716
)
18-
from homeassistant.components.sensor.helpers import async_parse_date_datetime
1917
from homeassistant.const import (
2018
CONF_DEVICE_CLASS,
2119
CONF_FORCE_UPDATE,
@@ -181,18 +179,6 @@ def _update_from_rest_data(self) -> None:
181179
self.entity_id, variables, None
182180
)
183181

184-
if value is None or self.device_class not in (
185-
SensorDeviceClass.DATE,
186-
SensorDeviceClass.TIMESTAMP,
187-
):
188-
self._attr_native_value = value
189-
self._process_manual_data(variables)
190-
self.async_write_ha_state()
191-
return
192-
193-
self._attr_native_value = async_parse_date_datetime(
194-
value, self.entity_id, self.device_class
195-
)
196-
182+
self._set_native_value_with_possible_timestamp(value)
197183
self._process_manual_data(variables)
198184
self.async_write_ha_state()

homeassistant/components/scrape/sensor.py

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,7 @@
77

88
import voluptuous as vol
99

10-
from homeassistant.components.sensor import CONF_STATE_CLASS, SensorDeviceClass
11-
from homeassistant.components.sensor.helpers import async_parse_date_datetime
10+
from homeassistant.components.sensor import CONF_STATE_CLASS
1211
from homeassistant.const import (
1312
CONF_ATTRIBUTE,
1413
CONF_DEVICE_CLASS,
@@ -218,17 +217,7 @@ def _async_update_from_rest_data(self) -> None:
218217
self.entity_id, variables, None
219218
)
220219

221-
if self.device_class not in {
222-
SensorDeviceClass.DATE,
223-
SensorDeviceClass.TIMESTAMP,
224-
}:
225-
self._attr_native_value = value
226-
self._process_manual_data(variables)
227-
return
228-
229-
self._attr_native_value = async_parse_date_datetime(
230-
value, self.entity_id, self.device_class
231-
)
220+
self._set_native_value_with_possible_timestamp(value)
232221
self._process_manual_data(variables)
233222

234223
@property

homeassistant/components/snmp/sensor.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ async def async_update(self) -> None:
217217
self.entity_id, variables, STATE_UNKNOWN
218218
)
219219

220-
self._attr_native_value = value
220+
self._set_native_value_with_possible_timestamp(value)
221221
self._process_manual_data(variables)
222222

223223

homeassistant/components/sql/sensor.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -401,9 +401,10 @@ def _update(self) -> None:
401401
if data is not None and self._template is not None:
402402
variables = self._template_variables_with_value(data)
403403
if self._render_availability_template(variables):
404-
self._attr_native_value = self._template.async_render_as_value_template(
404+
_value = self._template.async_render_as_value_template(
405405
self.entity_id, variables, None
406406
)
407+
self._set_native_value_with_possible_timestamp(_value)
407408
self._process_manual_data(variables)
408409
else:
409410
self._attr_native_value = data

homeassistant/helpers/trigger_template_entity.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,10 @@
1313
CONF_STATE_CLASS,
1414
DEVICE_CLASSES_SCHEMA,
1515
STATE_CLASSES_SCHEMA,
16+
SensorDeviceClass,
1617
SensorEntity,
1718
)
19+
from homeassistant.components.sensor.helpers import async_parse_date_datetime
1820
from homeassistant.const import (
1921
ATTR_ENTITY_PICTURE,
2022
ATTR_FRIENDLY_NAME,
@@ -389,3 +391,20 @@ def __init__(
389391
ManualTriggerEntity.__init__(self, hass, config)
390392
self._attr_native_unit_of_measurement = config.get(CONF_UNIT_OF_MEASUREMENT)
391393
self._attr_state_class = config.get(CONF_STATE_CLASS)
394+
395+
@callback
396+
def _set_native_value_with_possible_timestamp(self, value: Any) -> None:
397+
"""Set native value with possible timestamp.
398+
399+
If self.device_class is `date` or `timestamp`,
400+
it will try to parse the value to a date/datetime object.
401+
"""
402+
if self.device_class not in (
403+
SensorDeviceClass.DATE,
404+
SensorDeviceClass.TIMESTAMP,
405+
):
406+
self._attr_native_value = value
407+
elif value is not None:
408+
self._attr_native_value = async_parse_date_datetime(
409+
value, self.entity_id, self.device_class
410+
)

tests/helpers/test_trigger_template_entity.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@
44

55
import pytest
66

7+
from homeassistant.components.sensor import SensorDeviceClass
8+
from homeassistant.components.sensor.helpers import async_parse_date_datetime
79
from homeassistant.const import (
10+
CONF_DEVICE_CLASS,
811
CONF_ICON,
912
CONF_NAME,
1013
CONF_STATE,
@@ -20,6 +23,7 @@
2023
CONF_AVAILABILITY,
2124
CONF_PICTURE,
2225
ManualTriggerEntity,
26+
ManualTriggerSensorEntity,
2327
ValueTemplate,
2428
)
2529

@@ -288,3 +292,38 @@ def some_other_key(self) -> dict[str, Any] | None:
288292
await hass.async_block_till_done()
289293

290294
assert entity.some_other_key == {"test_key": "test_data"}
295+
296+
297+
async def test_manual_trigger_sensor_entity_with_date(
298+
hass: HomeAssistant, caplog: pytest.LogCaptureFixture
299+
) -> None:
300+
"""Test manual trigger template entity when availability template isn't used."""
301+
config = {
302+
CONF_NAME: template.Template("test_entity", hass),
303+
CONF_STATE: template.Template("{{ as_datetime(value) }}", hass),
304+
CONF_DEVICE_CLASS: SensorDeviceClass.TIMESTAMP,
305+
}
306+
307+
class TestEntity(ManualTriggerSensorEntity):
308+
"""Test entity class."""
309+
310+
extra_template_keys = (CONF_STATE,)
311+
312+
@property
313+
def state(self) -> bool | None:
314+
"""Return extra attributes."""
315+
return "2025-01-01T00:00:00+00:00"
316+
317+
entity = TestEntity(hass, config)
318+
entity.entity_id = "test.entity"
319+
variables = entity._template_variables_with_value("2025-01-01T00:00:00+00:00")
320+
assert entity._render_availability_template(variables) is True
321+
assert entity.available is True
322+
entity._set_native_value_with_possible_timestamp(entity.state)
323+
await hass.async_block_till_done()
324+
325+
assert entity.native_value == async_parse_date_datetime(
326+
"2025-01-01T00:00:00+00:00", entity.entity_id, entity.device_class
327+
)
328+
assert entity.state == "2025-01-01T00:00:00+00:00"
329+
assert entity.device_class == SensorDeviceClass.TIMESTAMP

0 commit comments

Comments
 (0)