use of org.apache.plc4x.java.api.messages.PlcReadRequest in project plc4x by apache.
the class Plc4xAbEthProtocol method decodeReadResponse.
private PlcResponse decodeReadResponse(CIPEncapsulationReadResponse plcReadResponse, PlcRequestContainer requestContainer) {
PlcReadRequest plcReadRequest = (PlcReadRequest) requestContainer.getRequest();
Map<String, ResponseItem<PlcValue>> values = new HashMap<>();
for (String fieldName : plcReadRequest.getFieldNames()) {
AbEthField field = (AbEthField) plcReadRequest.getField(fieldName);
PlcResponseCode responseCode = decodeResponseCode(plcReadResponse.getResponse().getStatus());
PlcValue plcValue = null;
if (responseCode == PlcResponseCode.OK) {
try {
switch(field.getFileType()) {
case // output as single bytes
INTEGER:
if (plcReadResponse.getResponse() instanceof DF1CommandResponseMessageProtectedTypedLogicalRead) {
DF1CommandResponseMessageProtectedTypedLogicalRead df1PTLR = (DF1CommandResponseMessageProtectedTypedLogicalRead) plcReadResponse.getResponse();
List<Short> data = df1PTLR.getData();
if (data.size() == 1) {
plcValue = new PlcINT(data.get(0));
} else {
plcValue = IEC61131ValueHandler.of(data);
}
}
break;
case WORD:
if (plcReadResponse.getResponse() instanceof DF1CommandResponseMessageProtectedTypedLogicalRead) {
DF1CommandResponseMessageProtectedTypedLogicalRead df1PTLR = (DF1CommandResponseMessageProtectedTypedLogicalRead) plcReadResponse.getResponse();
List<Short> data = df1PTLR.getData();
if (((data.get(1) >> 7) & 1) == 0) {
// positive number
plcValue = IEC61131ValueHandler.of((data.get(1) << 8) + data.get(0));
} else {
// negative number
plcValue = IEC61131ValueHandler.of((((~data.get(1) & 0b01111111) << 8) + (~(data.get(0) - 1) & 0b11111111)) * -1);
}
}
break;
case DWORD:
if (plcReadResponse.getResponse() instanceof DF1CommandResponseMessageProtectedTypedLogicalRead) {
DF1CommandResponseMessageProtectedTypedLogicalRead df1PTLR = (DF1CommandResponseMessageProtectedTypedLogicalRead) plcReadResponse.getResponse();
List<Short> data = df1PTLR.getData();
if (((data.get(3) >> 7) & 1) == 0) {
// positive number
plcValue = IEC61131ValueHandler.of((data.get(3) << 24) + (data.get(2) << 16) + (data.get(1) << 8) + data.get(0));
} else {
// negative number
plcValue = IEC61131ValueHandler.of((((~data.get(3) & 0b01111111) << 24) + ((~(data.get(2) - 1) & 0b11111111) << 16) + ((~(data.get(1) - 1) & 0b11111111) << 8) + (~(data.get(0) - 1) & 0b11111111)) * -1);
}
}
break;
case SINGLEBIT:
if (plcReadResponse.getResponse() instanceof DF1CommandResponseMessageProtectedTypedLogicalRead) {
DF1CommandResponseMessageProtectedTypedLogicalRead df1PTLR = (DF1CommandResponseMessageProtectedTypedLogicalRead) plcReadResponse.getResponse();
List<Short> data = df1PTLR.getData();
if (field.getBitNumber() < 8) {
// read from first byte
plcValue = IEC61131ValueHandler.of((data.get(0) & (1 << field.getBitNumber())) != 0);
} else {
// read from second byte
plcValue = IEC61131ValueHandler.of((data.get(1) & (1 << (field.getBitNumber() - 8))) != 0);
}
}
break;
default:
logger.warn("Problem during decoding of field {}: Decoding of file type not implemented; " + "FieldInformation: {}", fieldName, field);
}
} catch (Exception e) {
logger.warn("Some other error occurred casting field {}, FieldInformation: {}", fieldName, field, e);
}
}
ResponseItem<PlcValue> result = new ResponseItem<>(responseCode, plcValue);
values.put(fieldName, result);
}
return new DefaultPlcReadResponse(plcReadRequest, values);
}
use of org.apache.plc4x.java.api.messages.PlcReadRequest in project plc4x by apache.
the class Plc4xAbEthProtocol method decode.
@Override
protected void decode(ChannelHandlerContext ctx, CIPEncapsulationPacket packet, List<Object> out) throws Exception {
logger.trace("Received {}, decoding...", packet);
if (packet instanceof CIPEncapsulationConnectionResponse) {
CIPEncapsulationConnectionResponse connectionResponse = (CIPEncapsulationConnectionResponse) packet;
// Save the session handle
sessionHandle = connectionResponse.getSessionHandle();
// Tell Netty we're finished connecting
ctx.channel().pipeline().fireUserEventTriggered(new ConnectedEvent());
} else {
// We're currently just expecting responses.
if (!(packet instanceof CIPEncapsulationReadResponse)) {
return;
}
CIPEncapsulationReadResponse cipResponse = (CIPEncapsulationReadResponse) packet;
int transactionCounter = cipResponse.getResponse().getTransactionCounter();
if (!requests.containsKey(transactionCounter)) {
ctx.fireExceptionCaught(new PlcProtocolException("Couldn't find request for response with transaction counter " + transactionCounter));
return;
}
PlcRequestContainer requestContainer = requests.remove(transactionCounter);
PlcRequest request = requestContainer.getRequest();
PlcResponse response = null;
if (request instanceof PlcReadRequest) {
response = decodeReadResponse(cipResponse, requestContainer);
} else {
ctx.fireExceptionCaught(new PlcProtocolException("Unsupported request type " + request.getClass().getName()));
}
// Confirm the response being handled.
if (response != null) {
requestContainer.getResponseFuture().complete(response);
}
}
}
use of org.apache.plc4x.java.api.messages.PlcReadRequest in project plc4x by apache.
the class Plc4xReadClient method main.
public static void main(String[] args) throws Exception {
try (final PlcConnection connection = new PlcDriverManager().getConnection("plc4x://localhost?remote-connection-string=simulated%3A%2F%2Flocalhost")) {
final PlcReadRequest.Builder requestBuilder = connection.readRequestBuilder();
requestBuilder.addItem("test-BOOL", "RANDOM/foo:BOOL");
requestBuilder.addItem("test-BYTE", "RANDOM/foo:BYTE");
requestBuilder.addItem("test-WORD", "RANDOM/foo:WORD");
requestBuilder.addItem("test-DWORD", "RANDOM/foo:DWORD");
requestBuilder.addItem("test-USINT", "RANDOM/foo:USINT");
requestBuilder.addItem("test-UINT", "RANDOM/foo:UINT");
requestBuilder.addItem("test-UDINT", "RANDOM/foo:UDINT");
requestBuilder.addItem("test-ULINT", "RANDOM/foo:ULINT");
requestBuilder.addItem("test-SINT", "RANDOM/foo:SINT");
requestBuilder.addItem("test-INT", "RANDOM/foo:INT");
requestBuilder.addItem("test-DINT", "RANDOM/foo:DINT");
requestBuilder.addItem("test-LINT", "RANDOM/foo:LINT");
requestBuilder.addItem("test-REAL", "RANDOM/foo:REAL");
requestBuilder.addItem("test-LREAL", "RANDOM/foo:LREAL");
requestBuilder.addItem("test-CHAR", "RANDOM/foo:CHAR");
requestBuilder.addItem("test-WCHAR", "RANDOM/foo:WCHAR");
final PlcReadRequest readRequest = requestBuilder.build();
final PlcReadResponse readResponse = readRequest.execute().get();
System.out.println(readResponse);
}
}
use of org.apache.plc4x.java.api.messages.PlcReadRequest in project plc4x by apache.
the class ManualProfinetIoTest method main.
public static void main(String[] args) throws Exception {
final PlcConnection connection = new PlcDriverManager().getConnection("profinet://192.168.24.31");
final PlcReadRequest readRequest = connection.readRequestBuilder().addItem("test", "").build();
final PlcReadResponse plcReadResponse = readRequest.execute().get();
System.out.println(plcReadResponse);
}
use of org.apache.plc4x.java.api.messages.PlcReadRequest in project plc4x by apache.
the class S7PlcToGoogleIoTCoreSample method main.
/**
* Example code do demonstrate sending events from an S7 device to Microsoft Azure IoT Hub
*
* @param args Expected: [plc4x connection string, plc4x address, IoT-Hub connection string].
*/
public static void main(String[] args) throws Exception {
// [START iot_mqtt_configuremqtt]
CliOptions options = CliOptions.fromArgs(args);
if (options == null) {
CliOptions.printHelp();
// Could not parse.
System.exit(1);
}
// Build the connection string for Google's Cloud IoT Core MQTT server. Only SSL
// connections are accepted. For server authentication, the JVM's root certificates
// are used.
final String mqttServerAddress = String.format("ssl://%s:%s", options.getMqttBridgeHostname(), options.getMqttBridgePort());
// Create our MQTT client. The mqttClientId is a unique string that identifies this device. For
// Google Cloud IoT Core, it must be in the format below.
final String mqttClientId = String.format("projects/%s/locations/%s/registries/%s/devices/%s", options.getProjectId(), options.getCloudRegion(), options.getRegistryId(), options.getDeviceId());
MqttConnectOptions connectOptions = new MqttConnectOptions();
// Note that the Google Cloud IoT Core only supports MQTT 3.1.1, and Paho requires that we
// explictly set this. If you don't set MQTT version, the server will immediately close its
// connection to your device.
connectOptions.setMqttVersion(MqttConnectOptions.MQTT_VERSION_3_1_1);
// With Google Cloud IoT Core, the username field is ignored, however it must be set for the
// Paho client library to send the password field. The password field is used to transmit a JWT
// to authorize the device.
connectOptions.setUserName("unused");
DateTime iat = new DateTime();
setConnectPassword(options, connectOptions);
// [END iot_mqtt_configuremqtt]
// [START iot_mqtt_publish]
// Create a client, and connect to the Google MQTT bridge.
MqttClient client = new MqttClient(mqttServerAddress, mqttClientId, new MemoryPersistence());
// Both connect and publish operations may fail. If they do, allow retries but with an
// exponential backoff time period.
long initialConnectIntervalMillis = 500L;
long maxConnectIntervalMillis = 6000L;
long maxConnectRetryTimeElapsedMillis = 900000L;
float intervalMultiplier = 1.5f;
long retryIntervalMs = initialConnectIntervalMillis;
long totalRetryTimeMs = 0;
while (!client.isConnected() && totalRetryTimeMs < maxConnectRetryTimeElapsedMillis) {
try {
client.connect(connectOptions);
} catch (MqttException e) {
int reason = e.getReasonCode();
// If the connection is lost or if the server cannot be connected, allow retries, but with
// exponential backoff.
System.out.println("An error occurred: " + e.getMessage());
if (reason == MqttException.REASON_CODE_CONNECTION_LOST || reason == MqttException.REASON_CODE_SERVER_CONNECT_ERROR) {
System.out.println("Retrying in " + retryIntervalMs / 1000.0 + " seconds.");
Thread.sleep(retryIntervalMs);
totalRetryTimeMs += retryIntervalMs;
retryIntervalMs *= intervalMultiplier;
if (retryIntervalMs > maxConnectIntervalMillis) {
retryIntervalMs = maxConnectIntervalMillis;
}
} else {
throw e;
}
}
}
attachCallback(client, options.getDeviceId());
// Publish to the events or state topic based on the flag.
String subTopic = "event".equals(options.getMessageType()) ? "events" : options.getMessageType();
// The MQTT topic that this device will publish telemetry data to. The MQTT topic name is
// required to be in the format below. Note that this is not the same as the device registry's
// Cloud Pub/Sub topic.
String mqttTopic = String.format("/devices/%s/%s", options.getDeviceId(), subTopic);
// Connect to Plc
logger.info("Connecting to Plc");
try (PlcConnection plcConnection = new PlcDriverManager().getConnection("s7://10.10.64.20/1/1")) {
logger.info("Connected");
PlcReadRequest readRequest = plcConnection.readRequestBuilder().addItem("outputs", "OUTPUTS/0").build();
while (!Thread.currentThread().isInterrupted()) {
PlcReadResponse plcReadResponse = readRequest.execute().get();
// Refresh the connection credentials before the JWT expires.
// [START iot_mqtt_jwt_refresh]
long secsSinceRefresh = ((new DateTime()).getMillis() - iat.getMillis()) / 1000;
if (secsSinceRefresh > (options.getTokenExpMins() * 60)) {
System.out.format("\tRefreshing token after: %d seconds%n", secsSinceRefresh);
iat = new DateTime();
setConnectPassword(options, connectOptions);
client.disconnect();
client.connect();
attachCallback(client, options.getDeviceId());
}
// Send data to cloud
for (String fieldName : plcReadResponse.getFieldNames()) {
Long l = plcReadResponse.getLong(fieldName);
byte[] array = ByteBuffer.allocate(8).putLong(l).array();
String result = Long.toBinaryString(l);
System.out.println("Outputs: " + result);
// Publish "array" to the MQTT topic. qos=1 means at least once delivery. Cloud IoT Core
// also supports qos=0 for at most once delivery.
MqttMessage message = new MqttMessage(array);
message.setQos(1);
client.publish(mqttTopic, message);
if ("event".equals(options.getMessageType())) {
// Send telemetry events every second
Thread.sleep(1000);
} else {
// Note: Update Device state less frequently than with telemetry events
Thread.sleep(5000);
}
}
}
}
System.out.println("Sent all messages. Goodbye!");
// [END iot_mqtt_publish]
}
Aggregations