Skip to content

Commit f15d4d2

Browse files
authored
0.37.0 (#954)
* Switch to the new format for backend `ARConfig` (#949) * Use robust boottime feature of backend (#950) * Add ruff/isort config (#952) * Add DDNS support (#951) * Fix formatting and imports (#953) * Bump `asusrouter` to `1.18.0` * Bump version to `0.37.0`
1 parent 7553167 commit f15d4d2

File tree

21 files changed

+201
-77
lines changed

21 files changed

+201
-77
lines changed

custom_components/asusrouter/__init__.py

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,9 @@ async def async_close_connection(event):
4242
STOP_LISTENER: stop_listener,
4343
}
4444

45-
await hass.config_entries.async_forward_entry_setups(config_entry, PLATFORMS)
45+
await hass.config_entries.async_forward_entry_setups(
46+
config_entry, PLATFORMS
47+
)
4648

4749
return True
4850

@@ -55,7 +57,9 @@ async def async_unload_entry(
5557

5658
_LOGGER.debug("Unloading entry")
5759

58-
unload = await hass.config_entries.async_unload_platforms(config_entry, PLATFORMS)
60+
unload = await hass.config_entries.async_unload_platforms(
61+
config_entry, PLATFORMS
62+
)
5963

6064
if unload:
6165
# Close connection
@@ -90,10 +94,14 @@ async def async_migrate_entry(hass, config_entry: ConfigEntry):
9094

9195
if config_entry.version == 4:
9296
new_options = {**config_entry.options}
93-
new_options["interval_network"] = new_options.pop("interval_network_stat", 30)
97+
new_options["interval_network"] = new_options.pop(
98+
"interval_network_stat", 30
99+
)
94100

95101
config_entry.version = 5
96-
hass.config_entries.async_update_entry(config_entry, options=new_options)
102+
hass.config_entries.async_update_entry(
103+
config_entry, options=new_options
104+
)
97105

98106
_LOGGER.debug("Migration to version %s successful", config_entry.version)
99107

custom_components/asusrouter/aimesh.py

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,9 @@ def __init__(
3434
def update(
3535
self,
3636
node_info: Optional[AiMeshDevice] = None,
37-
event_call: Optional[Callable[[str, Optional[dict[str, Any]]], None]] = None,
37+
event_call: Optional[
38+
Callable[[str, Optional[dict[str, Any]]], None]
39+
] = None,
3840
) -> None:
3941
"""Update AiMesh device."""
4042

@@ -50,7 +52,9 @@ def update(
5052
"type"
5153
] = node_info.type
5254
# IP
53-
self._extra_state_attributes["ip"] = self.identity["ip"] = node_info.ip
55+
self._extra_state_attributes["ip"] = self.identity["ip"] = (
56+
node_info.ip
57+
)
5458
# Alias
5559
self._extra_state_attributes["alias"] = self.identity[
5660
"alias"
@@ -60,7 +64,9 @@ def update(
6064
"model"
6165
] = node_info.model
6266
# Product ID
63-
self._extra_state_attributes["product_id"] = node_info.product_id
67+
self._extra_state_attributes["product_id"] = (
68+
node_info.product_id
69+
)
6470
# Node level
6571
self._extra_state_attributes["level"] = node_info.level
6672
# Node parent
@@ -75,7 +81,9 @@ def update(
7581
# Access point
7682
# self._extra_state_attributes[ACCESS_POINT] = node_info.ap
7783
# Notify reconnect
78-
if self.identity["connected"] is False and callable(event_call):
84+
if self.identity["connected"] is False and callable(
85+
event_call
86+
):
7987
event_call(
8088
"node_reconnected",
8189
self.identity,

custom_components/asusrouter/binary_sensor.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,18 @@ async def async_setup_entry(
4141
binary_sensors = STATIC_BINARY_SENSORS.copy()
4242

4343
hide = []
44-
if config_entry.options.get(CONF_HIDE_PASSWORDS, CONF_DEFAULT_HIDE_PASSWORDS):
44+
if config_entry.options.get(
45+
CONF_HIDE_PASSWORDS, CONF_DEFAULT_HIDE_PASSWORDS
46+
):
4547
hide.append(PASSWORD)
4648

4749
await async_setup_ar_entry(
48-
hass, config_entry, async_add_entities, binary_sensors, ARBinarySensor, hide
50+
hass,
51+
config_entry,
52+
async_add_entities,
53+
binary_sensors,
54+
ARBinarySensor,
55+
hide,
4956
)
5057

5158
router = hass.data[DOMAIN][config_entry.entry_id][ASUSROUTER]
@@ -112,7 +119,9 @@ def __init__(
112119

113120
self._router = router
114121
self._node = node
115-
self._attr_unique_id = to_unique_id(f"{router.mac}_{AIMESH}_{node.mac}")
122+
self._attr_unique_id = to_unique_id(
123+
f"{router.mac}_{AIMESH}_{node.mac}"
124+
)
116125
self._attr_name = f"AiMesh {node.native.model} ({node.native.mac})"
117126

118127
@property

custom_components/asusrouter/bridge.py

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
import aiohttp
1010
from asusrouter import AsusRouter
11-
from asusrouter.config import ARConfig
11+
from asusrouter.config import ARConfig, ARConfigKey
1212
from asusrouter.error import AsusRouterError
1313
from asusrouter.modules.aimesh import AiMeshDevice
1414
from asusrouter.modules.client import AsusClient
@@ -44,6 +44,7 @@
4444
CONF_DEFAULT_PORT,
4545
CONF_MODE,
4646
CPU,
47+
DDNS,
4748
DEFAULT_SENSORS,
4849
DSL,
4950
FIRMWARE,
@@ -106,9 +107,15 @@ def __init__(
106107
# Initialize API
107108
self._api = self._get_api(self._configs, session)
108109

109-
# Switch API to optimistic
110+
# Switch API to optimistic mode
110111
# Optimistic temperature to avoid scaling issues from some devices
111-
ARConfig.set("optimistic_temperature", True)
112+
ARConfig.set(ARConfigKey.OPTIMISTIC_TEMPERATURE, True)
113+
# Switch API to robust mode
114+
# Robust boottime will avoid 1 second jitter due to the raw data
115+
# uncertainty. This can provide up to 1 second overestimation
116+
# of the boottime, but will avoid saving extra data when the
117+
# integration restarts and loses the previous boottime data.
118+
ARConfig.set(ARConfigKey.ROBUST_BOOTTIME, True)
112119

113120
self._host = self._configs[CONF_HOST]
114121
self._identity: Optional[AsusDevice] = None
@@ -219,6 +226,10 @@ async def async_get_available_sensors(self) -> dict[str, dict[str, Any]]:
219226
SENSORS: await self._get_sensors_modern(AsusData.CPU),
220227
METHOD: self._get_data_cpu,
221228
},
229+
DDNS: {
230+
SENSORS: await self._get_sensors_modern(AsusData.DDNS),
231+
METHOD: self._get_data_ddns,
232+
},
222233
DSL: {
223234
SENSORS: await self._get_sensors_modern(AsusData.DSL),
224235
METHOD: self._get_data_dsl,
@@ -360,6 +371,11 @@ async def _get_data_cpu(self) -> dict[str, Any]:
360371

361372
return await self._get_data(AsusData.CPU)
362373

374+
async def _get_data_ddns(self) -> dict[str, Any]:
375+
"""Get DDNS data from the device."""
376+
377+
return await self._get_data_modern(AsusData.DDNS)
378+
363379
async def _get_data_dsl(self) -> dict[str, Any]:
364380
"""Get DSL data from the device."""
365381

custom_components/asusrouter/button.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from __future__ import annotations
44

55
import logging
6-
from typing import Any, Optional
6+
from typing import Any
77

88
from asusrouter.modules.state import AsusState
99
from homeassistant.components.button import ButtonEntity

custom_components/asusrouter/client.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,6 @@
55
from datetime import datetime, timezone
66
from typing import Any, Callable, Optional
77

8-
from homeassistant.core import callback
9-
from homeassistant.helpers.device_registry import format_mac
10-
118
from asusrouter.modules.client import (
129
AsusClient,
1310
AsusClientConnection,
@@ -16,6 +13,8 @@
1613
)
1714
from asusrouter.modules.connection import ConnectionState, ConnectionType
1815
from asusrouter.modules.homeassistant import convert_to_ha_state_bool
16+
from homeassistant.core import callback
17+
from homeassistant.helpers.device_registry import format_mac
1918

2019
from .helpers import clean_dict
2120

custom_components/asusrouter/compilers.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,17 @@ def list_sensors_network(
3737
icon=data["icon"] or None,
3838
state_class=data["state_class"] or None,
3939
device_class=data["device_class"] or None,
40-
native_unit_of_measurement=data["native_unit_of_measurement"]
40+
native_unit_of_measurement=data[
41+
"native_unit_of_measurement"
42+
]
4143
or None,
42-
suggested_unit_of_measurement=data["suggested_unit_of_measurement"]
44+
suggested_unit_of_measurement=data[
45+
"suggested_unit_of_measurement"
46+
]
4347
or None,
44-
suggested_display_precision=data["suggested_display_precision"]
48+
suggested_display_precision=data[
49+
"suggested_display_precision"
50+
]
4551
or None,
4652
entity_registry_enabled_default=data[
4753
"entity_registry_enabled_default"

custom_components/asusrouter/config_flow.py

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,14 @@
66
import socket
77
from typing import Any
88

9-
import voluptuous as vol
9+
from asusrouter import AsusData
10+
from asusrouter.error import (
11+
AsusRouterAccessError,
12+
AsusRouterConnectionError,
13+
AsusRouterTimeoutError,
14+
)
15+
from asusrouter.modules.endpoint.error import AccessError
16+
from asusrouter.modules.homeassistant import convert_to_ha_sensors_group
1017
from homeassistant.config_entries import ConfigEntry, ConfigFlow, OptionsFlow
1118
from homeassistant.const import (
1219
CONF_HOST,
@@ -20,15 +27,7 @@
2027
from homeassistant.data_entry_flow import FlowResult
2128
from homeassistant.helpers import config_validation as cv
2229
from homeassistant.helpers.device_registry import format_mac
23-
24-
from asusrouter import AsusData
25-
from asusrouter.error import (
26-
AsusRouterAccessError,
27-
AsusRouterConnectionError,
28-
AsusRouterTimeoutError,
29-
)
30-
from asusrouter.modules.endpoint.error import AccessError
31-
from asusrouter.modules.homeassistant import convert_to_ha_sensors_group
30+
import voluptuous as vol
3231

3332
from .bridge import ARBridge
3433
from .const import (

custom_components/asusrouter/const.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@
9898
COORDINATOR = "coordinator"
9999
CORE = "core"
100100
CPU = "cpu"
101+
DDNS = "ddns"
101102
DEVICES = "devices"
102103
DNS = "dns"
103104
DSL = "dsl"
@@ -273,6 +274,7 @@
273274
MODE_ROUTER = MODE_ACCESS_POINT.copy()
274275
MODE_ROUTER.extend(
275276
[
277+
DDNS,
276278
DSL,
277279
GWLAN,
278280
"ovpn_client",
@@ -838,6 +840,7 @@
838840
# ICONS -->
839841

840842
ICON_CPU = "mdi:cpu-32-bit"
843+
ICON_DDNS = "mdi:dns-outline"
841844
ICON_DEVICES = "mdi:devices"
842845
ICON_DUALWAN = "mdi:call-split"
843846
ICON_ETHERNET_ON = "mdi:ethernet-cable"
@@ -867,6 +870,27 @@
867870

868871
# SENSORS -->
869872
STATIC_BINARY_SENSORS: list[AREntityDescription] = [
873+
# DDNS
874+
ARBinarySensorDescription(
875+
key="state",
876+
key_group="ddns",
877+
name="DDNS",
878+
icon=ICON_DDNS,
879+
entity_category=EntityCategory.DIAGNOSTIC,
880+
entity_registry_enabled_default=False,
881+
extra_state_attributes={
882+
"enabled": "enabled",
883+
"hostname": "hostname",
884+
"ip_address": "ip_address",
885+
"old_name": "old_name",
886+
"replace_status": "replace_status",
887+
"return_code": "return_code",
888+
"server": "server",
889+
"status": "status",
890+
"status_hint": "status_hint",
891+
"updated": "updated",
892+
},
893+
),
870894
# Dual WAN
871895
ARBinarySensorDescription(
872896
key="dualwan_state",

custom_components/asusrouter/dataclass.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@
77
from typing import Any, Optional
88

99
from asusrouter.modules.state import AsusState, AsusStateNone
10-
from homeassistant.components.binary_sensor import BinarySensorEntityDescription
10+
from homeassistant.components.binary_sensor import (
11+
BinarySensorEntityDescription,
12+
)
1113
from homeassistant.components.button import ButtonEntityDescription
1214
from homeassistant.components.light import LightEntityDescription
1315
from homeassistant.components.sensor import SensorEntityDescription
@@ -43,7 +45,9 @@ class ARSensorDescription(AREntityDescription, SensorEntityDescription):
4345

4446

4547
@dataclass
46-
class ARBinarySensorDescription(ARBinaryDescription, BinarySensorEntityDescription):
48+
class ARBinarySensorDescription(
49+
ARBinaryDescription, BinarySensorEntityDescription
50+
):
4751
"""Describe AsusRouter sensor."""
4852

4953

0 commit comments

Comments
 (0)