Стабилизация подключения K1 после сна и ожидания Bluetooth

This commit is contained in:
DCCONSTRUCTIONS
2026-08-23 16:24:05 +03:00
parent 5ebc9fc27c
commit c041a569f6
9 changed files with 393 additions and 29 deletions
@@ -545,6 +545,97 @@ def test_start_initialization_wait_has_fail_closed_watchdog() -> None:
assert executor.snapshot()["start_complete"] is False
def test_initialized_scanning_is_observed_before_post_start_refresh_timeout() -> None:
class PostStartRefreshTimeoutTransport(SyntheticAcceptanceTransport):
def exchange_batch_once(
self,
envelopes: Sequence[OneShotPublishEnvelope],
*,
required_response_operation_keys: Collection[str],
dispatch_admission_deadline_reached: Callable[[], bool] | None = None,
dispatch_admission_commit: Callable[[], None] | None = None,
) -> dict[str, bytes]:
operation_keys = tuple(envelope.operation_key for envelope in envelopes)
if operation_keys == (
"dialogue:13:DeviceInfoRequest",
"dialogue:14:ModelingStatusRequest",
):
self.batches.append(operation_keys)
raise ApplicationMqttTransportError(
"post-START read-only response timed out after host wake",
reason_code="mqtt_response_timeout",
)
return super().exchange_batch_once(
envelopes,
required_response_operation_keys=required_response_operation_keys,
dispatch_admission_deadline_reached=(
dispatch_admission_deadline_reached
),
dispatch_admission_commit=dispatch_admission_commit,
)
transport = PostStartRefreshTimeoutTransport()
executor = PhysicalAcceptanceDialogueExecutor(transport)
authority = ApplicationControlAuthority(openapi_key=APPLICATION_KEY)
orchestrator = ShadowApplicationBootstrapOrchestrator(
authority,
epoch_seconds=1_752_680_000,
timezone_name="Europe/Moscow",
)
binding = executor.run_connection_stage(orchestrator)
executor.run_workspace_entry_stage(
orchestrator,
executor.wait_for_operator_checkpoint("workspace-entered", lambda: True),
)
executor.run_project_prompt_stage(
orchestrator,
executor.wait_for_operator_checkpoint("project-prompt-opened", lambda: True),
)
command = ShadowModelingCommand.from_command(
encode_modeling_start(
CommandHeaderIdentity(
device_id=binding.vendor_device_id,
openapi_key=APPLICATION_KEY,
),
project_name="SLEEP_WAKE",
record_mode=RecordMode.RECORD_AND_CALCULATE,
scan_mode=ScanMode.LCC,
mount_type=MountType.HANDHELD,
)
)
observed_stages: list[str] = []
with pytest.raises(ApplicationMqttTransportError) as raised:
executor.execute_canonical_start(
command,
build_canonical_post_start_observation(authority, binding),
authority=authority,
binding=binding,
permit=PhysicalAcceptancePermit(_checklist(ModelingAction.START)),
checkpoint=executor.wait_for_operator_checkpoint(
"start-confirmed",
lambda: True,
),
start_active_observer=lambda: observed_stages.append(
str(executor.snapshot()["dialogue_stage"])
),
)
assert raised.value.reason_code == "mqtt_response_timeout"
assert observed_stages == ["start-active-observed"]
assert transport.batches[-3:] == [
("modeling:start",),
("dialogue:12:ModelingStatusRequest",),
(
"dialogue:13:DeviceInfoRequest",
"dialogue:14:ModelingStatusRequest",
),
]
assert executor.snapshot()["start_active_confirmed"] is True
assert executor.snapshot()["start_complete"] is False
assert transport.stop_emitted is False
@pytest.mark.parametrize(
("device_model", "device_type"),
(