Catch missing restore keys for template cover, device_tracker, and fan (#176724)

This commit is contained in:
Petro31
2026-07-30 11:29:31 +02:00
committed by Bram Kragten
parent 43a1c02329
commit 9e2b7d828a
6 changed files with 74 additions and 35 deletions
+10 -7
View File
@@ -175,14 +175,17 @@ class CoverExtraStoredData(ExtraStoredData):
return asdict(self)
@classmethod
def from_dict(cls, restored: dict[str, Any]) -> Self:
def from_dict(cls, restored: dict[str, Any]) -> Self | None:
"""Initialize a stored cover state from a dict."""
return cls(
current_cover_position=restored["current_cover_position"],
current_cover_tilt_position=restored["current_cover_tilt_position"],
is_opening=restored["is_opening"],
is_closing=restored["is_closing"],
)
try:
return cls(
current_cover_position=restored["current_cover_position"],
current_cover_tilt_position=restored["current_cover_tilt_position"],
is_opening=restored["is_opening"],
is_closing=restored["is_closing"],
)
except KeyError:
return None
class AbstractTemplateCover(AbstractTemplateEntity, CoverEntity, RestoreEntity):
@@ -191,14 +191,17 @@ class TrackerExtraStoredData(ExtraStoredData):
return asdict(self)
@classmethod
def from_dict(cls, restored: dict[str, Any]) -> Self:
def from_dict(cls, restored: dict[str, Any]) -> Self | None:
"""Initialize a stored tracker state from a dict."""
return cls(
in_zones=restored["in_zones"],
latitude=restored["latitude"],
longitude=restored["longitude"],
location_accuracy=restored["location_accuracy"],
)
try:
return cls(
in_zones=restored["in_zones"],
latitude=restored["latitude"],
longitude=restored["longitude"],
location_accuracy=restored["location_accuracy"],
)
except KeyError:
return None
class AbstractTemplateTracker(AbstractTemplateEntity, TrackerEntity, RestoreEntity):
+9 -21
View File
@@ -175,28 +175,16 @@ class FanExtraStoredData(ExtraStoredData):
@classmethod
def from_dict(cls, restored: dict[str, Any]) -> Self | None:
"""Initialize a stored fan data from a dict."""
is_on = restored.get("is_on")
percentage = restored.get("percentage")
preset_mode = restored.get("preset_mode")
oscillating = restored.get("oscillating")
direction = restored.get("direction")
if is_on is not None and not isinstance(is_on, bool):
try:
return cls(
is_on=restored["is_on"],
percentage=restored["percentage"],
preset_mode=restored["preset_mode"],
oscillating=restored["oscillating"],
direction=restored["direction"],
)
except KeyError:
return None
if percentage is not None and not isinstance(percentage, int):
return None
if preset_mode is not None and not isinstance(preset_mode, str):
return None
if oscillating is not None and not isinstance(oscillating, bool):
return None
if direction is not None and not isinstance(direction, str):
return None
return cls(
is_on=is_on,
percentage=percentage,
preset_mode=preset_mode,
oscillating=oscillating,
direction=direction,
)
class AbstractTemplateFan(AbstractTemplateEntity, FanEntity, RestoreEntity):
+15
View File
@@ -1192,6 +1192,21 @@ async def test_flow_preview(
},
CoverState.OPEN,
),
(
# Missing Key
CoverState.OPEN,
{
"current_cover_position": 0,
"current_cover_tilt_position": 10,
"is_closing": False,
},
STATE_UNKNOWN,
{
"current_position": None,
"current_tilt_position": None,
},
CoverState.OPEN,
),
(
STATE_UNAVAILABLE,
{
@@ -684,6 +684,21 @@ async def test_flow_preview(
"gps_accuracy": 10.0,
},
),
(
# Missing Key
STATE_HOME,
{
"in_zones": [],
"location_accuracy": 10.0,
},
STATE_UNKNOWN,
{
"in_zones": [],
"latitude": None,
"longitude": None,
"gps_accuracy": None,
},
),
(
STATE_UNAVAILABLE,
{
+15
View File
@@ -1435,6 +1435,21 @@ async def test_flow_preview(
"direction": DIRECTION_FORWARD,
},
),
(
# Missing Key
STATE_ON,
{
"is_on": True,
"percentage": 0,
},
STATE_UNKNOWN,
{
"percentage": None,
"preset_mode": None,
"oscillating": None,
"direction": None,
},
),
(
STATE_UNAVAILABLE,
{