Skip to main content

PLC TCP/IP Bridge

A Python library for communicating with PLCs (Programmable Logic Controllers) over TCP/IP with a simple, intuitive API that can be scaled for multiple applications e.g. for PC HMIs, ROS and ROS2 applications.

Features

  • Dynamic Data Structures: Define PLC data layouts with named fields
  • IEC 61131-3 data types: Full support for PLC data types (BOOL, BYTE, WORD, DWORD, INT, DINT, REAL, LREAL, etc.)
  • Client & Server: Both TCP/IP client and server implementations
  • Auto-Reconnection: Built-in retry logic for robust industrial applications
  • Performance Monitoring: Loop frequency tracking, timing statistics, and connection health monitoring

Installation

From PyPI

pip install plc-tcpip-bridge

From Source

git clone https://github.com/kkats-mech/plc-tcpip-bridge.git
cd plc-tcpip-bridge
pip install -e .

Quick Start

Define PLC Data Structure

from plc_tcpip_bridge.dataframe import PLCData

# Define your PLC memory layout
plc_data = (PLCData()
    .add_field('motor_speed', 'I', 0)      # DWORD (32-bit)
    .add_field('temperature', 'f', 0.0)    # REAL (32-bit float)
    .add_field('status', 'H', 0)           # WORD (16-bit)
    .add_field('enabled', '?', False))     # BOOL

Client Example

from plc_tcpip_bridge.client import PLCClient

client = PLCClient("192.168.1.100", 502, plc_data)

if client.connect():
    # Send data
    send_data = plc_data.clone()
    send_data.set('motor_speed', 1500)
    send_data.set('temperature', 25.5)
    client.send(send_data)
    
    # Receive data
    recv_data = client.receive()
    if recv_data:
        print(f"Speed: {recv_data.get('motor_speed')}")
    
    client.close()

Server Example

from plc_tcpip_bridge.server import PLCServer

server = PLCServer(host='0.0.0.0', port=502, data_template=plc_data)
server.run()

Using Utilities

from plc_tcpip_bridge.utils import FrequencyMonitor, RateLimiter

freq_mon = FrequencyMonitor(print_interval=1.0)
rate_limiter = RateLimiter(target_hz=50)

while running:
    # Your PLC communication
    client.send(data)
    recv_data = client.receive()
    
    freq_mon.print_if_ready("Loop")  # Prints: "Loop: 50.23 Hz"
    rate_limiter.sleep()  # Maintains 50 Hz

Supported Data Types

PLC Type Format Python Type Size Range
BOOL ? bool 1 byte True/False
BYTE/USINT B int 1 byte 0-255
SINT b int 1 byte -128 to 127
WORD/UINT H int 2 bytes 0-65535
INT h int 2 bytes -32768 to 32767
DWORD/UDINT I int 4 bytes 0-4294967295
DINT i int 4 bytes -2147483648 to 2147483647
LWORD/ULINT Q int 8 bytes 0-2^64-1
LINT q int 8 bytes -2^63 to 2^63-1
REAL f float 4 bytes IEEE 754
LREAL d float 8 bytes IEEE 754
CHAR c str 1 byte Single character
STRING Ns str N bytes Fixed length (e.g., 10s)

Utilities

FrequencyMonitor

Track and display loop execution frequency.

freq_mon = FrequencyMonitor(print_interval=1.0)
freq_mon.print_if_ready("Client loop")

RateLimiter

Maintain consistent loop timing.

limiter = RateLimiter(target_hz=100)
limiter.sleep()  # Enforces 100 Hz rate

ConnectionMonitor

Track connection health and statistics.

conn_mon = ConnectionMonitor(alert_threshold=5)
conn_mon.record_success()  # or record_failure()
conn_mon.print_stats()

DataLogger

Log PLC data with timestamps.

logger = DataLogger(max_entries=1000)
logger.log({'speed': 1500, 'temp': 25.5})
logger.save_to_file('plc_log.json')

Watchdog

Detect stalled communication loops.

watchdog = Watchdog(timeout=5.0)
while running:
    watchdog.kick()  # Reset timer
    # ... communication ...
    if watchdog.check():  # Returns True if timeout
        break

Project Structure

plc-tcpip-bridge/
├── plc_tcpip_bridge/          # Main package
│   ├── __init__.py
│   ├── dataframe.py           # PLCData class
│   ├── client.py              # TCP/IP client
│   ├── server.py              # TCP/IP server
│   └── utils.py               # Utilities (monitoring, logging, etc.)
├── examples/                  # Example scripts
│   ├── example_client.py      # Basic client example
│   └── example_server.py      # Basic server example
├── test/                      # Test suite
│   ├── __init__.py            # Makes test a package
│   ├── test_dataframe.py      # PLCData tests
│   ├── test_client.py         # Client tests
│   ├── test_server.py         # Server tests
│   └── test_utils.py          # Utils tests
├── .gitignore                 # Git ignore rules
├── CITATION.cff               # Citation metadata
├── LICENSE                    # MIT License
├── MANIFEST.in                # Package manifest
├── README.md                  # Documentation
├── requirements.txt           # Dependencies
└── setup.py                   # Package setup

Requirements

  • Python 3.7+
  • No external dependencies for core library
  • Optional: tkinter for HMI (usually included with Python)

Examples

See the examples/ directory for complete working examples:

  • example_client.py - Simple client with monitoring
  • example_server.py - Echo server implementation

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/AmazingFeature)
  3. Commit your changes (git commit -m 'Add some AmazingFeature')
  4. Push to the branch (git push origin feature/AmazingFeature)
  5. Open a Pull Request

License

This project is licensed under the MIT License - see the LICENSE file for details.

Citation

If you use this software in your research, please cite it as:

@software{katsampiris_salgado_2025_plc_tcpip_bridge,
  author       = {Katsampiris Salgado, Konstantinos},
  title        = {PLC TCP/IP Bridge},
  year         = 2025,
  url          = {https://github.com/kkats-mech/plc-tcpip-bridge},
  version      = {0.1.0}
}

Or in text format:

Katsampiris Salgado, K. (2025). PLC TCP/IP Bridge (Version 0.1.0) [Computer software]. https://github.com/kkats-mech/plc-tcpip-bridge

You may also refer to the CITATION.cff file too.

Acknowledgments

Inspired by industrial automation needs based on my experience in robotics research projects.

Support

For issues, questions, or contributions, please open an issue on GitHub.

Roadmap

  • TBD

Handle with care. Use wisely. Do not drink and drive. Be responsible.

Metadata

Release files for plc-tcpip-bridge 0.1.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 plc-tcpip-bridge 0.1.0
File Size Uploaded
plc_tcpip_bridge-0.1.0.tar.gz 22.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for plc-tcpip-bridge 0.1.0
File Interpreter ABI Platform
plc_tcpip_bridge-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 33.9 kB

Release files / plc_tcpip_bridge-0.1.0.tar.gz

Download URL plc_tcpip_bridge-0.1.0.tar.gz
Size 22.0 kB
Tags Source
SHA-256 checksum
How to use checksums
9a1aafd6f6616312fc91df7e0747d302b281bd96d942972977301ebd341c97c2
BLAKE2b-256 checksum
How to use checksums
42ebee99ba561060277b9b1f8d0af21aa2bc8ff635d6276f5fc8f22c10ab432d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 28, 2025.

Transparency log

Release files / plc_tcpip_bridge-0.1.0-py3-none-any.whl

Download URL plc_tcpip_bridge-0.1.0-py3-none-any.whl
Size 11.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
d318eebb725f5d8e0cb5a0ba40d2a4d63c2835cc591d967011a0473a8f16f573
BLAKE2b-256 checksum
How to use checksums
81cb886940846ed20542238bf282702d19e6b9c38d31fdd676758c75bef15c24
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 28, 2025.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.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