Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 18 additions & 4 deletions custom_components/siedle/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@

PLATFORMS = [Platform.SENSOR, Platform.BINARY_SENSOR, Platform.BUTTON, Platform.CAMERA]

_reloading_entries: set = set()

# This integration is config entry only
CONFIG_SCHEMA = cv.config_entry_only_config_schema(DOMAIN)

Expand Down Expand Up @@ -417,16 +419,28 @@ async def _start_fcm_handler():
# Register services
await async_setup_services(hass, siedle)

# Reload integration when options change (e.g. external SIP enabled/disabled)
# Reload integration when options change (e.g. SIP/FCM settings)
entry.async_on_unload(entry.add_update_listener(_async_reload_on_options_change))

return True


async def _async_reload_on_options_change(hass: HomeAssistant, entry: ConfigEntry) -> None:
"""Reload the config entry when options are updated via the UI."""
_LOGGER.info("Options changed, reloading Siedle integration...")
await hass.config_entries.async_reload(entry.entry_id)
"""Reload the config entry when options are updated via the UI.

Guard against double-reload: HA 2026.5 may trigger an additional reload after
OptionsFlow completes. If a reload for this entry is already in progress we skip
the second trigger instead of racing.
"""
if entry.entry_id in _reloading_entries:
_LOGGER.debug("Siedle reload already in progress for %s, skipping duplicate", entry.entry_id)
return
_reloading_entries.add(entry.entry_id)
try:
_LOGGER.info("Options changed, reloading Siedle integration...")
await hass.config_entries.async_reload(entry.entry_id)
finally:
_reloading_entries.discard(entry.entry_id)


async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry):
Expand Down
14 changes: 13 additions & 1 deletion custom_components/siedle/sip_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -643,7 +643,13 @@ def register(self) -> bool:
if not self._connected:
if not self.connect():
return False


# Cap recv timeout at 10s so executor threads don't block longer than needed
try:
self._socket.settimeout(10)
except Exception:
pass

try:
# Send initial REGISTER
_LOGGER.info(f"{self.name}: Sending initial REGISTER to {self.config.host}:{self.config.port} "
Expand Down Expand Up @@ -2242,6 +2248,12 @@ def _health_monitor_loop(self):
# Check Siedle connection
if self._siedle_conn and self._siedle_conn.connection_lost:
_LOGGER.warning("Siedle SIP connection lost — attempting reconnect...")
# Clean up any active call so RTP bridge doesn't keep running
if self._siedle_call is not None:
try:
self._end_call()
except Exception as e:
_LOGGER.warning(f"Error ending call on connection loss: {e}")
for attempt in range(3):
if not self._running:
break
Expand Down
Loading