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.2.tar.gz (303.8 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.2-py3-none-win_arm64.whl (95.9 kB view details)

Uploaded Python 3Windows ARM64

pyads_agile-0.3.2-py3-none-win_amd64.whl (95.9 kB view details)

Uploaded Python 3Windows x86-64

pyads_agile-0.3.2-py3-none-win32.whl (95.9 kB view details)

Uploaded Python 3Windows x86

pyads_agile-0.3.2-py3-none-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl (260.4 kB view details)

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

pyads_agile-0.3.2-py3-none-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl (238.6 kB view details)

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

pyads_agile-0.3.2-py3-none-macosx_11_0_arm64.whl (190.8 kB view details)

Uploaded Python 3macOS 11.0+ ARM64

pyads_agile-0.3.2-py3-none-macosx_10_15_x86_64.whl (196.7 kB view details)

Uploaded Python 3macOS 10.15+ x86-64

File details

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

File metadata

  • Download URL: pyads_agile-0.3.2.tar.gz
  • Upload date:
  • Size: 303.8 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.2.tar.gz
Algorithm Hash digest
SHA256 6932b772c5c2f786408595e8b014a270688ff7c81feafe1c303325eccb42977e
MD5 8e52a9e0921f46e04145d080b7f377d7
BLAKE2b-256 3fc5b21cc48c5061bfbfe50f421a12758e01987beace4ebc4b9e290005b35e1b

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyads_agile-0.3.2.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.2-py3-none-win_arm64.whl.

File metadata

  • Download URL: pyads_agile-0.3.2-py3-none-win_arm64.whl
  • Upload date:
  • Size: 95.9 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.2-py3-none-win_arm64.whl
Algorithm Hash digest
SHA256 0b192787a38950724c04607246c0c0f212649f99dfb2a68e323079c0d027b72a
MD5 c4d3e2d71e315b4058cabdf938fa56bd
BLAKE2b-256 d5f940ebf941ef4ca356b40b3cb001b686d54771dbb14d94aecebc0be5f791f3

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyads_agile-0.3.2-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.2-py3-none-win_amd64.whl.

File metadata

  • Download URL: pyads_agile-0.3.2-py3-none-win_amd64.whl
  • Upload date:
  • Size: 95.9 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.2-py3-none-win_amd64.whl
Algorithm Hash digest
SHA256 1e34bba7f1e5a1dfecbccd28ee4ad8f358c40a1917843e8a49cbee77e61b4e96
MD5 ad63c5b93d47dbb97dbd3a599e37aebd
BLAKE2b-256 3d1f35ec9c3f391272249d4286253c6af27fd5b064af62913f38f277b5db7b1f

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyads_agile-0.3.2-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.2-py3-none-win32.whl.

File metadata

  • Download URL: pyads_agile-0.3.2-py3-none-win32.whl
  • Upload date:
  • Size: 95.9 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.2-py3-none-win32.whl
Algorithm Hash digest
SHA256 7e57c7630fba559f105914b628da57b7e0200914ba687746b291703e270d49be
MD5 943bd319ba2dc7caa3327c22aadec270
BLAKE2b-256 ba30d254cfcc17c2ab3299a2ff18c4a7e8ae0a738088b021133b9c81428b47c6

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyads_agile-0.3.2-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.2-py3-none-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for pyads_agile-0.3.2-py3-none-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 fdd4a2945223c68acac0463fad9f93eb2d31bbc84575863238de3f05da1a1777
MD5 6af28de26ad0dd34a0cfaa57de80f70a
BLAKE2b-256 787b95c6352eff719dc4fc7f5ecc4595d2bf5d323237700b74b06cad5c3240c6

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyads_agile-0.3.2-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.2-py3-none-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for pyads_agile-0.3.2-py3-none-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 49fb2a02f266578b30092cc80bd2e19ded1f2df8b8f28352fdde7dabc2acdc40
MD5 016de7357431bd0e57006f9d5d18cd84
BLAKE2b-256 475ac6f1bc2dc6c463a28054c6c304e0b2708ef423335da47807ff2bfdeea076

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyads_agile-0.3.2-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.2-py3-none-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for pyads_agile-0.3.2-py3-none-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 7fa9a83253f8f9b9a81a9efc3dd3690c5df6b205366f3b4fe7c9d2c85dc0a0f2
MD5 eecd348d3d67fb2195a9ca9890a12c04
BLAKE2b-256 49206c987ef5ad5c6268bf3a365aa40fbd3e04ec759bd0a01497de602412b4f9

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyads_agile-0.3.2-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.2-py3-none-macosx_10_15_x86_64.whl.

File metadata

File hashes

Hashes for pyads_agile-0.3.2-py3-none-macosx_10_15_x86_64.whl
Algorithm Hash digest
SHA256 f4cdb81901d2f8fee5c16d701401f8eb58ca36ee6eeac3c1efa3694f03883e7c
MD5 768ca1d4dbbd3ba87cd188a042c5d899
BLAKE2b-256 48ac37630c32d8748a857e88c752bed7dab83111c120e422762dde412481a78b

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyads_agile-0.3.2-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