From 15bc29f8cac18ed22583b7c1a749050dfbc3f74c Mon Sep 17 00:00:00 2001
From: Jan Rieger <271149+jrieger@users.noreply.github.com>
Date: Wed, 5 Feb 2025 18:34:43 +0100
Subject: [PATCH] Add GPSd satellites sensors (#137320)

---
 homeassistant/components/gpsd/icons.json   |  6 ++++
 homeassistant/components/gpsd/sensor.py    | 36 ++++++++++++++++++++++
 homeassistant/components/gpsd/strings.json |  8 +++++
 3 files changed, 50 insertions(+)

diff --git a/homeassistant/components/gpsd/icons.json b/homeassistant/components/gpsd/icons.json
index 59d904f918c..3605bdc6d70 100644
--- a/homeassistant/components/gpsd/icons.json
+++ b/homeassistant/components/gpsd/icons.json
@@ -16,6 +16,12 @@
       },
       "elevation": {
         "default": "mdi:arrow-up-down"
+      },
+      "total_satellites": {
+        "default": "mdi:satellite-variant"
+      },
+      "used_satellites": {
+        "default": "mdi:satellite-variant"
       }
     }
   }
diff --git a/homeassistant/components/gpsd/sensor.py b/homeassistant/components/gpsd/sensor.py
index 1bac41ecaae..70d32f88a65 100644
--- a/homeassistant/components/gpsd/sensor.py
+++ b/homeassistant/components/gpsd/sensor.py
@@ -14,6 +14,7 @@ from homeassistant.components.sensor import (
     SensorDeviceClass,
     SensorEntity,
     SensorEntityDescription,
+    SensorStateClass,
 )
 from homeassistant.const import (
     ATTR_LATITUDE,
@@ -39,12 +40,31 @@ ATTR_CLIMB = "climb"
 ATTR_ELEVATION = "elevation"
 ATTR_GPS_TIME = "gps_time"
 ATTR_SPEED = "speed"
+ATTR_TOTAL_SATELLITES = "total_satellites"
+ATTR_USED_SATELLITES = "used_satellites"
 
 DEFAULT_NAME = "GPS"
 
 _MODE_VALUES = {2: "2d_fix", 3: "3d_fix"}
 
 
+def count_total_satellites_fn(agps_thread: AGPS3mechanism) -> int | None:
+    """Count the number of total satellites."""
+    satellites = agps_thread.data_stream.satellites
+    return None if satellites == "n/a" else len(satellites)
+
+
+def count_used_satellites_fn(agps_thread: AGPS3mechanism) -> int | None:
+    """Count the number of used satellites."""
+    satellites = agps_thread.data_stream.satellites
+    if satellites == "n/a":
+        return None
+
+    return sum(
+        1 for sat in satellites if isinstance(sat, dict) and sat.get("used", False)
+    )
+
+
 @dataclass(frozen=True, kw_only=True)
 class GpsdSensorDescription(SensorEntityDescription):
     """Class describing GPSD sensor entities."""
@@ -116,6 +136,22 @@ SENSOR_TYPES: tuple[GpsdSensorDescription, ...] = (
         suggested_display_precision=2,
         entity_registry_enabled_default=False,
     ),
+    GpsdSensorDescription(
+        key=ATTR_TOTAL_SATELLITES,
+        translation_key=ATTR_TOTAL_SATELLITES,
+        entity_category=EntityCategory.DIAGNOSTIC,
+        state_class=SensorStateClass.MEASUREMENT,
+        value_fn=count_total_satellites_fn,
+        entity_registry_enabled_default=False,
+    ),
+    GpsdSensorDescription(
+        key=ATTR_USED_SATELLITES,
+        translation_key=ATTR_USED_SATELLITES,
+        entity_category=EntityCategory.DIAGNOSTIC,
+        state_class=SensorStateClass.MEASUREMENT,
+        value_fn=count_used_satellites_fn,
+        entity_registry_enabled_default=False,
+    ),
 )
 
 
diff --git a/homeassistant/components/gpsd/strings.json b/homeassistant/components/gpsd/strings.json
index 867edf0b5a8..a5d6c570b54 100644
--- a/homeassistant/components/gpsd/strings.json
+++ b/homeassistant/components/gpsd/strings.json
@@ -50,6 +50,14 @@
           },
           "mode": { "name": "[%key:common::config_flow::data::mode%]" }
         }
+      },
+      "total_satellites": {
+        "name": "Total satellites",
+        "unit_of_measurement": "satellites"
+      },
+      "used_satellites": {
+        "name": "Used satellites",
+        "unit_of_measurement": "satellites"
       }
     }
   }
-- 
GitLab