Communication driver for reading and writing data from Rockwell Automation ControlLogix, CompactLogix, and Micro8xx PLCs over Ethernet I/P
—
Essential read and write operations for PLC tags, forming the foundation of PyLogix functionality. These operations support individual tags, arrays, batch operations, and complex data types with automatic type detection and conversion.
Read individual tag values from the PLC with automatic data type detection and conversion.
def Read(tag, count=1, datatype=None):
"""
Read tag values from the PLC.
Args:
tag (str): Tag name to read (e.g., 'MyTag', 'MyArray[5]', 'MyUDT.Field')
count (int): Number of elements for array reads (default 1)
datatype (int, optional): Force specific CIP data type code
Returns:
Response: Object with TagName, Value, and Status
"""Usage Examples:
from pylogix import PLC
with PLC() as comm:
comm.IPAddress = '192.168.1.100'
# Read a simple tag
response = comm.Read('TemperatureSetpoint')
print(f"Temperature: {response.Value}°C")
# Read an array element
response = comm.Read('RecipeData[0]')
# Read a UDT field
response = comm.Read('Motor1.Status.Running')
# Read with specific data type (force REAL)
response = comm.Read('ProcessValue', datatype=0xca)Read multiple consecutive elements from array tags with optimized batch operations.
def Read(tag, count, datatype=None):
"""
Read array elements from the PLC.
Args:
tag (str): Array tag name with starting index (e.g., 'MyArray[0]')
count (int): Number of consecutive elements to read
datatype (int, optional): Force specific CIP data type code
Returns:
Response: Object with TagName, Value (list), and Status
"""Usage Examples:
# Read 10 elements from an array starting at index 0
response = comm.Read('ProcessData[0]', 10)
if response.Status == 'Success':
for i, value in enumerate(response.Value):
print(f"ProcessData[{i}]: {value}")
# Read a portion of an array starting from index 5
response = comm.Read('RecipeValues[5]', 3)
# Returns RecipeValues[5], RecipeValues[6], RecipeValues[7]Read multiple different tags in a single optimized request, reducing network overhead and improving performance.
def Read(tags):
"""
Read multiple tags in a batch operation.
Args:
tags (list): List of tag specifications, each can be:
- str: Simple tag name
- tuple: (tag_name, count) for arrays
- tuple: (tag_name, count, datatype) for typed arrays
Returns:
list[Response]: List of Response objects, one per tag
"""Usage Examples:
# Read multiple simple tags
tags = ['Temperature', 'Pressure', 'FlowRate', 'Status']
responses = comm.Read(tags)
for resp in responses:
print(f"{resp.TagName}: {resp.Value}")
# Mixed batch read with arrays and typed reads
mixed_tags = [
'SetPoint', # Simple tag
('DataArray[0]', 5), # Array with 5 elements
('FloatValue', 1, 0xca), # Typed read (REAL)
'Motor.Speed' # UDT field
]
responses = comm.Read(mixed_tags)Write values to individual PLC tags with automatic type conversion and validation.
def Write(tag, value, datatype=None):
"""
Write a value to a PLC tag.
Args:
tag (str): Tag name to write to
value: Value to write (type depends on tag type)
datatype (int, optional): Force specific CIP data type code
Returns:
Response: Object with TagName, Value (written), and Status
"""Usage Examples:
with PLC() as comm:
comm.IPAddress = '192.168.1.100'
# Write integer value
response = comm.Write('SetPoint', 1500)
# Write float value
response = comm.Write('TemperatureLimit', 85.5)
# Write boolean value
response = comm.Write('EnableMotor', True)
# Write string value
response = comm.Write('OperatorMessage', "Process Complete")
# Write to UDT field
response = comm.Write('Recipe.BatchSize', 250)
# Check write success
if response.Status == 'Success':
print(f"Successfully wrote {response.Value} to {response.TagName}")
else:
print(f"Write failed: {response.Status}")Write values to array tags, supporting both single element and multi-element operations.
def Write(tag, values, datatype=None):
"""
Write values to array tags.
Args:
tag (str): Array tag name with starting index
values (list): List of values to write
datatype (int, optional): Force specific CIP data type code
Returns:
Response: Object with TagName, Value (list written), and Status
"""Usage Examples:
# Write multiple values to an array
values = [10.5, 20.3, 15.7, 30.1, 25.9]
response = comm.Write('ProcessData[0]', values)
# Write to specific array positions
response = comm.Write('RecipeSteps[5]', [100, 200, 300])
# Write single value to array element
response = comm.Write('Setpoints[3]', 42.5)Write multiple different tags in a single operation for improved performance.
def Write(write_data):
"""
Write multiple tags in a batch operation.
Args:
write_data (list): List of write specifications, each can be:
- tuple: (tag_name, value)
- tuple: (tag_name, value, datatype)
Returns:
list[Response]: List of Response objects, one per write operation
"""Usage Examples:
# Batch write multiple tags
write_operations = [
('Setpoint1', 100),
('Setpoint2', 200),
('EnableFlag', True),
('Description', "Batch Process"),
]
responses = comm.Write(write_operations)
# Check all write results
for resp in responses:
if resp.Status != 'Success':
print(f"Failed to write {resp.TagName}: {resp.Status}")Special handling for reading and writing individual bits within integer tags.
Reading Bits:
# Read specific bit from a DINT tag
response = comm.Read('StatusWord.5') # Read bit 5 of StatusWord
print(f"Bit 5 is: {response.Value}") # True or False
# Read multiple bits from a word
response = comm.Read('StatusBits[0]', 8) # Read 8 bits starting from bit 0Writing Bits:
# Write to a specific bit
response = comm.Write('ControlWord.3', True) # Set bit 3
response = comm.Write('ControlWord.7', False) # Clear bit 7
# Write multiple bits
bit_values = [True, False, True, False]
response = comm.Write('StatusBits[0]', bit_values)Handle string data types including standard PLC strings and custom string formats.
String Reading:
# Read standard string
response = comm.Read('OperatorMessage')
print(f"Message: {response.Value}")
# Read string array
response = comm.Read('MessageArray[0]', 5) # Read 5 stringsString Writing:
# Write string value
response = comm.Write('DisplayText', "System Ready")
# Write multiple strings
messages = ["Start", "Running", "Complete", "Error", "Stopped"]
response = comm.Write('StatusMessages[0]', messages)PyLogix automatically handles data type conversion but also supports explicit type specification.
Supported CIP Data Types:
# Common CIP data type codes
CIP_TYPES = {
0xc1: 'BOOL', # Boolean
0xc2: 'SINT', # 8-bit signed integer
0xc3: 'INT', # 16-bit signed integer
0xc4: 'DINT', # 32-bit signed integer
0xc5: 'LINT', # 64-bit signed integer
0xc6: 'USINT', # 8-bit unsigned integer
0xc7: 'UINT', # 16-bit unsigned integer
0xc8: 'UDINT', # 32-bit unsigned integer
0xca: 'REAL', # 32-bit float
0xcb: 'LREAL', # 64-bit float
0xda: 'STRING', # String type
0xa0: 'STRUCT', # Structure/UDT
}Explicit Type Usage:
# Force read as REAL even if tag appears as DINT
response = comm.Read('ProcessValue', datatype=0xca)
# Force write as specific type
response = comm.Write('ConfigValue', 42, datatype=0xc4) # Force DINTAll operations return Response objects with detailed status information.
Common Status Values:
"Success" - Operation completed successfully"Path destination unknown" - Tag name not found"Connection failure" - Cannot connect to PLC"Service not supported" - Operation not supported by PLC"Object does not exist" - Tag or path does not exist"Invalid parameter value" - Invalid data or parametersError Handling Example:
response = comm.Read('UnknownTag')
if response.Status != 'Success':
if 'unknown' in response.Status.lower():
print("Tag not found - check tag name spelling")
elif 'connection' in response.Status.lower():
print("Connection issue - check IP address and network")
else:
print(f"Unexpected error: {response.Status}")Install with Tessl CLI
npx tessl i tessl/pypi-pylogix