herosdevices.hardware.menlo.ofc¶
HERO driver for Menlo Systems frequency combs exposed via QWebChannel.
Module Contents¶
- herosdevices.hardware.menlo.ofc.WebChannelObject¶
- herosdevices.hardware.menlo.ofc.poll_observables(observables: dict[str, dict[str, str]], ensure_connected: collections.abc.Callable[[], None], get_value: collections.abc.Callable[[str], Any], context: str) dict[str, tuple[Any, str]][source]¶
Read a dict of {name: {“path”, “unit”}} observables, tolerating an unreachable device.
Shared by
OFCandFunctionalLayerModule, whose _observable_data implementations both poll the device on demand rather than react to pushed updates: the device is contacted once per poll (not once per observable), and a single unreachable device or a single failing path does not stop the rest of the observables from being read.- Parameters:
observables – Maps an observable’s name to a dict with keys “path” (passed to get_value) and “unit”.
ensure_connected – Called once before reading any observable; may raise if the device is unreachable.
get_value – Reads the current value for one observable’s “path”.
context – Identifies the device/module in the log message if it is unreachable.
- Returns:
A dict mapping each observable’s name to its (value, unit) pair. Empty if ensure_connected raised.
- class herosdevices.hardware.menlo.ofc.OFC(host: str, port: int = QWEBCHANNEL_DEFAULT_PORT, user: str = 'guest', password: str = '', timeout: float = 5.0, reconnect_cooldown: float = 30.0, observables: dict[str, dict[str, str]] | None = None)[source]¶
Driver for a Menlo Systems optical frequency comb (OFC) exposed via the QWebChannel websocket interface.
The OFC exposes its full control/status tree (functional layer, modules, settings, …) via Qt’s WebChannel protocol. Because that tree is deep and firmware-dependent, individual nodes are addressed by dotted path strings (see
get_node()) instead of being declared as fixed class attributes. Useexplore()interactively to discover which paths are available on a given device, then list the ones you want polled in observables.Values are pushed by the device and kept in a local cache as soon as the connection is established, so
get_node()and_observable_data()never trigger network traffic themselves.- Parameters:
host – Hostname or IP address of the OFC’s QWebChannel websocket endpoint.
port – Port of the websocket endpoint.
user – Username used for authentication.
password – Password used for authentication.
timeout – Seconds to wait for a single connection attempt, see
QWebChannelConnection.reconnect_cooldown – Minimum seconds between two connection attempts, see
QWebChannelConnection. Keeps a prolonged outage (e.g. the OFC being powered off for half an hour) from causing a reconnect attempt on every single poll tick; the OFC is picked back up automatically the next time it is read after coming back online, no restart needed.observables – Additional observables to poll, merged on top of
DEFAULT_OBSERVABLES(an entry here with the same name overrides the default) rather than replacing it. Each entry maps the name under which a value is emitted with the observable_data event to a dict with keys “path” (dotted node path, seeget_node()) and “unit”. The repetition-rate, CEO, and oscillator modules have their own default observables instead, seeRepetitionRate,CEO, andOscillator.
- DEFAULT_OBSERVABLES: dict[str, dict[str, str]]¶
- host¶
- observables¶
- connection¶
- get_node(path: str) Any[source]¶
Read the current (cached) value of a node in the OFC’s control tree.
- Parameters:
path – Dotted path to the node, e.g. functionalLayer.rrSettings.repetitionRate.rrCounterRepRate or, for dict-valued nodes such as modules, modules[“SYNCRO3U”].functionalLayer….
- Returns:
The current value of the node.
- set_node(path: str, value: Any) None[source]¶
Set the value of a node in the OFC’s control tree.
- Parameters:
path – Dotted path to the node, see
get_node().value – Value to set.
- call_method(path: str, *args: Any, timeout: float | None = None) Any[source]¶
Call a method on a node in the OFC’s control tree and wait for its result.
QWebChannel method calls are inherently asynchronous (the remote object’s generated method wrapper never returns a value, it only accepts a callback for the result). This wraps that callback in a blocking wait so call_method behaves like a normal synchronous function call.
- Parameters:
path – Dotted path to the method, see
get_node(). E.g. functionalLayer.rrSettings.mainControls.unlockHere.*args – Positional arguments to pass to the method.
timeout – Seconds to wait for the method’s response. Defaults to the connection’s own timeout.
- Returns:
The method’s return value.
- Raises:
TimeoutError – No response was received within timeout seconds.
- explore(path: str = '', depth: int = 1) Any[source]¶
Explore the OFC’s control/status node tree starting at path.
Use this interactively to find the dotted paths to put into observables, e.g. ofc.explore(“functionalLayer.rrSettings”, depth=2).
- Parameters:
path – Dotted path to start exploring from (same syntax as
get_node()). Defaults to the root object.depth – How many levels of children to expand. Children beyond this depth are listed by name only, without expanding further.
- Returns:
A nested dictionary mapping child names to either their value (leaf), a list of child names (unexpanded branch), or another such dictionary (expanded branch).