Skip to main content

Agile-maintained Python wrapper for the TwinCAT ADS library, based on pyads

Project description

pyads-agile

pyads-agile is a Python wrapper for the Beckhoff TwinCAT ADS library.

This distribution is maintained by Agile Automation Technologies GmbH and is based on the excellent upstream pyads project created by Stefan Lehmann: https://github.com/stlehmann/pyads

pyads-agile intentionally stays drop-in compatible with pyads. The public API, module name (import pyads), and supported interpreter/OS matrix mirror upstream, so existing applications can switch distributions without code changes. Current validated support target is Python 3.13 (CI runs on 3.13).

Attribution

  • Original project: pyads by Stefan Lehmann
  • Fork maintainer: Filippo Boido filippo.boido@agileautomation.eu (Agile Automation Technologies GmbH)
  • License: MIT
  • This repository keeps upstream credit and license notices as required

See ACKNOWLEDGMENTS.md for details.

Installation

Install the distribution:

pip install pyads-agile

Import stays compatible:

import pyads

Versioning

pyads-agile uses its own independent Semantic Versioning (MAJOR.MINOR.PATCH). It does not mirror upstream pyads version numbers.

Scope

This package provides Python APIs for communicating with TwinCAT devices using:

  • TcAdsDll.dll on Windows
  • adslib.so on Linux

Agile-specific enhancements

Beyond compatibility, this fork currently focuses on improved RPC ergonomics:

  • Convenient RPC object proxies. Connection.get_object() exposes TwinCAT function blocks as Python objects and lets you configure return and parameter types per method:

    TwinCAT requirement: each callable method must be annotated in PLC code with {attribute 'TcRpcEnable'} directly above the method declaration.

    rpc = plc.get_object(
        "GVL.fbTestRemoteMethodCall",
        method_return_types={"m_iSimpleCall": pyads.PLCTYPE_INT},
    )
    result = rpc.m_iSimpleCall()
    
  • Multi-parameter RPC calls with native syntax. Configure method signatures once and then call methods like normal Python methods:

    rpc = plc.get_object(
        "GVL.fbTestRemoteMethodCall",
        method_return_types={"m_iSum": pyads.PLCTYPE_INT},
        method_parameters={"m_iSum": [pyads.PLCTYPE_INT, pyads.PLCTYPE_INT]},
    )
    result = rpc.m_iSum(5, 5)
    
  • Typed RPC interfaces for IntelliSense. Decorate a Python class with @pyads.ads_path("GVL.fbTestRemoteMethodCall"), annotate method arguments and return types with TwinCAT PLC types, and pass the class into Connection.get_object. The returned proxy is typed as your class so IDEs can offer completions:

    @pyads.ads_path("GVL.fbTestRemoteMethodCall")
    class FB_TestRemoteMethodCall:
        def m_iSum(
            self,
            a: pyads.PLCTYPE_INT,
            b: pyads.PLCTYPE_INT,
        ) -> pyads.PLCTYPE_INT:
            ...
    
    rpc = plc.get_object(FB_TestRemoteMethodCall)
    result = rpc.m_iSum(5, 5)
    

    You can still use low-level direct calls when needed:

    result = plc.call_rpc_method(
        "GVL.fbTestRemoteMethodCall#m_iSimpleCall",
        return_type=pyads.PLCTYPE_INT,
        write_value=42,
        write_type=pyads.PLCTYPE_INT,
    )
    
  • Serialized async ADS runtime. AsyncConnection executes all ADS calls on a dedicated worker thread per connection (in-order, race-safe on connection state), and exposes awaitable helpers and submit-style futures:

    import asyncio
    import pyads
    
    async def main() -> None:
        async with pyads.AsyncConnection("127.0.0.1.1.1", pyads.PORT_TC3PLC1) as plc:
            fut = plc.submit_sum_read(["GVL.int_val", "GVL.bool_val"])
            # ... do other work
            values = await fut
    
            await plc.sum_write({"GVL.int_val": int(values["GVL.int_val"]) + 1})
    
    asyncio.run(main())
    
  • Async wrappers for the synchronous pyads Connection API. AsyncConnection now mirrors the core synchronous read/write surface while keeping single-threaded serialized execution under the hood. For most methods you get both:

    • submit_* returning asyncio.Future
    • async method variant that awaits the same operation

    Covered wrappers include:

    • read, write, read_write
    • read_by_name, write_by_name
    • read_structure_by_name, write_structure_by_name
    • read_state, read_device_info, write_control
    • get_local_address, get_handle, release_handle, set_timeout
    • sum_read / sum_write (submit_sum_read / submit_sum_write)
    import asyncio
    import pyads
    
    async def main() -> None:
        async with pyads.AsyncConnection("127.0.0.1.1.1", pyads.PORT_TC3PLC1) as plc:
            # Await-style
            value = await plc.read_by_name("GVL.int_val", pyads.PLCTYPE_INT)
            await plc.write_by_name("GVL.int_val", value + 1, pyads.PLCTYPE_INT)
    
            # Submit-style
            fut = plc.submit_read_state()
            state = await fut
            print(state)
    
    asyncio.run(main())
    
  • Async typed RPC objects. Use @pyads.ads_async_path(...) with AsyncConnection.get_async_object(...) for type-safe async RPC interfaces. Method calls return asyncio.Future objects:

    @pyads.ads_async_path("GVL.fbTestRemoteMethodCall")
    class FB_TestRemoteMethodCall:
        def m_iSum(
            self,
            a: pyads.PLCTYPE_INT,
            b: pyads.PLCTYPE_INT,
        ) -> asyncio.Future[pyads.PLCTYPE_INT]:
            ...
    
    async def main(plc: pyads.AsyncConnection) -> None:
        rpc = plc.get_async_object(FB_TestRemoteMethodCall)
        future = rpc.m_iSum(5, 5)
        result = await future
        print(result)
    
  • Native stepchain async RPC interfaces. Use @pyads.ads_async_path(...) on the interface, inherit from pyads.StepChainRpcInterface, and mark stepchain entry methods with @pyads.stepchain_start. Calls return a StepChainOperation containing:

    • accepted: RPC-return phase
    • done: completion phase based on PLC status fields
    • await op: completion snapshot with the latest ADS status symbol values The generic parameter on StepChainOperation[...] describes the ADS transport return type for the accepted phase.
    @pyads.ads_async_path("GVL.fbTestRemoteStepChainMethodCall")
    class FB_TestRemoteStepChainMethodCall(pyads.StepChainRpcInterface):
        __stepchain_completion__ = "poll"  # or "notify"
    
        @pyads.stepchain_start
        def m_xStartStepChain(
            self,
            udiRequestId: pyads.PLCTYPE_UDINT,
        ) -> pyads.StepChainOperation[pyads.PLCTYPE_BOOL]:
            ...
    
    async def run_stepchain(plc: pyads.AsyncConnection) -> None:
        rpc = plc.get_async_object(FB_TestRemoteStepChainMethodCall)
        status_root = rpc.status_symbol()
    
        # udiRequestId is auto-generated if omitted.
        op = rpc.m_xStartStepChain()
    
        accepted = await op.accepted
        if not accepted:
            raise RuntimeError("Stepchain start rejected by PLC.")
    
        # Wait until status reports completion or error and capture snapshot.
        completion_snapshot = await op
        request_id_symbol = f"{status_root}.udiRequestId"
        print("Completed request", completion_snapshot[request_id_symbol])
    
        # Built-in framework status read (predefined structure)
        status = await rpc.read_status()
        print(status["udiStep"], status["sStepName"])
    

    Completion backend options:

    • completion="poll": periodic sum_read checks (poll_interval/timeout_s)
    • completion="notify": ADS notifications trigger status reads in asyncio

    Built-in predefined stepchain status fields:

    • udiRequestId, xBusy, xDone, xError, diErrorCode, udiStep, sStepName

    Repository references:

Features

  • connect to remote TwinCAT devices
  • create routes on Linux and on remote PLCs
  • support for TwinCAT 2 and TwinCAT 3
  • read and write values by name or by address
  • read and write DUTs (structures)
  • notification callbacks
  • typed RPC interfaces via @pyads.ads_path(...)
  • async typed RPC interfaces via @pyads.ads_async_path(...)
  • serialized asyncio runtime via pyads.AsyncConnection
  • async wrappers for core sync ADS methods (submit_* + awaitable variants)
  • async typed RPC proxies via get_async_object(...)
  • native stepchain async RPC flow via StepChainRpcInterface + @pyads.stepchain_start
  • stepchain completion backends: polling (poll) and notification-driven (notify)

Basic usage

import pyads

plc = pyads.Connection("127.0.0.1.1.1", pyads.PORT_TC3PLC1)
plc.open()
i = plc.read_by_name("GVL.int_val")
plc.write_by_name("GVL.int_val", i)
plc.close()

Contribution Policy

This repository is maintained on a best-effort basis for internal and product needs.

At this time, we do not accept unsolicited pull requests, and we may not be able to respond to feature requests or general support issues.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pyads_agile-0.3.3.tar.gz (304.1 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

pyads_agile-0.3.3-py3-none-win_arm64.whl (96.1 kB view details)

Uploaded Python 3Windows ARM64

pyads_agile-0.3.3-py3-none-win_amd64.whl (96.1 kB view details)

Uploaded Python 3Windows x86-64

pyads_agile-0.3.3-py3-none-win32.whl (96.1 kB view details)

Uploaded Python 3Windows x86

pyads_agile-0.3.3-py3-none-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl (260.6 kB view details)

Uploaded Python 3manylinux: glibc 2.24+ x86-64manylinux: glibc 2.28+ x86-64

pyads_agile-0.3.3-py3-none-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl (238.9 kB view details)

Uploaded Python 3manylinux: glibc 2.24+ ARM64manylinux: glibc 2.28+ ARM64

pyads_agile-0.3.3-py3-none-macosx_11_0_arm64.whl (191.1 kB view details)

Uploaded Python 3macOS 11.0+ ARM64

pyads_agile-0.3.3-py3-none-macosx_10_15_x86_64.whl (196.9 kB view details)

Uploaded Python 3macOS 10.15+ x86-64

File details

Details for the file pyads_agile-0.3.3.tar.gz.

File metadata

  • Download URL: pyads_agile-0.3.3.tar.gz
  • Upload date:
  • Size: 304.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for pyads_agile-0.3.3.tar.gz
Algorithm Hash digest
SHA256 ff17a49f266bff57d26085e8514b2f239dcdb5468b1ac22eec4d7b8ea241fc3a
MD5 b235bc0d0ba81babea1921a80f8c290c
BLAKE2b-256 4b9125ec9526856cba168e14941a1ca5776f5c7cef54c986899f6fe301ddc948

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyads_agile-0.3.3.tar.gz:

Publisher: python-publish.yml on AgileAutomationTechnologies/pyads-agile

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pyads_agile-0.3.3-py3-none-win_arm64.whl.

File metadata

  • Download URL: pyads_agile-0.3.3-py3-none-win_arm64.whl
  • Upload date:
  • Size: 96.1 kB
  • Tags: Python 3, Windows ARM64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for pyads_agile-0.3.3-py3-none-win_arm64.whl
Algorithm Hash digest
SHA256 b6948d6c828dfa76c315f9fe0928e3d6776c37786ab3cb49080d992f3cdef736
MD5 ade48c29dcb2dc849b12126ba8f4ca12
BLAKE2b-256 bce761b96fec131d3d6650918cacaee64bdb312037c97e378471b821df1128d0

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyads_agile-0.3.3-py3-none-win_arm64.whl:

Publisher: python-publish.yml on AgileAutomationTechnologies/pyads-agile

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pyads_agile-0.3.3-py3-none-win_amd64.whl.

File metadata

  • Download URL: pyads_agile-0.3.3-py3-none-win_amd64.whl
  • Upload date:
  • Size: 96.1 kB
  • Tags: Python 3, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for pyads_agile-0.3.3-py3-none-win_amd64.whl
Algorithm Hash digest
SHA256 37ca01eeed222a70938d880b45783083f7eb78f8c915518b16b4ecaa4398bffc
MD5 8417db5ff9887f69f75b8a52b34609e1
BLAKE2b-256 7d39caf5b72d3332163a0313c0e47576d8bb03f18ee86926aa0ca755c177bfcd

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyads_agile-0.3.3-py3-none-win_amd64.whl:

Publisher: python-publish.yml on AgileAutomationTechnologies/pyads-agile

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pyads_agile-0.3.3-py3-none-win32.whl.

File metadata

  • Download URL: pyads_agile-0.3.3-py3-none-win32.whl
  • Upload date:
  • Size: 96.1 kB
  • Tags: Python 3, Windows x86
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for pyads_agile-0.3.3-py3-none-win32.whl
Algorithm Hash digest
SHA256 ccf271d7835a247283c207053637d1b7f3be36a978f71186ae70fc50a29d2f88
MD5 6f7a8327c187f6b9b3d1058a65a33961
BLAKE2b-256 27b0bb7eed726ce5cd847121bb4318f8b9bdb09c16acac8d7261323c07bf6351

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyads_agile-0.3.3-py3-none-win32.whl:

Publisher: python-publish.yml on AgileAutomationTechnologies/pyads-agile

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pyads_agile-0.3.3-py3-none-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for pyads_agile-0.3.3-py3-none-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 2716108263498324308d8b7b1efe672013492b60f831f00f119b969107a502a1
MD5 2b71d2a9e51c07676f2b5f2ac3bfb7fd
BLAKE2b-256 c3ad7c7eafa6e9cc7fda3f91808482772aaa79c45f47e384c0e8d073561f237e

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyads_agile-0.3.3-py3-none-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl:

Publisher: python-publish.yml on AgileAutomationTechnologies/pyads-agile

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pyads_agile-0.3.3-py3-none-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for pyads_agile-0.3.3-py3-none-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 327f319d3a716584407d9dff0bd3cde7bf3a41f6b88042dbfba1c2e2b8d06a7f
MD5 8894bcceb74cae36ed8d5df7fb64bd20
BLAKE2b-256 812bdb8a3328056738cbeba91b035c577c93ce3ad511f419099380e24871590f

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyads_agile-0.3.3-py3-none-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl:

Publisher: python-publish.yml on AgileAutomationTechnologies/pyads-agile

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pyads_agile-0.3.3-py3-none-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for pyads_agile-0.3.3-py3-none-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 021ed8628d9604ba16fb8263b886e91d02de5b0447820e54c6c52e44b6927958
MD5 61996bb089cd640449fb1fdfa0d7fcd6
BLAKE2b-256 8b02bd9542f7bac5cf630352f5baaa30b86dd2c4fa28ff34d511129839bdfa00

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyads_agile-0.3.3-py3-none-macosx_11_0_arm64.whl:

Publisher: python-publish.yml on AgileAutomationTechnologies/pyads-agile

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pyads_agile-0.3.3-py3-none-macosx_10_15_x86_64.whl.

File metadata

File hashes

Hashes for pyads_agile-0.3.3-py3-none-macosx_10_15_x86_64.whl
Algorithm Hash digest
SHA256 29a9d2d8d72baba389f3306161376dcc46afe75a01941e4a8a9bff490ca90f33
MD5 3948f601407c2fdd5b048572dd79b932
BLAKE2b-256 9b86a2f810328dddccdb926f50b165a08ed7e91014688750534c186e3e61995a

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyads_agile-0.3.3-py3-none-macosx_10_15_x86_64.whl:

Publisher: python-publish.yml on AgileAutomationTechnologies/pyads-agile

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page