fix(k1): stabilize repeated acquisition and live viewer recovery

This commit is contained in:
DCCONSTRUCTIONS
2026-07-29 01:55:12 +03:00
parent 37b8930527
commit 2a97cf28c0
28 changed files with 2776 additions and 286 deletions
+44
View File
@@ -58,6 +58,30 @@ export interface XgridsDeviceSession {
connectivity?: "unknown" | "offline" | "connecting" | "connected" | "degraded";
}
export interface XgridsConnectionVerification {
status?:
| "not-probed"
| "configured"
| "live-address-observed"
| "reachable"
| "recovered"
| "unreachable";
lease_state?: "disconnected" | "configured" | "reachable";
lease_generation?: number;
endpoint_validation?: string | null;
network_reachability?:
| "unknown"
| "not-probed"
| "reachable"
| "degraded"
| "unreachable";
address_changed?: boolean;
previous_address_present?: boolean;
write_performed?: boolean;
observed_at?: string | null;
reason_code?: string | null;
}
export interface XgridsCompatibilityState {
profile_id?: string | null;
decision?: "compatible" | "limited" | "unknown" | "incompatible";
@@ -167,6 +191,23 @@ export interface XgridsApplicationControlSession {
expected?: Record<string, unknown>;
observed?: Record<string, unknown>;
} | null;
status_reconciliation?: {
device_session_state?: string;
device_project_bound?: boolean;
system_error_code?: number | null;
decision?: "safe-explicit-prestart-retry";
automatic_retry?: false;
} | null;
network_change_admissible?: boolean;
network_change_reconciliation?: {
device_session_state?: "scan_stopping";
device_project_bound?: true;
system_error_code?: null;
stop_complete?: true;
standby_confirmed?: false;
decision?: "explicit-network-change-only-after-acknowledged-stop";
automatic_retry?: false;
} | null;
safe_to_retry?: boolean;
} | null;
dialogue?: Record<string, unknown> | null;
@@ -220,6 +261,8 @@ export interface XgridsOperation {
}
export interface XgridsK1Metrics {
pcl_frames?: number | null;
pose_frames?: number | null;
mqtt_to_decode_ms?: number | null;
decode_ms?: number | null;
publish_ms?: number | null;
@@ -308,6 +351,7 @@ export interface XgridsK1State {
application_control_session?: XgridsApplicationControlSession | null;
device_ref?: XgridsDeviceRef | null;
device_session?: XgridsDeviceSession | null;
connection_verification?: XgridsConnectionVerification | null;
acquisition?: XgridsAcquisition | null;
operations?: XgridsOperation[];
last_operation?: XgridsOperation | null;
@@ -104,6 +104,14 @@ function normalizeState(
viewerSettings: state.viewer_settings,
sourceMode: confirmedRuntimeSourceMode(state),
metrics: {
publishedFrameCount: (
Number.isSafeInteger(metrics?.pcl_frames) &&
Number.isSafeInteger(metrics?.pose_frames) &&
(metrics?.pcl_frames ?? -1) >= 0 &&
(metrics?.pose_frames ?? -1) >= 0
)
? (metrics?.pcl_frames ?? 0) + (metrics?.pose_frames ?? 0)
: null,
latencyMs: pipelineLatency(metrics),
frameRateHz: finiteMetric(metrics?.frame_rate ?? metrics?.frame_rate_hz),
pointCount: finiteMetric(metrics?.point_count),
@@ -70,6 +70,8 @@ function controlFailure(state: XgridsK1State): ApiError {
"Сканер не подтвердил канонические MQTT-подписки.",
mqtt_response_timeout:
"Ожидаемый ответ сканера не пришёл до безопасной границы ожидания.",
mqtt_network_loop_failed:
"Локальный MQTT-клиент потерял управляющее соединение со сканером.",
response_identity_decode_failed:
"Ответ сканера не удалось безопасно разобрать и привязать к операции.",
modeling_response_decode_failed:
@@ -124,7 +126,9 @@ function controlFailure(state: XgridsK1State): ApiError {
? "Команды START и STOP не отправлялись."
: "Факт отправки START или STOP диагностически не подтверждён; повтор запрещён.";
const retryStatus = failure?.safe_to_retry
? "Новая попытка возможна только отдельным нажатием оператора."
? failure.status_reconciliation?.decision === "safe-explicit-prestart-retry"
? "Живой статус READY без связанного проекта подтверждён; новая попытка возможна только отдельным нажатием оператора."
: "Новая попытка возможна только отдельным нажатием оператора."
: "Повтор заблокирован до ручной проверки состояния.";
const exchanges = typeof failure?.publish_attempts === "number"
? `MQTT-публикаций до остановки: ${failure.publish_attempts}.`