feat: improve mode and peripheral orchestration
This commit is contained in:
@@ -271,7 +271,7 @@ CAPABILITY_CASES = (
|
||||
),
|
||||
_CapabilityCase(
|
||||
"seat.set_driver_heating_native",
|
||||
"打开主驾座椅加热2档",
|
||||
"打开主驾座椅加热低档",
|
||||
"driver",
|
||||
{"state": "on", "level": 2},
|
||||
"activate",
|
||||
@@ -291,7 +291,7 @@ CAPABILITY_CASES = (
|
||||
),
|
||||
_CapabilityCase(
|
||||
"seat.set_driver_ventilation_native",
|
||||
"打开主驾座椅通风2档",
|
||||
"打开主驾座椅通风低档",
|
||||
"driver",
|
||||
{"state": "on", "level": 2},
|
||||
"activate",
|
||||
|
||||
@@ -48,6 +48,23 @@ def _learned_light() -> dict[str, object]:
|
||||
}
|
||||
|
||||
|
||||
def _learned_light_power_on() -> dict[str, object]:
|
||||
return {
|
||||
"id": "ir-slot:romance-light:1",
|
||||
"status": "learned",
|
||||
"enabled": True,
|
||||
"device_id": "romance-light",
|
||||
"device_name": "氛围灯带",
|
||||
"object_names": ["氛围灯带", "灯带"],
|
||||
"device_type": "light",
|
||||
"card_uid": "2CC8B103",
|
||||
"action": "打开",
|
||||
"action_names": ["打开", "开启", "点亮"],
|
||||
"risk": "low",
|
||||
"slot": 1,
|
||||
}
|
||||
|
||||
|
||||
def test_scene_composer_mixed_can_ir_preview_save_and_revalidate(
|
||||
tmp_path: Path,
|
||||
) -> None:
|
||||
@@ -61,13 +78,19 @@ def test_scene_composer_mixed_can_ir_preview_save_and_revalidate(
|
||||
SimulationGateway(),
|
||||
catalog_db_path=tmp_path / "infrared.sqlite3",
|
||||
)
|
||||
extension.sync_peripheral_catalog([_learned_light()])
|
||||
extension.sync_peripheral_catalog(
|
||||
[_learned_light_power_on(), _learned_light()]
|
||||
)
|
||||
catalog = AssistantCapabilityCatalog(
|
||||
service,
|
||||
peripheral_provider=extension.list_peripheral_routing_capabilities,
|
||||
)
|
||||
context = catalog.scene_composition_context(catalog.snapshot())
|
||||
capability_ref = context["peripheral_actions"][0]["ref"]
|
||||
capability_ref = next(
|
||||
item["ref"]
|
||||
for item in context["peripheral_actions"]
|
||||
if "红色" in str(item.get("action_label") or "")
|
||||
)
|
||||
encoded_context = json.dumps(context, ensure_ascii=False)
|
||||
assert "2CC8B103" not in encoded_context
|
||||
assert '"slot":7' not in encoded_context
|
||||
@@ -126,13 +149,19 @@ def test_scene_composer_mixed_can_ir_preview_save_and_revalidate(
|
||||
"climate",
|
||||
"self_extension",
|
||||
]
|
||||
assert preview["mode_profile_draft"]["operation_count"] == 2
|
||||
assert preview["mode_profile_draft"]["operation_count"] == 3
|
||||
assert set(preview["function_configs"]) == {"native_climate", "self_extension"}
|
||||
infrared_command = preview["command_plans"]["self_extension"]["spec"][
|
||||
infrared_commands = preview["command_plans"]["self_extension"]["spec"][
|
||||
"commands"
|
||||
][0]
|
||||
assert infrared_command["message"] == "infrared.emit"
|
||||
assert infrared_command["signals"] == {"slot": 7}
|
||||
]
|
||||
assert [command["message"] for command in infrared_commands] == [
|
||||
"infrared.emit",
|
||||
"infrared.emit",
|
||||
]
|
||||
assert [command["signals"] for command in infrared_commands] == [
|
||||
{"slot": 1},
|
||||
{"slot": 7},
|
||||
]
|
||||
assert preview["infrared_actions"][0]["parse_source"] == (
|
||||
"scene_composer_capability_ref"
|
||||
)
|
||||
@@ -156,9 +185,10 @@ def test_scene_composer_mixed_can_ir_preview_save_and_revalidate(
|
||||
assert [operation.capability for operation in profile.operations] == [
|
||||
"climate.set_temperature",
|
||||
"infrared.emit",
|
||||
"infrared.emit",
|
||||
]
|
||||
entries = handler._saved_mode_infrared_entries(profile)
|
||||
assert [entry["capability"]["slot"] for entry in entries] == [7]
|
||||
assert [entry["capability"]["slot"] for entry in entries] == [1, 7]
|
||||
native_execution = service.execute_mode_profile_card(
|
||||
profile.id,
|
||||
conversation_id="conv-saved-scene-peripheral",
|
||||
@@ -179,7 +209,7 @@ def test_scene_composer_mixed_can_ir_preview_save_and_revalidate(
|
||||
entries,
|
||||
)
|
||||
assert executed["status"] == "succeeded"
|
||||
assert [action["slot"] for action in executed["infrared_actions"]] == [7]
|
||||
assert [action["slot"] for action in executed["infrared_actions"]] == [1, 7]
|
||||
invoked = handler._execute_request_with_peripherals(
|
||||
"/api/requests/preview",
|
||||
{
|
||||
@@ -196,7 +226,7 @@ def test_scene_composer_mixed_can_ir_preview_save_and_revalidate(
|
||||
assert invoked is not None
|
||||
assert invoked["status"] == "succeeded"
|
||||
assert invoked["execution_mode"] == "dry_run"
|
||||
assert [action["slot"] for action in invoked["infrared_actions"]] == [7]
|
||||
assert [action["slot"] for action in invoked["infrared_actions"]] == [1, 7]
|
||||
|
||||
template_plan = _catalog_exact_scene_template_plan(
|
||||
catalog.snapshot(),
|
||||
@@ -301,8 +331,8 @@ def test_scene_composer_mixed_can_ir_preview_save_and_revalidate(
|
||||
assert explicit is not None
|
||||
assert explicit["status"] == "succeeded"
|
||||
assert explicit["execution_mode"] == "dry_run"
|
||||
assert explicit["mode_profile_draft"]["operation_count"] == 2
|
||||
assert explicit["infrared_actions"][0]["slot"] == 7
|
||||
assert explicit["mode_profile_draft"]["operation_count"] == 3
|
||||
assert [action["slot"] for action in explicit["infrared_actions"]] == [1, 7]
|
||||
|
||||
# Removing the durable NFC whitelist invalidates both cached refs and saved
|
||||
# mode execution before any transport can be reached.
|
||||
|
||||
Reference in New Issue
Block a user