mirror of
https://github.com/home-assistant/core.git
synced 2025-07-24 21:57:51 +00:00
Huawei LTE simplifications (#62770)
* Use enum types rather than strs in sensor type hints * Name sensor meta fields same as in SensorEntityDescription * Make integration shared state a NamedTuple * Use dataclasses instead of attr
This commit is contained in:
parent
e982e7403a
commit
3e3fb52dfa
@ -4,12 +4,12 @@ from __future__ import annotations
|
|||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
from collections.abc import Callable
|
from collections.abc import Callable
|
||||||
from contextlib import suppress
|
from contextlib import suppress
|
||||||
|
from dataclasses import dataclass, field
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
import logging
|
import logging
|
||||||
import time
|
import time
|
||||||
from typing import Any, cast
|
from typing import Any, NamedTuple, cast
|
||||||
|
|
||||||
import attr
|
|
||||||
from huawei_lte_api.AuthorizedConnection import AuthorizedConnection
|
from huawei_lte_api.AuthorizedConnection import AuthorizedConnection
|
||||||
from huawei_lte_api.Client import Client
|
from huawei_lte_api.Client import Client
|
||||||
from huawei_lte_api.Connection import Connection
|
from huawei_lte_api.Connection import Connection
|
||||||
@ -126,26 +126,28 @@ PLATFORMS = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
@attr.s
|
@dataclass
|
||||||
class Router:
|
class Router:
|
||||||
"""Class for router state."""
|
"""Class for router state."""
|
||||||
|
|
||||||
hass: HomeAssistant = attr.ib()
|
hass: HomeAssistant
|
||||||
config_entry: ConfigEntry = attr.ib()
|
config_entry: ConfigEntry
|
||||||
connection: Connection = attr.ib()
|
connection: Connection
|
||||||
url: str = attr.ib()
|
url: str
|
||||||
|
|
||||||
data: dict[str, Any] = attr.ib(init=False, factory=dict)
|
data: dict[str, Any] = field(default_factory=dict, init=False)
|
||||||
subscriptions: dict[str, set[str]] = attr.ib(
|
subscriptions: dict[str, set[str]] = field(
|
||||||
|
default_factory=lambda: defaultdict(
|
||||||
|
set, ((x, {"initial_scan"}) for x in ALL_KEYS)
|
||||||
|
),
|
||||||
init=False,
|
init=False,
|
||||||
factory=lambda: defaultdict(set, ((x, {"initial_scan"}) for x in ALL_KEYS)),
|
|
||||||
)
|
)
|
||||||
inflight_gets: set[str] = attr.ib(init=False, factory=set)
|
inflight_gets: set[str] = field(default_factory=set, init=False)
|
||||||
client: Client
|
client: Client = field(init=False)
|
||||||
suspended = attr.ib(init=False, default=False)
|
suspended: bool = field(default=False, init=False)
|
||||||
notify_last_attempt: float = attr.ib(init=False, default=-1)
|
notify_last_attempt: float = field(default=-1, init=False)
|
||||||
|
|
||||||
def __attrs_post_init__(self) -> None:
|
def __post_init__(self) -> None:
|
||||||
"""Set up internal state on init."""
|
"""Set up internal state on init."""
|
||||||
self.client = Client(self.connection)
|
self.client = Client(self.connection)
|
||||||
|
|
||||||
@ -293,14 +295,13 @@ class Router:
|
|||||||
self.logout()
|
self.logout()
|
||||||
|
|
||||||
|
|
||||||
@attr.s
|
class HuaweiLteData(NamedTuple):
|
||||||
class HuaweiLteData:
|
|
||||||
"""Shared state."""
|
"""Shared state."""
|
||||||
|
|
||||||
hass_config: ConfigType = attr.ib()
|
hass_config: ConfigType
|
||||||
# Our YAML config, keyed by router URL
|
# Our YAML config, keyed by router URL
|
||||||
config: dict[str, dict[str, Any]] = attr.ib()
|
config: dict[str, dict[str, Any]]
|
||||||
routers: dict[str, Router] = attr.ib(init=False, factory=dict)
|
routers: dict[str, Router]
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_entry( # noqa: C901
|
async def async_setup_entry( # noqa: C901
|
||||||
@ -509,7 +510,9 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
|
|||||||
# Arrange our YAML config to dict with normalized URLs as keys
|
# Arrange our YAML config to dict with normalized URLs as keys
|
||||||
domain_config: dict[str, dict[str, Any]] = {}
|
domain_config: dict[str, dict[str, Any]] = {}
|
||||||
if DOMAIN not in hass.data:
|
if DOMAIN not in hass.data:
|
||||||
hass.data[DOMAIN] = HuaweiLteData(hass_config=config, config=domain_config)
|
hass.data[DOMAIN] = HuaweiLteData(
|
||||||
|
hass_config=config, config=domain_config, routers={}
|
||||||
|
)
|
||||||
for router_config in config.get(DOMAIN, []):
|
for router_config in config.get(DOMAIN, []):
|
||||||
domain_config[url_normalize(router_config.pop(CONF_URL))] = router_config
|
domain_config[url_normalize(router_config.pop(CONF_URL))] = router_config
|
||||||
|
|
||||||
@ -607,14 +610,14 @@ async def async_migrate_entry(hass: HomeAssistant, config_entry: ConfigEntry) ->
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
@attr.s
|
@dataclass
|
||||||
class HuaweiLteBaseEntity(Entity):
|
class HuaweiLteBaseEntity(Entity):
|
||||||
"""Huawei LTE entity base class."""
|
"""Huawei LTE entity base class."""
|
||||||
|
|
||||||
router: Router = attr.ib()
|
router: Router
|
||||||
|
|
||||||
_available: bool = attr.ib(init=False, default=True)
|
_available: bool = field(default=True, init=False)
|
||||||
_unsub_handlers: list[Callable] = attr.ib(init=False, factory=list)
|
_unsub_handlers: list[Callable] = field(default_factory=list, init=False)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def _entity_name(self) -> str:
|
def _entity_name(self) -> str:
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
"""Support for Huawei LTE binary sensors."""
|
"""Support for Huawei LTE binary sensors."""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from dataclasses import dataclass, field
|
||||||
import logging
|
import logging
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
import attr
|
|
||||||
from huawei_lte_api.enums.cradle import ConnectionStatusEnum
|
from huawei_lte_api.enums.cradle import ConnectionStatusEnum
|
||||||
|
|
||||||
from homeassistant.components.binary_sensor import (
|
from homeassistant.components.binary_sensor import (
|
||||||
@ -48,13 +48,13 @@ async def async_setup_entry(
|
|||||||
async_add_entities(entities, True)
|
async_add_entities(entities, True)
|
||||||
|
|
||||||
|
|
||||||
@attr.s
|
@dataclass
|
||||||
class HuaweiLteBaseBinarySensor(HuaweiLteBaseEntity, BinarySensorEntity):
|
class HuaweiLteBaseBinarySensor(HuaweiLteBaseEntity, BinarySensorEntity):
|
||||||
"""Huawei LTE binary sensor device base class."""
|
"""Huawei LTE binary sensor device base class."""
|
||||||
|
|
||||||
key: str
|
key: str = field(init=False)
|
||||||
item: str
|
item: str = field(init=False)
|
||||||
_raw_state: str | None = attr.ib(init=False, default=None)
|
_raw_state: str | None = field(default=None, init=False)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def entity_registry_enabled_default(self) -> bool:
|
def entity_registry_enabled_default(self) -> bool:
|
||||||
@ -101,11 +101,11 @@ CONNECTION_STATE_ATTRIBUTES = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@attr.s
|
@dataclass
|
||||||
class HuaweiLteMobileConnectionBinarySensor(HuaweiLteBaseBinarySensor):
|
class HuaweiLteMobileConnectionBinarySensor(HuaweiLteBaseBinarySensor):
|
||||||
"""Huawei LTE mobile connection binary sensor."""
|
"""Huawei LTE mobile connection binary sensor."""
|
||||||
|
|
||||||
def __attrs_post_init__(self) -> None:
|
def __post_init__(self) -> None:
|
||||||
"""Initialize identifiers."""
|
"""Initialize identifiers."""
|
||||||
self.key = KEY_MONITORING_STATUS
|
self.key = KEY_MONITORING_STATUS
|
||||||
self.item = "ConnectionStatus"
|
self.item = "ConnectionStatus"
|
||||||
@ -172,11 +172,11 @@ class HuaweiLteBaseWifiStatusBinarySensor(HuaweiLteBaseBinarySensor):
|
|||||||
return "mdi:wifi" if self.is_on else "mdi:wifi-off"
|
return "mdi:wifi" if self.is_on else "mdi:wifi-off"
|
||||||
|
|
||||||
|
|
||||||
@attr.s
|
@dataclass
|
||||||
class HuaweiLteWifiStatusBinarySensor(HuaweiLteBaseWifiStatusBinarySensor):
|
class HuaweiLteWifiStatusBinarySensor(HuaweiLteBaseWifiStatusBinarySensor):
|
||||||
"""Huawei LTE WiFi status binary sensor."""
|
"""Huawei LTE WiFi status binary sensor."""
|
||||||
|
|
||||||
def __attrs_post_init__(self) -> None:
|
def __post_init__(self) -> None:
|
||||||
"""Initialize identifiers."""
|
"""Initialize identifiers."""
|
||||||
self.key = KEY_MONITORING_STATUS
|
self.key = KEY_MONITORING_STATUS
|
||||||
self.item = "WifiStatus"
|
self.item = "WifiStatus"
|
||||||
@ -186,11 +186,11 @@ class HuaweiLteWifiStatusBinarySensor(HuaweiLteBaseWifiStatusBinarySensor):
|
|||||||
return "WiFi status"
|
return "WiFi status"
|
||||||
|
|
||||||
|
|
||||||
@attr.s
|
@dataclass
|
||||||
class HuaweiLteWifi24ghzStatusBinarySensor(HuaweiLteBaseWifiStatusBinarySensor):
|
class HuaweiLteWifi24ghzStatusBinarySensor(HuaweiLteBaseWifiStatusBinarySensor):
|
||||||
"""Huawei LTE 2.4GHz WiFi status binary sensor."""
|
"""Huawei LTE 2.4GHz WiFi status binary sensor."""
|
||||||
|
|
||||||
def __attrs_post_init__(self) -> None:
|
def __post_init__(self) -> None:
|
||||||
"""Initialize identifiers."""
|
"""Initialize identifiers."""
|
||||||
self.key = KEY_WLAN_WIFI_FEATURE_SWITCH
|
self.key = KEY_WLAN_WIFI_FEATURE_SWITCH
|
||||||
self.item = "wifi24g_switch_enable"
|
self.item = "wifi24g_switch_enable"
|
||||||
@ -200,11 +200,11 @@ class HuaweiLteWifi24ghzStatusBinarySensor(HuaweiLteBaseWifiStatusBinarySensor):
|
|||||||
return "2.4GHz WiFi status"
|
return "2.4GHz WiFi status"
|
||||||
|
|
||||||
|
|
||||||
@attr.s
|
@dataclass
|
||||||
class HuaweiLteWifi5ghzStatusBinarySensor(HuaweiLteBaseWifiStatusBinarySensor):
|
class HuaweiLteWifi5ghzStatusBinarySensor(HuaweiLteBaseWifiStatusBinarySensor):
|
||||||
"""Huawei LTE 5GHz WiFi status binary sensor."""
|
"""Huawei LTE 5GHz WiFi status binary sensor."""
|
||||||
|
|
||||||
def __attrs_post_init__(self) -> None:
|
def __post_init__(self) -> None:
|
||||||
"""Initialize identifiers."""
|
"""Initialize identifiers."""
|
||||||
self.key = KEY_WLAN_WIFI_FEATURE_SWITCH
|
self.key = KEY_WLAN_WIFI_FEATURE_SWITCH
|
||||||
self.item = "wifi5g_enabled"
|
self.item = "wifi5g_enabled"
|
||||||
@ -214,11 +214,11 @@ class HuaweiLteWifi5ghzStatusBinarySensor(HuaweiLteBaseWifiStatusBinarySensor):
|
|||||||
return "5GHz WiFi status"
|
return "5GHz WiFi status"
|
||||||
|
|
||||||
|
|
||||||
@attr.s
|
@dataclass
|
||||||
class HuaweiLteSmsStorageFullBinarySensor(HuaweiLteBaseBinarySensor):
|
class HuaweiLteSmsStorageFullBinarySensor(HuaweiLteBaseBinarySensor):
|
||||||
"""Huawei LTE SMS storage full binary sensor."""
|
"""Huawei LTE SMS storage full binary sensor."""
|
||||||
|
|
||||||
def __attrs_post_init__(self) -> None:
|
def __post_init__(self) -> None:
|
||||||
"""Initialize identifiers."""
|
"""Initialize identifiers."""
|
||||||
self.key = KEY_MONITORING_CHECK_NOTIFICATIONS
|
self.key = KEY_MONITORING_CHECK_NOTIFICATIONS
|
||||||
self.item = "SmsStorageFull"
|
self.item = "SmsStorageFull"
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
"""Support for device tracking of Huawei LTE routers."""
|
"""Support for device tracking of Huawei LTE routers."""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from dataclasses import dataclass, field
|
||||||
import logging
|
import logging
|
||||||
import re
|
import re
|
||||||
from typing import Any, Dict, List, cast
|
from typing import Any, Dict, List, cast
|
||||||
|
|
||||||
import attr
|
|
||||||
from stringcase import snakecase
|
from stringcase import snakecase
|
||||||
|
|
||||||
from homeassistant.components.device_tracker.config_entry import ScannerEntity
|
from homeassistant.components.device_tracker.config_entry import ScannerEntity
|
||||||
@ -173,16 +173,16 @@ def _better_snakecase(text: str) -> str:
|
|||||||
return cast(str, snakecase(text))
|
return cast(str, snakecase(text))
|
||||||
|
|
||||||
|
|
||||||
@attr.s
|
@dataclass
|
||||||
class HuaweiLteScannerEntity(HuaweiLteBaseEntity, ScannerEntity):
|
class HuaweiLteScannerEntity(HuaweiLteBaseEntity, ScannerEntity):
|
||||||
"""Huawei LTE router scanner entity."""
|
"""Huawei LTE router scanner entity."""
|
||||||
|
|
||||||
_mac_address: str = attr.ib()
|
_mac_address: str
|
||||||
|
|
||||||
_ip_address: str | None = attr.ib(init=False, default=None)
|
_ip_address: str | None = field(default=None, init=False)
|
||||||
_is_connected: bool = attr.ib(init=False, default=False)
|
_is_connected: bool = field(default=False, init=False)
|
||||||
_hostname: str | None = attr.ib(init=False, default=None)
|
_hostname: str | None = field(default=None, init=False)
|
||||||
_extra_state_attributes: dict[str, Any] = attr.ib(init=False, factory=dict)
|
_extra_state_attributes: dict[str, Any] = field(default_factory=dict, init=False)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def _entity_name(self) -> str:
|
def _entity_name(self) -> str:
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
"""Support for Huawei LTE router notifications."""
|
"""Support for Huawei LTE router notifications."""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from dataclasses import dataclass
|
||||||
import logging
|
import logging
|
||||||
import time
|
import time
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
import attr
|
|
||||||
from huawei_lte_api.exceptions import ResponseErrorException
|
from huawei_lte_api.exceptions import ResponseErrorException
|
||||||
|
|
||||||
from homeassistant.components.notify import ATTR_TARGET, BaseNotificationService
|
from homeassistant.components.notify import ATTR_TARGET, BaseNotificationService
|
||||||
@ -33,12 +33,12 @@ async def async_get_service(
|
|||||||
return HuaweiLteSmsNotificationService(router, default_targets)
|
return HuaweiLteSmsNotificationService(router, default_targets)
|
||||||
|
|
||||||
|
|
||||||
@attr.s
|
@dataclass
|
||||||
class HuaweiLteSmsNotificationService(BaseNotificationService):
|
class HuaweiLteSmsNotificationService(BaseNotificationService):
|
||||||
"""Huawei LTE router SMS notification service."""
|
"""Huawei LTE router SMS notification service."""
|
||||||
|
|
||||||
router: Router = attr.ib()
|
router: Router
|
||||||
default_targets: list[str] = attr.ib()
|
default_targets: list[str]
|
||||||
|
|
||||||
def send_message(self, message: str = "", **kwargs: Any) -> None:
|
def send_message(self, message: str = "", **kwargs: Any) -> None:
|
||||||
"""Send message to target numbers."""
|
"""Send message to target numbers."""
|
||||||
|
@ -3,12 +3,11 @@ from __future__ import annotations
|
|||||||
|
|
||||||
from bisect import bisect
|
from bisect import bisect
|
||||||
from collections.abc import Callable
|
from collections.abc import Callable
|
||||||
|
from dataclasses import dataclass, field
|
||||||
import logging
|
import logging
|
||||||
import re
|
import re
|
||||||
from typing import NamedTuple
|
from typing import NamedTuple
|
||||||
|
|
||||||
import attr
|
|
||||||
|
|
||||||
from homeassistant.components.sensor import (
|
from homeassistant.components.sensor import (
|
||||||
DOMAIN as SENSOR_DOMAIN,
|
DOMAIN as SENSOR_DOMAIN,
|
||||||
SensorDeviceClass,
|
SensorDeviceClass,
|
||||||
@ -51,12 +50,12 @@ class SensorMeta(NamedTuple):
|
|||||||
"""Metadata for defining sensors."""
|
"""Metadata for defining sensors."""
|
||||||
|
|
||||||
name: str | None = None
|
name: str | None = None
|
||||||
device_class: str | None = None
|
device_class: SensorDeviceClass | None = None
|
||||||
icon: str | Callable[[StateType], str] | None = None
|
icon: str | Callable[[StateType], str] | None = None
|
||||||
unit: str | None = None
|
native_unit_of_measurement: str | None = None
|
||||||
state_class: str | None = None
|
state_class: SensorStateClass | None = None
|
||||||
enabled_default: bool = False
|
entity_registry_enabled_default: bool = False
|
||||||
entity_category: str | None = None
|
entity_category: EntityCategory | None = None
|
||||||
include: re.Pattern[str] | None = None
|
include: re.Pattern[str] | None = None
|
||||||
exclude: re.Pattern[str] | None = None
|
exclude: re.Pattern[str] | None = None
|
||||||
formatter: Callable[[str], tuple[StateType, str | None]] | None = None
|
formatter: Callable[[str], tuple[StateType, str | None]] | None = None
|
||||||
@ -70,7 +69,7 @@ SENSOR_META: dict[str | tuple[str, str], SensorMeta] = {
|
|||||||
name="WAN IP address",
|
name="WAN IP address",
|
||||||
icon="mdi:ip",
|
icon="mdi:ip",
|
||||||
entity_category=EntityCategory.DIAGNOSTIC,
|
entity_category=EntityCategory.DIAGNOSTIC,
|
||||||
enabled_default=True,
|
entity_registry_enabled_default=True,
|
||||||
),
|
),
|
||||||
(KEY_DEVICE_INFORMATION, "WanIPv6Address"): SensorMeta(
|
(KEY_DEVICE_INFORMATION, "WanIPv6Address"): SensorMeta(
|
||||||
name="WAN IPv6 address",
|
name="WAN IPv6 address",
|
||||||
@ -80,7 +79,7 @@ SENSOR_META: dict[str | tuple[str, str], SensorMeta] = {
|
|||||||
(KEY_DEVICE_INFORMATION, "uptime"): SensorMeta(
|
(KEY_DEVICE_INFORMATION, "uptime"): SensorMeta(
|
||||||
name="Uptime",
|
name="Uptime",
|
||||||
icon="mdi:timer-outline",
|
icon="mdi:timer-outline",
|
||||||
unit=TIME_SECONDS,
|
native_unit_of_measurement=TIME_SECONDS,
|
||||||
entity_category=EntityCategory.DIAGNOSTIC,
|
entity_category=EntityCategory.DIAGNOSTIC,
|
||||||
),
|
),
|
||||||
(KEY_DEVICE_SIGNAL, "band"): SensorMeta(
|
(KEY_DEVICE_SIGNAL, "band"): SensorMeta(
|
||||||
@ -181,7 +180,7 @@ SENSOR_META: dict[str | tuple[str, str], SensorMeta] = {
|
|||||||
)[bisect((-11, -8, -5), x if x is not None else -1000)],
|
)[bisect((-11, -8, -5), x if x is not None else -1000)],
|
||||||
state_class=SensorStateClass.MEASUREMENT,
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
entity_category=EntityCategory.DIAGNOSTIC,
|
entity_category=EntityCategory.DIAGNOSTIC,
|
||||||
enabled_default=True,
|
entity_registry_enabled_default=True,
|
||||||
),
|
),
|
||||||
(KEY_DEVICE_SIGNAL, "rsrp"): SensorMeta(
|
(KEY_DEVICE_SIGNAL, "rsrp"): SensorMeta(
|
||||||
name="RSRP",
|
name="RSRP",
|
||||||
@ -195,7 +194,7 @@ SENSOR_META: dict[str | tuple[str, str], SensorMeta] = {
|
|||||||
)[bisect((-110, -95, -80), x if x is not None else -1000)],
|
)[bisect((-110, -95, -80), x if x is not None else -1000)],
|
||||||
state_class=SensorStateClass.MEASUREMENT,
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
entity_category=EntityCategory.DIAGNOSTIC,
|
entity_category=EntityCategory.DIAGNOSTIC,
|
||||||
enabled_default=True,
|
entity_registry_enabled_default=True,
|
||||||
),
|
),
|
||||||
(KEY_DEVICE_SIGNAL, "rssi"): SensorMeta(
|
(KEY_DEVICE_SIGNAL, "rssi"): SensorMeta(
|
||||||
name="RSSI",
|
name="RSSI",
|
||||||
@ -209,7 +208,7 @@ SENSOR_META: dict[str | tuple[str, str], SensorMeta] = {
|
|||||||
)[bisect((-80, -70, -60), x if x is not None else -1000)],
|
)[bisect((-80, -70, -60), x if x is not None else -1000)],
|
||||||
state_class=SensorStateClass.MEASUREMENT,
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
entity_category=EntityCategory.DIAGNOSTIC,
|
entity_category=EntityCategory.DIAGNOSTIC,
|
||||||
enabled_default=True,
|
entity_registry_enabled_default=True,
|
||||||
),
|
),
|
||||||
(KEY_DEVICE_SIGNAL, "sinr"): SensorMeta(
|
(KEY_DEVICE_SIGNAL, "sinr"): SensorMeta(
|
||||||
name="SINR",
|
name="SINR",
|
||||||
@ -223,7 +222,7 @@ SENSOR_META: dict[str | tuple[str, str], SensorMeta] = {
|
|||||||
)[bisect((0, 5, 10), x if x is not None else -1000)],
|
)[bisect((0, 5, 10), x if x is not None else -1000)],
|
||||||
state_class=SensorStateClass.MEASUREMENT,
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
entity_category=EntityCategory.DIAGNOSTIC,
|
entity_category=EntityCategory.DIAGNOSTIC,
|
||||||
enabled_default=True,
|
entity_registry_enabled_default=True,
|
||||||
),
|
),
|
||||||
(KEY_DEVICE_SIGNAL, "rscp"): SensorMeta(
|
(KEY_DEVICE_SIGNAL, "rscp"): SensorMeta(
|
||||||
name="RSCP",
|
name="RSCP",
|
||||||
@ -298,13 +297,13 @@ SENSOR_META: dict[str | tuple[str, str], SensorMeta] = {
|
|||||||
),
|
),
|
||||||
(KEY_MONITORING_MONTH_STATISTICS, "CurrentMonthDownload"): SensorMeta(
|
(KEY_MONITORING_MONTH_STATISTICS, "CurrentMonthDownload"): SensorMeta(
|
||||||
name="Current month download",
|
name="Current month download",
|
||||||
unit=DATA_BYTES,
|
native_unit_of_measurement=DATA_BYTES,
|
||||||
icon="mdi:download",
|
icon="mdi:download",
|
||||||
state_class=SensorStateClass.TOTAL_INCREASING,
|
state_class=SensorStateClass.TOTAL_INCREASING,
|
||||||
),
|
),
|
||||||
(KEY_MONITORING_MONTH_STATISTICS, "CurrentMonthUpload"): SensorMeta(
|
(KEY_MONITORING_MONTH_STATISTICS, "CurrentMonthUpload"): SensorMeta(
|
||||||
name="Current month upload",
|
name="Current month upload",
|
||||||
unit=DATA_BYTES,
|
native_unit_of_measurement=DATA_BYTES,
|
||||||
icon="mdi:upload",
|
icon="mdi:upload",
|
||||||
state_class=SensorStateClass.TOTAL_INCREASING,
|
state_class=SensorStateClass.TOTAL_INCREASING,
|
||||||
),
|
),
|
||||||
@ -317,7 +316,7 @@ SENSOR_META: dict[str | tuple[str, str], SensorMeta] = {
|
|||||||
(KEY_MONITORING_STATUS, "BatteryPercent"): SensorMeta(
|
(KEY_MONITORING_STATUS, "BatteryPercent"): SensorMeta(
|
||||||
name="Battery",
|
name="Battery",
|
||||||
device_class=SensorDeviceClass.BATTERY,
|
device_class=SensorDeviceClass.BATTERY,
|
||||||
unit=PERCENTAGE,
|
native_unit_of_measurement=PERCENTAGE,
|
||||||
state_class=SensorStateClass.MEASUREMENT,
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
entity_category=EntityCategory.DIAGNOSTIC,
|
entity_category=EntityCategory.DIAGNOSTIC,
|
||||||
),
|
),
|
||||||
@ -351,47 +350,49 @@ SENSOR_META: dict[str | tuple[str, str], SensorMeta] = {
|
|||||||
exclude=re.compile(r"^showtraffic$", re.IGNORECASE)
|
exclude=re.compile(r"^showtraffic$", re.IGNORECASE)
|
||||||
),
|
),
|
||||||
(KEY_MONITORING_TRAFFIC_STATISTICS, "CurrentConnectTime"): SensorMeta(
|
(KEY_MONITORING_TRAFFIC_STATISTICS, "CurrentConnectTime"): SensorMeta(
|
||||||
name="Current connection duration", unit=TIME_SECONDS, icon="mdi:timer-outline"
|
name="Current connection duration",
|
||||||
|
native_unit_of_measurement=TIME_SECONDS,
|
||||||
|
icon="mdi:timer-outline",
|
||||||
),
|
),
|
||||||
(KEY_MONITORING_TRAFFIC_STATISTICS, "CurrentDownload"): SensorMeta(
|
(KEY_MONITORING_TRAFFIC_STATISTICS, "CurrentDownload"): SensorMeta(
|
||||||
name="Current connection download",
|
name="Current connection download",
|
||||||
unit=DATA_BYTES,
|
native_unit_of_measurement=DATA_BYTES,
|
||||||
icon="mdi:download",
|
icon="mdi:download",
|
||||||
state_class=SensorStateClass.TOTAL_INCREASING,
|
state_class=SensorStateClass.TOTAL_INCREASING,
|
||||||
),
|
),
|
||||||
(KEY_MONITORING_TRAFFIC_STATISTICS, "CurrentDownloadRate"): SensorMeta(
|
(KEY_MONITORING_TRAFFIC_STATISTICS, "CurrentDownloadRate"): SensorMeta(
|
||||||
name="Current download rate",
|
name="Current download rate",
|
||||||
unit=DATA_RATE_BYTES_PER_SECOND,
|
native_unit_of_measurement=DATA_RATE_BYTES_PER_SECOND,
|
||||||
icon="mdi:download",
|
icon="mdi:download",
|
||||||
state_class=SensorStateClass.MEASUREMENT,
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
),
|
),
|
||||||
(KEY_MONITORING_TRAFFIC_STATISTICS, "CurrentUpload"): SensorMeta(
|
(KEY_MONITORING_TRAFFIC_STATISTICS, "CurrentUpload"): SensorMeta(
|
||||||
name="Current connection upload",
|
name="Current connection upload",
|
||||||
unit=DATA_BYTES,
|
native_unit_of_measurement=DATA_BYTES,
|
||||||
icon="mdi:upload",
|
icon="mdi:upload",
|
||||||
state_class=SensorStateClass.TOTAL_INCREASING,
|
state_class=SensorStateClass.TOTAL_INCREASING,
|
||||||
),
|
),
|
||||||
(KEY_MONITORING_TRAFFIC_STATISTICS, "CurrentUploadRate"): SensorMeta(
|
(KEY_MONITORING_TRAFFIC_STATISTICS, "CurrentUploadRate"): SensorMeta(
|
||||||
name="Current upload rate",
|
name="Current upload rate",
|
||||||
unit=DATA_RATE_BYTES_PER_SECOND,
|
native_unit_of_measurement=DATA_RATE_BYTES_PER_SECOND,
|
||||||
icon="mdi:upload",
|
icon="mdi:upload",
|
||||||
state_class=SensorStateClass.MEASUREMENT,
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
),
|
),
|
||||||
(KEY_MONITORING_TRAFFIC_STATISTICS, "TotalConnectTime"): SensorMeta(
|
(KEY_MONITORING_TRAFFIC_STATISTICS, "TotalConnectTime"): SensorMeta(
|
||||||
name="Total connected duration",
|
name="Total connected duration",
|
||||||
unit=TIME_SECONDS,
|
native_unit_of_measurement=TIME_SECONDS,
|
||||||
icon="mdi:timer-outline",
|
icon="mdi:timer-outline",
|
||||||
state_class=SensorStateClass.TOTAL_INCREASING,
|
state_class=SensorStateClass.TOTAL_INCREASING,
|
||||||
),
|
),
|
||||||
(KEY_MONITORING_TRAFFIC_STATISTICS, "TotalDownload"): SensorMeta(
|
(KEY_MONITORING_TRAFFIC_STATISTICS, "TotalDownload"): SensorMeta(
|
||||||
name="Total download",
|
name="Total download",
|
||||||
unit=DATA_BYTES,
|
native_unit_of_measurement=DATA_BYTES,
|
||||||
icon="mdi:download",
|
icon="mdi:download",
|
||||||
state_class=SensorStateClass.TOTAL_INCREASING,
|
state_class=SensorStateClass.TOTAL_INCREASING,
|
||||||
),
|
),
|
||||||
(KEY_MONITORING_TRAFFIC_STATISTICS, "TotalUpload"): SensorMeta(
|
(KEY_MONITORING_TRAFFIC_STATISTICS, "TotalUpload"): SensorMeta(
|
||||||
name="Total upload",
|
name="Total upload",
|
||||||
unit=DATA_BYTES,
|
native_unit_of_measurement=DATA_BYTES,
|
||||||
icon="mdi:upload",
|
icon="mdi:upload",
|
||||||
state_class=SensorStateClass.TOTAL_INCREASING,
|
state_class=SensorStateClass.TOTAL_INCREASING,
|
||||||
),
|
),
|
||||||
@ -521,16 +522,16 @@ def format_default(value: StateType) -> tuple[StateType, str | None]:
|
|||||||
return value, unit
|
return value, unit
|
||||||
|
|
||||||
|
|
||||||
@attr.s
|
@dataclass
|
||||||
class HuaweiLteSensor(HuaweiLteBaseEntity, SensorEntity):
|
class HuaweiLteSensor(HuaweiLteBaseEntity, SensorEntity):
|
||||||
"""Huawei LTE sensor entity."""
|
"""Huawei LTE sensor entity."""
|
||||||
|
|
||||||
key: str = attr.ib()
|
key: str
|
||||||
item: str = attr.ib()
|
item: str
|
||||||
meta: SensorMeta = attr.ib()
|
meta: SensorMeta
|
||||||
|
|
||||||
_state: StateType = attr.ib(init=False, default=STATE_UNKNOWN)
|
_state: StateType = field(default=STATE_UNKNOWN, init=False)
|
||||||
_unit: str | None = attr.ib(init=False)
|
_unit: str | None = field(default=None, init=False)
|
||||||
|
|
||||||
async def async_added_to_hass(self) -> None:
|
async def async_added_to_hass(self) -> None:
|
||||||
"""Subscribe to needed data on add."""
|
"""Subscribe to needed data on add."""
|
||||||
@ -556,14 +557,14 @@ class HuaweiLteSensor(HuaweiLteBaseEntity, SensorEntity):
|
|||||||
return self._state
|
return self._state
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def device_class(self) -> str | None:
|
def device_class(self) -> SensorDeviceClass | None:
|
||||||
"""Return sensor device class."""
|
"""Return sensor device class."""
|
||||||
return self.meta.device_class
|
return self.meta.device_class
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def native_unit_of_measurement(self) -> str | None:
|
def native_unit_of_measurement(self) -> str | None:
|
||||||
"""Return sensor's unit of measurement."""
|
"""Return sensor's unit of measurement."""
|
||||||
return self.meta.unit or self._unit
|
return self.meta.native_unit_of_measurement or self._unit
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def icon(self) -> str | None:
|
def icon(self) -> str | None:
|
||||||
@ -574,14 +575,14 @@ class HuaweiLteSensor(HuaweiLteBaseEntity, SensorEntity):
|
|||||||
return icon
|
return icon
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def state_class(self) -> str | None:
|
def state_class(self) -> SensorStateClass | None:
|
||||||
"""Return sensor state class."""
|
"""Return sensor state class."""
|
||||||
return self.meta.state_class
|
return self.meta.state_class
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def entity_registry_enabled_default(self) -> bool:
|
def entity_registry_enabled_default(self) -> bool:
|
||||||
"""Return if the entity should be enabled when first added to the entity registry."""
|
"""Return if the entity should be enabled when first added to the entity registry."""
|
||||||
return self.meta.enabled_default
|
return self.meta.entity_registry_enabled_default
|
||||||
|
|
||||||
async def async_update(self) -> None:
|
async def async_update(self) -> None:
|
||||||
"""Update state."""
|
"""Update state."""
|
||||||
@ -599,6 +600,6 @@ class HuaweiLteSensor(HuaweiLteBaseEntity, SensorEntity):
|
|||||||
self._available = value is not None
|
self._available = value is not None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def entity_category(self) -> str | None:
|
def entity_category(self) -> EntityCategory | None:
|
||||||
"""Return category of entity, if any."""
|
"""Return category of entity, if any."""
|
||||||
return self.meta.entity_category
|
return self.meta.entity_category
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
"""Support for Huawei LTE switches."""
|
"""Support for Huawei LTE switches."""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from dataclasses import dataclass, field
|
||||||
import logging
|
import logging
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
import attr
|
|
||||||
|
|
||||||
from homeassistant.components.switch import (
|
from homeassistant.components.switch import (
|
||||||
DOMAIN as SWITCH_DOMAIN,
|
DOMAIN as SWITCH_DOMAIN,
|
||||||
SwitchDeviceClass,
|
SwitchDeviceClass,
|
||||||
@ -37,14 +36,17 @@ async def async_setup_entry(
|
|||||||
async_add_entities(switches, True)
|
async_add_entities(switches, True)
|
||||||
|
|
||||||
|
|
||||||
@attr.s
|
@dataclass
|
||||||
class HuaweiLteBaseSwitch(HuaweiLteBaseEntity, SwitchEntity):
|
class HuaweiLteBaseSwitch(HuaweiLteBaseEntity, SwitchEntity):
|
||||||
"""Huawei LTE switch device base class."""
|
"""Huawei LTE switch device base class."""
|
||||||
|
|
||||||
key: str
|
key: str = field(init=False)
|
||||||
item: str
|
item: str = field(init=False)
|
||||||
_attr_device_class = SwitchDeviceClass.SWITCH
|
|
||||||
_raw_state: str | None = attr.ib(init=False, default=None)
|
_attr_device_class: SwitchDeviceClass = field(
|
||||||
|
default=SwitchDeviceClass.SWITCH, init=False
|
||||||
|
)
|
||||||
|
_raw_state: str | None = field(default=None, init=False)
|
||||||
|
|
||||||
def _turn(self, state: bool) -> None:
|
def _turn(self, state: bool) -> None:
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
@ -79,11 +81,11 @@ class HuaweiLteBaseSwitch(HuaweiLteBaseEntity, SwitchEntity):
|
|||||||
self._raw_state = str(value)
|
self._raw_state = str(value)
|
||||||
|
|
||||||
|
|
||||||
@attr.s
|
@dataclass
|
||||||
class HuaweiLteMobileDataSwitch(HuaweiLteBaseSwitch):
|
class HuaweiLteMobileDataSwitch(HuaweiLteBaseSwitch):
|
||||||
"""Huawei LTE mobile data switch device."""
|
"""Huawei LTE mobile data switch device."""
|
||||||
|
|
||||||
def __attrs_post_init__(self) -> None:
|
def __post_init__(self) -> None:
|
||||||
"""Initialize identifiers."""
|
"""Initialize identifiers."""
|
||||||
self.key = KEY_DIALUP_MOBILE_DATASWITCH
|
self.key = KEY_DIALUP_MOBILE_DATASWITCH
|
||||||
self.item = "dataswitch"
|
self.item = "dataswitch"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user