Skip to main content

python-cybro

GitHub Release PyPI Python Versions License

GitHub Activity Code Coverage pre-commit Ruff

Project Maintenance

Asynchronous Python client for the Cybrotech scgi server. Use it to read and write variables of Cybro / HIQ PLCs through the scgi server's HTTP interface.

Requirements

  • Python 3.11 or newer
  • A running Cybrotech scgi server v3.2.6 or newer (tested with v3.2.6 and v3.3.1; earlier versions are not supported). You can install the server natively, or run it as a Docker container: dockerhub

Installation

pip install cybro

Usage

import asyncio

from cybro import Cybro


async def main() -> None:
    nad = 10000  # network address (NAD) of the PLC
    prefix = f"c{nad}."

    async with Cybro("192.168.1.100", port=4000, nad=nad) as cybro:
        # The first update reads server and PLC information.
        # It must run before variables can be added, read or written.
        device = await cybro.update()
        print("Server version:", device.server_info.server_version)
        print("Controllers:", device.server_info.nad_list)
        print("PLC status:", device.plc_info.plc_status)

        # Register variables that every following update() should refresh.
        cybro.add_var(f"{prefix}scan_time")
        cybro.add_var(f"{prefix}sys.response_time")

        device = await cybro.update()
        for name in device.user_vars:
            print(name, "->", device.vars[name].value)

        # Read and write single variables.
        print(await cybro.read_var(f"{prefix}lc00_qx00"))
        await cybro.write_var(f"{prefix}lc00_qx00", "1")


asyncio.run(main())

A longer example lives in examples/control.py.

Connecting

Cybro(host_str, port=4000, nad=0, session=None)

  • host_str can be a plain host name or IP address, or a URL with a path, e.g. http://example.com/scgi. The scheme is ignored; requests always use HTTP.
  • nad is the network address of the PLC. It is needed for PLC information and for add_var(). With nad=0 (the default), only server information is read. See Server only (nad=0).
  • session lets you pass your own aiohttp.ClientSession; you stay responsible for closing it. Otherwise one is created on the first request and closed when leaving async with Cybro(...) or calling await cybro.disconnect().

Reading data

await cybro.update(full_update=False, plc_nad=0, device_type=0) returns a Device:

Attribute Content
device.server_info Server data: version, uptime, request counters, active NADs (nad_list)
device.plc_info PLC data: IP/port, status, response time, ALC file, available variables
device.vars All read variables by name (Var objects); only variables that have been read
device.var_info Type and description of every PLC variable (VarInfo objects), values are not included
device.user_vars Variables registered with add_var()
  • The first call (or full_update=True) reads server and PLC information. Later calls only refresh the variables registered with add_var().
  • Set device_type=1 for HIQ controllers to also read their HIQ-specific variables.
  • plc_nad sets the PLC address if none was given to Cybro(). It only takes effect on the very first update() call.

Server only (nad=0)

Without a NAD, update() reads only the server information. Use this to check that the server is reachable, or to list the controllers it knows (device.server_info.nad_list). In this mode:

  • device.plc_info is None.
  • cybro.add_var(name) only accepts system variables (c<nad>.sys.*). Pass allow_all=True to register other variables.
  • read_var() and write_var() work with full variable names, e.g. c10000.scan_time.

To work with a PLC, create the Cybro object with its NAD.

Variables

  • cybro.add_var(name) registers a variable for update(). Only variables listed in the PLC's ALC file and system variables (c<nad>.sys.*) are accepted; pass allow_all=True to add any name.
  • cybro.remove_var(name) removes it again.
  • await cybro.read_var(name) and await cybro.write_var(name, value) read or write a single variable immediately.

Values are returned as strings. Each Var in device.vars has helpers to convert them: value_int(), value_float() and value_bool().

Errors

All exceptions derive from CybroError, so catching it is enough:

Exception Raised when
CybroConnectionError The scgi server cannot be reached
CybroConnectionTimeoutError The scgi server does not answer in time
CybroEmptyResponseError The scgi server returns an empty response
CybroPlcNotFoundError The PLC information for the NAD is missing
CybroError Any other error, e.g. add_var() or read_var() before update()

Connection errors, timeouts and server errors (HTTP 5xx) are retried up to three times before an exception is raised. Client errors (HTTP 4xx) are raised immediately. Writes are retried too, so after a timeout a write may reach the PLC twice.

Development

The project uses Poetry. A ready-to-use dev container is included for VS Code.

poetry install
poetry run pytest
poetry run pre-commit install  # run Ruff, prettier and the tests before every commit

Contributing

Contributions are welcome! Please read the contribution guidelines first.

License

MIT


Metadata

Release files for cybro 0.4.1

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

Source distribution (sdist)

Source distribution for cybro 0.4.1
File Size Uploaded
cybro-0.4.1.tar.gz 16.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for cybro 0.4.1
File Interpreter ABI Platform
cybro-0.4.1-py3-none-any.whl Python 3 none any Details

Total release size: 30.4 kB

Release files / cybro-0.4.1.tar.gz

Download URL cybro-0.4.1.tar.gz
Size 16.2 kB
Tags Source
SHA-256 checksum
How to use checksums
5b20f00871b55ccb73236261265c6f13a28e82257f6a1e9fc902c72ec5ac85ce
BLAKE2b-256 checksum
How to use checksums
bcf4b28712476dce3c820df63d02c08b0dd05bf9c9765f9e21e953a51c7d5d97
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release files / cybro-0.4.1-py3-none-any.whl

Download URL cybro-0.4.1-py3-none-any.whl
Size 14.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
ad86140a95e95f8b47d6463d93944d696090f21812d676c8355c6257f1bb3b80
BLAKE2b-256 checksum
How to use checksums
96b9625aeb9a9b72c1883c4b1d2068c6a11b2d4f53f0d95bd1c01e95bceb9b4d
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

0.4.1 This release

2 release files

0.4.0

2 release files

0.3.1

2 release files

0.2.0

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.0

2 release files

0.0.9

2 release files

0.0.8

2 release files

0.0.7

2 release files

0.0.6

2 release files

0.0.5

2 release files

0.0.4

2 release files

0.0.3

2 release files

0.0.2

2 release files

0.0.1

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