0
# Read Operations
1
2
Type-safe data reading from PLC tags with comprehensive value conversion and validation for Apache PLC4X Java API.
3
4
## Capabilities
5
6
### PlcReadRequest
7
8
Interface for building and executing read requests to PLC tags.
9
10
```java { .api }
11
/**
12
* Read request interface for retrieving data from PLC tags
13
*/
14
public interface PlcReadRequest extends PlcTagRequest {
15
/**
16
* Execute the read request asynchronously
17
* @return CompletableFuture containing the read response
18
*/
19
CompletableFuture<? extends PlcReadResponse> execute();
20
21
/**
22
* Builder interface for constructing read requests
23
*/
24
interface Builder extends PlcRequestBuilder {
25
/**
26
* Add a tag by address string
27
* @param name Logical name for the tag
28
* @param tagAddress PLC-specific tag address string
29
* @return Builder instance for method chaining
30
*/
31
Builder addTagAddress(String name, String tagAddress);
32
33
/**
34
* Add a pre-parsed tag object
35
* @param name Logical name for the tag
36
* @param tag PlcTag instance
37
* @return Builder instance for method chaining
38
*/
39
Builder addTag(String name, PlcTag tag);
40
41
/**
42
* Build the read request
43
* @return PlcReadRequest instance ready for execution
44
*/
45
PlcReadRequest build();
46
}
47
}
48
```
49
50
### PlcReadResponse
51
52
Interface for accessing read response data with type-safe value extraction.
53
54
```java { .api }
55
/**
56
* Read response interface providing type-safe access to read values
57
*/
58
public interface PlcReadResponse extends PlcTagResponse {
59
/**
60
* Get the originating read request
61
* @return PlcReadRequest that generated this response
62
*/
63
PlcReadRequest getRequest();
64
65
/**
66
* Get single PlcValue (experimental - for single-tag requests)
67
* @return PlcValue for single-tag responses
68
*/
69
@Experimental
70
PlcValue getAsPlcValue();
71
72
/**
73
* Get PlcValue by tag name
74
* @param name Tag name from request
75
* @return PlcValue for the specified tag
76
*/
77
PlcValue getPlcValue(String name);
78
79
/**
80
* Get number of values for a tag (for array tags)
81
* @param name Tag name from request
82
* @return Number of values available
83
*/
84
int getNumberOfValues(String name);
85
86
// Type-specific getters with validation
87
/**
88
* Check if tag value is a valid boolean
89
* @param name Tag name
90
* @return true if value can be converted to boolean
91
*/
92
boolean isValidBoolean(String name);
93
94
/**
95
* Get boolean value for tag
96
* @param name Tag name
97
* @return boolean value
98
* @throws PlcIncompatibleDatatypeException if conversion fails
99
*/
100
boolean getBoolean(String name);
101
102
/**
103
* Get boolean value at specific index for array tags
104
* @param name Tag name
105
* @param index Array index
106
* @return boolean value at index
107
*/
108
boolean getBoolean(String name, int index);
109
110
/**
111
* Check if tag value is a valid byte
112
* @param name Tag name
113
* @return true if value can be converted to byte
114
*/
115
boolean isValidByte(String name);
116
117
/**
118
* Get byte value for tag
119
* @param name Tag name
120
* @return byte value
121
*/
122
byte getByte(String name);
123
124
/**
125
* Get byte value at specific index
126
* @param name Tag name
127
* @param index Array index
128
* @return byte value at index
129
*/
130
byte getByte(String name, int index);
131
132
/**
133
* Check if tag value is a valid short
134
* @param name Tag name
135
* @return true if value can be converted to short
136
*/
137
boolean isValidShort(String name);
138
139
/**
140
* Get short value for tag
141
* @param name Tag name
142
* @return short value
143
*/
144
short getShort(String name);
145
146
/**
147
* Get short value at specific index
148
* @param name Tag name
149
* @param index Array index
150
* @return short value at index
151
*/
152
short getShort(String name, int index);
153
154
/**
155
* Check if tag value is a valid integer
156
* @param name Tag name
157
* @return true if value can be converted to integer
158
*/
159
boolean isValidInteger(String name);
160
161
/**
162
* Get integer value for tag
163
* @param name Tag name
164
* @return integer value
165
*/
166
int getInteger(String name);
167
168
/**
169
* Get integer value at specific index
170
* @param name Tag name
171
* @param index Array index
172
* @return integer value at index
173
*/
174
int getInteger(String name, int index);
175
176
/**
177
* Check if tag value is a valid long
178
* @param name Tag name
179
* @return true if value can be converted to long
180
*/
181
boolean isValidLong(String name);
182
183
/**
184
* Get long value for tag
185
* @param name Tag name
186
* @return long value
187
*/
188
long getLong(String name);
189
190
/**
191
* Get long value at specific index
192
* @param name Tag name
193
* @param index Array index
194
* @return long value at index
195
*/
196
long getLong(String name, int index);
197
198
/**
199
* Check if tag value is a valid float
200
* @param name Tag name
201
* @return true if value can be converted to float
202
*/
203
boolean isValidFloat(String name);
204
205
/**
206
* Get float value for tag
207
* @param name Tag name
208
* @return float value
209
*/
210
float getFloat(String name);
211
212
/**
213
* Get float value at specific index
214
* @param name Tag name
215
* @param index Array index
216
* @return float value at index
217
*/
218
float getFloat(String name, int index);
219
220
/**
221
* Check if tag value is a valid double
222
* @param name Tag name
223
* @return true if value can be converted to double
224
*/
225
boolean isValidDouble(String name);
226
227
/**
228
* Get double value for tag
229
* @param name Tag name
230
* @return double value
231
*/
232
double getDouble(String name);
233
234
/**
235
* Get double value at specific index
236
* @param name Tag name
237
* @param index Array index
238
* @return double value at index
239
*/
240
double getDouble(String name, int index);
241
242
/**
243
* Check if tag value is a valid string
244
* @param name Tag name
245
* @return true if value can be converted to string
246
*/
247
boolean isValidString(String name);
248
249
/**
250
* Get string value for tag
251
* @param name Tag name
252
* @return string value
253
*/
254
String getString(String name);
255
256
/**
257
* Get string value at specific index
258
* @param name Tag name
259
* @param index Array index
260
* @return string value at index
261
*/
262
String getString(String name, int index);
263
264
/**
265
* Check if tag value is a valid time
266
* @param name Tag name
267
* @return true if value can be converted to time
268
*/
269
boolean isValidTime(String name);
270
271
/**
272
* Get time value for tag
273
* @param name Tag name
274
* @return LocalTime value
275
*/
276
LocalTime getTime(String name);
277
278
/**
279
* Get time value at specific index
280
* @param name Tag name
281
* @param index Array index
282
* @return LocalTime value at index
283
*/
284
LocalTime getTime(String name, int index);
285
286
/**
287
* Check if tag value is a valid date
288
* @param name Tag name
289
* @return true if value can be converted to date
290
*/
291
boolean isValidDate(String name);
292
293
/**
294
* Get date value for tag
295
* @param name Tag name
296
* @return LocalDate value
297
*/
298
LocalDate getDate(String name);
299
300
/**
301
* Get date value at specific index
302
* @param name Tag name
303
* @param index Array index
304
* @return LocalDate value at index
305
*/
306
LocalDate getDate(String name, int index);
307
308
/**
309
* Check if tag value is a valid datetime
310
* @param name Tag name
311
* @return true if value can be converted to datetime
312
*/
313
boolean isValidDateTime(String name);
314
315
/**
316
* Get datetime value for tag
317
* @param name Tag name
318
* @return LocalDateTime value
319
*/
320
LocalDateTime getDateTime(String name);
321
322
/**
323
* Get datetime value at specific index
324
* @param name Tag name
325
* @param index Array index
326
* @return LocalDateTime value at index
327
*/
328
LocalDateTime getDateTime(String name, int index);
329
330
/**
331
* Check if tag value is a valid BigInteger
332
* @param name Tag name
333
* @return true if value can be converted to BigInteger
334
*/
335
boolean isValidBigInteger(String name);
336
337
/**
338
* Get BigInteger value for tag
339
* @param name Tag name
340
* @return BigInteger value
341
*/
342
BigInteger getBigInteger(String name);
343
344
/**
345
* Get BigInteger value at specific index
346
* @param name Tag name
347
* @param index Array index
348
* @return BigInteger value at index
349
*/
350
BigInteger getBigInteger(String name, int index);
351
352
/**
353
* Check if tag value is a valid BigDecimal
354
* @param name Tag name
355
* @return true if value can be converted to BigDecimal
356
*/
357
boolean isValidBigDecimal(String name);
358
359
/**
360
* Get BigDecimal value for tag
361
* @param name Tag name
362
* @return BigDecimal value
363
*/
364
BigDecimal getBigDecimal(String name);
365
366
/**
367
* Get BigDecimal value at specific index
368
* @param name Tag name
369
* @param index Array index
370
* @return BigDecimal value at index
371
*/
372
BigDecimal getBigDecimal(String name, int index);
373
374
// Collection getters for array values
375
/**
376
* Get all boolean values for array tag
377
* @param name Tag name
378
* @return Collection of boolean values
379
*/
380
Collection<Boolean> getAllBooleans(String name);
381
382
/**
383
* Get all byte values for array tag
384
* @param name Tag name
385
* @return Collection of byte values
386
*/
387
Collection<Byte> getAllBytes(String name);
388
389
/**
390
* Get all short values for array tag
391
* @param name Tag name
392
* @return Collection of short values
393
*/
394
Collection<Short> getAllShorts(String name);
395
396
/**
397
* Get all integer values for array tag
398
* @param name Tag name
399
* @return Collection of integer values
400
*/
401
Collection<Integer> getAllIntegers(String name);
402
403
/**
404
* Get all long values for array tag
405
* @param name Tag name
406
* @return Collection of long values
407
*/
408
Collection<Long> getAllLongs(String name);
409
410
/**
411
* Get all float values for array tag
412
* @param name Tag name
413
* @return Collection of float values
414
*/
415
Collection<Float> getAllFloats(String name);
416
417
/**
418
* Get all double values for array tag
419
* @param name Tag name
420
* @return Collection of double values
421
*/
422
Collection<Double> getAllDoubles(String name);
423
424
/**
425
* Get all string values for array tag
426
* @param name Tag name
427
* @return Collection of string values
428
*/
429
Collection<String> getAllStrings(String name);
430
}
431
```
432
433
**Usage Examples:**
434
435
```java
436
import org.apache.plc4x.java.DefaultPlcDriverManager;
437
import org.apache.plc4x.java.api.PlcConnection;
438
import org.apache.plc4x.java.api.messages.PlcReadRequest;
439
import org.apache.plc4x.java.api.messages.PlcReadResponse;
440
import org.apache.plc4x.java.api.types.PlcResponseCode;
441
442
// Basic read operation
443
PlcDriverManager driverManager = new DefaultPlcDriverManager();
444
try (PlcConnection connection = driverManager.getConnection("modbus-tcp://192.168.1.100:502")) {
445
connection.connect();
446
447
// Build read request
448
PlcReadRequest readRequest = connection.readRequestBuilder()
449
.addTagAddress("temperature", "holding-register:1")
450
.addTagAddress("pressure", "holding-register:2")
451
.addTagAddress("status", "coil:10")
452
.build();
453
454
// Execute asynchronously
455
CompletableFuture<? extends PlcReadResponse> future = readRequest.execute();
456
PlcReadResponse response = future.get(); // Or use async callbacks
457
458
// Check response codes and extract values
459
if (response.getResponseCode("temperature") == PlcResponseCode.OK) {
460
// Type validation
461
if (response.isValidFloat("temperature")) {
462
float temp = response.getFloat("temperature");
463
System.out.println("Temperature: " + temp + "°C");
464
}
465
466
if (response.isValidInteger("pressure")) {
467
int pressure = response.getInteger("pressure");
468
System.out.println("Pressure: " + pressure + " bar");
469
}
470
471
if (response.isValidBoolean("status")) {
472
boolean status = response.getBoolean("status");
473
System.out.println("Status: " + (status ? "ON" : "OFF"));
474
}
475
}
476
}
477
478
// Array tag reading
479
try (PlcConnection connection = driverManager.getConnection("s7://192.168.1.200/0/1")) {
480
connection.connect();
481
482
PlcReadRequest readRequest = connection.readRequestBuilder()
483
.addTagAddress("sensors", "DB1.DBD0:REAL[10]") // Array of 10 floats
484
.build();
485
486
PlcReadResponse response = readRequest.execute().get();
487
488
if (response.getResponseCode("sensors") == PlcResponseCode.OK) {
489
// Get number of values
490
int count = response.getNumberOfValues("sensors");
491
System.out.println("Array size: " + count);
492
493
// Access individual elements
494
for (int i = 0; i < count; i++) {
495
if (response.isValidFloat("sensors")) {
496
float value = response.getFloat("sensors", i);
497
System.out.println("Sensor[" + i + "]: " + value);
498
}
499
}
500
501
// Or get all values at once
502
Collection<Float> allValues = response.getAllFloats("sensors");
503
System.out.println("All sensor values: " + allValues);
504
}
505
}
506
507
// Using PlcValue directly for complex types
508
try (PlcConnection connection = driverManager.getConnection("modbus-tcp://192.168.1.100:502")) {
509
connection.connect();
510
511
PlcReadRequest readRequest = connection.readRequestBuilder()
512
.addTagAddress("data", "holding-register:100[5]")
513
.build();
514
515
PlcReadResponse response = readRequest.execute().get();
516
517
if (response.getResponseCode("data") == PlcResponseCode.OK) {
518
PlcValue value = response.getPlcValue("data");
519
520
// Check if it's a list/array
521
if (value.isList()) {
522
System.out.println("Array length: " + value.getLength());
523
524
// Access individual elements
525
for (int i = 0; i < value.getLength(); i++) {
526
PlcValue element = value.getIndex(i);
527
if (element.isInteger()) {
528
System.out.println("Element[" + i + "]: " + element.getInteger());
529
}
530
}
531
}
532
}
533
}
534
535
// Error handling
536
try (PlcConnection connection = driverManager.getConnection("modbus-tcp://192.168.1.100:502")) {
537
connection.connect();
538
539
PlcReadRequest readRequest = connection.readRequestBuilder()
540
.addTagAddress("invalid", "non-existent:999")
541
.build();
542
543
PlcReadResponse response = readRequest.execute().get();
544
545
// Check individual response codes
546
PlcResponseCode code = response.getResponseCode("invalid");
547
switch (code) {
548
case OK:
549
System.out.println("Success: " + response.getString("invalid"));
550
break;
551
case NOT_FOUND:
552
System.out.println("Tag not found");
553
break;
554
case ACCESS_DENIED:
555
System.out.println("Access denied");
556
break;
557
case INVALID_ADDRESS:
558
System.out.println("Invalid tag address");
559
break;
560
default:
561
System.out.println("Error: " + code);
562
break;
563
}
564
}
565
```
566
567
## Types
568
569
### Base Request/Response Types
570
571
```java { .api }
572
public interface PlcTagRequest extends PlcRequest {
573
CompletableFuture<? extends PlcTagResponse> execute();
574
int getNumberOfTags();
575
LinkedHashSet<String> getTagNames();
576
PlcResponseCode getTagResponseCode(String tagName);
577
PlcTag getTag(String tagName);
578
List<PlcTag> getTags();
579
}
580
581
public interface PlcTagResponse extends PlcResponse {
582
PlcTagRequest getRequest();
583
Collection<String> getTagNames();
584
PlcTag getTag(String name);
585
PlcResponseCode getResponseCode(String name);
586
Metadata getTagMetadata(String name);
587
}
588
```