Central API Module providing core interfaces and abstractions for unified access to industrial programmable logic controllers (PLCs)
—
Universal value abstraction providing type-safe access to PLC data with automatic conversion in Apache PLC4X Java API.
Universal value interface providing comprehensive type system for PLC data.
/**
* Universal value interface for type-safe access to PLC data
*/
public interface PlcValue {
/**
* Get the PLC value type
* @return PlcValueType enum indicating the data type
*/
PlcValueType getPlcValueType();
/**
* Get the raw object representation
* @return Object containing the raw value
*/
Object getObject();
// Type checking methods
/**
* Check if this is a simple (non-complex) value type
* @return true if simple type (not struct or list)
*/
boolean isSimple();
/**
* Check if this value type supports null values
* @return true if nullable
*/
boolean isNullable();
/**
* Check if this value is null
* @return true if null
*/
boolean isNull();
/**
* Check if value is of specific Java type
* @param clazz Java class to check against
* @return true if value is of specified type
*/
boolean is(Class<?> clazz);
/**
* Check if value can be converted to specific Java type
* @param clazz Java class to check conversion to
* @return true if convertible
*/
boolean isConvertibleTo(Class<?> clazz);
/**
* Get value as specific Java type with conversion
* @param clazz Target Java class
* @return Value converted to specified type
* @throws PlcIncompatibleDatatypeException if conversion fails
*/
<T> T get(Class<T> clazz);
// Boolean type methods
/**
* Check if value is boolean type
* @return true if boolean
*/
boolean isBoolean();
/**
* Get boolean value
* @return boolean value
* @throws PlcIncompatibleDatatypeException if not convertible
*/
boolean getBoolean();
// Byte type methods
/**
* Check if value is byte type
* @return true if byte
*/
boolean isByte();
/**
* Get byte value
* @return byte value
* @throws PlcIncompatibleDatatypeException if not convertible
*/
byte getByte();
// Short type methods
/**
* Check if value is short type
* @return true if short
*/
boolean isShort();
/**
* Get short value
* @return short value
* @throws PlcIncompatibleDatatypeException if not convertible
*/
short getShort();
// Integer type methods
/**
* Check if value is integer type
* @return true if integer
*/
boolean isInteger();
/**
* Get integer value
* @return integer value
* @throws PlcIncompatibleDatatypeException if not convertible
*/
int getInteger();
// Long type methods
/**
* Check if value is long type
* @return true if long
*/
boolean isLong();
/**
* Get long value
* @return long value
* @throws PlcIncompatibleDatatypeException if not convertible
*/
long getLong();
// Float type methods
/**
* Check if value is float type
* @return true if float
*/
boolean isFloat();
/**
* Get float value
* @return float value
* @throws PlcIncompatibleDatatypeException if not convertible
*/
float getFloat();
// Double type methods
/**
* Check if value is double type
* @return true if double
*/
boolean isDouble();
/**
* Get double value
* @return double value
* @throws PlcIncompatibleDatatypeException if not convertible
*/
double getDouble();
// String type methods
/**
* Check if value is string type
* @return true if string
*/
boolean isString();
/**
* Get string value
* @return string value
* @throws PlcIncompatibleDatatypeException if not convertible
*/
String getString();
// Time type methods
/**
* Check if value is time type
* @return true if time
*/
boolean isTime();
/**
* Get time value
* @return LocalTime value
* @throws PlcIncompatibleDatatypeException if not convertible
*/
LocalTime getTime();
// Date type methods
/**
* Check if value is date type
* @return true if date
*/
boolean isDate();
/**
* Get date value
* @return LocalDate value
* @throws PlcIncompatibleDatatypeException if not convertible
*/
LocalDate getDate();
// DateTime type methods
/**
* Check if value is datetime type
* @return true if datetime
*/
boolean isDateTime();
/**
* Get datetime value
* @return LocalDateTime value
* @throws PlcIncompatibleDatatypeException if not convertible
*/
LocalDateTime getDateTime();
// Duration type methods
/**
* Check if value is duration type
* @return true if duration
*/
boolean isDuration();
/**
* Get duration value
* @return Duration value
* @throws PlcIncompatibleDatatypeException if not convertible
*/
Duration getDuration();
// BigInteger type methods
/**
* Check if value is BigInteger type
* @return true if BigInteger
*/
boolean isBigInteger();
/**
* Get BigInteger value
* @return BigInteger value
* @throws PlcIncompatibleDatatypeException if not convertible
*/
BigInteger getBigInteger();
// BigDecimal type methods
/**
* Check if value is BigDecimal type
* @return true if BigDecimal
*/
boolean isBigDecimal();
/**
* Get BigDecimal value
* @return BigDecimal value
* @throws PlcIncompatibleDatatypeException if not convertible
*/
BigDecimal getBigDecimal();
// Raw data methods
/**
* Get raw byte array representation
* @return byte array containing raw data
*/
byte[] getRaw();
// List/Array methods
/**
* Check if value is a list/array type
* @return true if list
*/
boolean isList();
/**
* Get length of list/array
* @return number of elements
*/
int getLength();
/**
* Get element at specific index
* @param index Array index
* @return PlcValue at specified index
*/
PlcValue getIndex(int index);
/**
* Get all list elements
* @return List of PlcValue elements
*/
List<? extends PlcValue> getList();
// Struct methods
/**
* Check if value is a struct type
* @return true if struct
*/
boolean isStruct();
/**
* Get struct field names
* @return Set of field names
*/
Set<String> getKeys();
/**
* Check if struct has specific field
* @param key Field name
* @return true if field exists
*/
boolean hasKey(String key);
/**
* Get struct field value
* @param key Field name
* @return PlcValue for the field
*/
PlcValue getValue(String key);
/**
* Get struct as Map
* @return Map of field names to PlcValue
*/
Map<String, ? extends PlcValue> getStruct();
// Metadata methods
/**
* Get available metadata names
* @return Set of metadata names
*/
Set<String> getMetaDataNames();
/**
* Check if specific metadata exists
* @param key Metadata key
* @return true if metadata exists
*/
boolean hasMetaData(String key);
/**
* Get metadata value
* @param key Metadata key
* @return PlcValue containing metadata
*/
PlcValue getMetaData(String key);
}Usage Examples:
import org.apache.plc4x.java.DefaultPlcDriverManager;
import org.apache.plc4x.java.api.PlcConnection;
import org.apache.plc4x.java.api.messages.PlcReadRequest;
import org.apache.plc4x.java.api.messages.PlcReadResponse;
import org.apache.plc4x.java.api.value.PlcValue;
import org.apache.plc4x.java.api.types.PlcValueType;
// Basic value type checking and conversion
PlcDriverManager driverManager = new DefaultPlcDriverManager();
try (PlcConnection connection = driverManager.getConnection("modbus-tcp://192.168.1.100:502")) {
connection.connect();
PlcReadRequest readRequest = connection.readRequestBuilder()
.addTagAddress("temperature", "holding-register:1")
.addTagAddress("status", "coil:1")
.addTagAddress("device_name", "holding-register:100[10]")
.build();
PlcReadResponse response = readRequest.execute().get();
// Temperature - numeric value
PlcValue tempValue = response.getPlcValue("temperature");
System.out.println("Value type: " + tempValue.getPlcValueType());
// Check type and convert appropriately
if (tempValue.isFloat()) {
float temperature = tempValue.getFloat();
System.out.println("Temperature: " + temperature + "°C");
} else if (tempValue.isInteger()) {
int temperature = tempValue.getInteger();
System.out.println("Temperature: " + temperature + "°C");
} else if (tempValue.isConvertibleTo(Double.class)) {
double temperature = tempValue.get(Double.class);
System.out.println("Temperature: " + temperature + "°C");
}
// Status - boolean value
PlcValue statusValue = response.getPlcValue("status");
if (statusValue.isBoolean()) {
boolean status = statusValue.getBoolean();
System.out.println("Status: " + (status ? "ON" : "OFF"));
}
// Device name - string or array conversion
PlcValue nameValue = response.getPlcValue("device_name");
if (nameValue.isString()) {
String name = nameValue.getString();
System.out.println("Device: " + name);
} else if (nameValue.isList()) {
// Convert array of registers to string
StringBuilder name = new StringBuilder();
for (int i = 0; i < nameValue.getLength(); i++) {
PlcValue element = nameValue.getIndex(i);
if (element.isInteger()) {
int charValue = element.getInteger();
if (charValue != 0) { // Skip null terminators
name.append((char) charValue);
}
}
}
System.out.println("Device: " + name.toString());
}
}
// Array/List processing
try (PlcConnection connection = driverManager.getConnection("s7://192.168.1.200/0/1")) {
connection.connect();
PlcReadRequest readRequest = connection.readRequestBuilder()
.addTagAddress("sensor_array", "DB1.DBD0:REAL[10]")
.build();
PlcReadResponse response = readRequest.execute().get();
PlcValue arrayValue = response.getPlcValue("sensor_array");
if (arrayValue.isList()) {
System.out.println("Array length: " + arrayValue.getLength());
// Process each element
for (int i = 0; i < arrayValue.getLength(); i++) {
PlcValue element = arrayValue.getIndex(i);
if (element.isFloat()) {
float value = element.getFloat();
System.out.println("Sensor[" + i + "]: " + value);
}
}
// Get as Java list
List<? extends PlcValue> sensorList = arrayValue.getList();
double average = sensorList.stream()
.filter(PlcValue::isFloat)
.mapToDouble(PlcValue::getFloat)
.average()
.orElse(0.0);
System.out.println("Average sensor value: " + average);
}
}
// Struct/Complex data processing
try (PlcConnection connection = driverManager.getConnection("s7://192.168.1.200/0/1")) {
connection.connect();
PlcReadRequest readRequest = connection.readRequestBuilder()
.addTagAddress("recipe_data", "DB10:STRUCT")
.build();
PlcReadResponse response = readRequest.execute().get();
PlcValue structValue = response.getPlcValue("recipe_data");
if (structValue.isStruct()) {
System.out.println("Struct fields: " + structValue.getKeys());
// Access individual fields
if (structValue.hasKey("temperature")) {
PlcValue tempField = structValue.getValue("temperature");
if (tempField.isFloat()) {
float temperature = tempField.getFloat();
System.out.println("Recipe temperature: " + temperature);
}
}
if (structValue.hasKey("duration")) {
PlcValue durationField = structValue.getValue("duration");
if (durationField.isInteger()) {
int duration = durationField.getInteger();
System.out.println("Recipe duration: " + duration + " seconds");
}
}
// Get as map for bulk processing
Map<String, ? extends PlcValue> structMap = structValue.getStruct();
structMap.forEach((fieldName, fieldValue) -> {
System.out.println(fieldName + ": " + fieldValue.getObject());
});
}
}
// Type conversion and validation
try (PlcConnection connection = driverManager.getConnection("modbus-tcp://192.168.1.100:502")) {
connection.connect();
PlcReadRequest readRequest = connection.readRequestBuilder()
.addTagAddress("mixed_data", "holding-register:1")
.build();
PlcReadResponse response = readRequest.execute().get();
PlcValue value = response.getPlcValue("mixed_data");
// Safe type conversion with validation
if (value.isConvertibleTo(String.class)) {
String stringValue = value.get(String.class);
System.out.println("As string: " + stringValue);
}
if (value.isConvertibleTo(Integer.class)) {
Integer intValue = value.get(Integer.class);
System.out.println("As integer: " + intValue);
}
if (value.isConvertibleTo(BigDecimal.class)) {
BigDecimal decimalValue = value.get(BigDecimal.class);
System.out.println("As BigDecimal: " + decimalValue);
}
// Raw data access
byte[] rawData = value.getRaw();
System.out.println("Raw bytes: " + Arrays.toString(rawData));
}
// Time/Date handling
try (PlcConnection connection = driverManager.getConnection("s7://192.168.1.200/0/1")) {
connection.connect();
PlcReadRequest readRequest = connection.readRequestBuilder()
.addTagAddress("timestamp", "DB20.DBD0:DATE_AND_TIME")
.addTagAddress("duration", "DB20.DBD8:TIME")
.build();
PlcReadResponse response = readRequest.execute().get();
// DateTime handling
PlcValue timestampValue = response.getPlcValue("timestamp");
if (timestampValue.isDateTime()) {
LocalDateTime timestamp = timestampValue.getDateTime();
System.out.println("Timestamp: " + timestamp);
}
// Duration handling
PlcValue durationValue = response.getPlcValue("duration");
if (durationValue.isDuration()) {
Duration duration = durationValue.getDuration();
System.out.println("Duration: " + duration.toSeconds() + " seconds");
}
}
// Metadata access
try (PlcConnection connection = driverManager.getConnection("modbus-tcp://192.168.1.100:502")) {
connection.connect();
PlcReadRequest readRequest = connection.readRequestBuilder()
.addTagAddress("data", "holding-register:1")
.build();
PlcReadResponse response = readRequest.execute().get();
PlcValue value = response.getPlcValue("data");
// Check for metadata
if (!value.getMetaDataNames().isEmpty()) {
System.out.println("Available metadata: " + value.getMetaDataNames());
for (String metaKey : value.getMetaDataNames()) {
PlcValue metaValue = value.getMetaData(metaKey);
System.out.println("Metadata " + metaKey + ": " + metaValue.getObject());
}
}
}/**
* Comprehensive enumeration of PLC value types
*/
public enum PlcValueType {
// Null type
NULL,
// Boolean types
BOOL,
// Bit string types
BYTE, WORD, DWORD, LWORD,
// Unsigned integer types
USINT, // Unsigned 8-bit integer
UINT, // Unsigned 16-bit integer
UDINT, // Unsigned 32-bit integer
ULINT, // Unsigned 64-bit integer
// Signed integer types
SINT, // Signed 8-bit integer
INT, // Signed 16-bit integer
DINT, // Signed 32-bit integer
LINT, // Signed 64-bit integer
// Floating point types
REAL, // 32-bit floating point
LREAL, // 64-bit floating point
// Character types
CHAR, // Single character
WCHAR, // Wide character
// String types
STRING, // Character string
WSTRING, // Wide character string
// Time types
TIME, // Time duration
LTIME, // Long time duration
DATE, // Date
LDATE, // Long date
TIME_OF_DAY, // Time of day
LTIME_OF_DAY, // Long time of day
DATE_AND_TIME, // Date and time
DATE_AND_LTIME, // Date and long time
LDATE_AND_TIME, // Long date and time
// Complex types
Struct, // Structure/record type
List, // Array/list type
// Raw data
RAW_BYTE_ARRAY; // Raw byte array
/**
* Get numeric value for the type
* @return short value representing the type
*/
public short getValue();
/**
* Get the default Java type for this PLC type
* @return Class representing the default Java mapping
*/
public Class<?> getDefaultJavaType();
}| PlcValueType | Java Types | Description |
|---|---|---|
BOOL | boolean, Boolean | Boolean values |
BYTE, SINT | byte, Byte | 8-bit signed integers |
WORD, INT | short, Short | 16-bit signed integers |
DWORD, DINT | int, Integer | 32-bit signed integers |
LWORD, LINT | long, Long | 64-bit signed integers |
USINT | short, int | 8-bit unsigned integers |
UINT | int, Integer | 16-bit unsigned integers |
UDINT | long, Long | 32-bit unsigned integers |
ULINT | BigInteger | 64-bit unsigned integers |
REAL | float, Float | 32-bit floating point |
LREAL | double, Double | 64-bit floating point |
STRING, WSTRING | String | Character strings |
TIME, LTIME | Duration | Time durations |
DATE, LDATE | LocalDate | Date values |
TIME_OF_DAY | LocalTime | Time of day |
DATE_AND_TIME | LocalDateTime | Date and time |
List | List<PlcValue> | Arrays/lists |
Struct | Map<String, PlcValue> | Structures/records |
Install with Tessl CLI
npx tessl i tessl/maven-org-apache-plc4x--plc4j-api