pytactl
Python implementation of Test Automation Controller (TAC/Alpaca) for controlling Qualcomm debug boards. It uses config files and PSOC firmware from the original TAC (Alpaca) system.
Installation
Install the pytactl command on your system from PyPI
with pipx:
pipx install pytactl
To install from a checkout of this repository instead:
pipx install .
This puts a single pytactl entry point on your PATH. Note that the hid
dependency needs libhidapi package to be installed (required for Bughopper V2 boards).
Alternatively, for development in a virtualenv:
virtualenv -p python3 venv
. ./venv/bin/activate
pip install -e .
Run pytactl -h to see all available options.
System dependencies
pytactl uses hidapi for HID-based debug boards, including Bughopper V2.
Install the native HIDAPI library before installing or running pytactl.
Ubuntu / Debian
sudo apt update
sudo apt install -y libhidapi-hidraw0 libhidapi-libusb0
Fedora
sudo dnf install -y hidapi
USB permissions
By default, USB devices are not accessible without root. Create a udev rule for your board:
echo 'SUBSYSTEM=="usb", ATTR{idVendor}=="05c6", ATTR{idProduct}=="9302", MODE="0666", GROUP="plugdev"' \
| sudo tee /etc/udev/rules.d/99-alpaca.rules
sudo udevadm control --reload-rules && sudo udevadm trigger
Bughopper V2 also exposes a HID interface, so it needs a hidraw rule:
echo 'SUBSYSTEM=="hidraw", ATTRS{idVendor}=="2341", ATTRS{idProduct}=="b001", MODE="0660", GROUP="plugdev", TAG+="uaccess"' \
| sudo tee /etc/udev/rules.d/99-bughopper-v2.rules
sudo udevadm control --reload-rules && sudo udevadm trigger
Then make sure your user is in the plugdev group (log out and back in after):
sudo usermod -aG plugdev $USER
Configuration
Bughopper boards (V1 and V2) work out of the box. They are self-describing and need no config files.
All other debug boards (FTDI, PSOC) require configuration files that are NOT shipped with
pytactl. The easiest way to obtain them is the installconfigs subcommand, which downloads every
.tcnf file and devicelist.json from the
qcom-test-automation-controller
project:
pytactl installconfigs
With no arguments it fetches from the default config repository and installs into a per-user
data directory (resolved with platformdirs, e.g.
~/.local/share/pytactl on Linux). Once that directory is populated, the board subcommands use it
automatically as the default --tac-config-path. Override either with:
pytactl installconfigs \
--config-repository https://github.com/qualcomm/qcom-test-automation-controller/ \
--local-path /path/to/install \
--ref main \
--repository-path configurations
--ref selects the git ref (branch, tag, or commit; default HEAD) and --repository-path the
directory within the repository to fetch from (default configurations).
installconfigs also copies the default FTDI Alpaca-Lite config (which has no upstream .tcnf
file) in as default.tcnf and rewrites empty configPath entries in devicelist.json to point
at it.
You can also copy the configurations/ directory by hand and point pytactl at it with
--tac-config-path <dir>.
Note: some configs in qcom-test-automation-controller currently have syntax issues; pick the ones that match your board.
devicelist.json maps board hardware IDs to their .tcnf config files, and must be present in
the --tac-config-path directory for FTDI/PSOC boards. Example entry for a PSOC board:
{
"catalog": [
{
"platform_id": 17,
"configPath": "tac_configs/TAC_PSOC_17.tcnf"
}
]
}
Finding your board's serial number
The --serial argument takes the USB serial number, not a device path. The easiest way to
discover connected boards and their serial numbers is the list subcommand:
pytactl list
It prints every recognised debug board with its type, USB vendor/product ID, and serial number
(read from udev, the same ID_SERIAL_SHORT value you pass to --serial):
Connected debug boards:
Bughopper V1 vid:pid=0403:6015 serial=DP05DIAN
PSOC vid:pid=05c6:9302 serial=0123456789
Alternatively, find it manually with udevadm:
udevadm info /dev/ttyACM0 | grep ID_SERIAL_SHORT
Or using lsusb (replace VID:PID with 0403:6011 for FTDI or 05c6:9302 for PSOC):
lsusb -v -d VID:PID | grep iSerial
Using as a shell
Start the interactive shell with the shell subcommand:
pytactl shell --serial <ID_SERIAL_SHORT>
Optional arguments:
--tac-config-path <dir> # path to config directory (required for FTDI/PSOC boards, see Configuration)
--log-level DEBUG # log verbosity (default: DEBUG)
Once started, the shell prompt accepts commands generated from your board's config script. The available commands depend on the config — not all boards define every command (e.g. newer configs may omit powerOn/powerOff). Typical commands:
Power control:
powerOn
powerOff
devicePowerOn
devicePowerOff
usbDevicePowerOn
usbDevicePowerOff
Boot modes:
bootToEDL
bootToFastboot
bootToUEFI
reset
GPIO pins (use with 1 to assert, 0 to deassert):
pkey 1 # press power key
pkey 0 # release power key
volup 1
voldn 1
Type help in the shell to list all commands available for your specific board.
Running a single command
Use the oneshot subcommand to run one command and exit, without entering the interactive
shell. This is handy for scripting:
pytactl oneshot bootToEDL --serial <ID_SERIAL_SHORT>
pytactl oneshot reset --serial <ID_SERIAL_SHORT>
GPIO pin commands take an integer value (1 to assert, 0 to deassert):
pytactl oneshot pkey 1 --serial <ID_SERIAL_SHORT>
pytactl oneshot pkey 0 --serial <ID_SERIAL_SHORT>
The same commands available in the shell can be used here. An unknown command exits with an error listing the commands supported by your board.
Using as a service
pytactl service --serial <ID_SERIAL_SHORT_1> [<ID_SERIAL_SHORT_2> ...]
The REST API runs on http://localhost:5000. Example usage with curl:
# List connected boards
curl http://localhost:5000/
# List available quick methods (bootToEDL, powerOn, etc.)
curl http://localhost:5000/<boardid>/quick
# Power on/off
curl -X PUT http://localhost:5000/<boardid>/quick/powerOn
curl -X PUT http://localhost:5000/<boardid>/quick/powerOff
# Boot to EDL
curl -X PUT http://localhost:5000/<boardid>/quick/bootToEDL
# Boot to fastboot
curl -X PUT http://localhost:5000/<boardid>/quick/bootToFastboot
# Set a named pin
curl -X PUT "http://localhost:5000/<boardid>/command/reset?value=1"
# Set a raw pin (e.g., bus A, pin 0)
curl -X PUT "http://localhost:5000/<boardid>/pin/A0?value=1"
Note: REST API server runs in debug mode. Running with multiple concurrent threads may lead to unexpected behaviour.
License
pytactl is licensed under the BSD-3-clause License. See LICENSE for the full license text.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pytactl-2.0.0.tar.gz.
File metadata
- Download URL: pytactl-2.0.0.tar.gz
- Upload date:
- Size: 28.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3ee9d9a8925696c9e89b986b3ea7cc5a2d9b8b4ee0e5d76adec15e343e9df09f
|
|
| MD5 |
a71a5f9f28f2f50c317f118f409056f1
|
|
| BLAKE2b-256 |
5e3fd79e73c342573e89e2eeca0790ac7c108152c1d534b4f67b4931c17c6dad
|
Provenance
The following attestation bundles were made for pytactl-2.0.0.tar.gz:
Publisher:
publish.yml on qualcomm/pytactl
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pytactl-2.0.0.tar.gz -
Subject digest:
3ee9d9a8925696c9e89b986b3ea7cc5a2d9b8b4ee0e5d76adec15e343e9df09f - Sigstore transparency entry: 2551036173
- Sigstore integration time:
-
Permalink:
qualcomm/pytactl@6ee43578f983487821ade4feebebad94198da622 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/qualcomm
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@6ee43578f983487821ade4feebebad94198da622 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file pytactl-2.0.0-py3-none-any.whl.
File metadata
- Download URL: pytactl-2.0.0-py3-none-any.whl
- Upload date:
- Size: 23.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4b69bba90fe1e725d9ee0a38e2aa5cdde56340cbfbe6f9ed98162cdd31a828b1
|
|
| MD5 |
6471fc95cf595b26503113d0b0f29674
|
|
| BLAKE2b-256 |
ec38a354193fba456fabfd9ca719c5838d8eb85f1e37470de922fd79de38c876
|
Provenance
The following attestation bundles were made for pytactl-2.0.0-py3-none-any.whl:
Publisher:
publish.yml on qualcomm/pytactl
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pytactl-2.0.0-py3-none-any.whl -
Subject digest:
4b69bba90fe1e725d9ee0a38e2aa5cdde56340cbfbe6f9ed98162cdd31a828b1 - Sigstore transparency entry: 2551036254
- Sigstore integration time:
-
Permalink:
qualcomm/pytactl@6ee43578f983487821ade4feebebad94198da622 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/qualcomm
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@6ee43578f983487821ade4feebebad94198da622 -
Trigger Event:
workflow_dispatch
-
Statement type: