Developing a Measurement Plug-In with Python

This topic outlines the required steps for developing a measurement plug-in in Python. Use the Python examples in github and the remaining topics in this manual to understand how to develop a working measurement for your application.

Note If you are developing a measurement plug-in for use with TestStand, review the Running a Measurement from TestStand topic to understand additional design considerations.

Creating a Python Measurement Plug-In

Complete the following steps to generate a new measurement plug-in with Python. Ensure that you have installed the Python development dependencies before you begin.

  1. Open a command prompt.
  2. Run ni_measurement_plugin_generator measurement name --directory-out path to create a new measurement service.
    Note If you omit the --directory-out parameter the new measurement plug-in folder appears in the current directory.
    Note You can specify additional parameters. View the Python Measurement Plug-In Generator Parameters topic for details.
A folder containing the new measurement plug-in appears in the specified directory.

Configuring a Python Measurement Plug-In

You must modify a generated Python measurement plug-in to meet your specific needs.

  1. Navigate to your measurement folder and open measurement.py. This file defines your measurement logic.
  2. Add drivers and packages to the import list as necessary. You can create a measurement for any hardware with an accessible I/O library.
  3. Optionally, specify version and ui_file_path values for your measurement.
  4. Edit the measurement configuration (input parameters).
    1. Use the configuration() decorator to define a configuration. Configuration decorators must be listed in the same order as the parameters in the measurement function signature.

      Configuration decorator syntax:

      @meas_name_measurement_service.configuration("DisplayName", nims.DataType.Type, "DefaultValue")
    2. Use the output() decorator to define an output. Output decorators must be listed in the same order as the measurement function return (or yield) values.

      Output decorator syntax:

      @meas_name_measurement_service.output("DisplayName", nims.DataType.Type)
  5. To update the interactive UI while the measurement runs, use the yield keyword. The ui_progress_updates example demonstrates this feature.
  6. Implement your measurement logic within the measurement function. If you are developing a measurement plug-in for use with TestStand, review the Running a Measurement from TestStand topic to understand additional design considerations.
  7. Save and close measurement.py.
  8. Optionally, edit the *.serviceconfig file to customize the display name, service class, or provided interface for your measurement.

Setting Environmental Variables

You can set environment variables to configure ni_measurement_plugin_sdk settings. You can create a .env file to set environmental variables. A .env file is a text file containing environment variables in the form VAR=value. The .env may be located in these locations, listed in priority order:
  • The measurement service's current working directory or one of its parent directories. For example, you can place a .env file in <ProgramData>\National Instruments\Plug-Ins to configure statically registered services.
  • The path value set in the .serviceconfig file.
  • The path of the Python module calling into ni_measurement_plugin_sdk . This behavior provides support for TestStand code modules.
For example, the modular instrument initialize_${driver}_sessions(s) methods allow you to use .env settings to override the IVI option string and specify simulation options.
# Add this to your .env file to enable NI-DCPower simulation with PXIe-4141 instruments.
MEASUREMENT_PLUGIN_NIDCPOWER_SIMULATE=1
MEASUREMENT_PLUGIN_NIDCPOWER_BOARD_TYPE=PXIe
MEASUREMENT_PLUGIN_NIDCPOWER_MODEL=4141

For a complete reference of configurable settings, refer to the .env.sample file located in the root folder of the latest Measurement Plug-In release examples asset.

Use the Measurement Plug-In UI Editor to create a UI for your measurement.

Starting a Python Measurement Service

To manually run your Python measurement plug-in as a service, open a command prompt and run start.bat from your measurement folder.

Note Starting your measurement service from a development environment temporarily displaces any statically registered measurement service with the same service class. When you stop the service, the statically registered instance is restored upon being called. This behavior is useful for rapid debugging. Ensure a unique service class for each measurement service to avoid unexpected behavior.

To automatically run your measurement plug-in as a service, use the generated service configuration file to statically register your plug-in. You should statically register your measurement service when you deploy it to a production environment.

Statically Register a Measurement Service

The Measurement Plug-In discovery service automatically registers measurement services that are deployed to the Measurement Plug-In services folder. The discovery service continuously monitors this folder for changes.

You must do the following before you deploy your measurement plug-in:

  • Create a batch file that invokes the measurement logic or compile the measurement project as an executable.
  • Ensure that your measurement plug-in has a valid service configuration (*.serviceconfig) file.
    • LabVIEW measurement plug-ins can generate this file by running the included build specification.
    • For other scenarios, use the service configuration file template to create this file for your plug-in.
Complete the following steps to deploy your measurement plug-in and statically register your measurement service.
  1. Ensure the path value in the service configuration file is correct for your batch file or executable.
  2. Copy the measurement plug-in folder to the following location: <ProgramData>\National Instruments\ Plug-Ins \Services\
    Note The discovery directory is continously monitored. Service configuration file changes take immediate effect.
Once your measurement service is statically registered, the Measurement Plug-In discovery service makes it visible in supported NI applications.

Considerations when Deploying Python Measurement Plug-Ins

Be aware of the following considerations when deploying Python-based measurement plug-ins:
  • For errors indicating a file cannot be found or accessed, do one of the following:
    • ensure that you have enabled Win32 long paths.
    • move the plugin or restructure the measurement plug-in to use shorter paths. Note that only the *.serviceconfig file must be deployed to the discovery folder. The file can reference paths outside the discovery folder.
  • If you are using a virtual environment, recreate it in the deployed location. Do not move a virtual environment because some files may reference the path for the virtual environment.
    Note To exclude virtual environment files from being adding to a plug-in library, create a file titled .sericeignore within the directory containing the Python plugin. Add the following line to this file:
    .venv/*/**
    This will exclude all virtual environment files from being published to the plug-in library. For more information, refer to Using a Plug-In Library.

Service Configuration File Template

Use this template to create a service configuration file for your measurement plug-in.

A typical service configuration filename is measurement plug-in name.serviceconfig. The file contents are as follows:

{
  "services": [
    {
      "displayName": "display_name", 
      "serviceClass": "service_class", 
      "descriptionUrl": "description_url",
      "providedInterfaces": [ 
        "ni.
                ni_measurement_plugin_sdk
              .measurement.v1.MeasurementService",
        "ni.
                ni_measurement_plugin_sdk
              .measurement.v2.MeasurementService"
      ],
      "path": "service_filepath",
 "annotations": {
        "ni/service.description": "service_description",
        "ni/service.collection": "collection_name",
        "ni/service.tags": []
      }
    }
  ]
}
Object Name Description
displayName Specifies the display name of the measurement.
serviceClass Class name for the measurement service. Also serves as the ID for the measurement service and must be unique across all measurement services.
descriptionUrl Specifies a URL that contains more information about the measurement service.
providedInterfaces Lists the measurement service interfaces. Do not edit this value.
path Specifies the path to the measurement executable or start batch file.
ni/service.description A short description of the measurement.
ni/service.collection The collection that this measurement belongs to. Collection names are specified using a period-delimited namespace hierarchy and are case-insensitive.
ni/service.tags

Tags describing the measurement. This option may be repeated to specify multiple tags. Tags are case-insensitive.

installPath

Path to an executable or batch file used to install Python dependencies. For example, you might point to an install.bat file with the contents poetry install --only main.

Note

For measurement plug-ins sourced in LabVIEW, service configuration file values should match the values specified in your measurement plug-in project.