Add binary sensor support to the Flo integration (#38267)
* update device * add binary sensor * updates post rebase * fix entity type post rebase * fix post rebase * fix add entities * fix name * review comments
This commit is contained in:
parent
03676693ce
commit
86aa758ecd
5 changed files with 108 additions and 1 deletions
|
@ -19,7 +19,7 @@ CONFIG_SCHEMA = vol.Schema({DOMAIN: vol.Schema({})}, extra=vol.ALLOW_EXTRA)
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
PLATFORMS = ["sensor"]
|
PLATFORMS = ["binary_sensor", "sensor"]
|
||||||
|
|
||||||
|
|
||||||
async def async_setup(hass: HomeAssistant, config: dict):
|
async def async_setup(hass: HomeAssistant, config: dict):
|
||||||
|
|
49
homeassistant/components/flo/binary_sensor.py
Normal file
49
homeassistant/components/flo/binary_sensor.py
Normal file
|
@ -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
|
|
@ -138,6 +138,30 @@ class FloDeviceDataUpdateCoordinator(DataUpdateCoordinator):
|
||||||
"""Return the serial number for the device."""
|
"""Return the serial number for the device."""
|
||||||
return self._device_information["serialNumber"]
|
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:
|
async def _update_device(self, *_) -> None:
|
||||||
"""Update the device information from the API."""
|
"""Update the device information from the API."""
|
||||||
self._device_information = await self.api_client.device.get_info(
|
self._device_information = await self.api_client.device.get_info(
|
||||||
|
|
30
tests/components/flo/test_binary_sensor.py
Normal file
30
tests/components/flo/test_binary_sensor.py
Normal file
|
@ -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"
|
|
@ -41,6 +41,10 @@ async def test_device(hass, config_entry, aioclient_mock_fixture, aioclient_mock
|
||||||
assert device.manufacturer == "Flo by Moen"
|
assert device.manufacturer == "Flo by Moen"
|
||||||
assert device.device_name == "Flo by Moen flo_device_075_v2"
|
assert device.device_name == "Flo by Moen flo_device_075_v2"
|
||||||
assert device.rssi == -47
|
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
|
call_count = aioclient_mock.call_count
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue