1
mirror of https://github.com/home-assistant/core synced 2024-09-03 08:14:07 +02:00

Fix person device_trackers null (#31829)

This commit is contained in:
Paulus Schoutsen 2020-02-14 15:27:31 -08:00 committed by GitHub
parent f396f1cb18
commit 52b045ed30
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 49 additions and 10 deletions

View File

@ -88,7 +88,11 @@ _UNDEF = object()
async def async_create_person(hass, name, *, user_id=None, device_trackers=None): async def async_create_person(hass, name, *, user_id=None, device_trackers=None):
"""Create a new person.""" """Create a new person."""
await hass.data[DOMAIN][1].async_create_item( await hass.data[DOMAIN][1].async_create_item(
{ATTR_NAME: name, ATTR_USER_ID: user_id, "device_trackers": device_trackers} {
ATTR_NAME: name,
ATTR_USER_ID: user_id,
CONF_DEVICE_TRACKERS: device_trackers or [],
}
) )
@ -103,14 +107,14 @@ async def async_add_user_device_tracker(
if person.get(ATTR_USER_ID) != user_id: if person.get(ATTR_USER_ID) != user_id:
continue continue
device_trackers = person["device_trackers"] device_trackers = person[CONF_DEVICE_TRACKERS]
if device_tracker_entity_id in device_trackers: if device_tracker_entity_id in device_trackers:
return return
await coll.async_update_item( await coll.async_update_item(
person[collection.CONF_ID], person[collection.CONF_ID],
{"device_trackers": device_trackers + [device_tracker_entity_id]}, {CONF_DEVICE_TRACKERS: device_trackers + [device_tracker_entity_id]},
) )
break break
@ -161,6 +165,23 @@ class PersonStorageCollection(collection.StorageCollection):
super().__init__(store, logger, id_manager) super().__init__(store, logger, id_manager)
self.yaml_collection = yaml_collection self.yaml_collection = yaml_collection
async def _async_load_data(self) -> Optional[dict]:
"""Load the data.
A past bug caused onboarding to create invalid person objects.
This patches it up.
"""
data = await super()._async_load_data()
if data is None:
return data
for person in data["items"]:
if person[CONF_DEVICE_TRACKERS] is None:
person[CONF_DEVICE_TRACKERS] = []
return data
async def async_load(self) -> None: async def async_load(self) -> None:
"""Load the Storage collection.""" """Load the Storage collection."""
await super().async_load() await super().async_load()
@ -179,14 +200,16 @@ class PersonStorageCollection(collection.StorageCollection):
return return
for person in list(self.data.values()): for person in list(self.data.values()):
if entity_id not in person["device_trackers"]: if entity_id not in person[CONF_DEVICE_TRACKERS]:
continue continue
await self.async_update_item( await self.async_update_item(
person[collection.CONF_ID], person[collection.CONF_ID],
{ {
"device_trackers": [ CONF_DEVICE_TRACKERS: [
devt for devt in person["device_trackers"] if devt != entity_id devt
for devt in person[CONF_DEVICE_TRACKERS]
if devt != entity_id
] ]
}, },
) )
@ -408,7 +431,7 @@ class Person(RestoreEntity):
self._unsub_track_device() self._unsub_track_device()
self._unsub_track_device = None self._unsub_track_device = None
trackers = self._config.get(CONF_DEVICE_TRACKERS) trackers = self._config[CONF_DEVICE_TRACKERS]
if trackers: if trackers:
_LOGGER.debug("Subscribe to device trackers for %s", self.entity_id) _LOGGER.debug("Subscribe to device trackers for %s", self.entity_id)
@ -428,7 +451,7 @@ class Person(RestoreEntity):
def _update_state(self): def _update_state(self):
"""Update the state.""" """Update the state."""
latest_non_gps_home = latest_not_home = latest_gps = latest = None latest_non_gps_home = latest_not_home = latest_gps = latest = None
for entity_id in self._config.get(CONF_DEVICE_TRACKERS, []): for entity_id in self._config[CONF_DEVICE_TRACKERS]:
state = self.hass.states.get(entity_id) state = self.hass.states.get(entity_id)
if not state or state.state in IGNORE_STATES: if not state or state.state in IGNORE_STATES:

View File

@ -158,9 +158,13 @@ class StorageCollection(ObservableCollection):
"""Home Assistant object.""" """Home Assistant object."""
return self.store.hass return self.store.hass
async def _async_load_data(self) -> Optional[dict]:
"""Load the data."""
return cast(Optional[dict], await self.store.async_load())
async def async_load(self) -> None: async def async_load(self) -> None:
"""Load the storage Manager.""" """Load the storage Manager."""
raw_storage = cast(Optional[dict], await self.store.async_load()) raw_storage = await self._async_load_data()
if raw_storage is None: if raw_storage is None:
raw_storage = {"items": []} raw_storage = {"items": []}

View File

@ -1,7 +1,7 @@
"""The tests for the person component.""" """The tests for the person component."""
import logging import logging
from unittest.mock import patch
from asynctest import patch
import pytest import pytest
from homeassistant.components import person from homeassistant.components import person
@ -773,3 +773,15 @@ async def test_reload(hass, hass_admin_user):
assert state_2 is None assert state_2 is None
assert state_3 is not None assert state_3 is not None
assert state_3.name == "Person 3" assert state_3.name == "Person 3"
async def test_person_storage_fixing_device_trackers(storage_collection):
"""Test None device trackers become lists."""
with patch.object(
storage_collection.store,
"async_load",
return_value={"items": [{"id": "bla", "name": "bla", "device_trackers": None}]},
):
await storage_collection.async_load()
assert storage_collection.data["bla"]["device_trackers"] == []