mirror of
https://github.com/home-assistant/core.git
synced 2025-07-22 12:47:08 +00:00
Improve Life360 address attribute (#76269)
This commit is contained in:
parent
d3f5ccfed8
commit
a38c125765
@ -64,10 +64,7 @@ class Life360Circle:
|
|||||||
class Life360Member:
|
class Life360Member:
|
||||||
"""Life360 Member data."""
|
"""Life360 Member data."""
|
||||||
|
|
||||||
# Don't include address field in eq comparison because it often changes (back and
|
address: str | None
|
||||||
# forth) between updates. If it was included there would be way more state changes
|
|
||||||
# and database updates than is useful.
|
|
||||||
address: str | None = field(compare=False)
|
|
||||||
at_loc_since: datetime
|
at_loc_since: datetime
|
||||||
battery_charging: bool
|
battery_charging: bool
|
||||||
battery_level: int
|
battery_level: int
|
||||||
@ -201,15 +198,12 @@ class Life360DataUpdateCoordinator(DataUpdateCoordinator[Life360Data]):
|
|||||||
|
|
||||||
place = loc["name"] or None
|
place = loc["name"] or None
|
||||||
|
|
||||||
if place:
|
address1: str | None = loc["address1"] or None
|
||||||
address: str | None = place
|
address2: str | None = loc["address2"] or None
|
||||||
|
if address1 and address2:
|
||||||
|
address: str | None = ", ".join([address1, address2])
|
||||||
else:
|
else:
|
||||||
address1 = loc["address1"] or None
|
address = address1 or address2
|
||||||
address2 = loc["address2"] or None
|
|
||||||
if address1 and address2:
|
|
||||||
address = ", ".join([address1, address2])
|
|
||||||
else:
|
|
||||||
address = address1 or address2
|
|
||||||
|
|
||||||
speed = max(0, float(loc["speed"]) * SPEED_FACTOR_MPH)
|
speed = max(0, float(loc["speed"]) * SPEED_FACTOR_MPH)
|
||||||
if self._hass.config.units.is_metric:
|
if self._hass.config.units.is_metric:
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from collections.abc import Mapping
|
from collections.abc import Mapping
|
||||||
|
from contextlib import suppress
|
||||||
from typing import Any, cast
|
from typing import Any, cast
|
||||||
|
|
||||||
from homeassistant.components.device_tracker import SourceType
|
from homeassistant.components.device_tracker import SourceType
|
||||||
@ -114,6 +115,17 @@ class Life360DeviceTracker(
|
|||||||
self._attr_name = self._data.name
|
self._attr_name = self._data.name
|
||||||
self._attr_entity_picture = self._data.entity_picture
|
self._attr_entity_picture = self._data.entity_picture
|
||||||
|
|
||||||
|
# Server sends a pair of address values on alternate updates. Keep the pair of
|
||||||
|
# values so they can be combined into the one address attribute.
|
||||||
|
# The pair will either be two different address values, or one address and a
|
||||||
|
# copy of the Place value (if the Member is in a Place.) In the latter case we
|
||||||
|
# won't duplicate the Place name, but rather just use one the address value. Use
|
||||||
|
# the value of None to hold one of the "slots" in the list so we'll know not to
|
||||||
|
# expect another address value.
|
||||||
|
if (address := self._data.address) == self._data.place:
|
||||||
|
address = None
|
||||||
|
self._addresses = [address]
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def _options(self) -> Mapping[str, Any]:
|
def _options(self) -> Mapping[str, Any]:
|
||||||
"""Shortcut to config entry options."""
|
"""Shortcut to config entry options."""
|
||||||
@ -160,6 +172,30 @@ class Life360DeviceTracker(
|
|||||||
for attr in _LOC_ATTRS:
|
for attr in _LOC_ATTRS:
|
||||||
setattr(self._data, attr, getattr(self._prev_data, attr))
|
setattr(self._data, attr, getattr(self._prev_data, attr))
|
||||||
|
|
||||||
|
else:
|
||||||
|
# Process address field.
|
||||||
|
# Check if we got the name of a Place, which we won't use.
|
||||||
|
if (address := self._data.address) == self._data.place:
|
||||||
|
address = None
|
||||||
|
if last_seen != prev_seen:
|
||||||
|
# We have new location data, so we might have a new pair of address
|
||||||
|
# values.
|
||||||
|
if address not in self._addresses:
|
||||||
|
# We do.
|
||||||
|
# Replace the old values with the first value of the new pair.
|
||||||
|
self._addresses = [address]
|
||||||
|
elif self._data.address != self._prev_data.address:
|
||||||
|
# Location data didn't change in general, but the address field did.
|
||||||
|
# There are three possibilities:
|
||||||
|
# 1. The new value is one of the pair we've already seen before.
|
||||||
|
# 2. The new value is the second of the pair we haven't seen yet.
|
||||||
|
# 3. The new value is the first of a new pair of values.
|
||||||
|
if address not in self._addresses:
|
||||||
|
if len(self._addresses) < 2:
|
||||||
|
self._addresses.append(address)
|
||||||
|
else:
|
||||||
|
self._addresses = [address]
|
||||||
|
|
||||||
self._prev_data = self._data
|
self._prev_data = self._data
|
||||||
|
|
||||||
super()._handle_coordinator_update()
|
super()._handle_coordinator_update()
|
||||||
@ -250,8 +286,26 @@ class Life360DeviceTracker(
|
|||||||
ATTR_SPEED: None,
|
ATTR_SPEED: None,
|
||||||
ATTR_WIFI_ON: None,
|
ATTR_WIFI_ON: None,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Generate address attribute from pair of address values.
|
||||||
|
# There may be two, one or no values. If there are two, sort the strings since
|
||||||
|
# one value is typically a numbered street address and the other is a street,
|
||||||
|
# town or state name, and it's helpful to start with the more detailed address
|
||||||
|
# value. Also, sorting helps to generate the same result if we get a location
|
||||||
|
# update, and the same pair is sent afterwards, but where the value that comes
|
||||||
|
# first is swapped vs the order they came in before the update.
|
||||||
|
address1: str | None = None
|
||||||
|
address2: str | None = None
|
||||||
|
with suppress(IndexError):
|
||||||
|
address1 = self._addresses[0]
|
||||||
|
address2 = self._addresses[1]
|
||||||
|
if address1 and address2:
|
||||||
|
address: str | None = " / ".join(sorted([address1, address2]))
|
||||||
|
else:
|
||||||
|
address = address1 or address2
|
||||||
|
|
||||||
return {
|
return {
|
||||||
ATTR_ADDRESS: self._data.address,
|
ATTR_ADDRESS: address,
|
||||||
ATTR_AT_LOC_SINCE: self._data.at_loc_since,
|
ATTR_AT_LOC_SINCE: self._data.at_loc_since,
|
||||||
ATTR_BATTERY_CHARGING: self._data.battery_charging,
|
ATTR_BATTERY_CHARGING: self._data.battery_charging,
|
||||||
ATTR_DRIVING: self.driving,
|
ATTR_DRIVING: self.driving,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user