Skip to main content

ABB Robot Communication SDK for Python

PyPI PyPI downloads Python Platforms License

UnderAutomation.ABB is a Python package that talks to ABB industrial robot controllers over Robot Web Services (RWS). The same code runs on IRC5 (RobotWare 6) and on OmniCore (RobotWare 7). Nothing is installed on the controller. No RobotStudio, no PC SDK, no ABB runtime.

Use it to read and write RAPID variables, control I/O, read positions, jog the robot, manage programs, files and backups, and follow the state of the controller, from a Python script. It works with real controllers and with the virtual controllers of RobotStudio.

What you can do

  • RAPID variables and programs: read and write variables, persistents and constants, start and stop tasks, move the program pointer, load and save modules.
  • Inputs / Outputs: list, read and write digital, analog and group signals, pulse, invert or simulate a signal, browse I/O devices and networks.
  • Position and kinematics: read the current robtarget and jointtarget, convert between Cartesian pose and joint values, jog the robot.
  • Controller and state: identity, options, operation mode, controller state, speed ratio, clock, language and network.
  • Backup and restore: create a full backup, check it, restore it.
  • File system: browse the controller file system, download and upload files, create, copy, rename and delete files and directories.
  • Event log: read the event log by domain, in the language you ask, and clear it.
  • System and energy: system product list, options and energy counters.
  • Mastership: request and release the edit and motion mastership.
  • Discovery: find the ABB controllers of the local network and the virtual controllers of this machine, without a license and without a known address.
  • One API for both controller generations: IRC5 (RWS 1.0) and OmniCore (RWS 2.0), only one connection parameter changes.

No ABB option is required on the controller. Robot Web Services is part of a standard system.

How it works

The package wraps the .NET library UnderAutomation.ABB.dll with pythonnet. The DLL is inside the package: pip install installs everything, including pythonnet.

  • Windows: the DLL runs on the .NET Framework 4.x of Windows. Nothing else to install.

  • Linux and macOS: install the .NET runtime (for example .NET 8), then tell pythonnet to use it before you start Python:

    export PYTHONNET_RUNTIME=coreclr
    

    Without this variable, pythonnet uses Mono, its default runtime on Linux and macOS. You can also choose the runtime in your code, before the first import of the package:

    from pythonnet import load
    load("coreclr")
    

Installation

Python 3.7 to 3.13 is supported (the limit of pythonnet 3.0.5). Install the package in a virtual environment:

python -m venv .venv
# Windows
.venv\Scripts\activate
# Linux and macOS
source .venv/bin/activate

pip install UnderAutomation.ABB

Or install it from the sources of this repository:

git clone https://github.com/underautomation/ABB.py.git
cd ABB.py
pip install -e .

Getting started

from underautomation.abb.abb_controller import AbbController

# The SDK runs in trial mode for 30 days. Register your key to remove the trial limit.
# AbbController.register_license("Your Company", "your-license-key")

robot = AbbController()
robot.connect("192.168.125.1")

identity = robot.rws.controller.get_identity()
print(identity.name)

robot.disconnect()

Choose the controller generation

The default is OmniCore (RWS 2.0). For an IRC5 controller, set the version to RwsVersion.Irc5_V1_0. The rest of your code does not change.

from underautomation.abb.abb_controller import AbbController
from underautomation.abb.connection_parameters import ConnectionParameters
from underautomation.abb.rws.rws_version import RwsVersion

params = ConnectionParameters("192.168.125.1")
params.rws.username = "Default User"
params.rws.password = "robotics"
params.rws.use_https = True                    # OmniCore is reached over HTTPS
params.rws.version = RwsVersion.OmniCore_V2_0  # or RwsVersion.Irc5_V1_0 for IRC5

robot = AbbController()
robot.connect(params)

Without the license layer

RwsClient is a standalone RWS client that you can use without AbbController:

from underautomation.abb.rws.rws_client import RwsClient
from underautomation.abb.rws.rws_version import RwsVersion

client = RwsClient()
client.connect("192.168.125.1", useHttps=True, version=RwsVersion.OmniCore_V2_0)
print(client.controller.get_identity().name)

From .NET names to Python names

The Python API is the .NET API with Python names. The .NET documentation applies to Python.

.NET Python
Method GetIdentity() get_identity()
Property Rws.Controller rws.controller
Static method AbbController.RegisterLicense(...) AbbController.register_license(...)
Enum value RwsVersion.OmniCore_V2_0 RwsVersion.OmniCore_V2_0
Array IoSignalItem[] list-like object, use list(...) to copy it
Nullable<int> int | None

Each type is in the module named after it, in snake case: UnderAutomation.ABB.Rws.Data.MastershipDomain is underautomation.abb.rws.data.mastership_domain.MastershipDomain.

The async methods of the .NET API (...Async) have no Python equivalent: use the synchronous methods.

Features

Everything is reached through robot.rws, grouped by service: controller, io, rapid, motion_system, panel, system, file, elog, mastership.

RAPID variables and programs

from underautomation.abb.rws.data.mastership_domain import MastershipDomain

# Read a RAPID symbol, the value comes back the way RAPID writes it
reg1 = robot.rws.rapid.get_symbol_value("RAPID/T_ROB1/user/reg1")
print(reg1.value)

# Write a symbol (needs the edit mastership in automatic mode)
robot.rws.mastership.request(MastershipDomain.Edit)
robot.rws.rapid.set_symbol_value("RAPID/T_ROB1/user/reg1", "42")
robot.rws.mastership.release(MastershipDomain.Edit)

# Start and stop the program
robot.rws.rapid.start()
robot.rws.rapid.stop()

# Load a program, list tasks, follow the execution state
robot.rws.rapid.load_program("T_ROB1", "HOME:/myprogram.pgf")
tasks = robot.rws.rapid.get_tasks()
state = robot.rws.rapid.get_execution_state()

Inputs / Outputs

# List every signal
signals = robot.rws.io.get_signals()

# Read one signal
di1 = robot.rws.io.get_signal("EtherNetIP", "d652", "DI_01")
print(di1.logical_value)

# Write, pulse or invert an output
robot.rws.io.set_signal_value("EtherNetIP", "d652", "DO_01", 1)
robot.rws.io.pulse_signal("EtherNetIP", "d652", "DO_01", 1, pulses=3)
robot.rws.io.invert_signal("EtherNetIP", "d652", "DO_01", 1)

# Simulate a signal so a value can be forced without hardware
robot.rws.io.set_signal_state("EtherNetIP", "d652", "DI_01", simulated=True)

Position and kinematics

from underautomation.abb.common.robot_joints import RobotJoints

# Current Cartesian and joint position of a task
rob_target = robot.rws.rapid.get_rob_target("T_ROB1")
joint_target = robot.rws.rapid.get_joint_target("T_ROB1")

print(f"X={rob_target.x} Y={rob_target.y} Z={rob_target.z}")
print(f"J1={joint_target.robot_axes.axis1} J2={joint_target.robot_axes.axis2}")

# Jog the robot
robot.rws.motion_system.set_jogging_mechanical_unit("ROB_1")
robot.rws.motion_system.jog(RobotJoints(5, 0, 0, 0, 0, 0), 0)

Discover controllers

# Finds the controllers of the local network and the virtual controllers of this machine.
# No connection is opened and no license is needed.
found = AbbController.discover()

for controller in found:
    print(f"{controller.system_name} at {controller.address}:{controller.port}")

# to_connection_parameters carries the address, the port, the scheme and the RWS version found
robot = AbbController()
robot.connect(found[0].to_connection_parameters())

Controller and state

from datetime import datetime

identity = robot.rws.controller.get_identity()
info = robot.rws.controller.get_info()

mode = robot.rws.panel.get_operation_mode()
state = robot.rws.panel.get_controller_state()
speed_ratio = robot.rws.panel.get_speed_ratio()

robot.rws.panel.set_speed_ratio(50)
robot.rws.controller.set_clock(datetime.now())

has_option = robot.rws.controller.has_option("RobotWare-OS")

Backup and restore

robot.rws.controller.create_backup("HOME:/backups/2026-01-15")

check = robot.rws.controller.check_restore("HOME:/backups/2026-01-15")
if check.is_accepted:
    robot.rws.controller.restore_backup("HOME:/backups/2026-01-15")

File system

listing = robot.rws.file.list_directory("HOME:/")
for d in listing.directories:
    print(d.name)
for f in listing.files:
    print(f"{f.name} ({f.size} bytes)")

robot.rws.file.upload_file_from_path("HOME:/myprogram.mod", r"C:\rapid\myprogram.mod")
robot.rws.file.get_file_to_destination("HOME:/myprogram.mod", r"C:\backup\myprogram.mod")
robot.rws.file.delete_file("HOME:/old.mod")

Event log

messages = robot.rws.elog.get_messages(domain=0, language="en")
for m in messages:
    print(f"{m.timestamp} {m.title}")

robot.rws.elog.clear_all_messages()

Mastership

from underautomation.abb.rws.data.mastership_domain import MastershipDomain

robot.rws.mastership.request(MastershipDomain.Motion)
# ... jog or move the robot ...
robot.rws.mastership.release(MastershipDomain.Motion)

Examples

The folder examples contains scripts ready to run, one folder per RWS service. examples/__init__.py holds the shared helpers: Python path, connection settings and license registration. The first run asks the address of the controller, the RWS credentials and the protocol version, and saves them in examples/robot_config.json (ignored by git). Press Enter to accept the value between brackets.

Run a script from the root of the repository:

python examples/system/system_info.py

Or choose a script in a menu. The launcher runs it in the same process, so a breakpoint set in an example file is hit:

python examples/launcher.py
Script What it does
license/license_info.py License state and every license property, no connection needed.
controller/controller_identity.py Name, serial id, type, MAC address, installed systems, options and network interfaces.
controller/controller_clock.py Reads the controller clock, its time zone and its time server, and sets the clock.
controller/controller_backup.py Reads the backup state and the content of a backup, and creates a new one under $temp.
system/system_info.py RobotWare version, options, robot types, installed products and energy counters.
panel/panel_state.py Controller state, operation mode, mode selector lock and collision detection.
panel/panel_speed_ratio.py Reads and writes the speed ratio, switches the motors on and off.
io/io_list_signals.py Lists every signal with its value and its state, and searches signals by name.
io/io_read_signal.py Reads one signal in detail: values, states, quality, timestamps, configuration.
io/io_write_signal.py Writes, inverts, pulses and simulates an output signal, then restores it.
io/io_networks_devices.py Browses the I/O topology: fieldbus networks, devices and their signals.
rapid/rapid_tasks.py Lists the tasks, reads one in detail, its program, its pointers and the execution state.
rapid/rapid_read_symbol.py Searches the RAPID symbols of a task and reads the value and properties of one.
rapid/rapid_write_symbol.py Takes the edit mastership, writes a variable, restores it and releases the mastership.
rapid/rapid_modules.py Lists the modules of a task, prints the source code and searches a text in it.
rapid/rapid_start_stop.py Resets the program pointer, starts the execution, follows its state and stops it.
motion/motion_mechanical_units.py Lists the mechanical units, their axes, their base frame and their calibration.
motion/motion_current_position.py Reads the current robtarget in each coordinate system, the jointtarget and the axes.
motion/motion_kinematics.py Forward and inverse kinematics on the controller, and every joint solution of a pose.
file/file_browse.py Walks the controller file system, enters directories and reads the content of a file.
file/file_transfer.py Uploads a local file under $temp, downloads it back and deletes it.
elog/elog_messages.py Lists the event log domains and reads their messages with causes and actions.
mastership/mastership_info.py Lists the mastership domains, shows who holds them, takes one and releases it.

Notes:

  • An example that only reads is safe on any controller. The examples that write ask before each change and put the original value back.
  • A virtual controller does not implement every resource of a real one. When it answers 404, the example prints the reason and continues.
  • A controller refuses a write when the mode selector is on manual and the FlexPendant keeps the ownership. The example prints the 403 answer instead of stopping.
  • The certificate of an OmniCore controller is signed by the controller itself. examples/__init__.py accepts it before the connection, see allow_self_signed_certificates().

IRC5 and OmniCore, one API

ABB controllers expose Robot Web Services in two versions. This SDK covers both. The same code runs on an IRC5 and on an OmniCore. Only the connection parameters change.

Controller RobotWare Robot Web Services RwsVersion value
IRC5 RobotWare 6 and earlier RWS 1.0 RwsVersion.Irc5_V1_0
OmniCore RobotWare 7 and later RWS 2.0 RwsVersion.OmniCore_V2_0

HTTP or HTTPS is a separate setting (use_https), independent of the controller generation.

Compatibility

  • Python: 3.7 to 3.13, with pythonnet 3.0.5.
  • Operating systems: Windows (.NET Framework), Linux and macOS (.NET runtime and export PYTHONNET_RUNTIME=coreclr).
  • Controllers: IRC5, OmniCore, and their virtual controllers in RobotStudio.

License

This SDK needs a commercial license. A 30-day trial starts at the first use, no key needed. After the trial, register your key in your code:

from underautomation.abb.abb_controller import AbbController

license_info = AbbController.register_license("Your Company", "your-license-key")
print(license_info.state)

Support

Metadata

Release files for UnderAutomation.ABB 1.1.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for UnderAutomation.ABB 1.1.0.0
File Size Uploaded
underautomation_abb-1.1.0.0.tar.gz 245.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for UnderAutomation.ABB 1.1.0.0
File Interpreter ABI Platform
underautomation_abb-1.1.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 577.8 kB

Release files / underautomation_abb-1.1.0.0.tar.gz

Download URL underautomation_abb-1.1.0.0.tar.gz
Size 245.6 kB
Tags Source
SHA-256 checksum
How to use checksums
1c1b12e8e2204a91a7a8a1d67f7726ab53f603ac8bd3cff2689da56877d73aa7
BLAKE2b-256 checksum
How to use checksums
911cfbaaec4fee425e0111ce2d6f5132ccb4e9c0ba6b39519671b1706e04d6ab
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release files / underautomation_abb-1.1.0.0-py3-none-any.whl

Download URL underautomation_abb-1.1.0.0-py3-none-any.whl
Size 332.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
81749e06c215faa749b51f409743830ff3774d2c9032b8418b392850a0c190d5
BLAKE2b-256 checksum
How to use checksums
ad8003a1ffdbc1111bb13cedc8e76e260d7c8b1b9b1e5202a1becc102ba416da
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release history Release notifications | RSS feed

This release

1.1.0.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page