From d4470afd39ecc0e11e1b01da083bde006de57b2b Mon Sep 17 00:00:00 2001 From: Franck Nijhof Date: Wed, 7 Jul 2021 23:00:06 +0200 Subject: [PATCH] Add datetime object as valid StateType --- homeassistant/helpers/entity.py | 2 ++ homeassistant/helpers/typing.py | 3 ++- tests/helpers/test_entity.py | 16 +++++++++++++++- 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/homeassistant/helpers/entity.py b/homeassistant/helpers/entity.py index 6383de15b4aa6f..13ec0a0d3c793f 100644 --- a/homeassistant/helpers/entity.py +++ b/homeassistant/helpers/entity.py @@ -474,6 +474,8 @@ def _stringify_state(self) -> str: # If the entity's state is a float, limit precision according to machine # epsilon to make the string representation readable return f"{state:.{FLOAT_PRECISION}}" + if isinstance(state, datetime): + return state.isoformat() return str(state) @callback diff --git a/homeassistant/helpers/typing.py b/homeassistant/helpers/typing.py index 7d01b0b6a77fbf..99f25d1c83adb6 100644 --- a/homeassistant/helpers/typing.py +++ b/homeassistant/helpers/typing.py @@ -1,4 +1,5 @@ """Typing Helpers for Home Assistant.""" +from datetime import datetime from enum import Enum from typing import Any, Dict, Mapping, Optional, Tuple, Union @@ -10,7 +11,7 @@ DiscoveryInfoType = Dict[str, Any] EventType = homeassistant.core.Event ServiceDataType = Dict[str, Any] -StateType = Union[None, str, int, float] +StateType = Union[None, str, int, float, datetime] TemplateVarsType = Optional[Mapping[str, Any]] # Custom type for recorder Queries diff --git a/tests/helpers/test_entity.py b/tests/helpers/test_entity.py index 8142f563f0172f..aad80dfa1be47e 100644 --- a/tests/helpers/test_entity.py +++ b/tests/helpers/test_entity.py @@ -1,7 +1,7 @@ """Test the entity helper.""" # pylint: disable=protected-access import asyncio -from datetime import timedelta +from datetime import datetime, timedelta, timezone import threading from unittest.mock import MagicMock, PropertyMock, patch @@ -788,3 +788,17 @@ async def test_float_conversion(hass): state = hass.states.get("hello.world") assert state is not None assert state.state == "3.6" + + +async def test_datetime_conversion(hass): + """Test conversion of datetime state to ISO 8601 datetime strings.""" + object_state = datetime(2017, 12, 19, 18, 29, 42, tzinfo=timezone.utc) + with patch.object(entity.Entity, "state", PropertyMock(return_value=object_state)): + ent = entity.Entity() + ent.hass = hass + ent.entity_id = "hello.world" + ent.async_write_ha_state() + + state = hass.states.get("hello.world") + assert state is not None + assert state.state == "2017-12-19T18:29:42+00:00"