From 87c88c3f3dbc2c09c85c0ac2a988fe1de9ad26d2 Mon Sep 17 00:00:00 2001 From: Hector van der Aa Date: Thu, 6 Aug 2026 11:08:02 +0100 Subject: [PATCH] Added live value and signal descriptor fetching Live values are stored in the core and their fetch is relatively cheap as it only requires locking the core live values lock Signal descriptors are a much heavier call as they query the connector registry and trigger an O(n) search throughout the different endpoints, this method is not meant to be used heavily as it requires locking multiple locks and handling alot of data, this method is meant to be called once to retreive a list of signal descriptors that the user can then store and use to reference values against in their frontend code --- src/dynalab_core/__init__.py | 21 ++++++++++++++++ src/dynalab_core/protocols/endpoint.py | 34 ++++++++++++++++++++++++++ test/manual/core.py | 2 ++ 3 files changed, 57 insertions(+) diff --git a/src/dynalab_core/__init__.py b/src/dynalab_core/__init__.py index bba7540..f5a81dd 100644 --- a/src/dynalab_core/__init__.py +++ b/src/dynalab_core/__init__.py @@ -19,6 +19,7 @@ from dynalab_core.protocols.common import VersionDescriptor from dynalab_core.protocols.json.server import JsonServer from dynalab_core.protocols.packets import ProtocolMessage from dynalab_core.protocols.packets.data import ValueDescriptor +from dynalab_core.protocols.packets.handshake import SignalDescriptor from dynalab_core.values import Value @@ -102,6 +103,26 @@ class Core: extra={"event": "core.stopped", "core_state": self._state}, ) + def get_signal_descriptor(self, signal_id: UUID) -> SignalDescriptor | None: + return self._connector_registry.get_signal_descriptor(signal_id) + + def get_all_signal_descriptors(self) -> list[SignalDescriptor]: + return self._connector_registry.get_all_signal_descriptors() + + def get_live_value(self, signal_id: UUID) -> float | None: + with self._live_values_lock: + live_value = self._live_values.get(signal_id) + + if live_value is None: + return None + return live_value.get() + + def get_all_live_values(self) -> dict[UUID, float]: + with self._live_values_lock: + live_values = list(self._live_values.items()) + + return {signal_id: value.get() for signal_id, value in live_values} + def _input_worker(self) -> None: while not self._stop_event.is_set(): try: diff --git a/src/dynalab_core/protocols/endpoint.py b/src/dynalab_core/protocols/endpoint.py index d6bbdea..fd061b4 100644 --- a/src/dynalab_core/protocols/endpoint.py +++ b/src/dynalab_core/protocols/endpoint.py @@ -20,6 +20,7 @@ from dynalab_core.protocols.packets.handshake import ( ConnectorHello, HandshakeAccepted, HandshakeRejected, + SignalDescriptor, ) from dynalab_core.protocols.packets.heartbeat import Heartbeat @@ -111,6 +112,16 @@ class ConnectorEndpoint: def uuid(self) -> UUID: return self._connector_hello.connector_uuid + def get_signal_descriptor(self, signal_id: UUID) -> SignalDescriptor | None: + for signal in self._connector_hello.signals: + if signal.id == signal_id: + return signal + + return None + + def get_all_signal_descriptors(self) -> list[SignalDescriptor]: + return self._connector_hello.signals + def put_ingress_packet(self, packet: ProtocolMessage) -> None: try: self._packet_ingress_queue.put_nowait(packet) @@ -393,6 +404,29 @@ class ConnectorRegistry: with self._lock: return self._endpoints.get(connector_uuid) + def get_signal_descriptor(self, signal_id: UUID) -> SignalDescriptor | None: + with self._lock: + endpoints = list(self._endpoints.items()) + + for _, endpoint in endpoints: + signal = endpoint.get_signal_descriptor(signal_id) + if signal is not None: + return signal + + return None + + def get_all_signal_descriptors(self) -> list[SignalDescriptor]: + with self._lock: + endpoints = list(self._endpoints.items()) + + signals: list[SignalDescriptor] = [] + for _, endpoint in endpoints: + endpoint_signals = endpoint.get_all_signal_descriptors() + for signal in endpoint_signals: + signals.append(signal) + + return signals + def stop(self) -> None: with self._lock: endpoints = tuple(self._endpoints.values()) diff --git a/test/manual/core.py b/test/manual/core.py index a4656d5..8db3e19 100644 --- a/test/manual/core.py +++ b/test/manual/core.py @@ -23,6 +23,8 @@ dl_core.start() try: while True: dl_core.wait(1) + values = dl_core.get_all_live_values() + log.debug(f"Core values: {values}") except KeyboardInterrupt: log.info("Received keyboard interrupt") dl_core.stop()