From ce14544ec15c41099d12e5db285decd604b72c0c Mon Sep 17 00:00:00 2001 From: Michael <35783820+mib1185@users.noreply.github.com> Date: Sat, 6 Dec 2025 10:57:31 +0100 Subject: [PATCH] Add packet loss sensor to Ping integration (#158081) --- homeassistant/components/ping/helpers.py | 4 +- homeassistant/components/ping/icons.json | 9 ++++ homeassistant/components/ping/sensor.py | 12 ++++- homeassistant/components/ping/strings.json | 3 ++ .../ping/snapshots/test_sensor.ambr | 51 +++++++++++++++++++ tests/components/ping/test_sensor.py | 1 + 6 files changed, 78 insertions(+), 2 deletions(-) create mode 100644 homeassistant/components/ping/icons.json diff --git a/homeassistant/components/ping/helpers.py b/homeassistant/components/ping/helpers.py index ec77fe1b189..ff16db67dd3 100644 --- a/homeassistant/components/ping/helpers.py +++ b/homeassistant/components/ping/helpers.py @@ -64,10 +64,11 @@ class PingDataICMPLib(PingData): return _LOGGER.debug( - "async_ping returned: reachable=%s sent=%i received=%s", + "async_ping returned: reachable=%s sent=%i received=%s loss=%s", data.is_alive, data.packets_sent, data.packets_received, + data.packet_loss * 100, ) self.is_alive = data.is_alive @@ -80,6 +81,7 @@ class PingDataICMPLib(PingData): "max": data.max_rtt, "avg": data.avg_rtt, "jitter": data.jitter, + "loss": data.packet_loss * 100, } diff --git a/homeassistant/components/ping/icons.json b/homeassistant/components/ping/icons.json new file mode 100644 index 00000000000..8c84e8f4599 --- /dev/null +++ b/homeassistant/components/ping/icons.json @@ -0,0 +1,9 @@ +{ + "entity": { + "sensor": { + "loss": { + "default": "mdi:alert-circle-outline" + } + } + } +} diff --git a/homeassistant/components/ping/sensor.py b/homeassistant/components/ping/sensor.py index b3866c9f0e7..a86db25c957 100644 --- a/homeassistant/components/ping/sensor.py +++ b/homeassistant/components/ping/sensor.py @@ -10,7 +10,7 @@ from homeassistant.components.sensor import ( SensorStateClass, ) from homeassistant.config_entries import ConfigEntry -from homeassistant.const import EntityCategory, UnitOfTime +from homeassistant.const import PERCENTAGE, EntityCategory, UnitOfTime from homeassistant.core import HomeAssistant from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback @@ -82,6 +82,16 @@ SENSORS: tuple[PingSensorEntityDescription, ...] = ( value_fn=lambda result: result.data.get("jitter"), has_fn=lambda result: "jitter" in result.data, ), + PingSensorEntityDescription( + key="loss", + translation_key="loss", + native_unit_of_measurement=PERCENTAGE, + state_class=SensorStateClass.MEASUREMENT, + entity_registry_enabled_default=False, + entity_category=EntityCategory.DIAGNOSTIC, + value_fn=lambda result: result.data.get("loss"), + has_fn=lambda result: "loss" in result.data, + ), ) diff --git a/homeassistant/components/ping/strings.json b/homeassistant/components/ping/strings.json index ff3676bd471..3f04d728b68 100644 --- a/homeassistant/components/ping/strings.json +++ b/homeassistant/components/ping/strings.json @@ -22,6 +22,9 @@ "jitter": { "name": "Jitter" }, + "loss": { + "name": "Packet loss" + }, "round_trip_time_avg": { "name": "Round-trip time average" }, diff --git a/tests/components/ping/snapshots/test_sensor.ambr b/tests/components/ping/snapshots/test_sensor.ambr index 8cb8642f13a..7965fb69210 100644 --- a/tests/components/ping/snapshots/test_sensor.ambr +++ b/tests/components/ping/snapshots/test_sensor.ambr @@ -54,6 +54,57 @@ 'state': '3.5', }) # --- +# name: test_setup_and_update[packet_loss] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': dict({ + 'state_class': , + }), + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'sensor', + 'entity_category': , + 'entity_id': 'sensor.10_10_10_10_packet_loss', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Packet loss', + 'platform': 'ping', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': 'loss', + 'unit_of_measurement': '%', + }) +# --- +# name: test_setup_and_update[packet_loss].1 + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': '10.10.10.10 Packet loss', + 'state_class': , + 'unit_of_measurement': '%', + }), + 'context': , + 'entity_id': 'sensor.10_10_10_10_packet_loss', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': '0.0', + }) +# --- # name: test_setup_and_update[round_trip_time_average] EntityRegistryEntrySnapshot({ 'aliases': set({ diff --git a/tests/components/ping/test_sensor.py b/tests/components/ping/test_sensor.py index 95a31aa5c08..e203e473189 100644 --- a/tests/components/ping/test_sensor.py +++ b/tests/components/ping/test_sensor.py @@ -17,6 +17,7 @@ from homeassistant.helpers import entity_registry as er "round_trip_time_mean_deviation", # should be None in the snapshot "round_trip_time_minimum", "jitter", + "packet_loss", ], ) async def test_setup_and_update(