Add binary sensor platform to SFR Box (#85508)

* Add binary sensor platform to SFR Box

* Simplify
This commit is contained in:
epenet 2023-01-12 10:06:09 +01:00 committed by GitHub
parent 64e235285d
commit 5a4df9d870
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 142 additions and 1 deletions

View File

@ -0,0 +1,92 @@
"""SFR Box sensor platform."""
from __future__ import annotations
from collections.abc import Callable
from dataclasses import dataclass
from typing import Generic, TypeVar
from sfrbox_api.models import DslInfo, SystemInfo
from homeassistant.components.binary_sensor import (
BinarySensorDeviceClass,
BinarySensorEntity,
BinarySensorEntityDescription,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity import EntityCategory
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.update_coordinator import CoordinatorEntity
from .const import DOMAIN
from .coordinator import SFRDataUpdateCoordinator
from .models import DomainData
_T = TypeVar("_T")
@dataclass
class SFRBoxBinarySensorMixin(Generic[_T]):
"""Mixin for SFR Box sensors."""
value_fn: Callable[[_T], bool | None]
@dataclass
class SFRBoxBinarySensorEntityDescription(
BinarySensorEntityDescription, SFRBoxBinarySensorMixin[_T]
):
"""Description for SFR Box binary sensors."""
DSL_SENSOR_TYPES: tuple[SFRBoxBinarySensorEntityDescription[DslInfo], ...] = (
SFRBoxBinarySensorEntityDescription[DslInfo](
key="status",
name="Status",
device_class=BinarySensorDeviceClass.CONNECTIVITY,
entity_category=EntityCategory.DIAGNOSTIC,
value_fn=lambda x: x.status == "up",
),
)
async def async_setup_entry(
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
) -> None:
"""Set up the sensors."""
data: DomainData = hass.data[DOMAIN][entry.entry_id]
entities = [
SFRBoxBinarySensor(data.dsl, description, data.system.data)
for description in DSL_SENSOR_TYPES
]
async_add_entities(entities)
class SFRBoxBinarySensor(
CoordinatorEntity[SFRDataUpdateCoordinator[_T]], BinarySensorEntity
):
"""SFR Box sensor."""
entity_description: SFRBoxBinarySensorEntityDescription[_T]
_attr_has_entity_name = True
def __init__(
self,
coordinator: SFRDataUpdateCoordinator[_T],
description: SFRBoxBinarySensorEntityDescription,
system_info: SystemInfo,
) -> None:
"""Initialize the sensor."""
super().__init__(coordinator)
self.entity_description = description
self._attr_unique_id = (
f"{system_info.mac_addr}_{coordinator.name}_{description.key}"
)
self._attr_device_info = {"identifiers": {(DOMAIN, system_info.mac_addr)}}
@property
def is_on(self) -> bool | None:
"""Return the native value of the device."""
return self.entity_description.value_fn(self.coordinator.data)

View File

@ -5,4 +5,4 @@ DEFAULT_HOST = "192.168.0.1"
DOMAIN = "sfr_box"
PLATFORMS = [Platform.SENSOR]
PLATFORMS = [Platform.BINARY_SENSOR, Platform.SENSOR]

View File

@ -1,4 +1,5 @@
"""Constants for SFR Box tests."""
from homeassistant.components.binary_sensor import BinarySensorDeviceClass
from homeassistant.components.sensor import (
ATTR_OPTIONS,
ATTR_STATE_CLASS,
@ -16,6 +17,7 @@ from homeassistant.const import (
ATTR_SW_VERSION,
ATTR_UNIT_OF_MEASUREMENT,
SIGNAL_STRENGTH_DECIBELS,
STATE_ON,
Platform,
UnitOfDataRate,
UnitOfElectricPotential,
@ -38,6 +40,14 @@ EXPECTED_ENTITIES = {
ATTR_NAME: "SFR Box",
ATTR_SW_VERSION: "NB6VAC-MAIN-R4.0.44k",
},
Platform.BINARY_SENSOR: [
{
ATTR_DEVICE_CLASS: BinarySensorDeviceClass.CONNECTIVITY,
ATTR_ENTITY_ID: "binary_sensor.sfr_box_status",
ATTR_STATE: STATE_ON,
ATTR_UNIQUE_ID: "e4:5d:51:00:11:22_dsl_status",
},
],
Platform.SENSOR: [
{
ATTR_DEFAULT_DISABLED: True,

View File

@ -0,0 +1,39 @@
"""Test the SFR Box sensors."""
from collections.abc import Generator
from unittest.mock import patch
import pytest
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import Platform
from homeassistant.core import HomeAssistant
from . import check_device_registry, check_entities
from .const import EXPECTED_ENTITIES
from tests.common import mock_device_registry, mock_registry
pytestmark = pytest.mark.usefixtures("system_get_info", "dsl_get_info")
@pytest.fixture(autouse=True)
def override_platforms() -> Generator[None, None, None]:
"""Override PLATFORMS."""
with patch("homeassistant.components.sfr_box.PLATFORMS", [Platform.BINARY_SENSOR]):
yield
async def test_binary_sensors(hass: HomeAssistant, config_entry: ConfigEntry) -> None:
"""Test for SFR Box binary sensors."""
entity_registry = mock_registry(hass)
device_registry = mock_device_registry(hass)
await hass.config_entries.async_setup(config_entry.entry_id)
await hass.async_block_till_done()
check_device_registry(device_registry, EXPECTED_ENTITIES["expected_device"])
expected_entities = EXPECTED_ENTITIES[Platform.BINARY_SENSOR]
assert len(entity_registry.entities) == len(expected_entities)
check_entities(hass, entity_registry, expected_entities)