From e389ff253778d673c67e7ad7922bffb19b6ce7f6 Mon Sep 17 00:00:00 2001 From: Jan Bouwhuis Date: Thu, 24 Apr 2025 23:09:18 +0200 Subject: [PATCH] Allow float for device_tracker location accuracy (#143604) --- .../components/device_tracker/config_entry.py | 4 ++-- homeassistant/components/mqtt/device_tracker.py | 2 +- homeassistant/components/tile/device_tracker.py | 2 +- .../components/traccar_server/device_tracker.py | 2 +- .../components/tractive/device_tracker.py | 2 +- homeassistant/components/zone/__init__.py | 2 +- pylint/plugins/hass_enforce_type_hints.py | 2 +- .../device_tracker/test_config_entry.py | 16 ++++++++++++++++ .../components/owntracks/test_device_tracker.py | 2 +- tests/components/tile/conftest.py | 5 +++-- .../tile/snapshots/test_device_tracker.ambr | 2 +- 11 files changed, 29 insertions(+), 12 deletions(-) diff --git a/homeassistant/components/device_tracker/config_entry.py b/homeassistant/components/device_tracker/config_entry.py index db33d5038fc..b82cf0352a7 100644 --- a/homeassistant/components/device_tracker/config_entry.py +++ b/homeassistant/components/device_tracker/config_entry.py @@ -218,7 +218,7 @@ class TrackerEntity( entity_description: TrackerEntityDescription _attr_latitude: float | None = None - _attr_location_accuracy: int = 0 + _attr_location_accuracy: float = 0 _attr_location_name: str | None = None _attr_longitude: float | None = None _attr_source_type: SourceType = SourceType.GPS @@ -234,7 +234,7 @@ class TrackerEntity( return not self.should_poll @cached_property - def location_accuracy(self) -> int: + def location_accuracy(self) -> float: """Return the location accuracy of the device. Value in meters. diff --git a/homeassistant/components/mqtt/device_tracker.py b/homeassistant/components/mqtt/device_tracker.py index 9a10170641e..141e0478f2f 100644 --- a/homeassistant/components/mqtt/device_tracker.py +++ b/homeassistant/components/mqtt/device_tracker.py @@ -162,7 +162,7 @@ class MqttDeviceTracker(MqttEntity, TrackerEntity): ): latitude: float | None longitude: float | None - gps_accuracy: int + gps_accuracy: float # Reset manually set location to allow automatic zone detection self._attr_location_name = None if isinstance( diff --git a/homeassistant/components/tile/device_tracker.py b/homeassistant/components/tile/device_tracker.py index 66a3b8b0e27..c81c791cd5d 100644 --- a/homeassistant/components/tile/device_tracker.py +++ b/homeassistant/components/tile/device_tracker.py @@ -64,7 +64,7 @@ class TileDeviceTracker(TileEntity, TrackerEntity): ) self._attr_latitude = None if not self._tile.latitude else self._tile.latitude self._attr_location_accuracy = ( - 0 if not self._tile.accuracy else int(self._tile.accuracy) + 0 if not self._tile.accuracy else self._tile.accuracy ) self._attr_extra_state_attributes = { diff --git a/homeassistant/components/traccar_server/device_tracker.py b/homeassistant/components/traccar_server/device_tracker.py index 7f2a6dd7c40..33a7e511d09 100644 --- a/homeassistant/components/traccar_server/device_tracker.py +++ b/homeassistant/components/traccar_server/device_tracker.py @@ -54,6 +54,6 @@ class TraccarServerDeviceTracker(TraccarServerEntity, TrackerEntity): return self.traccar_position["longitude"] @property - def location_accuracy(self) -> int: + def location_accuracy(self) -> float: """Return the gps accuracy of the device.""" return self.traccar_position["accuracy"] diff --git a/homeassistant/components/tractive/device_tracker.py b/homeassistant/components/tractive/device_tracker.py index bd1380ade4c..09a4e3faf1f 100644 --- a/homeassistant/components/tractive/device_tracker.py +++ b/homeassistant/components/tractive/device_tracker.py @@ -49,7 +49,7 @@ class TractiveDeviceTracker(TractiveEntity, TrackerEntity): self._battery_level: int | None = item.hw_info.get("battery_level") self._attr_latitude = item.pos_report["latlong"][0] self._attr_longitude = item.pos_report["latlong"][1] - self._attr_location_accuracy: int = item.pos_report["pos_uncertainty"] + self._attr_location_accuracy: float = item.pos_report["pos_uncertainty"] self._source_type: str = item.pos_report["sensor_used"] self._attr_unique_id = item.trackable["_id"] diff --git a/homeassistant/components/zone/__init__.py b/homeassistant/components/zone/__init__.py index 42988f49dc0..6325f830ea0 100644 --- a/homeassistant/components/zone/__init__.py +++ b/homeassistant/components/zone/__init__.py @@ -115,7 +115,7 @@ DATA_ZONE_ENTITY_IDS: HassKey[list[str]] = HassKey(ZONE_ENTITY_IDS) @bind_hass def async_active_zone( - hass: HomeAssistant, latitude: float, longitude: float, radius: int = 0 + hass: HomeAssistant, latitude: float, longitude: float, radius: float = 0 ) -> State | None: """Find the active zone for given latitude, longitude. diff --git a/pylint/plugins/hass_enforce_type_hints.py b/pylint/plugins/hass_enforce_type_hints.py index 4f9f7603328..3e18aacaa93 100644 --- a/pylint/plugins/hass_enforce_type_hints.py +++ b/pylint/plugins/hass_enforce_type_hints.py @@ -1374,7 +1374,7 @@ _INHERITANCE_MATCH: dict[str, list[ClassTypeHintMatch]] = { ), TypeHintMatch( function_name="location_accuracy", - return_type="int", + return_type="float", ), TypeHintMatch( function_name="location_name", diff --git a/tests/components/device_tracker/test_config_entry.py b/tests/components/device_tracker/test_config_entry.py index fa1e65ded51..e792d239d59 100644 --- a/tests/components/device_tracker/test_config_entry.py +++ b/tests/components/device_tracker/test_config_entry.py @@ -146,12 +146,14 @@ class MockTrackerEntity(TrackerEntity): location_name: str | None = None, latitude: float | None = None, longitude: float | None = None, + location_accuracy: float = 0, ) -> None: """Initialize entity.""" self._battery_level = battery_level self._location_name = location_name self._latitude = latitude self._longitude = longitude + self._location_accuracy = location_accuracy @property def battery_level(self) -> int | None: @@ -181,6 +183,11 @@ class MockTrackerEntity(TrackerEntity): """Return longitude value of the device.""" return self._longitude + @property + def location_accuracy(self) -> float: + """Return the accuracy of the location in meters.""" + return self._location_accuracy + @pytest.fixture(name="battery_level") def battery_level_fixture() -> int | None: @@ -206,6 +213,12 @@ def longitude_fixture() -> float | None: return None +@pytest.fixture(name="location_accuracy") +def accuracy_fixture() -> float: + """Return the location accuracy of the entity for the test.""" + return 0 + + @pytest.fixture(name="tracker_entity") def tracker_entity_fixture( entity_id: str, @@ -213,6 +226,7 @@ def tracker_entity_fixture( location_name: str | None, latitude: float | None, longitude: float | None, + location_accuracy: float = 0, ) -> MockTrackerEntity: """Create a test tracker entity.""" entity = MockTrackerEntity( @@ -220,6 +234,7 @@ def tracker_entity_fixture( location_name=location_name, latitude=latitude, longitude=longitude, + location_accuracy=location_accuracy, ) entity.entity_id = entity_id return entity @@ -513,6 +528,7 @@ def test_tracker_entity() -> None: assert entity.battery_level is None assert entity.should_poll is False assert entity.force_update is True + assert entity.location_accuracy == 0 class MockEntity(TrackerEntity): """Mock tracker class.""" diff --git a/tests/components/owntracks/test_device_tracker.py b/tests/components/owntracks/test_device_tracker.py index a659244e0a0..41565c6b1fd 100644 --- a/tests/components/owntracks/test_device_tracker.py +++ b/tests/components/owntracks/test_device_tracker.py @@ -380,7 +380,7 @@ def assert_location_longitude(hass: HomeAssistant, longitude: float) -> None: assert state.attributes.get("longitude") == longitude -def assert_location_accuracy(hass: HomeAssistant, accuracy: int) -> None: +def assert_location_accuracy(hass: HomeAssistant, accuracy: float) -> None: """Test the assertion of a location accuracy.""" state = hass.states.get(DEVICE_TRACKER_STATE) assert state.attributes.get("gps_accuracy") == accuracy diff --git a/tests/components/tile/conftest.py b/tests/components/tile/conftest.py index 4391853c878..21ca2c90fa1 100644 --- a/tests/components/tile/conftest.py +++ b/tests/components/tile/conftest.py @@ -26,6 +26,7 @@ def tile() -> AsyncMock: mock.latitude = 1 mock.longitude = 1 mock.altitude = 0 + mock.accuracy = 13.496111 mock.lost = False mock.last_timestamp = datetime(2020, 8, 12, 17, 55, 26) mock.lost_timestamp = datetime(1969, 12, 31, 19, 0, 0) @@ -42,8 +43,8 @@ def tile() -> AsyncMock: "hardware_version": "02.09", "kind": "TILE", "last_timestamp": datetime(2020, 8, 12, 17, 55, 26), - "latitude": 0, - "longitude": 0, + "latitude": 1, + "longitude": 1, "lost": False, "lost_timestamp": datetime(1969, 12, 31, 19, 0, 0), "name": "Wallet", diff --git a/tests/components/tile/snapshots/test_device_tracker.ambr b/tests/components/tile/snapshots/test_device_tracker.ambr index f5de1511c99..3f94f679f10 100644 --- a/tests/components/tile/snapshots/test_device_tracker.ambr +++ b/tests/components/tile/snapshots/test_device_tracker.ambr @@ -38,7 +38,7 @@ 'attributes': ReadOnlyDict({ 'altitude': 0, 'friendly_name': 'Wallet', - 'gps_accuracy': 1, + 'gps_accuracy': 13.496111, 'is_lost': False, 'last_lost_timestamp': datetime.datetime(1970, 1, 1, 3, 0, tzinfo=datetime.timezone.utc), 'last_timestamp': datetime.datetime(2020, 8, 13, 0, 55, 26, tzinfo=datetime.timezone.utc),