From 5e04a87cc6a6a19830c131b03eb155c3913da7cd Mon Sep 17 00:00:00 2001 From: Jonno12345 Date: Wed, 28 Dec 2022 09:16:14 +0000 Subject: [PATCH] Fix Scrape integration for date and timestamp devices (#84480) * Scrape integration fix for date and timestamp devices * Changes advised by PR review. Merged test source and used walrus operator --- homeassistant/components/scrape/sensor.py | 19 +++- tests/components/scrape/__init__.py | 3 + tests/components/scrape/test_sensor.py | 113 ++++++++++++++++++++++ 3 files changed, 130 insertions(+), 5 deletions(-) diff --git a/homeassistant/components/scrape/sensor.py b/homeassistant/components/scrape/sensor.py index e16f6c20f8d..22184a17b80 100644 --- a/homeassistant/components/scrape/sensor.py +++ b/homeassistant/components/scrape/sensor.py @@ -13,7 +13,9 @@ from homeassistant.components.sensor import ( DEVICE_CLASSES_SCHEMA, PLATFORM_SCHEMA as PARENT_PLATFORM_SCHEMA, STATE_CLASSES_SCHEMA, + SensorDeviceClass, ) +from homeassistant.components.sensor.helpers import async_parse_date_datetime from homeassistant.config_entries import ConfigEntry from homeassistant.const import ( CONF_ATTRIBUTE, @@ -246,12 +248,19 @@ class ScrapeSensor(CoordinatorEntity[ScrapeCoordinator], TemplateSensor): """Update state from the rest data.""" value = self._extract_value() - if self._value_template is not None: - self._attr_native_value = ( - self._value_template.async_render_with_possible_json_value(value, None) - ) - else: + if (template := self._value_template) is not None: + value = template.async_render_with_possible_json_value(value, None) + + if self.device_class not in { + SensorDeviceClass.DATE, + SensorDeviceClass.TIMESTAMP, + }: self._attr_native_value = value + return + + self._attr_native_value = async_parse_date_datetime( + value, self.entity_id, self.device_class + ) @callback def _handle_coordinator_update(self) -> None: diff --git a/tests/components/scrape/__init__.py b/tests/components/scrape/__init__.py index b13cc4a7326..1bf3040513f 100644 --- a/tests/components/scrape/__init__.py +++ b/tests/components/scrape/__init__.py @@ -103,6 +103,9 @@ class MockRestData: "

Current Version: 2021.12.10

Released: January 17, 2022" "" "" + "
" + "

Current Time:

2022-12-22T13:15:30Z" + "
" ) if self.payload == "test_scrape_sensor2": self.data = ( diff --git a/tests/components/scrape/test_sensor.py b/tests/components/scrape/test_sensor.py index 83607f1b993..e9b66049e61 100644 --- a/tests/components/scrape/test_sensor.py +++ b/tests/components/scrape/test_sensor.py @@ -338,6 +338,119 @@ async def test_scrape_sensor_attribute_and_tag(hass: HomeAssistant) -> None: assert state2.state == "Trying to get" +async def test_scrape_sensor_device_date(hass: HomeAssistant) -> None: + """Test Scrape sensor with a device of type DATE.""" + config = { + DOMAIN: [ + return_integration_config( + sensors=[ + { + "select": ".release-date", + "name": "HA Date", + "device_class": "date", + "value_template": "{{ strptime(value, '%B %d, %Y').strftime('%Y-%m-%d') }}", + } + ], + ), + ] + } + + mocker = MockRestData("test_scrape_sensor") + with patch( + "homeassistant.components.rest.RestData", + return_value=mocker, + ): + assert await async_setup_component(hass, DOMAIN, config) + await hass.async_block_till_done() + + state = hass.states.get("sensor.ha_date") + assert state.state == "2022-01-17" + + +async def test_scrape_sensor_device_date_errors(hass: HomeAssistant) -> None: + """Test Scrape sensor with a device of type DATE.""" + config = { + DOMAIN: [ + return_integration_config( + sensors=[ + { + "select": ".current-version h1", + "name": "HA Date", + "device_class": "date", + } + ], + ), + ] + } + + mocker = MockRestData("test_scrape_sensor") + with patch( + "homeassistant.components.rest.RestData", + return_value=mocker, + ): + assert await async_setup_component(hass, DOMAIN, config) + await hass.async_block_till_done() + + state = hass.states.get("sensor.ha_date") + assert state.state == STATE_UNKNOWN + + +async def test_scrape_sensor_device_timestamp(hass: HomeAssistant) -> None: + """Test Scrape sensor with a device of type TIMESTAMP.""" + config = { + DOMAIN: [ + return_integration_config( + sensors=[ + { + "select": ".utc-time", + "name": "HA Timestamp", + "device_class": "timestamp", + } + ], + ), + ] + } + + mocker = MockRestData("test_scrape_sensor") + with patch( + "homeassistant.components.rest.RestData", + return_value=mocker, + ): + assert await async_setup_component(hass, DOMAIN, config) + await hass.async_block_till_done() + + state = hass.states.get("sensor.ha_timestamp") + assert state.state == "2022-12-22T13:15:30+00:00" + + +async def test_scrape_sensor_device_timestamp_error(hass: HomeAssistant) -> None: + """Test Scrape sensor with a device of type TIMESTAMP.""" + config = { + DOMAIN: [ + return_integration_config( + sensors=[ + { + "select": ".current-time", + "name": "HA Timestamp", + "device_class": "timestamp", + } + ], + ), + ] + } + + mocker = MockRestData("test_scrape_sensor") + with patch( + "homeassistant.components.rest.RestData", + return_value=mocker, + ): + assert await async_setup_component(hass, DOMAIN, config) + await hass.async_block_till_done() + + state = hass.states.get("sensor.ha_timestamp") + assert state.state == STATE_UNKNOWN + + async def test_scrape_sensor_errors(hass: HomeAssistant) -> None: """Test Scrape sensor handle errors.""" config = {