or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

browse-operations.mdconnection-management.mdexception-handling.mdindex.mdread-operations.mdsubscription-system.mdvalue-system.mdwrite-operations.md

write-operations.mddocs/

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

```