mirror of
https://github.com/home-assistant/core.git
synced 2025-04-23 08:47:57 +00:00
Add WAN information to SFR Box (#89678)
This commit is contained in:
parent
cb74b934dc
commit
c416d18506
@ -1,11 +1,13 @@
|
||||
"""SFR Box."""
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
|
||||
from sfrbox_api.bridge import SFRBox
|
||||
from sfrbox_api.exceptions import SFRBoxAuthenticationError, SFRBoxError
|
||||
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import CONF_HOST, CONF_PASSWORD, CONF_USERNAME, Platform
|
||||
from homeassistant.const import CONF_HOST, CONF_PASSWORD, CONF_USERNAME
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.exceptions import ConfigEntryAuthFailed, ConfigEntryNotReady
|
||||
from homeassistant.helpers import device_registry as dr
|
||||
@ -37,15 +39,17 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
||||
system=SFRDataUpdateCoordinator(
|
||||
hass, box, "system", lambda b: b.system_get_info()
|
||||
),
|
||||
wan=SFRDataUpdateCoordinator(hass, box, "wan", lambda b: b.wan_get_info()),
|
||||
)
|
||||
# Preload system information
|
||||
await data.system.async_config_entry_first_refresh()
|
||||
system_info = data.system.data
|
||||
|
||||
# Preload other coordinators (based on net infrastructure)
|
||||
tasks = [data.wan.async_config_entry_first_refresh()]
|
||||
if system_info.net_infra == "adsl":
|
||||
await data.dsl.async_config_entry_first_refresh()
|
||||
else:
|
||||
platforms = list(platforms)
|
||||
platforms.remove(Platform.BINARY_SENSOR)
|
||||
tasks.append(data.dsl.async_config_entry_first_refresh())
|
||||
await asyncio.gather(*tasks)
|
||||
|
||||
hass.data.setdefault(DOMAIN, {})[entry.entry_id] = data
|
||||
|
||||
|
@ -5,7 +5,7 @@ from collections.abc import Callable
|
||||
from dataclasses import dataclass
|
||||
from typing import Generic, TypeVar
|
||||
|
||||
from sfrbox_api.models import DslInfo, SystemInfo
|
||||
from sfrbox_api.models import DslInfo, SystemInfo, WanInfo
|
||||
|
||||
from homeassistant.components.binary_sensor import (
|
||||
BinarySensorDeviceClass,
|
||||
@ -48,6 +48,15 @@ DSL_SENSOR_TYPES: tuple[SFRBoxBinarySensorEntityDescription[DslInfo], ...] = (
|
||||
value_fn=lambda x: x.status == "up",
|
||||
),
|
||||
)
|
||||
WAN_SENSOR_TYPES: tuple[SFRBoxBinarySensorEntityDescription[WanInfo], ...] = (
|
||||
SFRBoxBinarySensorEntityDescription[WanInfo](
|
||||
key="status",
|
||||
name="WAN status",
|
||||
device_class=BinarySensorDeviceClass.CONNECTIVITY,
|
||||
entity_category=EntityCategory.DIAGNOSTIC,
|
||||
value_fn=lambda x: x.status == "up",
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
async def async_setup_entry(
|
||||
@ -56,10 +65,15 @@ async def async_setup_entry(
|
||||
"""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
|
||||
entities: list[SFRBoxBinarySensor] = [
|
||||
SFRBoxBinarySensor(data.wan, description, data.system.data)
|
||||
for description in WAN_SENSOR_TYPES
|
||||
]
|
||||
if data.system.data.net_infra == "adsl":
|
||||
entities.extend(
|
||||
SFRBoxBinarySensor(data.dsl, description, data.system.data)
|
||||
for description in DSL_SENSOR_TYPES
|
||||
)
|
||||
|
||||
async_add_entities(entities)
|
||||
|
||||
|
@ -11,7 +11,7 @@ from homeassistant.core import HomeAssistant
|
||||
from .const import DOMAIN
|
||||
from .models import DomainData
|
||||
|
||||
TO_REDACT = {"mac_addr", "serial_number"}
|
||||
TO_REDACT = {"mac_addr", "serial_number", "ip_addr", "ipv6_addr"}
|
||||
|
||||
|
||||
async def async_get_config_entry_diagnostics(
|
||||
@ -33,8 +33,6 @@ async def async_get_config_entry_diagnostics(
|
||||
"system": async_redact_data(
|
||||
dataclasses.asdict(data.system.data), TO_REDACT
|
||||
),
|
||||
"wan": async_redact_data(
|
||||
dataclasses.asdict(await data.system.box.wan_get_info()), TO_REDACT
|
||||
),
|
||||
"wan": async_redact_data(dataclasses.asdict(data.wan.data), TO_REDACT),
|
||||
},
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
from dataclasses import dataclass
|
||||
|
||||
from sfrbox_api.bridge import SFRBox
|
||||
from sfrbox_api.models import DslInfo, SystemInfo
|
||||
from sfrbox_api.models import DslInfo, SystemInfo, WanInfo
|
||||
|
||||
from .coordinator import SFRDataUpdateCoordinator
|
||||
|
||||
@ -14,3 +14,4 @@ class DomainData:
|
||||
box: SFRBox
|
||||
dsl: SFRDataUpdateCoordinator[DslInfo]
|
||||
system: SFRDataUpdateCoordinator[SystemInfo]
|
||||
wan: SFRDataUpdateCoordinator[WanInfo]
|
||||
|
@ -3,7 +3,7 @@ from collections.abc import Callable
|
||||
from dataclasses import dataclass
|
||||
from typing import Generic, TypeVar
|
||||
|
||||
from sfrbox_api.models import DslInfo, SystemInfo
|
||||
from sfrbox_api.models import DslInfo, SystemInfo, WanInfo
|
||||
|
||||
from homeassistant.components.sensor import (
|
||||
SensorDeviceClass,
|
||||
@ -195,6 +195,24 @@ SYSTEM_SENSOR_TYPES: tuple[SFRBoxSensorEntityDescription[SystemInfo], ...] = (
|
||||
value_fn=lambda x: x.temperature / 1000,
|
||||
),
|
||||
)
|
||||
WAN_SENSOR_TYPES: tuple[SFRBoxSensorEntityDescription[WanInfo], ...] = (
|
||||
SFRBoxSensorEntityDescription[WanInfo](
|
||||
key="mode",
|
||||
name="WAN mode",
|
||||
device_class=SensorDeviceClass.ENUM,
|
||||
entity_category=EntityCategory.DIAGNOSTIC,
|
||||
entity_registry_enabled_default=False,
|
||||
options=[
|
||||
"adsl_ppp",
|
||||
"adsl_routed",
|
||||
"ftth_routed",
|
||||
"grps_ppp",
|
||||
"unknown",
|
||||
],
|
||||
translation_key="wan_mode",
|
||||
value_fn=lambda x: x.mode.replace("/", "_"),
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
async def async_setup_entry(
|
||||
@ -207,6 +225,10 @@ async def async_setup_entry(
|
||||
SFRBoxSensor(data.system, description, data.system.data)
|
||||
for description in SYSTEM_SENSOR_TYPES
|
||||
]
|
||||
entities.extend(
|
||||
SFRBoxSensor(data.wan, description, data.system.data)
|
||||
for description in WAN_SENSOR_TYPES
|
||||
)
|
||||
if data.system.data.net_infra == "adsl":
|
||||
entities.extend(
|
||||
SFRBoxSensor(data.dsl, description, data.system.data)
|
||||
|
@ -63,6 +63,15 @@
|
||||
"showtime": "Showtime",
|
||||
"unknown": "Unknown"
|
||||
}
|
||||
},
|
||||
"wan_mode": {
|
||||
"state": {
|
||||
"adsl_ppp": "ADSL (PPP)",
|
||||
"adsl_routed": "ADSL (Routed)",
|
||||
"ftth_routed": "FTTH (Routed)",
|
||||
"grps_ppp": "GPRS (PPP)",
|
||||
"unknown": "Unknown"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -30,6 +30,34 @@
|
||||
# ---
|
||||
# name: test_binary_sensors.1
|
||||
list([
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'binary_sensor',
|
||||
'entity_category': <EntityCategory.DIAGNOSTIC: 'diagnostic'>,
|
||||
'entity_id': 'binary_sensor.sfr_box_wan_status',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': <BinarySensorDeviceClass.CONNECTIVITY: 'connectivity'>,
|
||||
'original_icon': None,
|
||||
'original_name': 'WAN status',
|
||||
'platform': 'sfr_box',
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': 'e4:5d:51:00:11:22_wan_status',
|
||||
'unit_of_measurement': None,
|
||||
}),
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
@ -73,3 +101,16 @@
|
||||
'state': 'on',
|
||||
})
|
||||
# ---
|
||||
# name: test_binary_sensors[binary_sensor.sfr_box_wan_status]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'connectivity',
|
||||
'friendly_name': 'SFR Box WAN status',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'binary_sensor.sfr_box_wan_status',
|
||||
'last_changed': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'on',
|
||||
})
|
||||
# ---
|
||||
|
@ -41,7 +41,7 @@
|
||||
'wan': dict({
|
||||
'infra': 'adsl',
|
||||
'infra6': '',
|
||||
'ip_addr': '1.2.3.4',
|
||||
'ip_addr': '**REDACTED**',
|
||||
'ipv6_addr': '',
|
||||
'mode': 'adsl/routed',
|
||||
'status': 'up',
|
||||
|
@ -119,6 +119,42 @@
|
||||
'unique_id': 'e4:5d:51:00:11:22_system_temperature',
|
||||
'unit_of_measurement': <UnitOfTemperature.CELSIUS: '°C'>,
|
||||
}),
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': dict({
|
||||
'options': list([
|
||||
'adsl_ppp',
|
||||
'adsl_routed',
|
||||
'ftth_routed',
|
||||
'grps_ppp',
|
||||
'unknown',
|
||||
]),
|
||||
}),
|
||||
'config_entry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': <RegistryEntryDisabler.INTEGRATION: 'integration'>,
|
||||
'domain': 'sensor',
|
||||
'entity_category': <EntityCategory.DIAGNOSTIC: 'diagnostic'>,
|
||||
'entity_id': 'sensor.sfr_box_wan_mode',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': <SensorDeviceClass.ENUM: 'enum'>,
|
||||
'original_icon': None,
|
||||
'original_name': 'WAN mode',
|
||||
'platform': 'sfr_box',
|
||||
'supported_features': 0,
|
||||
'translation_key': 'wan_mode',
|
||||
'unique_id': 'e4:5d:51:00:11:22_wan_mode',
|
||||
'unit_of_measurement': None,
|
||||
}),
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
@ -682,3 +718,23 @@
|
||||
'state': '12251',
|
||||
})
|
||||
# ---
|
||||
# name: test_sensors[sensor.sfr_box_wan_mode]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'enum',
|
||||
'friendly_name': 'SFR Box WAN mode',
|
||||
'options': list([
|
||||
'adsl_ppp',
|
||||
'adsl_routed',
|
||||
'ftth_routed',
|
||||
'grps_ppp',
|
||||
'unknown',
|
||||
]),
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.sfr_box_wan_mode',
|
||||
'last_changed': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'adsl_routed',
|
||||
})
|
||||
# ---
|
||||
|
@ -10,7 +10,7 @@ from homeassistant.const import Platform
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers import device_registry as dr, entity_registry as er
|
||||
|
||||
pytestmark = pytest.mark.usefixtures("system_get_info", "dsl_get_info")
|
||||
pytestmark = pytest.mark.usefixtures("system_get_info", "dsl_get_info", "wan_get_info")
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
|
@ -13,7 +13,7 @@ from homeassistant.core import HomeAssistant
|
||||
from homeassistant.exceptions import HomeAssistantError
|
||||
from homeassistant.helpers import device_registry as dr, entity_registry as er
|
||||
|
||||
pytestmark = pytest.mark.usefixtures("system_get_info", "dsl_get_info")
|
||||
pytestmark = pytest.mark.usefixtures("system_get_info", "dsl_get_info", "wan_get_info")
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
|
@ -17,7 +17,7 @@ def override_platforms() -> Generator[None, None, None]:
|
||||
yield
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("system_get_info", "dsl_get_info")
|
||||
@pytest.mark.usefixtures("system_get_info", "dsl_get_info", "wan_get_info")
|
||||
async def test_setup_unload_entry(
|
||||
hass: HomeAssistant, config_entry: ConfigEntry
|
||||
) -> None:
|
||||
|
@ -11,7 +11,7 @@ from homeassistant.const import Platform
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers import device_registry as dr, entity_registry as er
|
||||
|
||||
pytestmark = pytest.mark.usefixtures("system_get_info", "dsl_get_info")
|
||||
pytestmark = pytest.mark.usefixtures("system_get_info", "dsl_get_info", "wan_get_info")
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
|
Loading…
x
Reference in New Issue
Block a user