Getting Started with PyHamilton

Creating an Equipment Integration Module in Python

If the equipment you are integrating is not manufactured by Hamilton, you may want to write your equipment integration as a separate module in Python. This is harder to provide a specific playbook for because you are starting from scratch, rather than importing functions from a pre-written library in Venus. Still, there are some common patterns.

shaker-module
│   __init__.py
│   shaker.py

A folder with __init__.py defines a module in Python

class PyShaker:

    def __init__(self, comport):
        
        self.interface=serial.Serial(comport, 9600, timeout=1)
        
    def _send_command(self, cmd_string):
        cmd_string = cmd_string + " \r"
        command = bytes(cmd_string, encoding='utf-8')
        self.interface.write(command)
        return self.interface.readline()
        
    def start(self, rpm=100, ramp_time=10):
        er = self._send_command("V" + str(rpm))
        er = self._send_command("A" + str(ramp_time))
        er = self._send_command("G")
        time.sleep(ramp_time)
    
    def stop(self):
        er = self._send_command("S")
    
    def get_speed(self):
        er = self._send_command("?W")

A class that provides a firmware interface to a Shaker

We use __init__.py in the module folder to define the module. This file should import all functions from the other files in the module with from shaker import *. Each piece of equipment should be defined by a class that exposes methods that perform each of the high-level functions that a user would perform in a script.

These high-level functions run code that talks directly to your piece of equipment through that equipment’s API. This API will (should) be documented by the manufacturer. Almost all equipment APIs conform to one of two patterns, ActiveX/.NET and firmware.

ActiveX / .NET API

Equipment manufacturers often provide libraries for interacting with their equipment in ActiveX or .NET frameworks. An API in one of these frameworks will expose high-level functions that should cover all of your needs for interactivity. All you need to do is load the provided library into Python. For ActiveX this is done using the win32com library to run something like excel = win32com.client.Dispatch("Excel.Application") where the excel variable will contain the interface to the equipment.

For interacting with .NET APIs (usually provided as .dlls) you will use the clr module from the pythonnet library. Imports will look something like this: clr.AddReference("System.Windows.Forms") followed by from System.Windows.Forms import Form.

Firmware string API

Some manufacturers don’t provide libraries at all, and commands are sent as firmware strings over a USB connection. In this case you will have to reference the manufacturer’s documentation for mapping strings to commands. Remember to use end-of-line delimiters when formatting your command strings. The most common libraries for this purpose will be PySerial or PyUSB.

Other types of APIs

The above list covers many but not all APIs that automation equipment uses. Other frameworks include modbus, HTTP, and others. Python should have libraries for facilitating communication with all of these frameworks.

3 Likes