feat: integrate learned peripherals into mode creation

Expose safe NFC-bound infrared actions to semantic scene composition, require flashing-light actions for romantic and Mid-Autumn modes, and preserve mixed CAN/IR mode flows.

Fix NFC device reassignment and retry extension/toy MQTT publication when an active card's binding catalog changes.
This commit is contained in:
Miayui
2026-09-20 16:37:19 +08:00
parent 904f5f8a6c
commit bfff1b515c
25 changed files with 3073 additions and 102 deletions
@@ -1015,7 +1015,14 @@ class SeatDemoService(ModeScheduleServiceMixin):
requests = self.mode_profiles.requests_for_profiles([profile])
if profile.sync_origin != MQTT_MODE_SCENE_INGRESS_TOPIC:
return requests, []
return [
request
for operation, request in zip(profile.operations, requests, strict=True)
if not (
operation.domain == "self_extension"
and operation.capability == "infrared.emit"
)
], []
source_scene = (
profile.command_flow.get("source_scene")
if isinstance(profile.command_flow, dict)
@@ -1513,11 +1520,16 @@ class SeatDemoService(ModeScheduleServiceMixin):
continue
capability = str(operation.get("capability", "")).strip()
operation_target = operation.get("target") or {}
target = str(
operation_target.get("instance")
or operation_target.get("zone")
or ""
).strip()
if domain == "self_extension" and capability == "infrared.emit":
target = str(operation_target.get("device") or "").strip()
operation_name = "emit"
else:
target = str(
operation_target.get("instance")
or operation_target.get("zone")
or ""
).strip()
operation_name = "set"
parameters = operation.get("parameters") or {}
if not domain or not capability or not target or not isinstance(
parameters, dict
@@ -1537,7 +1549,7 @@ class SeatDemoService(ModeScheduleServiceMixin):
"domain": domain,
"capability": capability,
"target_scope": target,
"operation": "set",
"operation": operation_name,
"parameters": deepcopy(parameters),
"reason": f"由模式编辑器请求 {clean_request_id} 固化。",
}