Skip to content

Commit 0c61633

Browse files
authored
Merge pull request #232 from dinki/dev
Dev updates
2 parents f68689c + af981e2 commit 0c61633

File tree

5 files changed

+398
-12
lines changed

5 files changed

+398
-12
lines changed

custom_components/view_assist/devices/menu.py

Lines changed: 42 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -90,12 +90,48 @@ async def async_setup(self) -> bool:
9090

9191
d = self.config.runtime_data.dashboard.display_settings
9292

93-
self._internal_status_icons = list(d.status_icons.copy())
94-
self._internal_menu_items = [
95-
item
96-
for item in d.menu_items.copy()
97-
if item not in self._internal_status_icons
98-
]
93+
# Check for restored runtime state in extra_data
94+
# These are status icons/menu items that were added via add_status_item service
95+
# and persisted through a restart
96+
restored_status_icons = self.config.runtime_data.extra_data.get("restored_status_icons")
97+
restored_menu_items = self.config.runtime_data.extra_data.get("restored_menu_items")
98+
99+
# Use restored state if available, otherwise use config defaults
100+
if restored_status_icons is not None:
101+
# Restored state takes precedence over config
102+
# This preserves runtime additions from add_status_item service
103+
self._internal_status_icons = list(restored_status_icons)
104+
_LOGGER.info(
105+
"Restored %d status icons for %s (including runtime additions)",
106+
len(restored_status_icons),
107+
self.name
108+
)
109+
110+
# Clean up the extra_data key since we've consumed it
111+
self.config.runtime_data.extra_data.pop("restored_status_icons", None)
112+
else:
113+
# Fresh start or first run - use config defaults
114+
self._internal_status_icons = list(d.status_icons.copy())
115+
116+
if restored_menu_items is not None:
117+
# Restored state takes precedence over config
118+
self._internal_menu_items = list(restored_menu_items)
119+
_LOGGER.info(
120+
"Restored %d menu items for %s (including runtime additions)",
121+
len(restored_menu_items),
122+
self.name
123+
)
124+
125+
# Clean up the extra_data key since we've consumed it
126+
self.config.runtime_data.extra_data.pop("restored_menu_items", None)
127+
else:
128+
# Fresh start or first run - use config defaults
129+
self._internal_menu_items = [
130+
item
131+
for item in d.menu_items.copy()
132+
if item not in self._internal_status_icons
133+
]
134+
99135
self._menu_timeout = d.menu_timeout
100136

101137
self._build()

custom_components/view_assist/manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,5 @@
99
"iot_class": "calculated",
1010
"issue_tracker": "https://github.com/dinki/view_assist_integration/issues",
1111
"requirements": ["wordtodigits==1.0.2", "beautifulsoup4>=4.11.0"],
12-
"version": "2025.12.1"
12+
"version": "2026.1.0-beta"
1313
}

custom_components/view_assist/sensor.py

Lines changed: 79 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
import voluptuous as vol
1010

11-
from homeassistant.components.sensor import SensorEntity
11+
from homeassistant.components.sensor import RestoreSensor
1212
from homeassistant.core import HomeAssistant, callback
1313
from homeassistant.helpers import entity_platform
1414
import homeassistant.helpers.config_validation as cv
@@ -46,7 +46,7 @@ async def async_setup_entry(
4646
async_add_entities(sensors)
4747

4848

49-
class ViewAssistSensor(SensorEntity):
49+
class ViewAssistSensor(RestoreSensor):
5050
"""Representation of a View Assist Sensor."""
5151

5252
_attr_should_poll = False
@@ -72,6 +72,83 @@ def __init__(
7272
async def async_added_to_hass(self) -> None:
7373
"""Run when entity is about to be added to hass."""
7474

75+
# Restore previous sensor data if available
76+
last_sensor_data = await self.async_get_last_sensor_data()
77+
78+
if last_sensor_data:
79+
# Get the last state to access attributes
80+
last_state = await self.async_get_last_state()
81+
82+
if last_state and last_state.attributes:
83+
# FIRST: Restore status_icons and menu_items for MenuManager
84+
# These contain runtime additions from add_status_item service
85+
# Store them in extra_data so MenuManager can access them during async_setup
86+
restored_status_icons = last_state.attributes.get("status_icons")
87+
restored_menu_items = last_state.attributes.get("menu_items")
88+
89+
if restored_status_icons is not None:
90+
self.config.runtime_data.extra_data["restored_status_icons"] = restored_status_icons
91+
_LOGGER.debug(
92+
"Saved %d restored status icons for MenuManager: %s",
93+
len(restored_status_icons),
94+
self.entity_id
95+
)
96+
97+
if restored_menu_items is not None:
98+
self.config.runtime_data.extra_data["restored_menu_items"] = restored_menu_items
99+
_LOGGER.debug(
100+
"Saved %d restored menu items for MenuManager: %s",
101+
len(restored_menu_items),
102+
self.entity_id
103+
)
104+
105+
# Restore extra_data attributes
106+
# extra_data is used to store dynamic attributes set via view_assist.set_state
107+
restored_extra_data = {}
108+
109+
# Define attributes that are system-managed and should NOT be restored
110+
# These are rebuilt fresh on startup by their respective managers
111+
system_managed_attrs = {
112+
# Core entity properties (from config/runtime_data)
113+
"name", "type", "mic_device", "mic_device_id", "mute_switch",
114+
"display_device", "intent_device", "orientation_sensor",
115+
"mediaplayer_device", "musicplayer_device", "voice_device_id",
116+
117+
# Managed by MenuManager (now restored via extra_data above)
118+
"status_icons", "menu_items", "menu_active",
119+
120+
# Managed by TimerManager (has its own storage)
121+
"timers",
122+
123+
# From configuration/runtime_data
124+
"status_icons_size", "menu_config", "font_style",
125+
"use_24_hour_time", "background", "mode", "view_timeout",
126+
"weather_entity", "screen_mode", "do_not_disturb",
127+
"use_announce",
128+
129+
# Generated/ephemeral
130+
"last_updated", "active_overrides",
131+
132+
# Standard entity attributes
133+
"friendly_name", "icon", "device_class",
134+
"unit_of_measurement", "state_class"
135+
}
136+
137+
# Restore user/automation-set attributes
138+
# These include: alert_data, title, message, image, message_font_size, etc.
139+
for attr_name, attr_value in last_state.attributes.items():
140+
if attr_name not in system_managed_attrs:
141+
restored_extra_data[attr_name] = attr_value
142+
143+
# Update extra_data with restored values
144+
if restored_extra_data:
145+
self.config.runtime_data.extra_data.update(restored_extra_data)
146+
_LOGGER.info(
147+
"Restored %d extra attributes for %s: %s",
148+
len(restored_extra_data),
149+
self.entity_id,
150+
list(restored_extra_data.keys())
151+
)
75152
# Add internal event listeners
76153
self.async_on_remove(
77154
async_dispatcher_connect(

0 commit comments

Comments
 (0)