PLC TCP/IP bridge with client/server, IEC types, and utilities
Project description
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:
tkinterfor HMI (usually included with Python)
Examples
See the examples/ directory for complete working examples:
example_client.py- Simple client with monitoringexample_server.py- Echo server implementation
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/AmazingFeature) - Commit your changes (
git commit -m 'Add some AmazingFeature') - Push to the branch (
git push origin feature/AmazingFeature) - 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.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file plc_tcpip_bridge-0.1.0.tar.gz.
File metadata
- Download URL: plc_tcpip_bridge-0.1.0.tar.gz
- Upload date:
- Size: 22.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9a1aafd6f6616312fc91df7e0747d302b281bd96d942972977301ebd341c97c2
|
|
| MD5 |
97490f639ce658cd7c0223638369b914
|
|
| BLAKE2b-256 |
42ebee99ba561060277b9b1f8d0af21aa2bc8ff635d6276f5fc8f22c10ab432d
|
Provenance
The following attestation bundles were made for plc_tcpip_bridge-0.1.0.tar.gz:
Publisher:
publish.yaml on kkats-mech/plc-tcpip-bridge
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
plc_tcpip_bridge-0.1.0.tar.gz -
Subject digest:
9a1aafd6f6616312fc91df7e0747d302b281bd96d942972977301ebd341c97c2 - Sigstore transparency entry: 648706857
- Sigstore integration time:
-
Permalink:
kkats-mech/plc-tcpip-bridge@df8dbcdccb431d915632a7ad808a2421b129a07e -
Branch / Tag:
refs/heads/master - Owner: https://github.com/kkats-mech
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yaml@df8dbcdccb431d915632a7ad808a2421b129a07e -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file plc_tcpip_bridge-0.1.0-py3-none-any.whl.
File metadata
- Download URL: plc_tcpip_bridge-0.1.0-py3-none-any.whl
- Upload date:
- Size: 11.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d318eebb725f5d8e0cb5a0ba40d2a4d63c2835cc591d967011a0473a8f16f573
|
|
| MD5 |
06c94a626b9f92a40946acc123222742
|
|
| BLAKE2b-256 |
81cb886940846ed20542238bf282702d19e6b9c38d31fdd676758c75bef15c24
|
Provenance
The following attestation bundles were made for plc_tcpip_bridge-0.1.0-py3-none-any.whl:
Publisher:
publish.yaml on kkats-mech/plc-tcpip-bridge
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
plc_tcpip_bridge-0.1.0-py3-none-any.whl -
Subject digest:
d318eebb725f5d8e0cb5a0ba40d2a4d63c2835cc591d967011a0473a8f16f573 - Sigstore transparency entry: 648706870
- Sigstore integration time:
-
Permalink:
kkats-mech/plc-tcpip-bridge@df8dbcdccb431d915632a7ad808a2421b129a07e -
Branch / Tag:
refs/heads/master - Owner: https://github.com/kkats-mech
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yaml@df8dbcdccb431d915632a7ad808a2421b129a07e -
Trigger Event:
workflow_dispatch
-
Statement type: