ESPHome Migrate to dataclasses (#52305)

This commit is contained in:
Otto Winter 2021-06-29 19:53:57 +02:00 committed by GitHub
parent ba7ad8a58f
commit b43d0877e7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 27 additions and 37 deletions

View file

@ -555,7 +555,7 @@ async def _register_service(
"example": "['Example text', 'Another example']",
"selector": {"object": {}},
},
}[arg.type_]
}[arg.type]
schema[vol.Required(arg.name)] = metadata["validator"]
fields[arg.name] = {
"name": arg.name,

View file

@ -2,6 +2,7 @@
from __future__ import annotations
import asyncio
from dataclasses import dataclass, field
from typing import TYPE_CHECKING, Any, Callable
from aioesphomeapi import (
@ -22,7 +23,6 @@ from aioesphomeapi import (
TextSensorInfo,
UserService,
)
import attr
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant, callback
@ -49,32 +49,31 @@ INFO_TYPE_TO_PLATFORM = {
}
@attr.s
@dataclass
class RuntimeEntryData:
"""Store runtime data for esphome config entries."""
_storage_contents: dict | None = None
entry_id: str = attr.ib()
client: APIClient = attr.ib()
store: Store = attr.ib()
state: dict[str, dict[str, Any]] = attr.ib(factory=dict)
info: dict[str, dict[str, Any]] = attr.ib(factory=dict)
entry_id: str
client: APIClient
store: Store
state: dict[str, dict[str, Any]] = field(default_factory=dict)
info: dict[str, dict[str, Any]] = field(default_factory=dict)
# A second list of EntityInfo objects
# This is necessary for when an entity is being removed. HA requires
# some static info to be accessible during removal (unique_id, maybe others)
# If an entity can't find anything in the info array, it will look for info here.
old_info: dict[str, dict[str, Any]] = attr.ib(factory=dict)
old_info: dict[str, dict[str, Any]] = field(default_factory=dict)
services: dict[int, UserService] = attr.ib(factory=dict)
available: bool = attr.ib(default=False)
device_info: DeviceInfo | None = attr.ib(default=None)
api_version: APIVersion = attr.ib(factory=APIVersion)
cleanup_callbacks: list[Callable[[], None]] = attr.ib(factory=list)
disconnect_callbacks: list[Callable[[], None]] = attr.ib(factory=list)
loaded_platforms: set[str] = attr.ib(factory=set)
platform_load_lock: asyncio.Lock = attr.ib(factory=asyncio.Lock)
services: dict[int, UserService] = field(default_factory=dict)
available: bool = False
device_info: DeviceInfo | None = None
api_version: APIVersion = field(default_factory=APIVersion)
cleanup_callbacks: list[Callable[[], None]] = field(default_factory=list)
disconnect_callbacks: list[Callable[[], None]] = field(default_factory=list)
loaded_platforms: set[str] = field(default_factory=set)
platform_load_lock: asyncio.Lock = field(default_factory=asyncio.Lock)
_storage_contents: dict | None = None
@callback
def async_update_entity(
@ -142,20 +141,15 @@ class RuntimeEntryData:
return [], []
self._storage_contents = restored.copy()
self.device_info = _attr_obj_from_dict(
DeviceInfo, **restored.pop("device_info")
)
self.api_version = _attr_obj_from_dict(
APIVersion, **restored.pop("api_version", {})
)
self.device_info = DeviceInfo.from_dict(restored.pop("device_info"))
self.api_version = APIVersion.from_dict(restored.pop("api_version"))
infos = []
for comp_type, restored_infos in restored.items():
if comp_type not in COMPONENT_TYPE_TO_INFO:
continue
for info in restored_infos:
cls = COMPONENT_TYPE_TO_INFO[comp_type]
infos.append(_attr_obj_from_dict(cls, **info))
infos.append(cls.from_dict(info))
services = []
for service in restored.get("services", []):
services.append(UserService.from_dict(service))
@ -164,13 +158,13 @@ class RuntimeEntryData:
async def async_save_to_store(self) -> None:
"""Generate dynamic data to store and save it to the filesystem."""
store_data = {
"device_info": attr.asdict(self.device_info),
"device_info": self.device_info.to_dict(),
"services": [],
"api_version": attr.asdict(self.api_version),
"api_version": self.api_version.to_dict(),
}
for comp_type, infos in self.info.items():
store_data[comp_type] = [attr.asdict(info) for info in infos.values()]
store_data[comp_type] = [info.to_dict() for info in infos.values()]
for service in self.services.values():
store_data["services"].append(service.to_dict())
@ -182,7 +176,3 @@ class RuntimeEntryData:
return store_data
self.store.async_delay_save(_memorized_storage, SAVE_DELAY)
def _attr_obj_from_dict(cls, **kwargs):
return cls(**{key: kwargs[key] for key in attr.fields_dict(cls) if key in kwargs})

View file

@ -3,7 +3,7 @@
"name": "ESPHome",
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/esphome",
"requirements": ["aioesphomeapi==3.1.0"],
"requirements": ["aioesphomeapi==4.0.1"],
"zeroconf": ["_esphomelib._tcp.local."],
"codeowners": ["@OttoWinter", "@jesserockz"],
"after_dependencies": ["zeroconf", "tag"],

View file

@ -160,7 +160,7 @@ aioeafm==0.1.2
aioemonitor==1.0.5
# homeassistant.components.esphome
aioesphomeapi==3.1.0
aioesphomeapi==4.0.1
# homeassistant.components.flo
aioflo==0.4.1

View file

@ -100,7 +100,7 @@ aioeafm==0.1.2
aioemonitor==1.0.5
# homeassistant.components.esphome
aioesphomeapi==3.1.0
aioesphomeapi==4.0.1
# homeassistant.components.flo
aioflo==0.4.1