Package onboard K1 separately with a private portable installer

This commit is contained in:
DCCONSTRUCTIONS
2026-09-07 11:43:24 +03:00
parent 111fe3dcfb
commit d8cc5367c4
30 changed files with 1166 additions and 178 deletions
@@ -0,0 +1,61 @@
"""Local LAB composition; the onboard runtime does not import this module."""
from pathlib import Path
from missioncore_plugin_sdk.v0alpha2 import RuntimePluginDescriptor
from k1link.web.plugin_runtime import DevicePluginRuntimeContribution, InProcessDevicePluginRuntime
from .camera import build_xgrids_k1_camera_router
from .facade import (
XGRIDS_K1_PLUGIN_ID,
XGRIDS_K1_PLUGIN_VERSION,
XgridsK1CompatibilityService,
XgridsK1PluginFacade,
_validate_installed_compatibility_profile,
)
from .live_perception_shadow import (
build_live_perception_result_receiver,
build_live_perception_shadow_router,
)
def build_xgrids_k1_plugin(repository_root: Path) -> DevicePluginRuntimeContribution:
"""Manifest entrypoint for the reviewed XGRIDS compatibility adapter."""
from k1link.device_plugins.xgrids_k1 import build_xgrids_k1_observation
from k1link.device_plugins.xgrids_k1.legacy_api import build_xgrids_k1_legacy_router
_validate_installed_compatibility_profile(repository_root)
service = XgridsK1CompatibilityService(repository_root)
adapter = XgridsK1PluginFacade(service)
runtime = InProcessDevicePluginRuntime(
adapter,
RuntimePluginDescriptor(
plugin_id=XGRIDS_K1_PLUGIN_ID,
plugin_version=XGRIDS_K1_PLUGIN_VERSION,
supported_host_api_versions=("missioncore.nodedc/v1alpha2",),
action_ids=tuple(sorted(adapter.action_ids)),
),
close=service.close,
)
return DevicePluginRuntimeContribution(
runtime=runtime,
legacy_routers=(
build_xgrids_k1_legacy_router(runtime),
build_xgrids_k1_camera_router(
service.camera_preview,
XGRIDS_K1_PLUGIN_ID,
),
build_live_perception_shadow_router(
service.live_perception_ingress,
XGRIDS_K1_PLUGIN_ID,
bearer_token=service._live_perception_token,
result_receiver=build_live_perception_result_receiver(
service.live_perception_ingress,
service.runtime.publish_perception_frame,
),
),
),
observation=build_xgrids_k1_observation(repository_root),
)
@@ -31,7 +31,6 @@ from uuid import uuid4
from bleak.exc import BleakDeviceNotFoundError, BleakError
from missioncore_plugin_sdk.v0alpha2 import (
RuntimeActionInvocation,
RuntimePluginDescriptor,
)
from pydantic import (
BaseModel,
@@ -120,7 +119,6 @@ from k1link.device_plugins.xgrids_k1.camera import (
CameraSourceId,
CommittedCameraSegment,
XgridsK1CameraGateway,
build_xgrids_k1_camera_router,
classify_camera_recording_health,
)
from k1link.device_plugins.xgrids_k1.connection_attempt import (
@@ -155,8 +153,6 @@ from k1link.device_plugins.xgrids_k1.host_diagnostics import (
host_diagnostic_for_reason,
)
from k1link.device_plugins.xgrids_k1.live_perception_shadow import (
build_live_perception_result_receiver,
build_live_perception_shadow_router,
ensure_live_shadow_token,
)
from k1link.device_plugins.xgrids_k1.mqtt import validate_private_ipv4
@@ -263,8 +259,6 @@ from k1link.web.device_lifecycle import (
new_device_session_id,
)
from k1link.web.plugin_runtime import (
DevicePluginRuntimeContribution,
InProcessDevicePluginRuntime,
PluginActionNotFoundError,
PluginExecutionError,
)
@@ -35506,44 +35500,3 @@ def _validate_installed_compatibility_profile(repository_root: Path) -> None:
XGRIDS_K1_COMPATIBILITY_PROFILE_ID
):
raise RuntimeError("XGRIDS compatibility profile identity does not match the runtime")
def build_xgrids_k1_plugin(repository_root: Path) -> DevicePluginRuntimeContribution:
"""Manifest entrypoint for the reviewed XGRIDS compatibility adapter."""
from k1link.device_plugins.xgrids_k1 import build_xgrids_k1_observation
from k1link.device_plugins.xgrids_k1.legacy_api import build_xgrids_k1_legacy_router
_validate_installed_compatibility_profile(repository_root)
service = XgridsK1CompatibilityService(repository_root)
adapter = XgridsK1PluginFacade(service)
runtime = InProcessDevicePluginRuntime(
adapter,
RuntimePluginDescriptor(
plugin_id=XGRIDS_K1_PLUGIN_ID,
plugin_version=XGRIDS_K1_PLUGIN_VERSION,
supported_host_api_versions=("missioncore.nodedc/v1alpha2",),
action_ids=tuple(sorted(adapter.action_ids)),
),
close=service.close,
)
return DevicePluginRuntimeContribution(
runtime=runtime,
legacy_routers=(
build_xgrids_k1_legacy_router(runtime),
build_xgrids_k1_camera_router(
service.camera_preview,
XGRIDS_K1_PLUGIN_ID,
),
build_live_perception_shadow_router(
service.live_perception_ingress,
XGRIDS_K1_PLUGIN_ID,
bearer_token=service._live_perception_token,
result_receiver=build_live_perception_result_receiver(
service.live_perception_ingress,
service.runtime.publish_perception_frame,
),
),
),
observation=build_xgrids_k1_observation(repository_root),
)
+79 -34
View File
@@ -1,38 +1,42 @@
"""Configuration contracts for Mission Core laboratory evidence."""
"""Lazy public exports for laboratory evidence; leaf imports stay lightweight."""
from k1link.laboratory.evidence_registry import (
LABORATORY_EVIDENCE_DEFINITION_SCHEMA,
LABORATORY_EVIDENCE_LIFECYCLE_DEFINITION_SCHEMA,
LaboratoryEvidenceDefinition,
LaboratoryEvidenceRegistry,
LaboratoryEvidenceVariant,
LaboratoryRegistryError,
)
from k1link.laboratory.evidence_report import (
LABORATORY_EVIDENCE_REPORT_SCHEMA,
LaboratoryEvidenceReportError,
LaboratoryEvidenceReportNotFound,
LaboratoryEvidenceReportService,
verify_laboratory_evidence_result,
)
from k1link.laboratory.execution import (
LABORATORY_EXECUTION_REGISTRY_SCHEMA,
LABORATORY_RUN_RECEIPT_SCHEMA,
LaboratoryAdapterResult,
LaboratoryExecutionDefinition,
LaboratoryExecutionError,
LaboratoryExecutionRegistry,
LaboratoryRunner,
LaboratoryRunRequest,
LaboratoryRunResult,
)
from k1link.laboratory.value_review_registry import (
LABORATORY_VALUE_REVIEW_INDEX_SCHEMA,
LABORATORY_VALUE_REVIEW_REGISTRY_SCHEMA,
LaboratoryValueReviewEntry,
LaboratoryValueReviewRegistry,
LaboratoryValueReviewRegistryError,
)
from importlib import import_module
from typing import TYPE_CHECKING, Any, Final
if TYPE_CHECKING:
from k1link.laboratory.evidence_registry import (
LABORATORY_EVIDENCE_DEFINITION_SCHEMA,
LABORATORY_EVIDENCE_LIFECYCLE_DEFINITION_SCHEMA,
LaboratoryEvidenceDefinition,
LaboratoryEvidenceRegistry,
LaboratoryEvidenceVariant,
LaboratoryRegistryError,
)
from k1link.laboratory.evidence_report import (
LABORATORY_EVIDENCE_REPORT_SCHEMA,
LaboratoryEvidenceReportError,
LaboratoryEvidenceReportNotFound,
LaboratoryEvidenceReportService,
verify_laboratory_evidence_result,
)
from k1link.laboratory.execution import (
LABORATORY_EXECUTION_REGISTRY_SCHEMA,
LABORATORY_RUN_RECEIPT_SCHEMA,
LaboratoryAdapterResult,
LaboratoryExecutionDefinition,
LaboratoryExecutionError,
LaboratoryExecutionRegistry,
LaboratoryRunner,
LaboratoryRunRequest,
LaboratoryRunResult,
)
from k1link.laboratory.value_review_registry import (
LABORATORY_VALUE_REVIEW_INDEX_SCHEMA,
LABORATORY_VALUE_REVIEW_REGISTRY_SCHEMA,
LaboratoryValueReviewEntry,
LaboratoryValueReviewRegistry,
LaboratoryValueReviewRegistryError,
)
__all__ = [
"LABORATORY_EVIDENCE_DEFINITION_SCHEMA",
@@ -61,3 +65,44 @@ __all__ = [
"LaboratoryValueReviewRegistry",
"LaboratoryValueReviewRegistryError",
]
_EXPORTS: Final = {
"LABORATORY_EVIDENCE_DEFINITION_SCHEMA": "k1link.laboratory.evidence_registry",
"LABORATORY_EVIDENCE_LIFECYCLE_DEFINITION_SCHEMA": "k1link.laboratory.evidence_registry",
"LaboratoryEvidenceDefinition": "k1link.laboratory.evidence_registry",
"LaboratoryEvidenceRegistry": "k1link.laboratory.evidence_registry",
"LaboratoryEvidenceVariant": "k1link.laboratory.evidence_registry",
"LaboratoryRegistryError": "k1link.laboratory.evidence_registry",
"LABORATORY_EVIDENCE_REPORT_SCHEMA": "k1link.laboratory.evidence_report",
"LaboratoryEvidenceReportError": "k1link.laboratory.evidence_report",
"LaboratoryEvidenceReportNotFound": "k1link.laboratory.evidence_report",
"LaboratoryEvidenceReportService": "k1link.laboratory.evidence_report",
"verify_laboratory_evidence_result": "k1link.laboratory.evidence_report",
"LABORATORY_EXECUTION_REGISTRY_SCHEMA": "k1link.laboratory.execution",
"LABORATORY_RUN_RECEIPT_SCHEMA": "k1link.laboratory.execution",
"LaboratoryAdapterResult": "k1link.laboratory.execution",
"LaboratoryExecutionDefinition": "k1link.laboratory.execution",
"LaboratoryExecutionError": "k1link.laboratory.execution",
"LaboratoryExecutionRegistry": "k1link.laboratory.execution",
"LaboratoryRunner": "k1link.laboratory.execution",
"LaboratoryRunRequest": "k1link.laboratory.execution",
"LaboratoryRunResult": "k1link.laboratory.execution",
"LABORATORY_VALUE_REVIEW_INDEX_SCHEMA": "k1link.laboratory.value_review_registry",
"LABORATORY_VALUE_REVIEW_REGISTRY_SCHEMA": "k1link.laboratory.value_review_registry",
"LaboratoryValueReviewEntry": "k1link.laboratory.value_review_registry",
"LaboratoryValueReviewRegistry": "k1link.laboratory.value_review_registry",
"LaboratoryValueReviewRegistryError": "k1link.laboratory.value_review_registry",
}
def __getattr__(name: str) -> Any:
module_name = _EXPORTS.get(name)
if module_name is None:
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
value = getattr(import_module(module_name), name)
globals()[name] = value
return value
def __dir__() -> list[str]:
return sorted({*globals(), *__all__})