diff --git a/src/dynalab_core/__init__.py b/src/dynalab_core/__init__.py index db8d46a..0b4c8c8 100644 --- a/src/dynalab_core/__init__.py +++ b/src/dynalab_core/__init__.py @@ -3,6 +3,7 @@ # SPDX-License-Identifier: GPL-3.0-or-later +from copy import copy from datetime import datetime, timezone import logging from pathlib import Path @@ -225,11 +226,6 @@ class Core: return stopped def set_mode(self, mode: CoreMode) -> None: - if mode not in ("realtime", "playback"): - raise CoreError( - f"Unknown core mode {mode!r}; expected 'realtime' or 'playback'", - code="invalid_mode", - ) if self._recording.is_set(): raise CoreError( "Cannot change core mode while a recording is active", @@ -241,7 +237,7 @@ class Core: self._live_values = {} def get_mode(self) -> CoreMode: - return self._mode.value + return copy(self._mode.value) def load_playback_engine(self, input: Path | None = None) -> None: if self._mode.value != "playback": @@ -255,11 +251,14 @@ class Core: "Cannot load playback because no recording is available", code="no_playback_data", ) - loaded_data = self._processing_buffer + loaded_data = copy(self._processing_buffer) else: loaded_data = DLPak().read(input) self._playback_engine.set_data(loaded_data) + def load_processing_buffer(self, input: Path | None = None) -> None: + pass + # def unload_playback_engine def start_recording(self) -> None: @@ -299,8 +298,7 @@ class Core: time.sleep(1) self._recording_buffer.normalize() self._recording_buffer.sort() - self._processing_buffer = DLPak() - self._processing_buffer.set_data(self._recording_buffer) + self._processing_buffer = DLPak().set_data(copy(self._recording_buffer)) connector_signal_descriptors = ( self._connector_registry.get_all_signal_descriptors() ) @@ -343,7 +341,7 @@ class Core: if signal is None and self._core_config.playback_mode == "reprocess": signal = self._derive_registry.get_signal_descriptor(signal_id) - return signal + return copy(signal) def get_all_signal_descriptors(self) -> list[SignalDescriptor]: root_signals: list[SignalDescriptor] = [] @@ -358,7 +356,7 @@ class Core: or self._mode.value == "realtime" ): derive_signals = self._derive_registry.get_all_signal_descriptors() - return root_signals + derive_signals + return copy(root_signals + derive_signals) def get_live_value(self, signal_id: UUID) -> float | None: with self._live_values_lock: @@ -391,7 +389,7 @@ class Core: ) unit = self._derive_registry.register(dlunit) - return unit.uuid() + return copy(unit.uuid()) def unbind_derive_unit(self, unit_id: UUID) -> None: self._derive_registry.unregister(unit_id) diff --git a/src/dynalab_core/dlpak.py b/src/dynalab_core/dlpak.py index a40efe2..23f206f 100644 --- a/src/dynalab_core/dlpak.py +++ b/src/dynalab_core/dlpak.py @@ -12,14 +12,17 @@ from pydantic import BaseModel, Field from dynalab_core.buffer import ValueBuffer from dynalab_core.errors import DLPakError -from dynalab_core.protocols.packets.handshake import SignalDescriptor +from dynalab_core.protocols.packets.handshake import ( + JsonSignalDescriptor, + SignalDescriptor, +) log = logging.getLogger(__name__) class RecordManifest(BaseModel): timestamp: datetime = Field(default_factory=lambda: datetime.now(timezone.utc)) - signals: list[SignalDescriptor] = Field(default_factory=list) + signals: list[JsonSignalDescriptor] = Field(default_factory=list) comments: str = "" @@ -45,11 +48,11 @@ class DLPak: data_signal_ids = self._data.get_signal_ids() - manifest_signals: list[SignalDescriptor] = [] + manifest_signals: list[JsonSignalDescriptor] = [] for signal in all_signals: if signal.id in data_signal_ids: - manifest_signals.append(signal) + manifest_signals.append(signal.to_json()) self._manifest = RecordManifest( timestamp=timestamp, signals=manifest_signals, comments="" diff --git a/src/dynalab_core/dlunit.py b/src/dynalab_core/dlunit.py index 22ab478..4c5b27a 100644 --- a/src/dynalab_core/dlunit.py +++ b/src/dynalab_core/dlunit.py @@ -11,7 +11,10 @@ from zipfile import ZIP_DEFLATED, ZipFile from pydantic import BaseModel, Field from dynalab_core.errors import DLPakError, DLUnitError -from dynalab_core.protocols.packets.handshake import SignalDescriptor +from dynalab_core.protocols.packets.handshake import ( + JsonSignalDescriptor, + SignalDescriptor, +) log = logging.getLogger(__name__) @@ -19,8 +22,8 @@ log = logging.getLogger(__name__) class DeriveManifest(BaseModel): unit_uuid: UUID - input_signals: list[SignalDescriptor] = Field(default_factory=list) - return_signal: SignalDescriptor + input_signals: list[JsonSignalDescriptor] = Field(default_factory=list) + return_signal: JsonSignalDescriptor comments: str = "" @@ -42,10 +45,13 @@ class DLUnit: return_signal: SignalDescriptor, ) -> None: + json_input_signals = [signal.to_json() for signal in input_signals] + json_return_signal = return_signal.to_json() + self._manifest = DeriveManifest( unit_uuid=unit_uuid, - input_signals=input_signals, - return_signal=return_signal, + input_signals=json_input_signals, + return_signal=json_return_signal, ) def read(self, file: str | Path) -> Self: diff --git a/src/dynalab_core/types.py b/src/dynalab_core/types.py index 7812ffa..f4d563f 100644 --- a/src/dynalab_core/types.py +++ b/src/dynalab_core/types.py @@ -7,7 +7,7 @@ from dataclasses import dataclass from typing import Literal -CoreMode = Literal["realtime", "playback"] +CoreMode = Literal["realtime", "playback", "offline"] @dataclass