0
# Write Operations
1
2
Type-safe data writing to PLC tags with value validation and conversion for Apache PLC4X Java API.
3
4
## Capabilities
5
6
### PlcWriteRequest
7
8
Interface for building and executing write requests to PLC tags.
9
10
```java { .api }
11
/**
12
* Write request interface for sending data to PLC tags
13
*/
14
public interface PlcWriteRequest extends PlcTagRequest {
15
/**
16
* Execute the write request asynchronously
17
* @return CompletableFuture containing the write response
18
*/
19
CompletableFuture<? extends PlcWriteResponse> execute();
20
21
/**
22
* Get number of values for a specific tag
23
* @param name Tag name from request
24
* @return Number of values to write
25
*/
26
int getNumberOfValues(String name);
27
28
/**
29
* Get PlcValue for a specific tag
30
* @param name Tag name from request
31
* @return PlcValue containing the data to write
32
*/
33
PlcValue getPlcValue(String name);
34
35
/**
36
* Builder interface for constructing write requests
37
*/
38
interface Builder extends PlcRequestBuilder {
39
/**
40
* Add a tag by address string with values to write
41
* @param name Logical name for the tag
42
* @param tagAddress PLC-specific tag address string
43
* @param values Values to write (varargs for arrays)
44
* @return Builder instance for method chaining
45
*/
46
Builder addTagAddress(String name, String tagAddress, Object... values);
47
48
/**
49
* Add a pre-parsed tag object with values to write
50
* @param name Logical name for the tag
51
* @param tag PlcTag instance
52
* @param values Values to write (varargs for arrays)
53
* @return Builder instance for method chaining
54
*/
55
Builder addTag(String name, PlcTag tag, Object... values);
56
57
/**
58
* Build the write request
59
* @return PlcWriteRequest instance ready for execution
60
*/
61
PlcWriteRequest build();
62
}
63
}
64
```
65
66
### PlcWriteResponse
67
68
Interface for accessing write response status and confirmation.
69
70
```java { .api }
71
/**
72
* Write response interface providing status information for write operations
73
*/
74
public interface PlcWriteResponse extends PlcTagResponse {
75
/**
76
* Get the originating write request
77
* @return PlcWriteRequest that generated this response
78
*/
79
PlcWriteRequest getRequest();
80
}
81
```
82
83
**Usage Examples:**
84
85
```java
86
import org.apache.plc4x.java.DefaultPlcDriverManager;
87
import org.apache.plc4x.java.api.PlcConnection;
88
import org.apache.plc4x.java.api.messages.PlcWriteRequest;
89
import org.apache.plc4x.java.api.messages.PlcWriteResponse;
90
import org.apache.plc4x.java.api.types.PlcResponseCode;
91
92
// Basic write operation
93
PlcDriverManager driverManager = new DefaultPlcDriverManager();
94
try (PlcConnection connection = driverManager.getConnection("modbus-tcp://192.168.1.100:502")) {
95
connection.connect();
96
97
// Build write request with single values
98
PlcWriteRequest writeRequest = connection.writeRequestBuilder()
99
.addTagAddress("setpoint", "holding-register:1", 25.5f)
100
.addTagAddress("enable", "coil:10", true)
101
.addTagAddress("counter", "holding-register:5", 1234)
102
.build();
103
104
// Execute asynchronously
105
CompletableFuture<? extends PlcWriteResponse> future = writeRequest.execute();
106
PlcWriteResponse response = future.get(); // Or use async callbacks
107
108
// Check response codes
109
if (response.getResponseCode("setpoint") == PlcResponseCode.OK) {
110
System.out.println("Setpoint written successfully");
111
}
112
113
if (response.getResponseCode("enable") == PlcResponseCode.OK) {
114
System.out.println("Enable flag written successfully");
115
}
116
117
if (response.getResponseCode("counter") == PlcResponseCode.OK) {
118
System.out.println("Counter written successfully");
119
}
120
}
121
122
// Array write operation
123
try (PlcConnection connection = driverManager.getConnection("s7://192.168.1.200/0/1")) {
124
connection.connect();
125
126
// Write array of values
127
float[] sensorValues = {12.5f, 13.2f, 14.1f, 15.0f, 16.8f};
128
129
PlcWriteRequest writeRequest = connection.writeRequestBuilder()
130
.addTagAddress("sensors", "DB1.DBD0:REAL[5]", (Object[]) sensorValues)
131
.build();
132
133
PlcWriteResponse response = writeRequest.execute().get();
134
135
if (response.getResponseCode("sensors") == PlcResponseCode.OK) {
136
System.out.println("Sensor array written successfully");
137
}
138
}
139
140
// Mixed data types write
141
try (PlcConnection connection = driverManager.getConnection("modbus-tcp://192.168.1.100:502")) {
142
connection.connect();
143
144
PlcWriteRequest writeRequest = connection.writeRequestBuilder()
145
.addTagAddress("temperature", "holding-register:100", 23.5)
146
.addTagAddress("humidity", "holding-register:101", 65)
147
.addTagAddress("alarm_status", "coil:1", false)
148
.addTagAddress("device_id", "holding-register:200", "DEV001")
149
.build();
150
151
PlcWriteResponse response = writeRequest.execute().get();
152
153
// Check all response codes
154
for (String tagName : response.getTagNames()) {
155
PlcResponseCode code = response.getResponseCode(tagName);
156
if (code == PlcResponseCode.OK) {
157
System.out.println("Tag '" + tagName + "' written successfully");
158
} else {
159
System.out.println("Failed to write tag '" + tagName + "': " + code);
160
}
161
}
162
}
163
164
// Error handling and validation
165
try (PlcConnection connection = driverManager.getConnection("modbus-tcp://192.168.1.100:502")) {
166
connection.connect();
167
168
PlcWriteRequest writeRequest = connection.writeRequestBuilder()
169
.addTagAddress("readonly", "input-register:1", 100) // This might fail
170
.addTagAddress("outofrange", "holding-register:999", 50) // This might fail
171
.build();
172
173
PlcWriteResponse response = writeRequest.execute().get();
174
175
// Handle different error conditions
176
PlcResponseCode readonlyCode = response.getResponseCode("readonly");
177
switch (readonlyCode) {
178
case OK:
179
System.out.println("Write successful");
180
break;
181
case ACCESS_DENIED:
182
System.out.println("Tag is read-only");
183
break;
184
case INVALID_ADDRESS:
185
System.out.println("Invalid tag address");
186
break;
187
case INVALID_DATATYPE:
188
System.out.println("Data type mismatch");
189
break;
190
case INVALID_DATA:
191
System.out.println("Invalid data value");
192
break;
193
default:
194
System.out.println("Write failed: " + readonlyCode);
195
break;
196
}
197
}
198
199
// Complex data structure write
200
try (PlcConnection connection = driverManager.getConnection("s7://192.168.1.200/0/1")) {
201
connection.connect();
202
203
// Write multiple related values as a batch
204
PlcWriteRequest writeRequest = connection.writeRequestBuilder()
205
.addTagAddress("recipe.temperature", "DB10.DBD0:REAL", 180.5f)
206
.addTagAddress("recipe.pressure", "DB10.DBD4:REAL", 2.5f)
207
.addTagAddress("recipe.duration", "DB10.DBD8:DINT", 3600)
208
.addTagAddress("recipe.active", "DB10.DBX12.0:BOOL", true)
209
.build();
210
211
PlcWriteResponse response = writeRequest.execute().get();
212
213
// Verify all recipe parameters were written
214
boolean allSuccess = response.getTagNames().stream()
215
.allMatch(tagName -> response.getResponseCode(tagName) == PlcResponseCode.OK);
216
217
if (allSuccess) {
218
System.out.println("Recipe parameters written successfully");
219
} else {
220
System.out.println("Some recipe parameters failed to write");
221
response.getTagNames().forEach(tagName -> {
222
PlcResponseCode code = response.getResponseCode(tagName);
223
if (code != PlcResponseCode.OK) {
224
System.out.println("Failed: " + tagName + " - " + code);
225
}
226
});
227
}
228
}
229
230
// Async write with callbacks
231
try (PlcConnection connection = driverManager.getConnection("modbus-tcp://192.168.1.100:502")) {
232
connection.connect();
233
234
PlcWriteRequest writeRequest = connection.writeRequestBuilder()
235
.addTagAddress("status", "coil:1", true)
236
.build();
237
238
// Use async callbacks instead of blocking
239
writeRequest.execute()
240
.thenAccept(response -> {
241
if (response.getResponseCode("status") == PlcResponseCode.OK) {
242
System.out.println("Status updated successfully");
243
} else {
244
System.out.println("Failed to update status");
245
}
246
})
247
.exceptionally(throwable -> {
248
System.err.println("Write operation failed: " + throwable.getMessage());
249
return null;
250
});
251
}
252
```
253
254
## Types
255
256
### Value Conversion Support
257
258
The write operations support automatic conversion from Java types to PLC values:
259
260
- **Boolean**: `true`/`false` → PLC BOOL
261
- **Byte**: `byte` values → PLC BYTE/SINT
262
- **Short**: `short` values → PLC WORD/INT
263
- **Integer**: `int` values → PLC DWORD/DINT
264
- **Long**: `long` values → PLC LWORD/LINT
265
- **Float**: `float` values → PLC REAL
266
- **Double**: `double` values → PLC LREAL
267
- **String**: `String` values → PLC STRING/WSTRING
268
- **Arrays**: Java arrays → PLC arrays
269
- **Time Types**: `LocalTime`, `LocalDate`, `LocalDateTime` → PLC time types
270
- **Numeric Types**: `BigInteger`, `BigDecimal` → PLC numeric types
271
272
### Error Response Codes
273
274
```java { .api }
275
public enum PlcResponseCode {
276
OK, // Write successful
277
NOT_FOUND, // Tag not found
278
ACCESS_DENIED, // Tag is read-only or access denied
279
INVALID_ADDRESS, // Invalid tag address format
280
INVALID_DATATYPE, // Data type mismatch
281
INVALID_DATA, // Invalid data value or out of range
282
INTERNAL_ERROR, // PLC internal error
283
REMOTE_BUSY, // PLC is busy
284
REMOTE_ERROR, // PLC reported an error
285
UNSUPPORTED, // Operation not supported
286
RESPONSE_PENDING // Response still pending
287
}
288
```