Harden bridge state and reauthentication handling

This commit is contained in:
2026-09-04 13:07:21 +02:00
parent 9766f7f9b2
commit 1d51e56272
9 changed files with 264 additions and 12 deletions
@@ -38,6 +38,8 @@ async def async_setup_entry(
class MBSecureAlarmEntity(MBSecureEntity, AlarmControlPanelEntity):
"""Represent one normalized security area."""
_attr_code_arm_required = False
def __init__(
self, coordinator: MBSecureCoordinator, bridge_id: str, object_id: str
) -> None:
+5 -1
View File
@@ -46,4 +46,8 @@ class MBSecurePointEntity(MBSecureEntity, BinarySensorEntity):
item = self.bridge_object
if item is None:
return None
return item.state in {"active", "on", "open", "triggered"}
if item.state in {"active", "on", "open", "triggered"}:
return True
if item.state in {"clear", "closed", "inactive", "off"}:
return False
return None
+11 -1
View File
@@ -160,13 +160,23 @@ class MBSecureConfigFlow(ConfigFlow, domain=DOMAIN):
if user_input is not None:
reauth_entry = self._get_reauth_entry()
candidate = {**reauth_entry.data, CONF_TOKEN: user_input[CONF_TOKEN]}
error, _ = await self._async_validate(candidate)
error, info = await self._async_validate(candidate)
if error is None:
assert info is not None
if info.bridge_id is None:
errors["base"] = "missing_bridge_id"
return self._show_reauth_form(errors)
await self.async_set_unique_id(info.bridge_id)
self._abort_if_unique_id_mismatch(reason="wrong_account")
return self.async_update_reload_and_abort(
reauth_entry,
data_updates={CONF_TOKEN: user_input[CONF_TOKEN]},
)
errors["base"] = error
return self._show_reauth_form(errors)
def _show_reauth_form(self, errors: dict[str, str]) -> ConfigFlowResult:
"""Show the bridge token replacement form."""
return self.async_show_form(
step_id="reauth_confirm",
data_schema=vol.Schema(
+6 -1
View File
@@ -56,7 +56,12 @@ class MBSecureEntity(CoordinatorEntity[MBSecureCoordinator]):
@property
def available(self) -> bool:
"""Report availability from both transport and topology state."""
return super().available and self.bridge_object is not None
return (
super().available
and self.bridge_object is not None
and self.coordinator.info is not None
and self.coordinator.info.connected
)
@property
def name(self) -> str | None:
+5 -1
View File
@@ -48,7 +48,11 @@ class MBSecureOutputEntity(MBSecureEntity, SwitchEntity):
item = self.bridge_object
if item is None:
return None
return item.state == "on"
if item.state == "on":
return True
if item.state == "off":
return False
return None
async def async_turn_on(self, **kwargs: Any) -> None:
"""Turn the output on."""
@@ -36,7 +36,8 @@
},
"abort": {
"already_configured": "This bridge is already configured",
"invalid_discovery": "The discovered bridge information is invalid"
"invalid_discovery": "The discovered bridge information is invalid",
"wrong_account": "The token belongs to a different bridge installation"
}
}
}