mirror of
https://github.com/home-assistant/core.git
synced 2026-09-09 23:21:00 +01:00
Catch missing restore keys for template cover, device_tracker, and fan (#176724)
This commit is contained in:
@@ -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):
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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,
|
||||
{
|
||||
|
||||
@@ -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,
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user