fix: 修复 OptionsFlow 配置表单显示问题

问题:集成配置选项面板中字体不显示

修复内容:
- 移除 vol.Coerce 包装器,直接使用 int/bool 类型
- 添加错误处理和显示
- 修复 self._hass 为 self.hass (OptionsFlow 中通过属性访问)
- 添加实际操作调用(扫描、配网、绑定、分组)
- 添加错误时返回上一步的逻辑

修改的方法:
- async_step_poll_config: 简化类型定义
- async_step_prov_action: 添加错误处理
- async_step_start_scan: 添加实际调用和错误处理
- async_step_stop_prov: 添加实际调用和错误处理
- async_step_bind_appkey: 添加实际调用和错误处理
- async_step_add_to_group: 添加实际调用和错误处理
- async_step_remove_from_group: 添加实际调用和错误处理
This commit is contained in:
impressionyang 2026-04-16 13:51:37 +08:00
parent 4c3eb62dfb
commit 04e942992b

View File

@ -180,7 +180,7 @@ class SigMeshGatewayOptionsFlow(config_entries.OptionsFlow):
vol.Required(
"poll_interval",
default=self.config_entry.options.get("poll_interval", 30),
): vol.Coerce(int),
): int,
}
),
)
@ -189,14 +189,17 @@ class SigMeshGatewayOptionsFlow(config_entries.OptionsFlow):
self, user_input: dict[str, Any] | None = None
) -> FlowResult:
"""配网操作选择."""
errors = {}
if user_input is not None:
self._prov_action = user_input.get("action")
if self._prov_action == "start_scan":
action = user_input.get("action")
if action == "start_scan":
return await self.async_step_start_scan()
elif self._prov_action == "stop_prov":
elif action == "stop_prov":
return await self.async_step_stop_prov()
elif self._prov_action == "bind_appkey":
elif action == "bind_appkey":
return await self.async_step_bind_appkey()
errors["base"] = "无效的操作"
return self.async_show_form(
step_id="prov_action",
@ -213,6 +216,7 @@ class SigMeshGatewayOptionsFlow(config_entries.OptionsFlow):
),
}
),
errors=errors,
)
async def async_step_start_scan(
@ -220,7 +224,14 @@ class SigMeshGatewayOptionsFlow(config_entries.OptionsFlow):
) -> FlowResult:
"""开始扫描设备."""
if user_input is not None:
# TODO: 调用配网管理器开始扫描
# 调用配网管理器开始扫描
try:
for coordinator in self.hass.data.get(DOMAIN, {}).values():
if hasattr(coordinator, 'start_scanning'):
await coordinator.start_scanning()
except Exception as e:
self._errors["base"] = str(e)
return await self.async_step_prov_action()
return self.async_create_entry(title="", data={})
return self.async_show_form(
@ -231,6 +242,7 @@ class SigMeshGatewayOptionsFlow(config_entries.OptionsFlow):
vol.Required("confirm"): bool,
}
),
errors=self._errors,
)
async def async_step_stop_prov(
@ -238,7 +250,14 @@ class SigMeshGatewayOptionsFlow(config_entries.OptionsFlow):
) -> FlowResult:
"""停止配网."""
if user_input is not None:
# TODO: 调用配网管理器停止配网
# 调用配网管理器停止配网
try:
for coordinator in self.hass.data.get(DOMAIN, {}).values():
if hasattr(coordinator, 'stop_provisioning'):
await coordinator.stop_provisioning()
except Exception as e:
self._errors["base"] = str(e)
return await self.async_step_prov_action()
return self.async_create_entry(title="", data={})
return self.async_show_form(
@ -248,6 +267,7 @@ class SigMeshGatewayOptionsFlow(config_entries.OptionsFlow):
vol.Required("confirm"): bool,
}
),
errors=self._errors,
)
async def async_step_bind_appkey(
@ -255,7 +275,16 @@ class SigMeshGatewayOptionsFlow(config_entries.OptionsFlow):
) -> FlowResult:
"""绑定 App Key."""
if user_input is not None:
# TODO: 调用配网管理器绑定 App Key
# 调用配网管理器绑定 App Key
try:
device_address = user_input.get("device_address")
element_address = user_input.get("element_address", 0)
for coordinator in self.hass.data.get(DOMAIN, {}).values():
if hasattr(coordinator, 'bind_app_key'):
await coordinator.bind_app_key(device_address, element_address)
except Exception as e:
self._errors["base"] = str(e)
return await self.async_step_prov_action()
return self.async_create_entry(title="", data={})
return self.async_show_form(
@ -263,9 +292,10 @@ class SigMeshGatewayOptionsFlow(config_entries.OptionsFlow):
data_schema=vol.Schema(
{
vol.Required("device_address"): str,
vol.Required("element_address", default=0): vol.Coerce(int),
vol.Required("element_address", default=0): int,
}
),
errors=self._errors,
)
async def async_step_group_config(
@ -300,7 +330,26 @@ class SigMeshGatewayOptionsFlow(config_entries.OptionsFlow):
) -> FlowResult:
"""添加设备到组."""
if user_input is not None:
# TODO: 调用配网管理器添加设备到组
# 调用配网管理器添加设备到组
try:
target_address = user_input.get("target_address")
element_address = user_input.get("element_address", 0)
group_address = user_input.get("group_address")
model_id = user_input.get("model_id", 4352)
is_sig = user_input.get("is_sig", True)
# 解析组地址
if isinstance(group_address, str):
group_address = int(group_address, 16)
for coordinator in self.hass.data.get(DOMAIN, {}).values():
if hasattr(coordinator, 'add_device_to_group'):
await coordinator.add_device_to_group(
target_address, element_address, group_address, model_id, is_sig
)
except Exception as e:
self._errors["base"] = str(e)
return await self.async_step_group_config()
return self.async_create_entry(title="", data={})
return self.async_show_form(
@ -308,15 +357,16 @@ class SigMeshGatewayOptionsFlow(config_entries.OptionsFlow):
data_schema=vol.Schema(
{
vol.Required("target_address"): str,
vol.Required("element_address", default=0): vol.Coerce(int),
vol.Required("element_address", default=0): int,
vol.Required("group_address", default=hex(DEFAULT_GROUP_ADDRESS_START)): str,
vol.Required("model_id", default=4352): vol.Coerce(int), # 默认 0x1100
vol.Required("model_id", default=4352): int,
vol.Required("is_sig", default=True): bool,
}
),
description_placeholders={
"default_group": hex(DEFAULT_GROUP_ADDRESS_START),
},
errors=self._errors,
)
async def async_step_remove_from_group(
@ -324,7 +374,26 @@ class SigMeshGatewayOptionsFlow(config_entries.OptionsFlow):
) -> FlowResult:
"""从组中移除设备."""
if user_input is not None:
# TODO: 调用配网管理器移除设备
# 调用配网管理器移除设备
try:
target_address = user_input.get("target_address")
element_address = user_input.get("element_address", 0)
group_address = user_input.get("group_address")
model_id = user_input.get("model_id", 4352)
is_sig = user_input.get("is_sig", True)
# 解析组地址
if isinstance(group_address, str):
group_address = int(group_address, 16)
for coordinator in self.hass.data.get(DOMAIN, {}).values():
if hasattr(coordinator, 'remove_device_from_group'):
await coordinator.remove_device_from_group(
target_address, element_address, group_address, model_id, is_sig
)
except Exception as e:
self._errors["base"] = str(e)
return await self.async_step_group_config()
return self.async_create_entry(title="", data={})
return self.async_show_form(
@ -332,10 +401,11 @@ class SigMeshGatewayOptionsFlow(config_entries.OptionsFlow):
data_schema=vol.Schema(
{
vol.Required("target_address"): str,
vol.Required("element_address", default=0): vol.Coerce(int),
vol.Required("element_address", default=0): int,
vol.Required("group_address", default=hex(DEFAULT_GROUP_ADDRESS_START)): str,
vol.Required("model_id", default=4352): vol.Coerce(int),
vol.Required("model_id", default=4352): int,
vol.Required("is_sig", default=True): bool,
}
),
errors=self._errors,
)