0
# Core Tag Operations
1
2
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.
3
4
## Capabilities
5
6
### Single Tag Reading
7
8
Read individual tag values from the PLC with automatic data type detection and conversion.
9
10
```python { .api }
11
def Read(tag, count=1, datatype=None):
12
"""
13
Read tag values from the PLC.
14
15
Args:
16
tag (str): Tag name to read (e.g., 'MyTag', 'MyArray[5]', 'MyUDT.Field')
17
count (int): Number of elements for array reads (default 1)
18
datatype (int, optional): Force specific CIP data type code
19
20
Returns:
21
Response: Object with TagName, Value, and Status
22
"""
23
```
24
25
**Usage Examples:**
26
27
```python
28
from pylogix import PLC
29
30
with PLC() as comm:
31
comm.IPAddress = '192.168.1.100'
32
33
# Read a simple tag
34
response = comm.Read('TemperatureSetpoint')
35
print(f"Temperature: {response.Value}°C")
36
37
# Read an array element
38
response = comm.Read('RecipeData[0]')
39
40
# Read a UDT field
41
response = comm.Read('Motor1.Status.Running')
42
43
# Read with specific data type (force REAL)
44
response = comm.Read('ProcessValue', datatype=0xca)
45
```
46
47
### Array Reading
48
49
Read multiple consecutive elements from array tags with optimized batch operations.
50
51
```python { .api }
52
def Read(tag, count, datatype=None):
53
"""
54
Read array elements from the PLC.
55
56
Args:
57
tag (str): Array tag name with starting index (e.g., 'MyArray[0]')
58
count (int): Number of consecutive elements to read
59
datatype (int, optional): Force specific CIP data type code
60
61
Returns:
62
Response: Object with TagName, Value (list), and Status
63
"""
64
```
65
66
**Usage Examples:**
67
68
```python
69
# Read 10 elements from an array starting at index 0
70
response = comm.Read('ProcessData[0]', 10)
71
if response.Status == 'Success':
72
for i, value in enumerate(response.Value):
73
print(f"ProcessData[{i}]: {value}")
74
75
# Read a portion of an array starting from index 5
76
response = comm.Read('RecipeValues[5]', 3)
77
# Returns RecipeValues[5], RecipeValues[6], RecipeValues[7]
78
```
79
80
### Batch Tag Reading
81
82
Read multiple different tags in a single optimized request, reducing network overhead and improving performance.
83
84
```python { .api }
85
def Read(tags):
86
"""
87
Read multiple tags in a batch operation.
88
89
Args:
90
tags (list): List of tag specifications, each can be:
91
- str: Simple tag name
92
- tuple: (tag_name, count) for arrays
93
- tuple: (tag_name, count, datatype) for typed arrays
94
95
Returns:
96
list[Response]: List of Response objects, one per tag
97
"""
98
```
99
100
**Usage Examples:**
101
102
```python
103
# Read multiple simple tags
104
tags = ['Temperature', 'Pressure', 'FlowRate', 'Status']
105
responses = comm.Read(tags)
106
for resp in responses:
107
print(f"{resp.TagName}: {resp.Value}")
108
109
# Mixed batch read with arrays and typed reads
110
mixed_tags = [
111
'SetPoint', # Simple tag
112
('DataArray[0]', 5), # Array with 5 elements
113
('FloatValue', 1, 0xca), # Typed read (REAL)
114
'Motor.Speed' # UDT field
115
]
116
responses = comm.Read(mixed_tags)
117
```
118
119
### Single Tag Writing
120
121
Write values to individual PLC tags with automatic type conversion and validation.
122
123
```python { .api }
124
def Write(tag, value, datatype=None):
125
"""
126
Write a value to a PLC tag.
127
128
Args:
129
tag (str): Tag name to write to
130
value: Value to write (type depends on tag type)
131
datatype (int, optional): Force specific CIP data type code
132
133
Returns:
134
Response: Object with TagName, Value (written), and Status
135
"""
136
```
137
138
**Usage Examples:**
139
140
```python
141
with PLC() as comm:
142
comm.IPAddress = '192.168.1.100'
143
144
# Write integer value
145
response = comm.Write('SetPoint', 1500)
146
147
# Write float value
148
response = comm.Write('TemperatureLimit', 85.5)
149
150
# Write boolean value
151
response = comm.Write('EnableMotor', True)
152
153
# Write string value
154
response = comm.Write('OperatorMessage', "Process Complete")
155
156
# Write to UDT field
157
response = comm.Write('Recipe.BatchSize', 250)
158
159
# Check write success
160
if response.Status == 'Success':
161
print(f"Successfully wrote {response.Value} to {response.TagName}")
162
else:
163
print(f"Write failed: {response.Status}")
164
```
165
166
### Array Writing
167
168
Write values to array tags, supporting both single element and multi-element operations.
169
170
```python { .api }
171
def Write(tag, values, datatype=None):
172
"""
173
Write values to array tags.
174
175
Args:
176
tag (str): Array tag name with starting index
177
values (list): List of values to write
178
datatype (int, optional): Force specific CIP data type code
179
180
Returns:
181
Response: Object with TagName, Value (list written), and Status
182
"""
183
```
184
185
**Usage Examples:**
186
187
```python
188
# Write multiple values to an array
189
values = [10.5, 20.3, 15.7, 30.1, 25.9]
190
response = comm.Write('ProcessData[0]', values)
191
192
# Write to specific array positions
193
response = comm.Write('RecipeSteps[5]', [100, 200, 300])
194
195
# Write single value to array element
196
response = comm.Write('Setpoints[3]', 42.5)
197
```
198
199
### Batch Tag Writing
200
201
Write multiple different tags in a single operation for improved performance.
202
203
```python { .api }
204
def Write(write_data):
205
"""
206
Write multiple tags in a batch operation.
207
208
Args:
209
write_data (list): List of write specifications, each can be:
210
- tuple: (tag_name, value)
211
- tuple: (tag_name, value, datatype)
212
213
Returns:
214
list[Response]: List of Response objects, one per write operation
215
"""
216
```
217
218
**Usage Examples:**
219
220
```python
221
# Batch write multiple tags
222
write_operations = [
223
('Setpoint1', 100),
224
('Setpoint2', 200),
225
('EnableFlag', True),
226
('Description', "Batch Process"),
227
]
228
responses = comm.Write(write_operations)
229
230
# Check all write results
231
for resp in responses:
232
if resp.Status != 'Success':
233
print(f"Failed to write {resp.TagName}: {resp.Status}")
234
```
235
236
### Bit Operations
237
238
Special handling for reading and writing individual bits within integer tags.
239
240
**Reading Bits:**
241
242
```python
243
# Read specific bit from a DINT tag
244
response = comm.Read('StatusWord.5') # Read bit 5 of StatusWord
245
print(f"Bit 5 is: {response.Value}") # True or False
246
247
# Read multiple bits from a word
248
response = comm.Read('StatusBits[0]', 8) # Read 8 bits starting from bit 0
249
```
250
251
**Writing Bits:**
252
253
```python
254
# Write to a specific bit
255
response = comm.Write('ControlWord.3', True) # Set bit 3
256
response = comm.Write('ControlWord.7', False) # Clear bit 7
257
258
# Write multiple bits
259
bit_values = [True, False, True, False]
260
response = comm.Write('StatusBits[0]', bit_values)
261
```
262
263
### String Operations
264
265
Handle string data types including standard PLC strings and custom string formats.
266
267
**String Reading:**
268
269
```python
270
# Read standard string
271
response = comm.Read('OperatorMessage')
272
print(f"Message: {response.Value}")
273
274
# Read string array
275
response = comm.Read('MessageArray[0]', 5) # Read 5 strings
276
```
277
278
**String Writing:**
279
280
```python
281
# Write string value
282
response = comm.Write('DisplayText', "System Ready")
283
284
# Write multiple strings
285
messages = ["Start", "Running", "Complete", "Error", "Stopped"]
286
response = comm.Write('StatusMessages[0]', messages)
287
```
288
289
### Data Type Handling
290
291
PyLogix automatically handles data type conversion but also supports explicit type specification.
292
293
**Supported CIP Data Types:**
294
295
```python
296
# Common CIP data type codes
297
CIP_TYPES = {
298
0xc1: 'BOOL', # Boolean
299
0xc2: 'SINT', # 8-bit signed integer
300
0xc3: 'INT', # 16-bit signed integer
301
0xc4: 'DINT', # 32-bit signed integer
302
0xc5: 'LINT', # 64-bit signed integer
303
0xc6: 'USINT', # 8-bit unsigned integer
304
0xc7: 'UINT', # 16-bit unsigned integer
305
0xc8: 'UDINT', # 32-bit unsigned integer
306
0xca: 'REAL', # 32-bit float
307
0xcb: 'LREAL', # 64-bit float
308
0xda: 'STRING', # String type
309
0xa0: 'STRUCT', # Structure/UDT
310
}
311
```
312
313
**Explicit Type Usage:**
314
315
```python
316
# Force read as REAL even if tag appears as DINT
317
response = comm.Read('ProcessValue', datatype=0xca)
318
319
# Force write as specific type
320
response = comm.Write('ConfigValue', 42, datatype=0xc4) # Force DINT
321
```
322
323
### Error Handling and Status Codes
324
325
All operations return Response objects with detailed status information.
326
327
**Common Status Values:**
328
329
- `"Success"` - Operation completed successfully
330
- `"Path destination unknown"` - Tag name not found
331
- `"Connection failure"` - Cannot connect to PLC
332
- `"Service not supported"` - Operation not supported by PLC
333
- `"Object does not exist"` - Tag or path does not exist
334
- `"Invalid parameter value"` - Invalid data or parameters
335
336
**Error Handling Example:**
337
338
```python
339
response = comm.Read('UnknownTag')
340
if response.Status != 'Success':
341
if 'unknown' in response.Status.lower():
342
print("Tag not found - check tag name spelling")
343
elif 'connection' in response.Status.lower():
344
print("Connection issue - check IP address and network")
345
else:
346
print(f"Unexpected error: {response.Status}")
347
```