pyopticon package

Subpackages

Submodules

pyopticon.dashboard module

class pyopticon.dashboard.PyOpticonDashboard(dashboard_name, **kwargs)

Bases: object

A Dashboard is our term for a GUI window containing various ‘widgets’. A standalone program should initialize, configure, and run each dashboard. One dashboard may contain many widgets, each representing a physical device or some other functionality.

See the tutorials for examples of initializing and populating a dashboard. Generally, the workflow is to:

  • Initialize a dashboard

  • Initialize widgets and add them to the dashboard

  • Define any desired interlocks and add them to the dashboard

  • Launch the dashboard

Parameters:
  • dashboard_name (str) – The name of the dashboard, which appears in any data logging files that the dashboard creates.

  • offline_mode (bool, optional) – Defaults to False. If True, doesn’t attempt to build any serial.Serial objects, and widgets may also check to behave differently.

  • polling_interval_ms (int, optional) – The interval for polling all connected devices, in milliseconds. Defaults to 1000. You may want to use a larger interval if certain devices are slow to poll, or polling them involves blocking code (not recommended).

  • window_resizeable (bool, optional) – Whether or not you can manually resize the dashboard by dragging and dropping the corner. Defaults to false. If True, the window is resizeable, but the widgets don’t scale or center themselves.

  • persistent_console_logfile (bool, optional) – Whether or not to log console events to a persistent file (same throughout multiple dashboard relaunches) in the same directory as the dashboard initialization script.

  • print_stacktraces (bool, optional) – If true, exception stack traces are printed to console; if false, only to the logfile. Exception names are printed regardless.

  • x_pad (int, optional) – The horizontal pad between widgets, in pixels.

  • y_pad (int, optional) – The vertical pad between widgets, in pixels.

  • socket_ports (list, optional) – A list of integer ports on which to open sockets for client connections. Defaults to [12345].

  • include_auto_widget (bool, optional) – Whether or not to display an automation widget on the dashboard.

  • include_socket_widget (bool, optional) – Whether or not to display a socket widget on the dashboard.

add_widget(widget, row, column)

Add a widget to the dashboard at the specified row and column, each indexed from 0. Note that rows 0-3 in column 0 are reserved for the four dashboard control widgets. If the specified grid coordinates are already occupied, add_widget hides the widget that was there before. It warns to console if the widget added shares a name or nickname with an existing widget.

Parameters:
add_interlock(fn)

Add an interlock function that will be called once every polling cycle.

You’ll probably want to define such a function in the same file where the dashboard is constructed. You can use the dashboard’s get_field and/or get_widgets_by_nickname methods to check whether the system state violates a certain interlock condition (e.g., a certain temperature reading is too high), and then respond accordingly (e.g., use the dashboard’s set_field method to shut off the flow of reactive gases, or use the gmail_helper module to email or text the operator that something has gone wrong).

Parameters:

fn (function) – The interlock function to add. Should take no arguments and return nothing.

start()

Launch the dashboard, including all necessary threads.

exc_handler(exc, source='system', widget=None)

Handle an exception according to the protocol configured when the dashboard was launched. Generate a message about what subprocess raised the exception.

Parameters:
  • exc (Exception) – The Exception being raised

  • source (str, optional) – The source of the exception according to a scheme outlined in the if-statement in the function definition. Defaults to ‘system’.

  • widget (str, optional) – The nickname of the widget that raised the exception, if applicable

check_offline_mode()

Check whether dashboard is in offline mode.

Returns:

Whether the dashboard is in offline mode.

Return type:

bool

return self.offline_mode

check_serial_connected()

Check whether serial is currently connected

Returns:

Whether the dashboard’s serial is connected.

Return type:

bool

get_field(target_widget_nickname, target_field)

Get the current value of a certain field of a certain widget. The field must have been created with the add_field method of the GenericWidget class. To access an instance variable of a widget, use get_widget_by_nickname instead. To see a list of widgets’ nicknames and fields, run the dashboard and use the ‘automation help’ button.

Parameters:
  • target_widget_nickname (str) – The nickname of the widget

  • target_field (str) – The name of the field to read

Returns:

The value of the field that you queried

Return type:

str

set_field(target_widget_nickname, target_field, new_value, confirm=True)

Set the value of a certain field of a certain widget and, optionally, execute the widget’s confirm function. The field must have been created with the add_field method of the GenericWidget class. To modify an instance variable of a widget, use get_widget_by_nickname instead. To see a list of widgets’ nicknames and fields, run the dashboard and use the ‘automation help’ button.

Parameters:
  • target_widget_nickname (str) – The nickname of the widget

  • target_field (str) – The name of the field to modify

  • new_value (str) – The new value for the field. Fields’ values are always stored as strings, even if they represent numbers.

  • confirm (bool) – Whether or not to execute the widget’s confirm function, which usually sends a command to the physical device based on the newly updated field.

get_widget_by_nickname(nickname)

Get a certain widget based on its nickname. To see a list of widgets’ nicknames and fields, run the dashboard and use the ‘automation help’ button.

Parameters:

target_widget_nickname (str) – The nickname of the widget

Returns:

The corresponding widget

Return type:

pyopticon.generic_widget.GenericWidget or pyopticon.minimal_widget.MinimalWidget

get_widgets_by_nickname()

Get a dict that maps widgets’ nicknames to the corresponding widget objects. Widgets that were added with no or None nicknames are excluded.

Returns:

A dict mapping nicknames (str) to widgets (GenericWidget)

Return type:

dict

get_tkinter_object()

Get the dashboard’s Tkinter frame object, through which Tkinter functions like after() can be accessed.

Returns:

The dashboard’s Tkinter frame object.

Return type:

tkinter.Tk

scale_all_text(scale_factor)

Go through all the widgets and scale the font on any tkinter Label, Text, OptionMenu, or Button objects. Meant as a quick fix for using dashboards on smaller or larger screems.

Parameters:

scale_factor (float) – A factor by which to scale text, e.g. 1.2. Values are calculated in font units and are rounded to the nearest int.

pyopticon.generic_serial_emulator module

pyopticon.generic_widget module

class pyopticon.generic_widget.GenericWidget(parent_dashboard, name, nickname, color, **kwargs)

Bases: object

This is the superclass for all widgets representing physical devices. It contains a lot of the machinery for generating GUI elements, setting up a serial connection, and logging data, so that subclass implementation is mostly defining the input/output fields and the serial communication protocol for a given instrument.

Parameters:
  • parent_dashboard (pyopticon.dashboard.PyOpticonDashboard) – The dashboard object to which this device will be added

  • name (str) – The name that the widget will be labeled with, and under which its data will be logged, e.g. “Methane Mass Flow Controller”

  • nickname (str) – A shortened nickname that can be used to identify the widget in automation scripts, e.g. “CH4 MFC”

  • color (str) – The color of the widget’s frame, as a RGB hex string, e.g. ‘#00FF00’

  • use_serial (bool, optional) – True if this widget needs to have a serial connection; False otherwise. Defaults to True.

  • default_serial_port (str, optional) – The name of the default selected serial port, e.g. ‘COM9’

  • default_serial_port – The name of the default selected serial port, e.g. ‘COM9’. Required unless no_serial is True.

  • baudrate (int, optional) – The baud rate of the serial connection, as an integer, e.g. 19200. Required unless no_serial is True or build_serial_object is overridden.

  • widget_to_share_thread_with (pyopticon.generic_widget.GenericWidget, optional) – A widget whose thread this widget will share, rather than creating its own. If use_serial = True, it’s assumed the widget will share the serial.Serial object.

  • update_every_n_cycles – Set the widget to poll its serial connection for updates every n cycles. Useful for instruments that poll slowly for some reason, or whose state changes infrequently. Defaults to 1.

on_failed_serial_open()

This function is called when the Dashboard attempts to open a Serial port and it fails for some reason. It can be used to set the readout fields to ‘None’ or something, if desired.

on_handshake()

This function gets called whenever the widget is initialized. If the widget uses a Serial connection, you can assume that the serial connection was already initialized successfully. If not, you’ll need to initialize whatever objects are needed to update the widget in this method (say, an OEM Python driver).

By default, it just calls on_update(), assuming that the handshake was successful if (and only if) no exception was raised.

on_update()

This function gets called once every polling interval when the dashboard prompts each device to update itself. It should be overridden in a subclass implementation; if not, it prints a warning.

on_confirm()

This function gets called whenever a widget’s ‘confirm’ button is pressed, which should result in a command (reflecting the latest entries in user input fields) getting sent through the serial connection. This method should be overridden in a subclass implementation, unless the widget has no user input fields. If it’s called without being implemented in the subclass, a warning is printed.

on_serial_close()

This function gets called whenever serial connections are closed. It should be overridden in a subclass implementation. Usually, this function sets readout fields to something like ‘no reading’ after serial communications are closed. Note that while the other user-defined methods run in the widget’s thread, this method runs immediately in the main GUI thread, ensuring that the serial connection closure happens immediately.

add_field(field_type, name, label, default_value=None, **kwargs)

Adds a field (i.e., a text entry box, a dropdown menu, or a text display) to the widget.

Adding a field is like making an instance variable for the widget, except 1) the GUI elements get autogenerated for you and 2) fields’ values are, by default, logged whenever the dashboard’s data logging is active. This method is meant to streamline adding input and output fields, though you can of course define your own instance variables, configure data logging, and add GUI elements by hand to the tkinter frame from widget.get_frame() if you want more granular control. Underlying each field is a tkinter StringVar bound to some tkinter GUI element.

If you add the first input field to a widget, a ‘Confirm’ button will also automatically be generated and placed. Use the move_confirm_button method to change its location.

Parameters:
  • field_type (str) – Valid options are ‘text output’, ‘text input’, ‘dropdown’, or ‘button’

  • name (str) – The name of the field, which will be used to identify it for automation and for data logging

  • label (str) – The text label that will appear to the left of the field. This may differ from the name if you want to include units or abbreviate the label; e.g., the name might be ‘Temperature’ and the label might be ‘Temp. (C)’. If this argument is ‘’ (an empty string), no label is added.

  • default_value (str) – The starting value that appears in the field

  • options (list, optional) – The options in the dropdown option menu. Required if field_type is ‘dropdown’, ignored otherwise.

  • log (bool, optional) – Whether or not to log this field’s contents when the dashboard’s data logging is active. Defaults to True.

  • custom_stringvar (tkinter.StringVar, optional) – If you want to pass a pre-existing tkinter StringVar to be bound to the field’s GUI element, rather than letting this method initialize a new one.

do_threadsafe(to_do)

Feeds the specified function to tkinter’s after() method with a delay of 0, so that it will be executed in a thread-safe way.

Parameters:

to_do (function) – The function to execute.

get_field(which_field)

Get the current value of the specified field.

Parameters:

which_field (str) – The name of the field whose value to get.

Returns:

The current value of the specified field

Return type:

str

set_field(which_field, new_value, hush_warning=False)

Set the value of the specified field to a specified value.

Parameters:
  • which_field (str) – The name of the field whose value to set.

  • new_value (str) – The value to which to set the specified field.

  • hush_warning (True) – Silence the warning when you set a field while a widget’s serial isn’t connected.

log_data()

Generate a dict of data that is sent to the dashboard’s data logging script. The dict contains the current values of all fields that were created using add_field with the option log=True. This method may be overridden in a subclass if you would like to do some kind of preprocessing on data before it’s logged, e.g. stripping out units or typecasting to int or float.

Returns:

A dict of the widget’s loggable fields and their current values

Return type:

dict

disable_field(which_field)

Grey out an input field so that it can’t be interacted with.

Parameters:

which_field (str) – The name of the field that will be greyed out.

enable_field(which_field)

Un-grey out an input field that had previously been greyed out, allowing it to be interacted with again.

Parameters:

which_field (Str) – The name of the field to re-enable.

move_confirm_button(row, column)

Move the confirm button, which is automatically placed when using the add_field method to add an input field.

Parameters:
  • row (int) – The row at which to place the confirm button, indexed from 0

  • column (int) – The column at which to place the confirm button, indexed from 0

override_color(new_color)

Manually change the color of a widget’s frame to something besides its default defined in its constructor.

Parameters:

new_color (str) – The new color, in hex, e.g. ‘#FF00FF’

confirm()

Method executed when the Confirm button is pressed. Checks whether serial is connected and unfocuses any input field that’s focused, then calls the on_confirm method that is hopefully defined in a subclass.

close_serial()

Closes the serial object, if needed, and returns the GUI fields to their default non-connected states. Executes on_serial_close, which is hopefully implemented in a subclass.

get_serial_object()

Get the serial object that this widget is using

Returns:

This widget’s serial object, which is probably a Pyserial Serial object.

Return type:

serial.Serial

show_serial()

Show the serial port selector and status GUI elements, if they were hidden

hide_serial()

Hide the serial port selector and status GUI elements

update_serial_ports(new_serial_options)

Update the dropdown list of available serial ports

Parameters:

new_serial_options (list) – The new list of available serial ports

get_frame()

Get the tkinter frame on which this object is drawn.

Returns:

The widget’s tkinter frame

Return type:

tkinter.Frame

Module contents