Hello!
When we launched logic2-automation, the API for automating capture, analysis, save, and export from our devices, we embedded the API server directly into the Logic 2 desktop software.
The main reason for this was because much of the necessary application logic to drive the API was only implemented in the GUI application, and in typescript.
Today, we’re releasing a preview of a new, native, headless implementation of the same API. Existing python automation scripts can use this with just one change.
We’re still working on this, but as of right now, it fully implements all the functionality of the existing API for the Logic 8, Logic Pro 8, and Logic Pro 16 devices.
We’re going to start adding Logic MSO support next week, and we think that will be out shortly after.
We’re making this available right now in two different ways:
- A Python wheel file you can download and install with
pip install. The python library is almost unchanged, and it includes a copy of the new automation server binary. - A zip file containing the gRPC proto files and the automation server binary. This is for users who have or will consume the the API from other programing languages.
Python Downloads
Note: We don’t provide an Windows-arm64 python Library because a pre-built gRPC library is not available for that platform. There are workarounds for this.
- Windows (x64) logic2_automation-1.1.0-py3-none-win_amd64.whl
- Windows (arm64) not available
- macOS (Intel) logic2_automation-1.1.0-py3-none-macosx_10_14_x86_64.whl
- macOS (Apple Silicon) logic2_automation-1.1.0-py3-none-macosx_11_0_arm64.whl
- Linux (x64) logic2_automation-1.1.0-py3-none-manylinux_2_27_x86_64.whl
- Linux (arm64) logic2_automation-1.1.0-py3-none-manylinux_2_27_aarch64.whl
Server Binary Downloads
- Windows (x64) logic_automation_server-windows-x64.zip
- Windows (arm64) logic_automation_server-windows-arm64.zip
- macOS (Intel) logic_automation_server-macos-x64.zip
- macOS (Apple Silicon) logic_automation_server-macos-arm64.zip
- Linux (x64) logic_automation_server-linux-x64.zip
- Linux (arm64) logic_automation_server-linux-arm64.zip
Requirements
- Only supports Logic 8, Logic Pro 8, and Logic Pro 16. MSO coming soon. Let us know if you need support for our older devices.
- Windows: you need to have installed our drivers first. These come with the Logic 2 software.
- Linux: you need to install the udev rules file first. Our software normally helps you with this.
Documentation
We haven’t updated our public documentation yet. This release is just a few hours old, and we haven’t even merged the PR for it yet. We’ll be working on updating our documentation on docs.saleae.com once we have MSO support shipped. However, our existing documentation mostly applies, with a few changes.
Our existing automation documentation can be found here: Getting Started - Saleae API Documentation
There are only 2 changes to the python interface, and 1 change to the gRPC interface.
First, to use the headless automation API from the python library, you must use the launch class method with the headless=true argument. Otherwise, it will attempt to launch the Logic 2 GUI software. automation.Manager.connect can still be used to connect to the GUI application, or, you can manually launch the automation server binary first and connect to that - no headless argument needed.
Required: Specify headless when using the Python library
# typical usage:
with automation.Manager.launch(headless=True) as manager:
Second, there is a new method, which you can call to enable crash reporting and/or analytics. Both are optional and are disabled by default.
If you experience crashes when using the headless automation API, please turn on crash reporting, repeat the operation, then contact Saleae support.
Analytics are helpful too, since these capture non-crash errors and help us find bugs in the application. Also, it makes us feel better when we can see that all this work is going to good use. Totally optional of course.
manager.set_reporting(analytics=True, crashes=True)
This wraps a matching method in the gRPC proto specification. It’s use is optional.
Getting Started Sample
This example is taken from our public documentation, with the two changes above.
from saleae import automation
import os
import os.path
from datetime import datetime
# launch the headless automation server binary by providing headless=True.
with automation.Manager.launch(headless=True) as manager:
# Optional: Enable crash reporting and analytics to help Saleae catch issues, both hard crashes and unexpected behavior.
manager.set_reporting(analytics=True, crashes=True)
# Configure the capturing device to record on digital channels 0, 1, 2, and 3,
# with a sampling rate of 10 MSa/s, and a logic level of 3.3V.
# The settings chosen here will depend on your device's capabilities and what
# you can configure in the Logic 2 UI.
device_configuration = automation.LogicDeviceConfiguration(
enabled_digital_channels=[0, 1, 2, 3],
digital_sample_rate=10_000_000,
digital_threshold_volts=3.3,
)
# Record 5 seconds of data before stopping the capture
capture_configuration = automation.CaptureConfiguration(
capture_mode=automation.TimedCaptureMode(duration_seconds=5.0)
)
# Start a capture - the capture will be automatically closed when leaving the `with` block
# Note: The serial number 'F4241' is for the Logic Pro 16 demo device.
# To use a real device, you can:
# 1. Omit the `device_id` argument. Logic 2 will choose the first real (non-simulated) device.
# 2. Use the serial number for your device. See the "Finding the Serial Number
# of a Device" section for information on finding your device's serial number.
with manager.start_capture(
device_id='F4241',
device_configuration=device_configuration,
capture_configuration=capture_configuration) as capture:
# Wait until the capture has finished
# This will take about 5 seconds because we are using a timed capture mode
capture.wait()
# Add an analyzer to the capture
# Note: The simulator output is not actual SPI data
spi_analyzer = capture.add_analyzer('SPI', label=f'Test Analyzer', settings={
'MISO': 0,
'Clock': 1,
'Enable': 2,
'Bits per Transfer': '8 Bits per Transfer (Standard)'
})
# Store output in a timestamped directory
output_dir = os.path.join(os.getcwd(), f'output-{datetime.now().strftime("%Y-%m-%d_%H-%M-%S")}')
os.makedirs(output_dir)
# Export analyzer data to a CSV file
analyzer_export_filepath = os.path.join(output_dir, 'spi_export.csv')
capture.export_data_table(
filepath=analyzer_export_filepath,
analyzers=[spi_analyzer]
)
# Export raw digital data to a CSV file
capture.export_raw_data_csv(directory=output_dir, digital_channels=[0, 1, 2, 3])
# Finally, save the capture to a file
capture_filepath = os.path.join(output_dir, 'example_capture.sal')
capture.save_capture(filepath=capture_filepath)