Metadata-Version: 2.4
Name: pyads-agile
Version: 0.2.0
Summary: Agile-maintained Python wrapper for the TwinCAT ADS library, based on pyads
Author: Agile Automation Technologies GmbH
Maintainer: Agile Automation Technologies GmbH
License-Expression: MIT
Project-URL: Homepage, https://github.com/AgileAutomationTechnologies/pyads-agile
Project-URL: Repository, https://github.com/AgileAutomationTechnologies/pyads-agile.git
Project-URL: Issues, https://github.com/AgileAutomationTechnologies/pyads-agile/issues
Project-URL: Documentation, https://agileautomationtechnologies.github.io/pyads-agile/
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Software Development :: Libraries
Classifier: Operating System :: Microsoft :: Windows
Classifier: Operating System :: POSIX :: Linux
Requires-Python: <4,>=3.13
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: setuptools>=82.0.0
Provides-Extra: docs
Requires-Dist: sphinx; extra == "docs"
Requires-Dist: sphinx_rtd_theme; extra == "docs"
Requires-Dist: recommonmark; extra == "docs"
Provides-Extra: tests
Requires-Dist: pytest; extra == "tests"
Requires-Dist: pytest-cov; extra == "tests"
Requires-Dist: tox; extra == "tests"
Provides-Extra: dev
Requires-Dist: build; extra == "dev"
Requires-Dist: flake8; extra == "dev"
Requires-Dist: pytest; extra == "dev"
Requires-Dist: coverage; extra == "dev"
Requires-Dist: coveralls; extra == "dev"
Dynamic: license-file

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](ACKNOWLEDGMENTS.md) for details.

## Installation

Install the distribution:

```bash
pip install pyads-agile
```

Import stays compatible:

```python
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.

  ```python
  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:

  ```python
  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:

  ```python
  @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:

  ```python
  result = plc.call_rpc_method(
      "GVL.fbTestRemoteMethodCall#m_iSimpleCall",
      return_type=pyads.PLCTYPE_INT,
      write_value=42,
      write_type=pyads.PLCTYPE_INT,
  )
  ```

## 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

## Basic usage

```python
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.
