Skip to content

This Instrument category is new and is currently available only in the Unstable package

Flow Controller¤

Interface¤

Bases: Instrument

Flow-controller instrument. Methods return Measurement/Command for publishing.

Parameters:

  • name ¤

    (str) –

    Channel-name prefix for published data.

  • driver ¤

    (FlowControllerDriverBase) –

    Concrete flow-controller driver; owns its own transport::

    fc = InstroFlowController( "main", driver=AlicatMC("ASRL7::INSTR", "M"), )

  • publishers ¤

    (list[Publisher] | None, default: None ) –

    Publishers that receive emitted Measurement/Command data.

  • **kwargs ¤

    Default tags applied to every emitted Measurement/Command. Pass dataset_rid="<rid>" to auto-create a NominalCorePublisher.

Note

Direct access to driver-specific methods not in FlowControllerDriverBase (e.g., AlicatMC.set_loop_control_variable, gas-mixture methods) bypasses _resource_lock and is the caller's responsibility to synchronize if mixed with concurrent InstroFlowController method calls.

name instance-attribute ¤

name = name

legacy_naming instance-attribute ¤

legacy_naming = legacy_naming

publishers instance-attribute ¤

publishers = publishers or []

default_tags instance-attribute ¤

default_tags: dict[str, str] = {}

background_interval property writable ¤

background_interval

Seconds between background daemon iterations (0 = no wait).

channel_names property ¤

channel_names: tuple[str, ...]

Return an insertion-ordered snapshot of all published channel names.

Names are complete after one full daemon iteration: {name}.loop_time publishes every iteration, so call get_channel("loop_time", wait_for_new_samples=True) then read channel_names to ensure the complete set has arrived.

Raises:

  • RuntimeError

    No background buffer; start() was not called.

add_publisher ¤

add_publisher(publisher: Publisher)

Register a publisher to receive this instrument's Measurement/Command data.

publish ¤

publish(data: Measurement | Command, **kwargs)

Fan data out to every configured publisher; kwargs pass through.

add_background_daemon_function ¤

add_background_daemon_function(method: Callable, *args, **kwargs)

Append method to the daemon's call list. Use define_background_daemon to replace instead.

start ¤

start()

Start the background daemon thread. No-op if already running.

stop ¤

stop()

Signal the background daemon to stop and join it. No-op if not running.

get_channel ¤

get_channel(
    channel_name: str,
    length: int = 1,
    wait_for_new_samples: bool = False,
    timeout: float = 10.0,
) -> Measurement

Return the most recent length samples for channel_name from the in-memory buffer.

If the channel does not exist yet, or no sample is available, the code will always block until timeout expires.

Parameters:

  • channel_name ¤

    (str) –

    Name of the channel to retrieve.

  • length ¤

    (int, default: 1 ) –

    Number of trailing samples to return.

  • wait_for_new_samples ¤

    (bool, default: False ) –

    Block until at least length new values arrive.

  • timeout ¤

    (float, default: 10.0 ) –

    Seconds to wait when insufficient data exists or wait_for_new_samples=True.

Raises:

  • RuntimeError

    No background buffer; start() was not called.

  • ChannelNotFoundError

    channel had no values and no data appeared before timeout. wait_for_new_samples=True and channel did not appear within timeout.

  • ChannelValueTimeoutError

    wait_for_new_samples=True and values did not arrive within timeout.

get_single_channel_value ¤

get_single_channel_value(channel_name: str) -> float | None

Return the most recent sample for channel_name from the in-memory buffer.

This will not wait, if data is not available then None is returned.

Parameters:

  • channel_name ¤

    (str) –

    Name of the channel to retrieve.

Raises:

  • RuntimeError

    No background buffer; start() was not called.

define_background_daemon ¤

define_background_daemon(method: Callable, *args, **kwargs)

Replace all daemon functions with a single method (called with the given args).

open ¤

open() -> None

Open the underlying driver.

close ¤

close() -> None

Close the underlying driver and stop the daemon.

get_flow_data ¤

get_flow_data(**kwargs) -> Measurement | None

Poll the device and publish all live measurements at once.

set_setpoint ¤

set_setpoint(value: float, **kwargs) -> Command

Command a new flow setpoint in the device's configured engineering units.

select_working_fluid ¤

select_working_fluid(fluid_name: str, **kwargs) -> Command

Select the active working fluid by name.

tare_flow ¤

tare_flow(**kwargs) -> Command

Zero the flow reading. Device must have zero flow when called.

get_setpoint ¤

get_setpoint(**kwargs) -> Measurement | None

Read the current setpoint. A subset of get_flow_data(); driver implementations may fetch a full frame internally.

get_mass_flow ¤

get_mass_flow(**kwargs) -> Measurement | None

Read the current mass flow. A subset of get_flow_data(); driver implementations may fetch a full frame internally.

get_volumetric_flow ¤

get_volumetric_flow(**kwargs) -> Measurement | None

Read the current volumetric flow. A subset of get_flow_data(); driver implementations may fetch a full frame internally.

get_pressure ¤

get_pressure(**kwargs) -> Measurement | None

Read the current pressure. A subset of get_flow_data(); driver implementations may fetch a full frame internally.

get_process_value ¤

get_process_value(**kwargs) -> Measurement | None

Read the current process value (primary feedback measurement for control).

The key used in the channel name is determined by the driver's process_value_source property. For mass-flow controllers this is mass_flow; for liquid-flow controllers, volumetric_flow; etc.

Driver Interface¤

Bases: ABC

Vendor flow-controller driver contract. Concrete drivers own their transport and lifecycle.

setpoint abstractmethod property ¤

setpoint: float

Current setpoint in the device's configured engineering units. Required for all controller types.

mass_flow property ¤

mass_flow: float

Current mass flow reading. Raises NotImplementedError if controller does not measure mass flow.

volumetric_flow property ¤

volumetric_flow: float

Current volumetric flow reading. Raises NotImplementedError if controller does not measure volumetric flow.

pressure property ¤

pressure: float

Current pressure reading. Raises NotImplementedError if controller does not measure pressure.

process_value abstractmethod property ¤

process_value: float

Current process value (primary feedback measurement for control). Each controller variant returns its primary measured value.

process_value_source abstractmethod property ¤

process_value_source: str

Key constant (e.g. MASS_FLOW_KEY, VOLUMETRIC_FLOW_KEY, PRESSURE_KEY) indicating which measurement is the process value.

open abstractmethod ¤

open() -> None

Open the underlying transport.

close abstractmethod ¤

close() -> None

Close the underlying transport. Idempotent.

get_flow_data abstractmethod ¤

get_flow_data() -> FlowData

Read a full measurement frame from the device.

set_setpoint abstractmethod ¤

set_setpoint(setpt: float) -> float

Command a new flow setpoint in the device's configured engineering units.

select_working_fluid abstractmethod ¤

select_working_fluid(fluid_name: str) -> str

Select the active working fluid by name; driver resolves the device-internal identifier.

tare_flow ¤

tare_flow() -> FlowData

Zero the flow reading. Device must have zero flow when called. Raises NotImplementedError if controller does not support taring.

Measurement keys¤

FlowControllerDriverBase defines string constants for the keys returned by get_flow_data() and used by the single-value properties:

Constant Key Description
SETPOINT_KEY "setpoint" Commanded flow setpoint
MASS_FLOW_KEY "mass_flow" Measured mass flow
VOLUMETRIC_FLOW_KEY "vol_flow" Measured volumetric flow
PRESSURE_KEY "pressure" Absolute pressure
TEMPERATURE_KEY "temperature" Gas temperature

Vendor Drivers¤

Alicat MC-series¤

Bases: FlowControllerDriverBase

Alicat MC-series mass-flow controller (MC-100SCCM and related MC models).

Communicates in RS-232 polling mode. device_id is the single-letter address (A–Z) configured on the device; default is "A". Default baud is 19200 with 8data-1stop-none_parity-none_flow Termination is always carriage return.

GAS_KEY class-attribute instance-attribute ¤

GAS_KEY: Final[Literal['gas']] = 'gas'

unit_id instance-attribute ¤

unit_id: str = device_id

known_gas_types instance-attribute ¤

known_gas_types: list[GasTypeEntry] = []

measurement_headings instance-attribute ¤

measurement_headings: list[MeasurementHeaderEntry] = []

setpoint property ¤

setpoint: float

Current setpoint in the device's configured engineering units.

mass_flow property ¤

mass_flow: float

Current mass flow reading in the device's configured engineering units.

volumetric_flow property ¤

volumetric_flow: float

Current volumetric flow reading in the device's configured engineering units.

pressure property ¤

pressure: float

Current absolute pressure reading in the device's configured engineering units.

process_value property ¤

process_value: float

Current process value. Returns the measurement corresponding to the device's loop control variable.

process_value_source property ¤

process_value_source: str

Key constant for the process value measurement. Determined by the device's loop control variable.

open ¤

open() -> None

Open the VISA transport.

close ¤

close() -> None

Close the VISA transport.

tare_flow ¤

tare_flow() -> AlicatMCFlowData

Zero the flow reading; device must have zero flow and must support tare.

tare_barometer ¤

tare_barometer() -> AlicatMCFlowData

Zero the barometer reading; device must support barometer tare.

list_gas_types ¤

list_gas_types(refresh=False) -> list[GasTypeEntry]

Return all gas types the device supports; cached after first call unless refresh=True.

select_working_fluid ¤

select_working_fluid(fluid_name: str) -> str

Select the active working fluid (gas) by name and return the confirmed fluid name.

set_loop_control_variable ¤

set_loop_control_variable(loop_variable: LoopVariable) -> float

Set the loop control variable (process value source) and update the cache.

Parameters:

  • loop_variable ¤
    (LoopVariable) –

    The loop variable (e.g. LoopVariable.MASS_FLOW, LoopVariable.VOLUMETRIC_FLOW).

Returns:

  • float

    The confirmed setpoint value from the device.

define_gas_mixture ¤

define_gas_mixture(
    mix_name: str, mixture: list[GasMixEntry], gas_id: int = 0
) -> GasTypeEntry

Allows defining an arbitrary gas mixture of 2-5 components.

mix_name is an alias for the mixture. Use a maximum of 6 letters (upper and/or lower case), numbers and symbols (space, period or hyphen only).

gas_id is a number from 236-255, selecting 0 will get the next available ID

Returns selected gas_id. If gas_id is not 0, it should return gas_id. If gas_id is 0, it should return an integer from 236-255.

get_flow_data ¤

get_flow_data() -> AlicatMCFlowData

Poll the device for a single measurement frame.

get_flow_sample_metadata ¤

get_flow_sample_metadata(refresh=False) -> list[MeasurementHeaderEntry]

Return measurement field descriptors; cached after first call unless refresh=True.

set_setpoint ¤

set_setpoint(setpt: float) -> float

Command a float setpoint in the device's configured engineering units.

You can fetch the current units for each value using get_flow_sample_metadata or on the front panel of the device itself.

set_setpoint_int ¤

set_setpoint_int(
    setpt: float, full_scale_range: float, range_minimum: float
) -> float

Command a setpoint using integer encoding for the given full-scale range and minimum.

full_scale_range is the span of the control range. For unidirectional controllers (0 to max), use the max value. For bidirectional controllers (+/- max), use the full range (2 * max).

hold_valve_at_position ¤

hold_valve_at_position() -> AlicatMCFlowData

Hold the valve at its current position.

Use cancel_valve_hold to remove the hold.

hold_valve_closed ¤

hold_valve_closed() -> AlicatMCFlowData

Hold the valve closed.

Use cancel_valve_hold to remove the hold.

cancel_valve_hold ¤

cancel_valve_hold() -> AlicatMCFlowData

Release any active valve hold and return to normal setpoint control.