Area registry (#20435)

* First draft of area registry

* Refactor based on input

* Add tests for areas
Add tests for updating device

* Updating a device shouldn't require area

* Fix Martins comment

* Require admin

* Save after deleting

* Rename read to list_areas
Fix device entry_dict
Remove area id from device when deleting area

* Fix tests
This commit is contained in:
Robert Svensson 2019-01-29 00:52:42 +01:00 committed by Paulus Schoutsen
parent 2c7060896b
commit bd335e1ac1
9 changed files with 714 additions and 35 deletions

View file

@ -36,6 +36,7 @@ class DeviceEntry:
name = attr.ib(type=str, default=None)
sw_version = attr.ib(type=str, default=None)
hub_device_id = attr.ib(type=str, default=None)
area_id = attr.ib(type=str, default=None)
id = attr.ib(type=str, default=attr.Factory(lambda: uuid.uuid4().hex))
@ -119,9 +120,14 @@ class DeviceRegistry:
manufacturer=manufacturer,
model=model,
name=name,
sw_version=sw_version,
sw_version=sw_version
)
@callback
def async_update_device(self, device_id, *, area_id=_UNDEF):
"""Update properties of a device."""
return self._async_update_device(device_id, area_id=area_id)
@callback
def _async_update_device(self, device_id, *, add_config_entry_id=_UNDEF,
remove_config_entry_id=_UNDEF,
@ -131,7 +137,8 @@ class DeviceRegistry:
model=_UNDEF,
name=_UNDEF,
sw_version=_UNDEF,
hub_device_id=_UNDEF):
hub_device_id=_UNDEF,
area_id=_UNDEF):
"""Update device attributes."""
old = self.devices[device_id]
@ -169,6 +176,9 @@ class DeviceRegistry:
if value is not _UNDEF and value != getattr(old, attr_name):
changes[attr_name] = value
if (area_id is not _UNDEF and area_id != old.area_id):
changes['area_id'] = area_id
if not changes:
return old
@ -197,6 +207,8 @@ class DeviceRegistry:
id=device['id'],
# Introduced in 0.79
hub_device_id=device.get('hub_device_id'),
# Introduced in 0.87
area_id=device.get('area_id')
)
self.devices = devices
@ -222,6 +234,7 @@ class DeviceRegistry:
'sw_version': entry.sw_version,
'id': entry.id,
'hub_device_id': entry.hub_device_id,
'area_id': entry.area_id
} for entry in self.devices.values()
]
@ -235,6 +248,13 @@ class DeviceRegistry:
self._async_update_device(
dev_id, remove_config_entry_id=config_entry_id)
@callback
def async_clear_area_id(self, area_id: str) -> None:
"""Clear area id from registry entries."""
for dev_id, device in self.devices.items():
if area_id == device.area_id:
self._async_update_device(dev_id, area_id=None)
@bind_hass
async def async_get_registry(hass) -> DeviceRegistry: