8000 Add Freebox device connectivty and signal sensors by adriencog · Pull Request #144056 · home-assistant/core · GitHub
[go: up one dir, main page]

Skip to content

Add Freebox device connectivty and signal sensors #144056

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: dev
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions homeassistant/components/freebox/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,3 +93,18 @@ class FreeboxHomeCategory(enum.StrEnum):
FreeboxHomeCategory.PIR,
FreeboxHomeCategory.RTS,
]


class DeviceConnectivityType(enum.StrEnum):
"""Freebox Connectivity types for device."""

ETHERNET = "Ethernet"
WIFI = "Wifi"
WIFI_2D4GHZ = "Wifi 2.4 GHz"
WIFI_5GHZ = "Wifi 5 GHz"


WIFI_BANDS_TO_CONNECTIVITY = {
"2d4g": DeviceConnectivityType.WIFI_2D4GHZ,
"5g": DeviceConnectivityType.WIFI_5GHZ,
}
121 changes: 118 additions & 3 deletions homeassistant/components/freebox/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,20 @@
SensorEntityDescription,
SensorStateClass,
)
from homeassistant.const import PERCENTAGE, UnitOfDataRate, UnitOfTemperature
from homeassistant.const import (
PERCENTAGE,
SIGNAL_STRENGTH_DECIBELS_MILLIWATT,
EntityCategory,
UnitOfDataRate,
UnitOfTemperature,
)
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.device_registry import DeviceInfo
from homeassistant.helpers.device_registry import CONNECTION_NETWORK_MAC, DeviceInfo
from homeassistant.helpers.dispatcher import async_dispatcher_connect
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from homeassistant.util import dt as dt_util

from .const import DOMAIN
from .const import DOMAIN, WIFI_BANDS_TO_CONNECTIVITY, DeviceConnectivityType
from .entity import FreeboxHomeEntity
from .router import FreeboxConfigEntry, FreeboxRouter

Expand Down Expand Up @@ -60,6 +66,38 @@
),
)

DEVICE_SENSORS: tuple[SensorEntityDescription, ...] = (
SensorEntityDescription(
key="connectivity",
name="Connectivity",
device_class=SensorDeviceClass.ENUM,
options=[e.value for e in DeviceConnectivityType.__members__.values()],
icon="mdi:network",
entity_category=EntityCategory.DIAGNOSTIC,
entity_registry_enabled_default=True,
),
)

WIFI_DEVICE_SENSORS: tuple[SensorEntityDescription, ...] = (
SensorEntityDescription(
key="wifi_signal_dbm",
name="Wifi signal strength",
device_class=SensorDeviceClass.SIGNAL_STRENGTH,
native_unit_of_measurement=SIGNAL_STRENGTH_DECIBELS_MILLIWATT,
icon="mdi:signal",
entity_category=EntityCategory.DIAGNOSTIC,
entity_registry_enabled_default=True,
),
SensorEntityDescription(
key="wifi_signal_percentage",
name="Wifi signal level",
native_unit_of_measurement=PERCENTAGE,
icon="mdi:signal",
entity_category=EntityCategory.DIAGNOSTIC,
entity_registry_enabled_default=True,
),
)


async def async_setup_entry(
hass: HomeAssistant,
Expand Down Expand Up @@ -113,6 +151,20 @@
):
entities.append(FreeboxBatterySensor(hass, router, node, endpoint))

for device in router.devices.values():
if not device.get("persistent", False):
continue
entities.extend(

Check warning on line 157 in homeassistant/components/freebox/sensor.py

View check run for this annotation

Codecov / codecov/patch

homeassistant/components/freebox/sensor.py#L157

Added line #L157 was not covered by tests
FreeboxDeviceSensor(router, device, description)
for description in DEVICE_SENSORS
)
if (

Check warning on line 161 in homeassistant/components/freebox/sensor.py

View check run for this annotation

Codecov / codecov/patch

homeassistant/components/freebox/sensor.py#L161

Added line #L161 was not covered by tests
connectivity_type := get_device_connectity_type(device)
) and connectivity_type != DeviceConnectivityType.ETHERNET:
entities.extend(

Check warning on line 164 in homeassistant/components/freebox/sensor.py

View check run for this annotation

Codecov / codecov/patch

homeassistant/components/freebox/sensor.py#L164

Added line #L164 was not covered by tests
FreeboxDeviceSensor(router, device, description)
for description in WIFI_DEVICE_SENSORS
)
if entities:
async_add_entities(entities, True)

Expand Down Expand Up @@ -241,3 +293,66 @@
def native_value(self) -> int:
"""Return the current state of the device."""
return self.get_value("signal", "battery")


class FreeboxDeviceSensor(FreeboxSensor):
"""Representation of a Freebox device sensor."""

def __init__(
self,
router: FreeboxRouter,
device: dict[str, Any],
description: SensorEntityDescription,
) -> None:
"""Initialize a Freebox device sensor."""
super().__init__(router, description)
self._device = device
mac_address = device["l2ident"]["id"]
self._attr_unique_id = f"{router.mac} {description.key} {mac_address}"
self._attr_device_info = DeviceInfo(

Check warning on line 312 in homeassistant/components/freebox/sensor.py

View check run for this annotation

Codecov / codecov/patch

homeassistant/components/freebox/sensor.py#L308-L312

Added lines #L308 - L312 were not covered by tests
identifiers={(DOMAIN, mac_address)},
manufacturer=device["vendor_name"],
name=device["primary_name"],
via_device=(DOMAIN, router.mac),
connections={(CONNECTION_NETWORK_MAC, mac_address)},
)
self._attr_name = f"{device['primary_name']} {description.name}"

Check warning on line 319 in homeassistant/components/freebox/sensor.py

View check run for this annotation

Codecov / codecov/patch

homeassistant/components/freebox/sensor.py#L319

Added line #L319 was not covered by tests

def async_update_state(self) -> None:
"""Update the Freebox device sensor."""
if self.entity_description.key == "connectivity":
self._attr_native_value = get_device_connectity_type(self._device)
elif self.entity_description.key == "wifi_signal_dbm":
self._attr_native_value = get_device_wifi_signal_strength_dbm(self._device)
elif self.entity_description.key == "wifi_signal_percentage":
self._attr_native_value = get_device_wifi_signal_strength_percentage(

Check warning on line 328 in homeassistant/components/freebox/sensor.py

View check run for this annotation

Codecov / codecov/patch

homeassistant/components/freebox/sensor.py#L323-L328

Added lines #L323 - L328 were not covered by tests
self._device
)


def get_device_connectity_type(device: dict[str, Any]) -> str | None:
"""Get the connectivity type of a device."""
result = None
access_point = device.get("access_point", {})
if connectivity_type := access_point.get("connectivity_type"):
if connectivity_type == "wifi":
wifi_information = access_point.get("wifi_information", {})
band = wifi_information.get("band", "")
result = WIFI_BANDS_TO_CONNECTIVITY.get(band, DeviceConnectivityType.WIFI)
if connectivity_type == "ethernet":
result = DeviceConnectivityType.ETHERNET
return result.value if result else None

Check warning on line 344 in homeassistant/components/freebox/sensor.py

View check run for this annotation

Codecov / codecov/patch

homeassistant/components/freebox/sensor.py#L335-L344

Added lines #L335 - L344 were not covered by tests


def get_device_wifi_signal_strength_dbm(device: dict[str, Any]) -> int | None:
"""Get the wifi signal strength 700D of a device in dBm."""
access_point = device.get("access_point", {})
wifi_information = access_point.get("wifi_information", {})
return wifi_information.get("signal")

Check warning on line 351 in homeassistant/components/freebox/sensor.py

View check run for this annotation

Codecov / codecov/patch

homeassistant/components/freebox/sensor.py#L349-L351

Added lines #L349 - L351 were not covered by tests


def get_device_wifi_signal_strength_percentage(device: dict[str, Any]) -> int | None:
"""Get the wifi signal strength of a device in percentage."""
if dbm := get_device_wifi_signal_strength_dbm(device):
return min(max(2 * (dbm + 100), 0), 100)
return None

Check warning on line 358 in homeassistant/components/freebox/sensor.py

View check run for this annotation

Codecov / codecov/patch

homeassistant/components/freebox/sensor.py#L356-L358

Added lines #L356 - L358 were not covered by tests
Loading
0