diff --git a/homeassistant/components/flo/__init__.py b/homeassistant/components/flo/__init__.py index 2c267addb0c..b02a848de7c 100644 --- a/homeassistant/components/flo/__init__.py +++ b/homeassistant/components/flo/__init__.py @@ -19,7 +19,7 @@ CONFIG_SCHEMA = vol.Schema({DOMAIN: vol.Schema({})}, extra=vol.ALLOW_EXTRA) _LOGGER = logging.getLogger(__name__) -PLATFORMS = ["sensor"] +PLATFORMS = ["binary_sensor", "sensor"] async def async_setup(hass: HomeAssistant, config: dict): diff --git a/homeassistant/components/flo/binary_sensor.py b/homeassistant/components/flo/binary_sensor.py new file mode 100644 index 00000000000..09facae53ed --- /dev/null +++ b/homeassistant/components/flo/binary_sensor.py @@ -0,0 +1,49 @@ +"""Support for Flo Water Monitor binary sensors.""" + +from typing import List + +from homeassistant.components.binary_sensor import ( + DEVICE_CLASS_PROBLEM, + BinarySensorEntity, +) + +from .const import DOMAIN as FLO_DOMAIN +from .device import FloDeviceDataUpdateCoordinator +from .entity import FloEntity + +DEPENDENCIES = ["flo"] + + +async def async_setup_entry(hass, config_entry, async_add_entities): + """Set up the Flo sensors from config entry.""" + devices: List[FloDeviceDataUpdateCoordinator] = hass.data[FLO_DOMAIN]["devices"] + entities = [FloPendingAlertsBinarySensor(device) for device in devices] + async_add_entities(entities) + + +class FloPendingAlertsBinarySensor(FloEntity, BinarySensorEntity): + """Binary sensor that reports on if there are any pending system alerts.""" + + def __init__(self, device): + """Initialize the pending alerts binary sensor.""" + super().__init__("pending_system_alerts", "Pending System Alerts", device) + + @property + def is_on(self): + """Return true if the Flo device has pending alerts.""" + return self._device.has_alerts + + @property + def device_state_attributes(self): + """Return the state attributes.""" + attr = {} + if self._device.has_alerts: + attr["info"] = self._device.pending_info_alerts_count + attr["warning"] = self._device.pending_warning_alerts_count + attr["critical"] = self._device.pending_critical_alerts_count + return attr + + @property + def device_class(self): + """Return the device class for the binary sensor.""" + return DEVICE_CLASS_PROBLEM diff --git a/homeassistant/components/flo/device.py b/homeassistant/components/flo/device.py index ad7973f4c9a..abba045693d 100644 --- a/homeassistant/components/flo/device.py +++ b/homeassistant/components/flo/device.py @@ -138,6 +138,30 @@ class FloDeviceDataUpdateCoordinator(DataUpdateCoordinator): """Return the serial number for the device.""" return self._device_information["serialNumber"] + @property + def pending_info_alerts_count(self) -> int: + """Return the number of pending info alerts for the device.""" + return self._device_information["notifications"]["pending"]["infoCount"] + + @property + def pending_warning_alerts_count(self) -> int: + """Return the number of pending warning alerts for the device.""" + return self._device_information["notifications"]["pending"]["warningCount"] + + @property + def pending_critical_alerts_count(self) -> int: + """Return the number of pending critical alerts for the device.""" + return self._device_information["notifications"]["pending"]["criticalCount"] + + @property + def has_alerts(self) -> bool: + """Return True if any alert counts are greater than zero.""" + return bool( + self.pending_info_alerts_count + or self.pending_warning_alerts_count + or self.pending_warning_alerts_count + ) + async def _update_device(self, *_) -> None: """Update the device information from the API.""" self._device_information = await self.api_client.device.get_info( diff --git a/tests/components/flo/test_binary_sensor.py b/tests/components/flo/test_binary_sensor.py new file mode 100644 index 00000000000..9f727c5a10b --- /dev/null +++ b/tests/components/flo/test_binary_sensor.py @@ -0,0 +1,30 @@ +"""Test Flo by Moen binary sensor entities.""" +from homeassistant.components.flo.const import DOMAIN as FLO_DOMAIN +from homeassistant.const import ( + ATTR_FRIENDLY_NAME, + CONF_PASSWORD, + CONF_USERNAME, + STATE_ON, +) +from homeassistant.setup import async_setup_component + +from .common import TEST_PASSWORD, TEST_USER_ID + + +async def test_binary_sensors(hass, config_entry, aioclient_mock_fixture): + """Test Flo by Moen sensors.""" + config_entry.add_to_hass(hass) + assert await async_setup_component( + hass, FLO_DOMAIN, {CONF_USERNAME: TEST_USER_ID, CONF_PASSWORD: TEST_PASSWORD} + ) + await hass.async_block_till_done() + + assert len(hass.data[FLO_DOMAIN]["devices"]) == 1 + + # we should have 6 entities for the device + state = hass.states.get("binary_sensor.pending_system_alerts") + assert state.state == STATE_ON + assert state.attributes.get("info") == 0 + assert state.attributes.get("warning") == 2 + assert state.attributes.get("critical") == 0 + assert state.attributes.get(ATTR_FRIENDLY_NAME) == "Pending System Alerts" diff --git a/tests/components/flo/test_device.py b/tests/components/flo/test_device.py index 13f6cd5293a..5f5a035ecbd 100644 --- a/tests/components/flo/test_device.py +++ b/tests/components/flo/test_device.py @@ -41,6 +41,10 @@ async def test_device(hass, config_entry, aioclient_mock_fixture, aioclient_mock assert device.manufacturer == "Flo by Moen" assert device.device_name == "Flo by Moen flo_device_075_v2" assert device.rssi == -47 + assert device.pending_info_alerts_count == 0 + assert device.pending_critical_alerts_count == 0 + assert device.pending_warning_alerts_count == 2 + assert device.has_alerts is True call_count = aioclient_mock.call_count