fix(k1): stabilize repeated acquisition and live viewer recovery
This commit is contained in:
@@ -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}.`
|
||||
|
||||
Reference in New Issue
Block a user