From a6c5f09689e2743e97d652eb71203e702165efd2 Mon Sep 17 00:00:00 2001 From: Luis Teixeira Date: Sat, 11 Oct 2025 13:00:52 +0100 Subject: [PATCH 01/16] Added LTE sensors --- custom_components/tplink_router/sensor.py | 140 +++++++++++++++++++++- 1 file changed, 138 insertions(+), 2 deletions(-) diff --git a/custom_components/tplink_router/sensor.py b/custom_components/tplink_router/sensor.py index 74707eb..bbe5254 100644 --- a/custom_components/tplink_router/sensor.py +++ b/custom_components/tplink_router/sensor.py @@ -6,14 +6,14 @@ SensorEntity, SensorEntityDescription, ) -from homeassistant.const import PERCENTAGE +from homeassistant.const import PERCENTAGE, DATA_RATE_BYTES_PER_SECOND, SIGNAL_STRENGTH_DECIBELS_MILLIWATT from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from .const import DOMAIN from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .coordinator import TPLinkRouterCoordinator -from tplinkrouterc6u import Status, IPv4Status +from tplinkrouterc6u import Status, IPv4Status, LTEStatus @dataclass @@ -25,6 +25,9 @@ class TPLinkRouterSensorRequiredKeysMixin: class TPLinkRouterIpv4SensorRequiredKeysMixin: value: Callable[[IPv4Status], Any] +@dataclass +class TPLinkRouterLteSensorRequiredKeysMixin: + value: Callable[[LTEStatus], Any] @dataclass class TPLinkRouterSensorEntityDescription( @@ -43,6 +46,13 @@ class TPLinkRouterIpv4SensorEntityDescription( sensor_type: str = "ipv4_status" +@dataclass +class TPLinkRouterLteSensorEntityDescription( + SensorEntityDescription, TPLinkRouterLteSensorRequiredKeysMixin +): + """A class that describes LTE entities.""" + + sensor_type: str = "lte_status" SENSOR_TYPES: tuple[TPLinkRouterSensorEntityDescription, ...] = ( TPLinkRouterSensorEntityDescription( @@ -106,6 +116,101 @@ class TPLinkRouterIpv4SensorEntityDescription( ), ) +LTE_SENSOR_TYPES: tuple[TPLinkRouterLteSensorEntityDescription, ...] = ( + # 3G/4G cellular data sensors: + TPLinkRouterLteSensorEntityDescription( + key="enable", + name="LTE Enabled", + icon="mdi:sim-outline", + value=lambda status: status.enable, + ), + TPLinkRouterLteSensorEntityDescription( + key="connect_status", + name="LTE Connection Status", + icon="mdi:sim-outline", + value=lambda status: status.connect_status, + ), + TPLinkRouterLteSensorEntityDescription( + key="network_type", + name="LTE Network Type", + icon="mdi:sim-outline", + value=lambda status: status.network_type, + ), + TPLinkRouterLteSensorEntityDescription( + key="sim_status", + name="LTE SIM Status", + icon="mdi:sim-outline", + value=lambda status: status.sim_status, + ), + TPLinkRouterLteSensorEntityDescription( + key="total_statistics", + name="LTE Total Statistics", + icon="mdi:sim-outline", + state_class=SensorStateClass.TOTAL, + value=lambda status: status.total_statistics, + ), + TPLinkRouterLteSensorEntityDescription( + key="cur_rx_speed", + name="LTE Current RX Speed", + icon="mdi:sim-outline", + state_class=SensorStateClass.MEASUREMENT, + native_unit_of_measurement=DATA_RATE_BYTES_PER_SECOND, + value=lambda status: status.cur_rx_speed, + ), + TPLinkRouterLteSensorEntityDescription( + key="cur_tx_speed", + name="LTE Current TX Speed", + icon="mdi:sim-outline", + state_class=SensorStateClass.MEASUREMENT, + native_unit_of_measurement=DATA_RATE_BYTES_PER_SECOND, + value=lambda status: status.cur_tx_speed, + ), + TPLinkRouterLteSensorEntityDescription( + key="sms_unread_count", + name="Unread SMS", + icon="mdi:sim-outline", + state_class=SensorStateClass.TOTAL, + value=lambda status: status.sms_unread_count, + ), + TPLinkRouterLteSensorEntityDescription( + key="sig_level", + name="LTE Signal Level", + icon="mdi:sim-outline", + state_class=SensorStateClass.MEASUREMENT, + native_unit_of_measurement=PERCENTAGE, + value=lambda status: status.sig_level, + ), + TPLinkRouterLteSensorEntityDescription( + key="rsrp", + name="LTE RSRP", + icon="mdi:sim-outline", + state_class=SensorStateClass.MEASUREMENT, + native_unit_of_measurement=SIGNAL_STRENGTH_DECIBELS_MILLIWATT, + value=lambda status: status.rsrp, + ), + TPLinkRouterLteSensorEntityDescription( + key="rsrq", + name="LTE RSRQ", + icon="mdi:sim-outline", + state_class=SensorStateClass.MEASUREMENT, + native_unit_of_measurement=SIGNAL_STRENGTH_DECIBELS_MILLIWATT, + value=lambda status: status.rsrq, + ), + TPLinkRouterLteSensorEntityDescription( + key="snr", + name="LTE SNR", + icon="mdi:sim-outline", + state_class=SensorStateClass.MEASUREMENT, + native_unit_of_measurement=SIGNAL_STRENGTH_DECIBELS_MILLIWATT, + value=lambda status: status.snr, + ), + TPLinkRouterLteSensorEntityDescription( + key="isp_name", + name="LTE ISP Name", + icon="mdi:sim-outline", + value=lambda status: status.isp_name, + ), +) async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback @@ -117,6 +222,9 @@ async def async_setup_entry( for description in SENSOR_TYPES: sensors.append(TPLinkRouterSensor(coordinator, description)) + for description in LTE_SENSOR_TYPES: + sensors.append(TPLinkRouterSensor(coordinator, description)) + async_add_entities(sensors, False) @@ -147,3 +255,31 @@ def _handle_coordinator_update(self) -> None: def available(self) -> bool: """Return True if entity is available.""" return self.entity_description.value(self.coordinator.status) is not None + +class TPLinkRouterLteSensor( + CoordinatorEntity[TPLinkRouterCoordinator], SensorEntity +): + _attr_has_entity_name = True + entity_description: TPLinkRouterLteSensorEntityDescription + + def __init__( + self, + coordinator: TPLinkRouterCoordinator, + description: TPLinkRouterLteSensorEntityDescription, + ) -> None: + super().__init__(coordinator) + + self._attr_device_info = coordinator.device_info + self._attr_unique_id = f"{coordinator.unique_id}_{DOMAIN}_{description.key}" + self.entity_description = description + + @callback + def _handle_coordinator_update(self) -> None: + """Handle updated data from the coordinator.""" + self._attr_native_value = self.entity_description.value(self.coordinator.status) + self.async_write_ha_state() + + @property + def available(self) -> bool: + """Return True if entity is available.""" + return self.entity_description.value(self.coordinator.status) is not None From bcae74cecf8dc5306c9bbbdbc2f3a3dee61ef48f Mon Sep 17 00:00:00 2001 From: Luis Teixeira Date: Sat, 11 Oct 2025 13:23:04 +0100 Subject: [PATCH 02/16] Updated manifest --- custom_components/tplink_router/manifest.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/custom_components/tplink_router/manifest.json b/custom_components/tplink_router/manifest.json index 8b7284b..beb7b31 100644 --- a/custom_components/tplink_router/manifest.json +++ b/custom_components/tplink_router/manifest.json @@ -1,11 +1,11 @@ { "domain": "tplink_router", "name": "TP-Link Router", - "codeowners": ["@AlexandrErohin"], + "codeowners": ["@AlexandrErohin","@teixeluis"], "config_flow": true, - "documentation": "https://github.com/AlexandrErohin/home-assistant-tplink-router", + "documentation": "https://github.com/teixeluis/home-assistant-tplink-router", "iot_class": "local_polling", - "issue_tracker": "https://github.com/AlexandrErohin/home-assistant-tplink-router/issues", + "issue_tracker": "https://github.com/teixeluis/home-assistant-tplink-router/issues", "requirements": ["tplinkrouterc6u==5.9.3"], "version": "2.9.0" } \ No newline at end of file From e4911815de0ab71c6e0a134aea66afeb450b4368 Mon Sep 17 00:00:00 2001 From: Luis Teixeira Date: Sat, 11 Oct 2025 14:19:53 +0100 Subject: [PATCH 03/16] Bumped release version --- custom_components/tplink_router/manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/custom_components/tplink_router/manifest.json b/custom_components/tplink_router/manifest.json index beb7b31..a6bcd2e 100644 --- a/custom_components/tplink_router/manifest.json +++ b/custom_components/tplink_router/manifest.json @@ -7,5 +7,5 @@ "iot_class": "local_polling", "issue_tracker": "https://github.com/teixeluis/home-assistant-tplink-router/issues", "requirements": ["tplinkrouterc6u==5.9.3"], - "version": "2.9.0" + "version": "2.10.0" } \ No newline at end of file From bfca2a611c441005829b3ebd2fc4a72f95fdc7f5 Mon Sep 17 00:00:00 2001 From: Luis Teixeira Date: Sat, 11 Oct 2025 14:50:05 +0100 Subject: [PATCH 04/16] A few issues --- custom_components/tplink_router/sensor.py | 94 ++++------------------- 1 file changed, 17 insertions(+), 77 deletions(-) diff --git a/custom_components/tplink_router/sensor.py b/custom_components/tplink_router/sensor.py index bbe5254..653edce 100644 --- a/custom_components/tplink_router/sensor.py +++ b/custom_components/tplink_router/sensor.py @@ -6,7 +6,7 @@ SensorEntity, SensorEntityDescription, ) -from homeassistant.const import PERCENTAGE, DATA_RATE_BYTES_PER_SECOND, SIGNAL_STRENGTH_DECIBELS_MILLIWATT +from homeassistant.const import PERCENTAGE, BYTES_PER_SECOND, SIGNAL_STRENGTH_DECIBELS_MILLIWATT from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from .const import DOMAIN @@ -18,16 +18,7 @@ @dataclass class TPLinkRouterSensorRequiredKeysMixin: - value: Callable[[Status], Any] - - -@dataclass -class TPLinkRouterIpv4SensorRequiredKeysMixin: - value: Callable[[IPv4Status], Any] - -@dataclass -class TPLinkRouterLteSensorRequiredKeysMixin: - value: Callable[[LTEStatus], Any] + value: Callable[[Status,IPv4Status, LTEStatus], Any] @dataclass class TPLinkRouterSensorEntityDescription( @@ -38,22 +29,6 @@ class TPLinkRouterSensorEntityDescription( sensor_type: str = "status" -@dataclass -class TPLinkRouterIpv4SensorEntityDescription( - SensorEntityDescription, TPLinkRouterIpv4SensorRequiredKeysMixin -): - """A class that describes Ipv4Sensor entities.""" - - sensor_type: str = "ipv4_status" - -@dataclass -class TPLinkRouterLteSensorEntityDescription( - SensorEntityDescription, TPLinkRouterLteSensorRequiredKeysMixin -): - """A class that describes LTE entities.""" - - sensor_type: str = "lte_status" - SENSOR_TYPES: tuple[TPLinkRouterSensorEntityDescription, ...] = ( TPLinkRouterSensorEntityDescription( key="guest_wifi_clients_total", @@ -114,65 +89,61 @@ class TPLinkRouterLteSensorEntityDescription( icon="mdi:wan", value=lambda status: status.conn_type, ), -) - -LTE_SENSOR_TYPES: tuple[TPLinkRouterLteSensorEntityDescription, ...] = ( - # 3G/4G cellular data sensors: - TPLinkRouterLteSensorEntityDescription( + TPLinkRouterSensorEntityDescription( key="enable", name="LTE Enabled", icon="mdi:sim-outline", value=lambda status: status.enable, ), - TPLinkRouterLteSensorEntityDescription( + TPLinkRouterSensorEntityDescription( key="connect_status", name="LTE Connection Status", icon="mdi:sim-outline", value=lambda status: status.connect_status, ), - TPLinkRouterLteSensorEntityDescription( + TPLinkRouterSensorEntityDescription( key="network_type", name="LTE Network Type", icon="mdi:sim-outline", value=lambda status: status.network_type, ), - TPLinkRouterLteSensorEntityDescription( + TPLinkRouterSensorEntityDescription( key="sim_status", name="LTE SIM Status", icon="mdi:sim-outline", value=lambda status: status.sim_status, ), - TPLinkRouterLteSensorEntityDescription( + TPLinkRouterSensorEntityDescription( key="total_statistics", name="LTE Total Statistics", icon="mdi:sim-outline", state_class=SensorStateClass.TOTAL, value=lambda status: status.total_statistics, ), - TPLinkRouterLteSensorEntityDescription( + TPLinkRouterSensorEntityDescription( key="cur_rx_speed", name="LTE Current RX Speed", icon="mdi:sim-outline", state_class=SensorStateClass.MEASUREMENT, - native_unit_of_measurement=DATA_RATE_BYTES_PER_SECOND, + native_unit_of_measurement=BYTES_PER_SECOND, value=lambda status: status.cur_rx_speed, ), - TPLinkRouterLteSensorEntityDescription( + TPLinkRouterSensorEntityDescription( key="cur_tx_speed", name="LTE Current TX Speed", icon="mdi:sim-outline", state_class=SensorStateClass.MEASUREMENT, - native_unit_of_measurement=DATA_RATE_BYTES_PER_SECOND, + native_unit_of_measurement=BYTES_PER_SECOND, value=lambda status: status.cur_tx_speed, ), - TPLinkRouterLteSensorEntityDescription( + TPLinkRouterSensorEntityDescription( key="sms_unread_count", name="Unread SMS", icon="mdi:sim-outline", state_class=SensorStateClass.TOTAL, value=lambda status: status.sms_unread_count, ), - TPLinkRouterLteSensorEntityDescription( + TPLinkRouterSensorEntityDescription( key="sig_level", name="LTE Signal Level", icon="mdi:sim-outline", @@ -180,7 +151,7 @@ class TPLinkRouterLteSensorEntityDescription( native_unit_of_measurement=PERCENTAGE, value=lambda status: status.sig_level, ), - TPLinkRouterLteSensorEntityDescription( + TPLinkRouterSensorEntityDescription( key="rsrp", name="LTE RSRP", icon="mdi:sim-outline", @@ -188,7 +159,7 @@ class TPLinkRouterLteSensorEntityDescription( native_unit_of_measurement=SIGNAL_STRENGTH_DECIBELS_MILLIWATT, value=lambda status: status.rsrp, ), - TPLinkRouterLteSensorEntityDescription( + TPLinkRouterSensorEntityDescription( key="rsrq", name="LTE RSRQ", icon="mdi:sim-outline", @@ -196,7 +167,7 @@ class TPLinkRouterLteSensorEntityDescription( native_unit_of_measurement=SIGNAL_STRENGTH_DECIBELS_MILLIWATT, value=lambda status: status.rsrq, ), - TPLinkRouterLteSensorEntityDescription( + TPLinkRouterSensorEntityDescription( key="snr", name="LTE SNR", icon="mdi:sim-outline", @@ -204,7 +175,7 @@ class TPLinkRouterLteSensorEntityDescription( native_unit_of_measurement=SIGNAL_STRENGTH_DECIBELS_MILLIWATT, value=lambda status: status.snr, ), - TPLinkRouterLteSensorEntityDescription( + TPLinkRouterSensorEntityDescription( key="isp_name", name="LTE ISP Name", icon="mdi:sim-outline", @@ -222,9 +193,6 @@ async def async_setup_entry( for description in SENSOR_TYPES: sensors.append(TPLinkRouterSensor(coordinator, description)) - for description in LTE_SENSOR_TYPES: - sensors.append(TPLinkRouterSensor(coordinator, description)) - async_add_entities(sensors, False) @@ -255,31 +223,3 @@ def _handle_coordinator_update(self) -> None: def available(self) -> bool: """Return True if entity is available.""" return self.entity_description.value(self.coordinator.status) is not None - -class TPLinkRouterLteSensor( - CoordinatorEntity[TPLinkRouterCoordinator], SensorEntity -): - _attr_has_entity_name = True - entity_description: TPLinkRouterLteSensorEntityDescription - - def __init__( - self, - coordinator: TPLinkRouterCoordinator, - description: TPLinkRouterLteSensorEntityDescription, - ) -> None: - super().__init__(coordinator) - - self._attr_device_info = coordinator.device_info - self._attr_unique_id = f"{coordinator.unique_id}_{DOMAIN}_{description.key}" - self.entity_description = description - - @callback - def _handle_coordinator_update(self) -> None: - """Handle updated data from the coordinator.""" - self._attr_native_value = self.entity_description.value(self.coordinator.status) - self.async_write_ha_state() - - @property - def available(self) -> bool: - """Return True if entity is available.""" - return self.entity_description.value(self.coordinator.status) is not None From 74de31edb38b8edebccc242f2a1d99d775c00315 Mon Sep 17 00:00:00 2001 From: Luis Teixeira Date: Sat, 11 Oct 2025 15:17:59 +0100 Subject: [PATCH 05/16] bugfixing, troubleshooting --- custom_components/tplink_router/sensor.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/custom_components/tplink_router/sensor.py b/custom_components/tplink_router/sensor.py index 653edce..e4d3b84 100644 --- a/custom_components/tplink_router/sensor.py +++ b/custom_components/tplink_router/sensor.py @@ -6,7 +6,7 @@ SensorEntity, SensorEntityDescription, ) -from homeassistant.const import PERCENTAGE, BYTES_PER_SECOND, SIGNAL_STRENGTH_DECIBELS_MILLIWATT +from homeassistant.const import PERCENTAGE, SIGNAL_STRENGTH_DECIBELS_MILLIWATT, UnitOfDataRate from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from .const import DOMAIN @@ -15,10 +15,13 @@ from .coordinator import TPLinkRouterCoordinator from tplinkrouterc6u import Status, IPv4Status, LTEStatus +@dataclass +class CombinedStatus(Status, IPv4Status, LTEStatus): + pass @dataclass class TPLinkRouterSensorRequiredKeysMixin: - value: Callable[[Status,IPv4Status, LTEStatus], Any] + value: Callable[[CombinedStatus], Any] @dataclass class TPLinkRouterSensorEntityDescription( @@ -125,7 +128,7 @@ class TPLinkRouterSensorEntityDescription( name="LTE Current RX Speed", icon="mdi:sim-outline", state_class=SensorStateClass.MEASUREMENT, - native_unit_of_measurement=BYTES_PER_SECOND, + native_unit_of_measurement=UnitOfDataRate.BYTES_PER_SECOND, value=lambda status: status.cur_rx_speed, ), TPLinkRouterSensorEntityDescription( @@ -133,7 +136,7 @@ class TPLinkRouterSensorEntityDescription( name="LTE Current TX Speed", icon="mdi:sim-outline", state_class=SensorStateClass.MEASUREMENT, - native_unit_of_measurement=BYTES_PER_SECOND, + native_unit_of_measurement=UnitOfDataRate.BYTES_PER_SECOND, value=lambda status: status.cur_tx_speed, ), TPLinkRouterSensorEntityDescription( From d188a94e815065cbb95ac4c78bfbcca9d208a9a9 Mon Sep 17 00:00:00 2001 From: Luis Teixeira Date: Sat, 11 Oct 2025 22:16:11 +0100 Subject: [PATCH 06/16] Initial working version --- custom_components/tplink_router/sensor.py | 30 ++++++++++------------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/custom_components/tplink_router/sensor.py b/custom_components/tplink_router/sensor.py index e4d3b84..c5ebb74 100644 --- a/custom_components/tplink_router/sensor.py +++ b/custom_components/tplink_router/sensor.py @@ -13,15 +13,11 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .coordinator import TPLinkRouterCoordinator -from tplinkrouterc6u import Status, IPv4Status, LTEStatus - -@dataclass -class CombinedStatus(Status, IPv4Status, LTEStatus): - pass +from tplinkrouterc6u import Status @dataclass class TPLinkRouterSensorRequiredKeysMixin: - value: Callable[[CombinedStatus], Any] + value: Callable[[Status], Any] @dataclass class TPLinkRouterSensorEntityDescription( @@ -93,19 +89,19 @@ class TPLinkRouterSensorEntityDescription( value=lambda status: status.conn_type, ), TPLinkRouterSensorEntityDescription( - key="enable", + key="lte_enabled", name="LTE Enabled", icon="mdi:sim-outline", value=lambda status: status.enable, ), TPLinkRouterSensorEntityDescription( - key="connect_status", + key="lte_connect_status", name="LTE Connection Status", icon="mdi:sim-outline", value=lambda status: status.connect_status, ), TPLinkRouterSensorEntityDescription( - key="network_type", + key="lte_network_type", name="LTE Network Type", icon="mdi:sim-outline", value=lambda status: status.network_type, @@ -117,14 +113,14 @@ class TPLinkRouterSensorEntityDescription( value=lambda status: status.sim_status, ), TPLinkRouterSensorEntityDescription( - key="total_statistics", + key="lte_total_statistics", name="LTE Total Statistics", icon="mdi:sim-outline", state_class=SensorStateClass.TOTAL, value=lambda status: status.total_statistics, ), TPLinkRouterSensorEntityDescription( - key="cur_rx_speed", + key="lte_cur_rx_speed", name="LTE Current RX Speed", icon="mdi:sim-outline", state_class=SensorStateClass.MEASUREMENT, @@ -132,7 +128,7 @@ class TPLinkRouterSensorEntityDescription( value=lambda status: status.cur_rx_speed, ), TPLinkRouterSensorEntityDescription( - key="cur_tx_speed", + key="lte_cur_tx_speed", name="LTE Current TX Speed", icon="mdi:sim-outline", state_class=SensorStateClass.MEASUREMENT, @@ -147,7 +143,7 @@ class TPLinkRouterSensorEntityDescription( value=lambda status: status.sms_unread_count, ), TPLinkRouterSensorEntityDescription( - key="sig_level", + key="lte_sig_level", name="LTE Signal Level", icon="mdi:sim-outline", state_class=SensorStateClass.MEASUREMENT, @@ -155,7 +151,7 @@ class TPLinkRouterSensorEntityDescription( value=lambda status: status.sig_level, ), TPLinkRouterSensorEntityDescription( - key="rsrp", + key="lte_rsrp", name="LTE RSRP", icon="mdi:sim-outline", state_class=SensorStateClass.MEASUREMENT, @@ -163,7 +159,7 @@ class TPLinkRouterSensorEntityDescription( value=lambda status: status.rsrp, ), TPLinkRouterSensorEntityDescription( - key="rsrq", + key="lte_rsrq", name="LTE RSRQ", icon="mdi:sim-outline", state_class=SensorStateClass.MEASUREMENT, @@ -171,7 +167,7 @@ class TPLinkRouterSensorEntityDescription( value=lambda status: status.rsrq, ), TPLinkRouterSensorEntityDescription( - key="snr", + key="lte_snr", name="LTE SNR", icon="mdi:sim-outline", state_class=SensorStateClass.MEASUREMENT, @@ -179,7 +175,7 @@ class TPLinkRouterSensorEntityDescription( value=lambda status: status.snr, ), TPLinkRouterSensorEntityDescription( - key="isp_name", + key="lte_isp_name", name="LTE ISP Name", icon="mdi:sim-outline", value=lambda status: status.isp_name, From b495693cfd693bea19f2e58d734348dd18b49ef4 Mon Sep 17 00:00:00 2001 From: Alex Erohin Date: Sun, 12 Oct 2025 12:46:03 +0300 Subject: [PATCH 07/16] update README --- README.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/README.md b/README.md index 544bc57..0cbbfe3 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,21 @@ If you forget to enable it back - it would be automatically enable after 20 minu - Memory used - Connection Type +For LTE Routers +- LTE Enabled +- LTE Connection Status +- LTE Network Type +- LTE SIM Status +- LTE Total Statistics +- LTE Current RX Speed +- LTE Current TX Speed +- Unread SMS +- LTE Signal Level +- LTE RSRP +- LTE RSRQ +- LTE SNR +- LTE ISP Name + ### Device Tracker - Track connected to router devices by MAC address with connection information From 7a144e0893bee5037c920599efdf561e7b80ee95 Mon Sep 17 00:00:00 2001 From: Luis Teixeira Date: Sun, 12 Oct 2025 12:34:43 +0100 Subject: [PATCH 08/16] Revert "Initial working version" This reverts commit d188a94e815065cbb95ac4c78bfbcca9d208a9a9. --- custom_components/tplink_router/sensor.py | 30 +++++++++++++---------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/custom_components/tplink_router/sensor.py b/custom_components/tplink_router/sensor.py index c5ebb74..e4d3b84 100644 --- a/custom_components/tplink_router/sensor.py +++ b/custom_components/tplink_router/sensor.py @@ -13,11 +13,15 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .coordinator import TPLinkRouterCoordinator -from tplinkrouterc6u import Status +from tplinkrouterc6u import Status, IPv4Status, LTEStatus + +@dataclass +class CombinedStatus(Status, IPv4Status, LTEStatus): + pass @dataclass class TPLinkRouterSensorRequiredKeysMixin: - value: Callable[[Status], Any] + value: Callable[[CombinedStatus], Any] @dataclass class TPLinkRouterSensorEntityDescription( @@ -89,19 +93,19 @@ class TPLinkRouterSensorEntityDescription( value=lambda status: status.conn_type, ), TPLinkRouterSensorEntityDescription( - key="lte_enabled", + key="enable", name="LTE Enabled", icon="mdi:sim-outline", value=lambda status: status.enable, ), TPLinkRouterSensorEntityDescription( - key="lte_connect_status", + key="connect_status", name="LTE Connection Status", icon="mdi:sim-outline", value=lambda status: status.connect_status, ), TPLinkRouterSensorEntityDescription( - key="lte_network_type", + key="network_type", name="LTE Network Type", icon="mdi:sim-outline", value=lambda status: status.network_type, @@ -113,14 +117,14 @@ class TPLinkRouterSensorEntityDescription( value=lambda status: status.sim_status, ), TPLinkRouterSensorEntityDescription( - key="lte_total_statistics", + key="total_statistics", name="LTE Total Statistics", icon="mdi:sim-outline", state_class=SensorStateClass.TOTAL, value=lambda status: status.total_statistics, ), TPLinkRouterSensorEntityDescription( - key="lte_cur_rx_speed", + key="cur_rx_speed", name="LTE Current RX Speed", icon="mdi:sim-outline", state_class=SensorStateClass.MEASUREMENT, @@ -128,7 +132,7 @@ class TPLinkRouterSensorEntityDescription( value=lambda status: status.cur_rx_speed, ), TPLinkRouterSensorEntityDescription( - key="lte_cur_tx_speed", + key="cur_tx_speed", name="LTE Current TX Speed", icon="mdi:sim-outline", state_class=SensorStateClass.MEASUREMENT, @@ -143,7 +147,7 @@ class TPLinkRouterSensorEntityDescription( value=lambda status: status.sms_unread_count, ), TPLinkRouterSensorEntityDescription( - key="lte_sig_level", + key="sig_level", name="LTE Signal Level", icon="mdi:sim-outline", state_class=SensorStateClass.MEASUREMENT, @@ -151,7 +155,7 @@ class TPLinkRouterSensorEntityDescription( value=lambda status: status.sig_level, ), TPLinkRouterSensorEntityDescription( - key="lte_rsrp", + key="rsrp", name="LTE RSRP", icon="mdi:sim-outline", state_class=SensorStateClass.MEASUREMENT, @@ -159,7 +163,7 @@ class TPLinkRouterSensorEntityDescription( value=lambda status: status.rsrp, ), TPLinkRouterSensorEntityDescription( - key="lte_rsrq", + key="rsrq", name="LTE RSRQ", icon="mdi:sim-outline", state_class=SensorStateClass.MEASUREMENT, @@ -167,7 +171,7 @@ class TPLinkRouterSensorEntityDescription( value=lambda status: status.rsrq, ), TPLinkRouterSensorEntityDescription( - key="lte_snr", + key="snr", name="LTE SNR", icon="mdi:sim-outline", state_class=SensorStateClass.MEASUREMENT, @@ -175,7 +179,7 @@ class TPLinkRouterSensorEntityDescription( value=lambda status: status.snr, ), TPLinkRouterSensorEntityDescription( - key="lte_isp_name", + key="isp_name", name="LTE ISP Name", icon="mdi:sim-outline", value=lambda status: status.isp_name, From 4134d64d332b0148d26997bee0b22d8fceb7dbd2 Mon Sep 17 00:00:00 2001 From: Luis Teixeira Date: Sun, 12 Oct 2025 12:34:49 +0100 Subject: [PATCH 09/16] Revert "bugfixing, troubleshooting" This reverts commit 74de31edb38b8edebccc242f2a1d99d775c00315. --- custom_components/tplink_router/sensor.py | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/custom_components/tplink_router/sensor.py b/custom_components/tplink_router/sensor.py index e4d3b84..653edce 100644 --- a/custom_components/tplink_router/sensor.py +++ b/custom_components/tplink_router/sensor.py @@ -6,7 +6,7 @@ SensorEntity, SensorEntityDescription, ) -from homeassistant.const import PERCENTAGE, SIGNAL_STRENGTH_DECIBELS_MILLIWATT, UnitOfDataRate +from homeassistant.const import PERCENTAGE, BYTES_PER_SECOND, SIGNAL_STRENGTH_DECIBELS_MILLIWATT from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from .const import DOMAIN @@ -15,13 +15,10 @@ from .coordinator import TPLinkRouterCoordinator from tplinkrouterc6u import Status, IPv4Status, LTEStatus -@dataclass -class CombinedStatus(Status, IPv4Status, LTEStatus): - pass @dataclass class TPLinkRouterSensorRequiredKeysMixin: - value: Callable[[CombinedStatus], Any] + value: Callable[[Status,IPv4Status, LTEStatus], Any] @dataclass class TPLinkRouterSensorEntityDescription( @@ -128,7 +125,7 @@ class TPLinkRouterSensorEntityDescription( name="LTE Current RX Speed", icon="mdi:sim-outline", state_class=SensorStateClass.MEASUREMENT, - native_unit_of_measurement=UnitOfDataRate.BYTES_PER_SECOND, + native_unit_of_measurement=BYTES_PER_SECOND, value=lambda status: status.cur_rx_speed, ), TPLinkRouterSensorEntityDescription( @@ -136,7 +133,7 @@ class TPLinkRouterSensorEntityDescription( name="LTE Current TX Speed", icon="mdi:sim-outline", state_class=SensorStateClass.MEASUREMENT, - native_unit_of_measurement=UnitOfDataRate.BYTES_PER_SECOND, + native_unit_of_measurement=BYTES_PER_SECOND, value=lambda status: status.cur_tx_speed, ), TPLinkRouterSensorEntityDescription( From 509ea9dcdfd08aa14f930fdbf5ca5b55fd963d38 Mon Sep 17 00:00:00 2001 From: Luis Teixeira Date: Sun, 12 Oct 2025 12:34:53 +0100 Subject: [PATCH 10/16] Revert "A few issues" This reverts commit bfca2a611c441005829b3ebd2fc4a72f95fdc7f5. --- custom_components/tplink_router/sensor.py | 94 +++++++++++++++++++---- 1 file changed, 77 insertions(+), 17 deletions(-) diff --git a/custom_components/tplink_router/sensor.py b/custom_components/tplink_router/sensor.py index 653edce..bbe5254 100644 --- a/custom_components/tplink_router/sensor.py +++ b/custom_components/tplink_router/sensor.py @@ -6,7 +6,7 @@ SensorEntity, SensorEntityDescription, ) -from homeassistant.const import PERCENTAGE, BYTES_PER_SECOND, SIGNAL_STRENGTH_DECIBELS_MILLIWATT +from homeassistant.const import PERCENTAGE, DATA_RATE_BYTES_PER_SECOND, SIGNAL_STRENGTH_DECIBELS_MILLIWATT from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from .const import DOMAIN @@ -18,7 +18,16 @@ @dataclass class TPLinkRouterSensorRequiredKeysMixin: - value: Callable[[Status,IPv4Status, LTEStatus], Any] + value: Callable[[Status], Any] + + +@dataclass +class TPLinkRouterIpv4SensorRequiredKeysMixin: + value: Callable[[IPv4Status], Any] + +@dataclass +class TPLinkRouterLteSensorRequiredKeysMixin: + value: Callable[[LTEStatus], Any] @dataclass class TPLinkRouterSensorEntityDescription( @@ -29,6 +38,22 @@ class TPLinkRouterSensorEntityDescription( sensor_type: str = "status" +@dataclass +class TPLinkRouterIpv4SensorEntityDescription( + SensorEntityDescription, TPLinkRouterIpv4SensorRequiredKeysMixin +): + """A class that describes Ipv4Sensor entities.""" + + sensor_type: str = "ipv4_status" + +@dataclass +class TPLinkRouterLteSensorEntityDescription( + SensorEntityDescription, TPLinkRouterLteSensorRequiredKeysMixin +): + """A class that describes LTE entities.""" + + sensor_type: str = "lte_status" + SENSOR_TYPES: tuple[TPLinkRouterSensorEntityDescription, ...] = ( TPLinkRouterSensorEntityDescription( key="guest_wifi_clients_total", @@ -89,61 +114,65 @@ class TPLinkRouterSensorEntityDescription( icon="mdi:wan", value=lambda status: status.conn_type, ), - TPLinkRouterSensorEntityDescription( +) + +LTE_SENSOR_TYPES: tuple[TPLinkRouterLteSensorEntityDescription, ...] = ( + # 3G/4G cellular data sensors: + TPLinkRouterLteSensorEntityDescription( key="enable", name="LTE Enabled", icon="mdi:sim-outline", value=lambda status: status.enable, ), - TPLinkRouterSensorEntityDescription( + TPLinkRouterLteSensorEntityDescription( key="connect_status", name="LTE Connection Status", icon="mdi:sim-outline", value=lambda status: status.connect_status, ), - TPLinkRouterSensorEntityDescription( + TPLinkRouterLteSensorEntityDescription( key="network_type", name="LTE Network Type", icon="mdi:sim-outline", value=lambda status: status.network_type, ), - TPLinkRouterSensorEntityDescription( + TPLinkRouterLteSensorEntityDescription( key="sim_status", name="LTE SIM Status", icon="mdi:sim-outline", value=lambda status: status.sim_status, ), - TPLinkRouterSensorEntityDescription( + TPLinkRouterLteSensorEntityDescription( key="total_statistics", name="LTE Total Statistics", icon="mdi:sim-outline", state_class=SensorStateClass.TOTAL, value=lambda status: status.total_statistics, ), - TPLinkRouterSensorEntityDescription( + TPLinkRouterLteSensorEntityDescription( key="cur_rx_speed", name="LTE Current RX Speed", icon="mdi:sim-outline", state_class=SensorStateClass.MEASUREMENT, - native_unit_of_measurement=BYTES_PER_SECOND, + native_unit_of_measurement=DATA_RATE_BYTES_PER_SECOND, value=lambda status: status.cur_rx_speed, ), - TPLinkRouterSensorEntityDescription( + TPLinkRouterLteSensorEntityDescription( key="cur_tx_speed", name="LTE Current TX Speed", icon="mdi:sim-outline", state_class=SensorStateClass.MEASUREMENT, - native_unit_of_measurement=BYTES_PER_SECOND, + native_unit_of_measurement=DATA_RATE_BYTES_PER_SECOND, value=lambda status: status.cur_tx_speed, ), - TPLinkRouterSensorEntityDescription( + TPLinkRouterLteSensorEntityDescription( key="sms_unread_count", name="Unread SMS", icon="mdi:sim-outline", state_class=SensorStateClass.TOTAL, value=lambda status: status.sms_unread_count, ), - TPLinkRouterSensorEntityDescription( + TPLinkRouterLteSensorEntityDescription( key="sig_level", name="LTE Signal Level", icon="mdi:sim-outline", @@ -151,7 +180,7 @@ class TPLinkRouterSensorEntityDescription( native_unit_of_measurement=PERCENTAGE, value=lambda status: status.sig_level, ), - TPLinkRouterSensorEntityDescription( + TPLinkRouterLteSensorEntityDescription( key="rsrp", name="LTE RSRP", icon="mdi:sim-outline", @@ -159,7 +188,7 @@ class TPLinkRouterSensorEntityDescription( native_unit_of_measurement=SIGNAL_STRENGTH_DECIBELS_MILLIWATT, value=lambda status: status.rsrp, ), - TPLinkRouterSensorEntityDescription( + TPLinkRouterLteSensorEntityDescription( key="rsrq", name="LTE RSRQ", icon="mdi:sim-outline", @@ -167,7 +196,7 @@ class TPLinkRouterSensorEntityDescription( native_unit_of_measurement=SIGNAL_STRENGTH_DECIBELS_MILLIWATT, value=lambda status: status.rsrq, ), - TPLinkRouterSensorEntityDescription( + TPLinkRouterLteSensorEntityDescription( key="snr", name="LTE SNR", icon="mdi:sim-outline", @@ -175,7 +204,7 @@ class TPLinkRouterSensorEntityDescription( native_unit_of_measurement=SIGNAL_STRENGTH_DECIBELS_MILLIWATT, value=lambda status: status.snr, ), - TPLinkRouterSensorEntityDescription( + TPLinkRouterLteSensorEntityDescription( key="isp_name", name="LTE ISP Name", icon="mdi:sim-outline", @@ -193,6 +222,9 @@ async def async_setup_entry( for description in SENSOR_TYPES: sensors.append(TPLinkRouterSensor(coordinator, description)) + for description in LTE_SENSOR_TYPES: + sensors.append(TPLinkRouterSensor(coordinator, description)) + async_add_entities(sensors, False) @@ -223,3 +255,31 @@ def _handle_coordinator_update(self) -> None: def available(self) -> bool: """Return True if entity is available.""" return self.entity_description.value(self.coordinator.status) is not None + +class TPLinkRouterLteSensor( + CoordinatorEntity[TPLinkRouterCoordinator], SensorEntity +): + _attr_has_entity_name = True + entity_description: TPLinkRouterLteSensorEntityDescription + + def __init__( + self, + coordinator: TPLinkRouterCoordinator, + description: TPLinkRouterLteSensorEntityDescription, + ) -> None: + super().__init__(coordinator) + + self._attr_device_info = coordinator.device_info + self._attr_unique_id = f"{coordinator.unique_id}_{DOMAIN}_{description.key}" + self.entity_description = description + + @callback + def _handle_coordinator_update(self) -> None: + """Handle updated data from the coordinator.""" + self._attr_native_value = self.entity_description.value(self.coordinator.status) + self.async_write_ha_state() + + @property + def available(self) -> bool: + """Return True if entity is available.""" + return self.entity_description.value(self.coordinator.status) is not None From 78384533572541c2f57faab2a2d9939ba6b4a5ff Mon Sep 17 00:00:00 2001 From: Luis Teixeira Date: Sun, 12 Oct 2025 12:34:55 +0100 Subject: [PATCH 11/16] Revert "Bumped release version" This reverts commit e4911815de0ab71c6e0a134aea66afeb450b4368. --- custom_components/tplink_router/manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/custom_components/tplink_router/manifest.json b/custom_components/tplink_router/manifest.json index a6bcd2e..beb7b31 100644 --- a/custom_components/tplink_router/manifest.json +++ b/custom_components/tplink_router/manifest.json @@ -7,5 +7,5 @@ "iot_class": "local_polling", "issue_tracker": "https://github.com/teixeluis/home-assistant-tplink-router/issues", "requirements": ["tplinkrouterc6u==5.9.3"], - "version": "2.10.0" + "version": "2.9.0" } \ No newline at end of file From 0096fccef69c45a372024d1c4d22a49d90ea7061 Mon Sep 17 00:00:00 2001 From: Luis Teixeira Date: Sun, 12 Oct 2025 12:34:57 +0100 Subject: [PATCH 12/16] Revert "Updated manifest" This reverts commit bcae74cecf8dc5306c9bbbdbc2f3a3dee61ef48f. --- custom_components/tplink_router/manifest.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/custom_components/tplink_router/manifest.json b/custom_components/tplink_router/manifest.json index beb7b31..8b7284b 100644 --- a/custom_components/tplink_router/manifest.json +++ b/custom_components/tplink_router/manifest.json @@ -1,11 +1,11 @@ { "domain": "tplink_router", "name": "TP-Link Router", - "codeowners": ["@AlexandrErohin","@teixeluis"], + "codeowners": ["@AlexandrErohin"], "config_flow": true, - "documentation": "https://github.com/teixeluis/home-assistant-tplink-router", + "documentation": "https://github.com/AlexandrErohin/home-assistant-tplink-router", "iot_class": "local_polling", - "issue_tracker": "https://github.com/teixeluis/home-assistant-tplink-router/issues", + "issue_tracker": "https://github.com/AlexandrErohin/home-assistant-tplink-router/issues", "requirements": ["tplinkrouterc6u==5.9.3"], "version": "2.9.0" } \ No newline at end of file From 44b3000964c08368011075341f9598e77b454af0 Mon Sep 17 00:00:00 2001 From: Luis Teixeira Date: Sun, 12 Oct 2025 12:34:58 +0100 Subject: [PATCH 13/16] Revert "Added LTE sensors" This reverts commit a6c5f09689e2743e97d652eb71203e702165efd2. --- custom_components/tplink_router/sensor.py | 140 +--------------------- 1 file changed, 2 insertions(+), 138 deletions(-) diff --git a/custom_components/tplink_router/sensor.py b/custom_components/tplink_router/sensor.py index bbe5254..74707eb 100644 --- a/custom_components/tplink_router/sensor.py +++ b/custom_components/tplink_router/sensor.py @@ -6,14 +6,14 @@ SensorEntity, SensorEntityDescription, ) -from homeassistant.const import PERCENTAGE, DATA_RATE_BYTES_PER_SECOND, SIGNAL_STRENGTH_DECIBELS_MILLIWATT +from homeassistant.const import PERCENTAGE from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from .const import DOMAIN from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .coordinator import TPLinkRouterCoordinator -from tplinkrouterc6u import Status, IPv4Status, LTEStatus +from tplinkrouterc6u import Status, IPv4Status @dataclass @@ -25,9 +25,6 @@ class TPLinkRouterSensorRequiredKeysMixin: class TPLinkRouterIpv4SensorRequiredKeysMixin: value: Callable[[IPv4Status], Any] -@dataclass -class TPLinkRouterLteSensorRequiredKeysMixin: - value: Callable[[LTEStatus], Any] @dataclass class TPLinkRouterSensorEntityDescription( @@ -46,13 +43,6 @@ class TPLinkRouterIpv4SensorEntityDescription( sensor_type: str = "ipv4_status" -@dataclass -class TPLinkRouterLteSensorEntityDescription( - SensorEntityDescription, TPLinkRouterLteSensorRequiredKeysMixin -): - """A class that describes LTE entities.""" - - sensor_type: str = "lte_status" SENSOR_TYPES: tuple[TPLinkRouterSensorEntityDescription, ...] = ( TPLinkRouterSensorEntityDescription( @@ -116,101 +106,6 @@ class TPLinkRouterLteSensorEntityDescription( ), ) -LTE_SENSOR_TYPES: tuple[TPLinkRouterLteSensorEntityDescription, ...] = ( - # 3G/4G cellular data sensors: - TPLinkRouterLteSensorEntityDescription( - key="enable", - name="LTE Enabled", - icon="mdi:sim-outline", - value=lambda status: status.enable, - ), - TPLinkRouterLteSensorEntityDescription( - key="connect_status", - name="LTE Connection Status", - icon="mdi:sim-outline", - value=lambda status: status.connect_status, - ), - TPLinkRouterLteSensorEntityDescription( - key="network_type", - name="LTE Network Type", - icon="mdi:sim-outline", - value=lambda status: status.network_type, - ), - TPLinkRouterLteSensorEntityDescription( - key="sim_status", - name="LTE SIM Status", - icon="mdi:sim-outline", - value=lambda status: status.sim_status, - ), - TPLinkRouterLteSensorEntityDescription( - key="total_statistics", - name="LTE Total Statistics", - icon="mdi:sim-outline", - state_class=SensorStateClass.TOTAL, - value=lambda status: status.total_statistics, - ), - TPLinkRouterLteSensorEntityDescription( - key="cur_rx_speed", - name="LTE Current RX Speed", - icon="mdi:sim-outline", - state_class=SensorStateClass.MEASUREMENT, - native_unit_of_measurement=DATA_RATE_BYTES_PER_SECOND, - value=lambda status: status.cur_rx_speed, - ), - TPLinkRouterLteSensorEntityDescription( - key="cur_tx_speed", - name="LTE Current TX Speed", - icon="mdi:sim-outline", - state_class=SensorStateClass.MEASUREMENT, - native_unit_of_measurement=DATA_RATE_BYTES_PER_SECOND, - value=lambda status: status.cur_tx_speed, - ), - TPLinkRouterLteSensorEntityDescription( - key="sms_unread_count", - name="Unread SMS", - icon="mdi:sim-outline", - state_class=SensorStateClass.TOTAL, - value=lambda status: status.sms_unread_count, - ), - TPLinkRouterLteSensorEntityDescription( - key="sig_level", - name="LTE Signal Level", - icon="mdi:sim-outline", - state_class=SensorStateClass.MEASUREMENT, - native_unit_of_measurement=PERCENTAGE, - value=lambda status: status.sig_level, - ), - TPLinkRouterLteSensorEntityDescription( - key="rsrp", - name="LTE RSRP", - icon="mdi:sim-outline", - state_class=SensorStateClass.MEASUREMENT, - native_unit_of_measurement=SIGNAL_STRENGTH_DECIBELS_MILLIWATT, - value=lambda status: status.rsrp, - ), - TPLinkRouterLteSensorEntityDescription( - key="rsrq", - name="LTE RSRQ", - icon="mdi:sim-outline", - state_class=SensorStateClass.MEASUREMENT, - native_unit_of_measurement=SIGNAL_STRENGTH_DECIBELS_MILLIWATT, - value=lambda status: status.rsrq, - ), - TPLinkRouterLteSensorEntityDescription( - key="snr", - name="LTE SNR", - icon="mdi:sim-outline", - state_class=SensorStateClass.MEASUREMENT, - native_unit_of_measurement=SIGNAL_STRENGTH_DECIBELS_MILLIWATT, - value=lambda status: status.snr, - ), - TPLinkRouterLteSensorEntityDescription( - key="isp_name", - name="LTE ISP Name", - icon="mdi:sim-outline", - value=lambda status: status.isp_name, - ), -) async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback @@ -222,9 +117,6 @@ async def async_setup_entry( for description in SENSOR_TYPES: sensors.append(TPLinkRouterSensor(coordinator, description)) - for description in LTE_SENSOR_TYPES: - sensors.append(TPLinkRouterSensor(coordinator, description)) - async_add_entities(sensors, False) @@ -255,31 +147,3 @@ def _handle_coordinator_update(self) -> None: def available(self) -> bool: """Return True if entity is available.""" return self.entity_description.value(self.coordinator.status) is not None - -class TPLinkRouterLteSensor( - CoordinatorEntity[TPLinkRouterCoordinator], SensorEntity -): - _attr_has_entity_name = True - entity_description: TPLinkRouterLteSensorEntityDescription - - def __init__( - self, - coordinator: TPLinkRouterCoordinator, - description: TPLinkRouterLteSensorEntityDescription, - ) -> None: - super().__init__(coordinator) - - self._attr_device_info = coordinator.device_info - self._attr_unique_id = f"{coordinator.unique_id}_{DOMAIN}_{description.key}" - self.entity_description = description - - @callback - def _handle_coordinator_update(self) -> None: - """Handle updated data from the coordinator.""" - self._attr_native_value = self.entity_description.value(self.coordinator.status) - self.async_write_ha_state() - - @property - def available(self) -> bool: - """Return True if entity is available.""" - return self.entity_description.value(self.coordinator.status) is not None From 0b729a1584f48e4d0b5603b7c30890c90cad0ed1 Mon Sep 17 00:00:00 2001 From: Luis Teixeira Date: Sun, 12 Oct 2025 17:59:51 +0100 Subject: [PATCH 14/16] Added conversions and proper state name lookups on some LTE sensors. --- custom_components/tplink_router/sensor.py | 34 +++++++++++++++++++---- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/custom_components/tplink_router/sensor.py b/custom_components/tplink_router/sensor.py index 495028b..32ba6f4 100644 --- a/custom_components/tplink_router/sensor.py +++ b/custom_components/tplink_router/sensor.py @@ -6,7 +6,7 @@ SensorEntity, SensorEntityDescription, ) -from homeassistant.const import PERCENTAGE, SIGNAL_STRENGTH_DECIBELS_MILLIWATT, UnitOfDataRate +from homeassistant.const import PERCENTAGE, SIGNAL_STRENGTH_DECIBELS_MILLIWATT, UnitOfDataRate, UnitOfInformation from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from .const import DOMAIN @@ -106,6 +106,29 @@ class TPLinkRouterLTESensorEntityDescription( ), ) +network_types = { + 0: "No Service", + 1: "GSM", + 2: "WCDMA", + 3: "4G LTE", + 4: "TD-SCDMA", + 5: "CDMA 1x", + 6: "CDMA 1x Ev-Do", + 7: "4G+ LTE" +} + +sim_statuses = { + 0: "No SIM card detected or SIM card error.", + 1: "No SIM card detected.", + 2: "SIM card error.", + 3: "SIM card prepared.", + 4: "SIM locked.", + 5: "SIM unlocked. Authentication succeeded.", + 6: "PIN locked.", + 7: "SIM card is locked permanently.", + 8: "suspension of transmission", + 9: "Unopened" +} LTE_SENSOR_TYPES: tuple[TPLinkRouterLTESensorEntityDescription, ...] = ( TPLinkRouterLTESensorEntityDescription( @@ -124,19 +147,20 @@ class TPLinkRouterLTESensorEntityDescription( key="lte_network_type", name="LTE Network Type", icon="mdi:sim-outline", - value=lambda status: status.network_type, + value=lambda status: network_types[status.network_type], ), TPLinkRouterLTESensorEntityDescription( key="lte_sim_status", name="LTE SIM Status", icon="mdi:sim-outline", - value=lambda status: status.sim_status, + value=lambda status: sim_statuses[status.sim_status], ), TPLinkRouterLTESensorEntityDescription( key="lte_total_statistics", name="LTE Total Statistics", icon="mdi:sim-outline", state_class=SensorStateClass.TOTAL, + native_unit_of_measurement=UnitOfInformation.BYTES, value=lambda status: status.total_statistics, ), TPLinkRouterLTESensorEntityDescription( @@ -168,7 +192,7 @@ class TPLinkRouterLTESensorEntityDescription( icon="mdi:sim-outline", state_class=SensorStateClass.MEASUREMENT, native_unit_of_measurement=PERCENTAGE, - value=lambda status: status.sig_level, + value=lambda status: status.sig_level * 25, ), TPLinkRouterLTESensorEntityDescription( key="lte_rsrp", @@ -192,7 +216,7 @@ class TPLinkRouterLTESensorEntityDescription( icon="mdi:sim-outline", state_class=SensorStateClass.MEASUREMENT, native_unit_of_measurement=SIGNAL_STRENGTH_DECIBELS_MILLIWATT, - value=lambda status: status.snr, + value=lambda status: 0.1 * status.snr, ), TPLinkRouterLTESensorEntityDescription( key="lte_isp_name", From 133bb5681a62051f0739fcc016c0383f3bf5d72e Mon Sep 17 00:00:00 2001 From: Luis Teixeira Date: Sun, 12 Oct 2025 18:02:44 +0100 Subject: [PATCH 15/16] Version bump --- custom_components/tplink_router/manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/custom_components/tplink_router/manifest.json b/custom_components/tplink_router/manifest.json index 111d593..7fef0fb 100644 --- a/custom_components/tplink_router/manifest.json +++ b/custom_components/tplink_router/manifest.json @@ -7,5 +7,5 @@ "iot_class": "local_polling", "issue_tracker": "https://github.com/AlexandrErohin/home-assistant-tplink-router/issues", "requirements": ["tplinkrouterc6u==5.9.4"], - "version": "2.10.0" + "version": "2.11.0" } \ No newline at end of file From 5c14cf7b195e2c933509b32a62a3f14060531f87 Mon Sep 17 00:00:00 2001 From: Luis Teixeira Date: Thu, 16 Oct 2025 20:14:14 +0100 Subject: [PATCH 16/16] Small change, in adjustment to changes proposed by AlexandrErohin (https://github.com/AlexandrErohin/home-assistant-tplink-router/pull/244#discussion_r2435752841) and changes to the lib tplinkrouterc6u --- custom_components/tplink_router/sensor.py | 28 ++--------------------- 1 file changed, 2 insertions(+), 26 deletions(-) diff --git a/custom_components/tplink_router/sensor.py b/custom_components/tplink_router/sensor.py index 32ba6f4..777bee6 100644 --- a/custom_components/tplink_router/sensor.py +++ b/custom_components/tplink_router/sensor.py @@ -106,30 +106,6 @@ class TPLinkRouterLTESensorEntityDescription( ), ) -network_types = { - 0: "No Service", - 1: "GSM", - 2: "WCDMA", - 3: "4G LTE", - 4: "TD-SCDMA", - 5: "CDMA 1x", - 6: "CDMA 1x Ev-Do", - 7: "4G+ LTE" -} - -sim_statuses = { - 0: "No SIM card detected or SIM card error.", - 1: "No SIM card detected.", - 2: "SIM card error.", - 3: "SIM card prepared.", - 4: "SIM locked.", - 5: "SIM unlocked. Authentication succeeded.", - 6: "PIN locked.", - 7: "SIM card is locked permanently.", - 8: "suspension of transmission", - 9: "Unopened" -} - LTE_SENSOR_TYPES: tuple[TPLinkRouterLTESensorEntityDescription, ...] = ( TPLinkRouterLTESensorEntityDescription( key="lte_enabled", @@ -147,13 +123,13 @@ class TPLinkRouterLTESensorEntityDescription( key="lte_network_type", name="LTE Network Type", icon="mdi:sim-outline", - value=lambda status: network_types[status.network_type], + value=lambda status: status.network_type_info, ), TPLinkRouterLTESensorEntityDescription( key="lte_sim_status", name="LTE SIM Status", icon="mdi:sim-outline", - value=lambda status: sim_statuses[status.sim_status], + value=lambda status: status.sim_status_info, ), TPLinkRouterLTESensorEntityDescription( key="lte_total_statistics",