diff --git a/homeassistant/components/scrape/sensor.py b/homeassistant/components/scrape/sensor.py index c2ba370a660..b13b5d8463b 100644 --- a/homeassistant/components/scrape/sensor.py +++ b/homeassistant/components/scrape/sensor.py @@ -23,6 +23,7 @@ from homeassistant.const import ( CONF_NAME, CONF_PASSWORD, CONF_RESOURCE, + CONF_UNIQUE_ID, CONF_UNIT_OF_MEASUREMENT, CONF_USERNAME, CONF_VALUE_TEMPLATE, @@ -66,6 +67,7 @@ PLATFORM_SCHEMA = PARENT_PLATFORM_SCHEMA.extend( vol.Optional(CONF_UNIT_OF_MEASUREMENT): cv.string, vol.Optional(CONF_DEVICE_CLASS): DEVICE_CLASSES_SCHEMA, vol.Optional(CONF_STATE_CLASS): STATE_CLASSES_SCHEMA, + vol.Optional(CONF_UNIQUE_ID): cv.string, vol.Optional(CONF_USERNAME): cv.string, vol.Optional(CONF_VALUE_TEMPLATE): cv.template, vol.Optional(CONF_VERIFY_SSL, default=DEFAULT_VERIFY_SSL): cv.boolean, @@ -92,6 +94,7 @@ async def async_setup_platform( unit: str | None = config.get(CONF_UNIT_OF_MEASUREMENT) device_class: str | None = config.get(CONF_DEVICE_CLASS) state_class: str | None = config.get(CONF_STATE_CLASS) + unique_id: str | None = config.get(CONF_UNIQUE_ID) username: str | None = config.get(CONF_USERNAME) password: str | None = config.get(CONF_PASSWORD) value_template: Template | None = config.get(CONF_VALUE_TEMPLATE) @@ -117,6 +120,7 @@ async def async_setup_platform( [ ScrapeSensor( coordinator, + unique_id, name, select, attr, @@ -136,6 +140,7 @@ class ScrapeSensor(CoordinatorEntity[ScrapeCoordinator], SensorEntity): def __init__( self, coordinator: ScrapeCoordinator, + unique_id: str | None, name: str, select: str | None, attr: str | None, @@ -153,6 +158,7 @@ class ScrapeSensor(CoordinatorEntity[ScrapeCoordinator], SensorEntity): self._index = index self._value_template = value_template self._attr_name = name + self._attr_unique_id = unique_id self._attr_native_unit_of_measurement = unit self._attr_device_class = device_class self._attr_state_class = state_class diff --git a/tests/components/scrape/__init__.py b/tests/components/scrape/__init__.py index 0ba9266a79d..644ea84854a 100644 --- a/tests/components/scrape/__init__.py +++ b/tests/components/scrape/__init__.py @@ -18,6 +18,7 @@ def return_config( username=None, password=None, headers=None, + unique_id=None, ) -> dict[str, dict[str, Any]]: """Return config.""" config = { @@ -44,6 +45,8 @@ def return_config( config["password"] = password if headers: config["headers"] = headers + if unique_id: + config["unique_id"] = unique_id return config diff --git a/tests/components/scrape/test_sensor.py b/tests/components/scrape/test_sensor.py index 3ad19ed25af..aacd89b2eb9 100644 --- a/tests/components/scrape/test_sensor.py +++ b/tests/components/scrape/test_sensor.py @@ -18,6 +18,7 @@ from homeassistant.const import ( TEMP_CELSIUS, ) from homeassistant.core import HomeAssistant +from homeassistant.helpers import entity_registry as er from homeassistant.setup import async_setup_component from . import MockRestData, return_config @@ -93,6 +94,34 @@ async def test_scrape_uom_and_classes(hass: HomeAssistant) -> None: assert state.attributes[CONF_STATE_CLASS] == SensorStateClass.MEASUREMENT +async def test_scrape_unique_id(hass: HomeAssistant) -> None: + """Test Scrape sensor for unique id.""" + config = { + "sensor": return_config( + select=".current-temp h3", + name="Current Temp", + template="{{ value.split(':')[1] }}", + unique_id="very_unique_id", + ) + } + + mocker = MockRestData("test_scrape_uom_and_classes") + with patch( + "homeassistant.components.scrape.sensor.RestData", + return_value=mocker, + ): + assert await async_setup_component(hass, "sensor", config) + await hass.async_block_till_done() + + state = hass.states.get("sensor.current_temp") + assert state.state == "22.1" + + registry = er.async_get(hass) + entry = registry.async_get("sensor.current_temp") + assert entry + assert entry.unique_id == "very_unique_id" + + async def test_scrape_sensor_authentication(hass: HomeAssistant) -> None: """Test Scrape sensor with authentication.""" config = {