diff --git a/homeassistant/components/blebox/__init__.py b/homeassistant/components/blebox/__init__.py index e99be780563..1196deb27b7 100644 --- a/homeassistant/components/blebox/__init__.py +++ b/homeassistant/components/blebox/__init__.py @@ -17,7 +17,7 @@ from .const import DEFAULT_SETUP_TIMEOUT, DOMAIN, PRODUCT _LOGGER = logging.getLogger(__name__) -PLATFORMS = ["cover"] +PLATFORMS = ["cover", "sensor"] PARALLEL_UPDATES = 0 diff --git a/homeassistant/components/blebox/const.py b/homeassistant/components/blebox/const.py index a53ec39fd47..71d2193f904 100644 --- a/homeassistant/components/blebox/const.py +++ b/homeassistant/components/blebox/const.py @@ -9,6 +9,7 @@ from homeassistant.components.cover import ( STATE_OPEN, STATE_OPENING, ) +from homeassistant.const import DEVICE_CLASS_TEMPERATURE, TEMP_CELSIUS DOMAIN = "blebox" PRODUCT = "product" @@ -41,5 +42,8 @@ BLEBOX_TO_HASS_COVER_STATES = { 8: STATE_OPEN, # safety stop } +BLEBOX_TO_UNIT_MAP = {"celsius": TEMP_CELSIUS} +BLEBOX_DEV_CLASS_MAP = {"temperature": DEVICE_CLASS_TEMPERATURE} + DEFAULT_HOST = "192.168.0.2" DEFAULT_PORT = 80 diff --git a/homeassistant/components/blebox/sensor.py b/homeassistant/components/blebox/sensor.py new file mode 100644 index 00000000000..b43b4f21da5 --- /dev/null +++ b/homeassistant/components/blebox/sensor.py @@ -0,0 +1,33 @@ +"""BleBox sensor entities.""" + +from homeassistant.helpers.entity import Entity + +from . import BleBoxEntity, create_blebox_entities +from .const import BLEBOX_DEV_CLASS_MAP, BLEBOX_TO_UNIT_MAP, DOMAIN, PRODUCT + + +async def async_setup_entry(hass, config_entry, async_add): + """Set up a BleBox entry.""" + + product = hass.data[DOMAIN][config_entry.entry_id][PRODUCT] + create_blebox_entities(product, async_add, BleBoxSensorEntity, "sensors") + return True + + +class BleBoxSensorEntity(BleBoxEntity, Entity): + """Representation of a BleBox sensor feature.""" + + @property + def state(self): + """Return the state.""" + return self._feature.current + + @property + def unit_of_measurement(self): + """Return the unit.""" + return BLEBOX_TO_UNIT_MAP[self._feature.unit] + + @property + def device_class(self): + """Return the device class.""" + return BLEBOX_DEV_CLASS_MAP[self._feature.device_class] diff --git a/tests/components/blebox/test_sensor.py b/tests/components/blebox/test_sensor.py new file mode 100644 index 00000000000..a19e628181c --- /dev/null +++ b/tests/components/blebox/test_sensor.py @@ -0,0 +1,88 @@ +"""Blebox sensors tests.""" + +import logging + +import blebox_uniapi +import pytest + +from homeassistant.const import ( + ATTR_DEVICE_CLASS, + ATTR_UNIT_OF_MEASUREMENT, + DEVICE_CLASS_TEMPERATURE, + STATE_UNKNOWN, + TEMP_CELSIUS, +) + +from .conftest import async_setup_entity, mock_feature + +from tests.async_mock import AsyncMock, PropertyMock + + +@pytest.fixture(name="tempsensor") +def tempsensor_fixture(): + """Return a default sensor mock.""" + feature = mock_feature( + "sensors", + blebox_uniapi.sensor.Temperature, + unique_id="BleBox-tempSensor-1afe34db9437-0.temperature", + full_name="tempSensor-0.temperature", + device_class="temperature", + unit="celsius", + current=None, + ) + product = feature.product + type(product).name = PropertyMock(return_value="My temperature sensor") + type(product).model = PropertyMock(return_value="tempSensor") + return (feature, "sensor.tempsensor_0_temperature") + + +async def test_init(tempsensor, hass, config): + """Test sensor default state.""" + + _, entity_id = tempsensor + entry = await async_setup_entity(hass, config, entity_id) + assert entry.unique_id == "BleBox-tempSensor-1afe34db9437-0.temperature" + + state = hass.states.get(entity_id) + assert state.name == "tempSensor-0.temperature" + + assert state.attributes[ATTR_DEVICE_CLASS] == DEVICE_CLASS_TEMPERATURE + assert state.attributes[ATTR_UNIT_OF_MEASUREMENT] == TEMP_CELSIUS + assert state.state == STATE_UNKNOWN + + device_registry = await hass.helpers.device_registry.async_get_registry() + device = device_registry.async_get(entry.device_id) + + assert device.name == "My temperature sensor" + assert device.identifiers == {("blebox", "abcd0123ef5678")} + assert device.manufacturer == "BleBox" + assert device.model == "tempSensor" + assert device.sw_version == "1.23" + + +async def test_update(tempsensor, hass, config): + """Test sensor update.""" + + feature_mock, entity_id = tempsensor + + def initial_update(): + feature_mock.current = 25.18 + + feature_mock.async_update = AsyncMock(side_effect=initial_update) + await async_setup_entity(hass, config, entity_id) + + state = hass.states.get(entity_id) + assert state.attributes[ATTR_UNIT_OF_MEASUREMENT] == TEMP_CELSIUS + assert state.state == "25.18" + + +async def test_update_failure(tempsensor, hass, config, caplog): + """Test that update failures are logged.""" + + caplog.set_level(logging.ERROR) + + feature_mock, entity_id = tempsensor + feature_mock.async_update = AsyncMock(side_effect=blebox_uniapi.error.ClientError) + await async_setup_entity(hass, config, entity_id) + + assert f"Updating '{feature_mock.full_name}' failed: " in caplog.text