npx skills add https://www.modelscope.cn/skills/@majiayu000/plc4x
smithery/oriolrius
plc4x
Expert guidance for Apache PLC4X industrial protocols library including Siemens S7, Modbus, OPC-UA, integration with Apache NiFi, connection strings, and field addressing. Use this when working with industrial automation and PLC communication.
Similar popular skills
Related neighbors and high-traction skills in the same topics — useful to compare before installing.
Guidance for distinctive, intentional visual design when building new UI or reshaping an existi…
866.4K installsBrowser automation CLI for AI agents. Use when the user needs to interact with websites, includ…
810.4K installsReview UI code for Web Interface Guidelines compliance. Use when asked to "review my UI", "chec…
617.3K installsBuild, deploy, evaluate, optimize, fine-tune, and manage Microsoft Foundry agents, models, and …
576.5K installsDebug Azure production issues on Azure using AppLens, Azure Monitor, resource health, and safe …
568.9K installsAlso in this package
Other skills from smithery/oriolrius.
npx skills add smithery/oriolrius
More details
Agent compatibility
Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.
Also listed on
Alternate registries and mirrors of this skill.
Package contents
Files included with this skill beyond the listing page.
-
skill md
SKILL.md10,702 B -
docs
SUMMARY.md256 B
History
- First recorded snapshot · 0 installs
SKILL.md
Apache PLC4X Expert Skill
You are an expert in Apache PLC4X, a universal protocol adapter for industrial automation that allows communication with PLCs using various protocols.
Core Concepts
Supported Protocols
- S7 (Siemens): S7-300, S7-400, S7-1200, S7-1500
- Modbus: TCP, RTU, ASCII
- OPC-UA: Industrial standard protocol
- Beckhoff ADS: TwinCAT PLCs
- EtherNet/IP: Allen-Bradley PLCs
- KNX: Building automation
- BACnet: Building automation
Architecture
Application Layer
↓
PLC4X API (Protocol-independent)
↓
Protocol Drivers (S7, Modbus, OPC-UA, etc.)
↓
Network Layer (TCP/IP, Serial, etc.)
↓
PLC Device
Connection Strings
Format
protocol://host:port/options?parameter1=value1¶meter2=value2
Examples by Protocol
Siemens S7
s7://192.168.1.100 # Default (rack=0, slot=0)
s7://192.168.1.100:102 # Custom port
s7://192.168.1.100?rack=0&slot=2 # S7-1200/1500 (slot 2)
s7://192.168.1.100?controller-type=S7_400 # Explicit controller type
Modbus TCP
modbus-tcp://192.168.1.200 # Default port 502
modbus-tcp://192.168.1.200:502 # Explicit port
modbus-tcp://192.168.1.200?unit-identifier=1 # Slave/unit ID
OPC-UA
opcua:tcp://192.168.1.50:4840 # Standard OPC-UA
opcua:tcp://192.168.1.50:4840?discovery=true # Enable discovery
opcua:tcp://user:[email protected]:4840 # With authentication
EtherNet/IP
eip://192.168.1.150 # Allen-Bradley PLC
Field Addressing
Siemens S7
# Data Blocks (DB)
DB1.DBB0 # Byte at DB1, offset 0
DB1.DBW2 # Word (2 bytes) at DB1, offset 2
DB1.DBD4 # Double word (4 bytes) at DB1, offset 4
DB1.DBX0.0 # Bit 0 at DB1, byte 0
# Memory Areas
%I0.0 # Input bit 0.0
%IB0 # Input byte 0
%IW0 # Input word 0
%ID0 # Input double word 0
%Q0.0 # Output bit 0.0
%QB0 # Output byte 0
%QW0 # Output word 0
%QD0 # Output double word 0
%M0.0 # Memory bit 0.0
%MB0 # Memory byte 0
%MW0 # Memory word 0
%MD0 # Memory double word 0
# Data Types
:BOOL # Boolean
:BYTE # Byte (8 bits)
:INT # Integer (16 bits)
:DINT # Double Integer (32 bits)
:REAL # Real (32-bit float)
:STRING(10) # String with max length
Modbus
# Function Codes
holding-register:0 # Read Holding Register (FC03)
input-register:0 # Read Input Register (FC04)
coil:0 # Read Coil (FC01)
discrete-input:0 # Read Discrete Input (FC02)
# Extended addressing
holding-register:0:INT # As 16-bit integer
holding-register:0:REAL # As 32-bit float (2 registers)
holding-register:0[10] # Array of 10 registers
OPC-UA
# Node IDs
ns=2;s=MyVariable # String identifier
ns=2;i=1001 # Numeric identifier
ns=3;g=09087e75-8e5e-499b-954f-f2a9603db28a # GUID
Java API Usage
Basic Read Example
// Connect to PLC
try (PlcConnection connection = new PlcDriverManager()
.getConnection("s7://192.168.1.100")) {
// Build read request
PlcReadRequest request = connection.readRequestBuilder()
.addTagAddress("temperature", "DB1.DBD0:REAL")
.addTagAddress("pressure", "DB1.DBD4:REAL")
.addTagAddress("running", "DB1.DBX8.0:BOOL")
.build();
// Execute read
PlcReadResponse response = request.execute().get();
// Get values
float temp = response.getFloat("temperature");
float press = response.getFloat("pressure");
boolean running = response.getBoolean("running");
System.out.println("Temperature: " + temp);
System.out.println("Pressure: " + press);
System.out.println("Running: " + running);
}
Write Example
try (PlcConnection connection = new PlcDriverManager()
.getConnection("s7://192.168.1.100")) {
PlcWriteRequest request = connection.writeRequestBuilder()
.addTagAddress("setpoint", "DB1.DBD10:REAL", 75.5f)
.addTagAddress("enable", "DB1.DBX12.0:BOOL", true)
.build();
PlcWriteResponse response = request.execute().get();
if (response.getResponseCode("setpoint") == PlcResponseCode.OK) {
System.out.println("Write successful");
}
}
Subscription (Polling)
try (PlcConnection connection = new PlcDriverManager()
.getConnection("s7://192.168.1.100")) {
PlcSubscriptionRequest request = connection.subscriptionRequestBuilder()
.addCyclicTagAddress("sensor1", "DB1.DBW0:INT", Duration.ofSeconds(1))
.addCyclicTagAddress("sensor2", "DB1.DBW2:INT", Duration.ofSeconds(1))
.build();
PlcSubscriptionResponse response = request.execute().get();
response.getSubscriptionHandle("sensor1").register(event -> {
int value = event.getInteger("sensor1");
System.out.println("Sensor1: " + value);
});
}
NiFi Integration
PLC4X Processors in NiFi
GetPLC4X (Read from PLC)
Properties:
- PLC Connection String: s7://192.168.1.100
- Fields to Read: temperature:DB1.DBD0:REAL,pressure:DB1.DBD4:REAL,status:DB1.DBX8.0:BOOL
- Polling Interval: 1 sec
- Timeout: 5 sec
Output:
- FlowFile per polling cycle with attributes:
temperature=25.5
pressure=1.2
status=true
PutPLC4X (Write to PLC)
Properties:
- PLC Connection String: s7://192.168.1.100
- Fields to Write: setpoint:DB1.DBD10:REAL,enable:DB1.DBX12.0:BOOL
Input FlowFile Attributes:
setpoint=75.5
enable=true
Result: Values written to PLC
NiFi Flow Example
GetPLC4X (Read sensor data)
↓
RouteOnAttribute (Filter by status)
↓
UpdateAttribute (Add timestamp)
↓
JoltTransformJSON (Format data)
↓
PublishKafka (Send to analytics)
Expression Language in NiFi
# Read PLC value and use in flow
${plc.temperature} # Access temperature attribute
${plc.temperature:toNumber()} # Convert to number
${plc.temperature:gt(50)} # Compare value
Docker Deployment
Standalone PLC4X Application
FROM eclipse-temurin:11-jre
COPY plc4x-app.jar /app/
COPY plc4x-drivers/ /app/drivers/
CMD ["java", "-jar", "/app/plc4x-app.jar"]
With NiFi
services:
nifi:
image: apache/nifi:latest
volumes:
- ./nifi-plc4x-nar:/opt/nifi/nifi-current/lib/nifi-plc4x-nar.nar
environment:
- NIFI_WEB_HTTP_PORT=8080
networks:
- plc-network
networks:
plc-network:
driver: bridge
Data Type Mapping
S7 to Java
| S7 Type | PLC4X Type | Java Type |
|---|---|---|
| BOOL | BOOL | boolean |
| BYTE | USINT | byte |
| WORD | UINT | short |
| DWORD | UDINT | int |
| INT | INT | short |
| DINT | DINT | int |
| REAL | REAL | float |
| STRING | STRING | String |
| TIME | TIME | Duration |
| DATE | DATE | LocalDate |
Modbus to Java
| Modbus | PLC4X Type | Java Type |
|---|---|---|
| Coil | BOOL | boolean |
| Discrete Input | BOOL | boolean |
| Holding Register | UINT | short |
| Input Register | UINT | short |
| 2x Holding Reg | REAL | float |
Best Practices
Connection Management
// Use connection pooling for multiple requests
PlcConnectionManager manager = new CachedPlcConnectionManager();
try (PlcConnection connection = manager.getConnection(connectionString)) {
// Reuse connection
}
Error Handling
try {
PlcReadResponse response = request.execute().get(5, TimeUnit.SECONDS);
for (String tagName : response.getTagNames()) {
if (response.getResponseCode(tagName) == PlcResponseCode.OK) {
// Process value
} else {
// Handle error
System.err.println("Error reading " + tagName + ": " +
response.getResponseCode(tagName));
}
}
} catch (TimeoutException e) {
System.err.println("PLC read timeout");
} catch (ExecutionException e) {
System.err.println("PLC communication error: " + e.getMessage());
}
Performance Optimization
- Batch reads: Request multiple tags in one call
- Connection pooling: Reuse connections
- Appropriate polling intervals: Don't poll faster than needed
- Use subscriptions: More efficient than polling for frequent updates
Troubleshooting
Common Issues
| Issue | Solution |
|---|---|
| Connection timeout | Check IP, port, firewall, PLC rack/slot |
| Access denied | Verify PLC security settings, PUT/GET enabled |
| Invalid address | Check field addressing syntax, data block exists |
| Data type mismatch | Verify PLC data type matches field specification |
| Performance issues | Reduce polling frequency, batch requests |
Logging
<!-- logback.xml -->
<logger name="org.apache.plc4x" level="DEBUG"/>
<logger name="org.apache.plc4x.java.s7" level="TRACE"/>
Network Diagnostics
# Test TCP connection to PLC
nc -zv 192.168.1.100 102
# Monitor network traffic
tcpdump -i eth0 host 192.168.1.100 -w plc-traffic.pcap
# Analyze with Wireshark
wireshark plc-traffic.pcap
Siemens S7 Specific
Controller Types
- S7_300: Rack 0, Slot 2
- S7_400: Rack 0, Slot 3
- S7_1200: Rack 0, Slot 1
- S7_1500: Rack 0, Slot 1
Configuration Requirements
- Enable PUT/GET in PLC configuration
- Disable block protection for accessed DBs
- Configure network (IP, subnet, gateway)
- Allow external access in security settings
TIA Portal Setup
1. Open PLC Properties → Protection & Security
2. Connection mechanisms:
✓ Permit access with PUT/GET
3. Compile and download to PLC