use of org.apache.plc4x.java.api.exceptions.PlcInvalidFieldException in project plc4x by apache.
the class FirmataDriverContext method processSubscriptionRequest.
public List<FirmataMessage> processSubscriptionRequest(PlcSubscriptionRequest subscriptionRequest) {
// Convert the request into maps of bit sets.
Map<Integer, PinMode> requestDigitalFieldPinModes = new HashMap<>();
Map<Integer, PinMode> requestAnalogFieldPinModes = new HashMap<>();
for (String fieldName : subscriptionRequest.getFieldNames()) {
final PlcField field = subscriptionRequest.getField(fieldName);
DefaultPlcSubscriptionField subscriptionField = (DefaultPlcSubscriptionField) field;
if (subscriptionField.getPlcField() instanceof FirmataFieldDigital) {
FirmataFieldDigital fieldDigital = (FirmataFieldDigital) subscriptionField.getPlcField();
PinMode fieldPinMode = (fieldDigital.getPinMode() != null) ? fieldDigital.getPinMode() : PinMode.PinModeInput;
if (!(fieldPinMode.equals(PinMode.PinModeInput) || fieldPinMode.equals(PinMode.PinModePullup))) {
throw new PlcInvalidFieldException("Subscription field must be of type 'INPUT' (default) or 'PULLUP'");
}
for (int pin = fieldDigital.getAddress(); pin < fieldDigital.getAddress() + fieldDigital.getNumberOfElements(); pin++) {
requestDigitalFieldPinModes.put(pin, fieldPinMode);
}
} else if (subscriptionField.getPlcField() instanceof FirmataFieldAnalog) {
FirmataFieldAnalog fieldAnalog = (FirmataFieldAnalog) subscriptionField.getPlcField();
for (int pin = fieldAnalog.getAddress(); pin < fieldAnalog.getAddress() + fieldAnalog.getNumberOfElements(); pin++) {
requestAnalogFieldPinModes.put(pin, PinMode.PinModeInput);
}
} else {
throw new PlcRuntimeException("Unsupported field type " + field.getClass().getSimpleName());
}
}
// If a requested digital pin is already subscribed, blank this out
for (Map.Entry<Integer, PinMode> entry : requestDigitalFieldPinModes.entrySet()) {
int pin = entry.getKey();
PinMode pinMode = entry.getValue();
if (digitalPins.containsKey(pin)) {
if (!digitalPins.get(pin).equals(pinMode)) {
throw new PlcInvalidFieldException(String.format("Error setting digital pin to mode %s, pin is already set to mode %s", pinMode.toString(), digitalPins.get(pin).toString()));
} else {
requestDigitalFieldPinModes.remove(pin);
}
}
}
// If a requested analog pin is already subscribed, blank this out
for (Map.Entry<Integer, PinMode> entry : requestAnalogFieldPinModes.entrySet()) {
int pin = entry.getKey();
if (analogPins.containsKey(pin)) {
requestAnalogFieldPinModes.remove(pin);
}
}
// Remember the subscription itself.
subscriptions.add(subscriptionRequest);
// Create a list of messages that need to be sent to achieve the desired subscriptions.
List<FirmataMessage> messages = new LinkedList<>();
for (Map.Entry<Integer, PinMode> entry : requestDigitalFieldPinModes.entrySet()) {
int pin = entry.getKey();
PinMode pinMode = entry.getValue();
// Digital pins can be input and output, so first we have to set it to "input"
messages.add(new FirmataMessageCommand(new FirmataCommandSetPinMode((byte) pin, pinMode, false), false));
// And then tell the remote to send change of state information.
messages.add(new FirmataMessageSubscribeDigitalPinValue((byte) pin, true, false));
}
for (Map.Entry<Integer, PinMode> entry : requestAnalogFieldPinModes.entrySet()) {
int pin = entry.getKey();
// Tell the remote to send change of state information for this analog pin.
messages.add(new FirmataMessageSubscribeAnalogPinValue((byte) pin, true, false));
}
return messages;
}
use of org.apache.plc4x.java.api.exceptions.PlcInvalidFieldException in project plc4x by apache.
the class FirmataField method of.
public static FirmataField of(String fieldString) {
Matcher matcher = FirmataFieldAnalog.ADDRESS_PATTERN.matcher(fieldString);
if (matcher.matches()) {
return FirmataFieldAnalog.of(fieldString);
}
matcher = FirmataFieldDigital.ADDRESS_PATTERN.matcher(fieldString);
if (matcher.matches()) {
return FirmataFieldDigital.of(fieldString);
}
throw new PlcInvalidFieldException("Unable to parse address: " + fieldString);
}
use of org.apache.plc4x.java.api.exceptions.PlcInvalidFieldException in project plc4x by apache.
the class FirmataFieldAnalog method of.
public static FirmataFieldAnalog of(String addressString) throws PlcInvalidFieldException {
Matcher matcher = ADDRESS_PATTERN.matcher(addressString);
if (!matcher.matches()) {
throw new PlcInvalidFieldException(addressString, ADDRESS_PATTERN);
}
int address = Integer.parseInt(matcher.group("address"));
String quantityString = matcher.group("quantity");
Integer quantity = quantityString != null ? Integer.valueOf(quantityString) : null;
return new FirmataFieldAnalog(address, quantity);
}
use of org.apache.plc4x.java.api.exceptions.PlcInvalidFieldException in project plc4x by apache.
the class Plc4XProducer method process.
@Override
public void process(Exchange exchange) throws Exception {
Message in = exchange.getIn();
Object body = in.getBody();
PlcWriteRequest.Builder builder = plcConnection.writeRequestBuilder();
if (body instanceof Map) {
// Check if we have a Map
Map<String, Map<String, Object>> tags = (Map<String, Map<String, Object>>) body;
for (Map.Entry<String, Map<String, Object>> entry : tags.entrySet()) {
// Tags are stored like this --> Map<Tagname,Map<Query,Value>> for writing
String name = entry.getKey();
String query = entry.getValue().keySet().iterator().next();
Object value = entry.getValue().get(query);
builder.addItem(name, query, value);
}
} else {
throw new PlcInvalidFieldException("The body must contain a Map<String,Map<String,Object>");
}
CompletableFuture<? extends PlcWriteResponse> completableFuture = builder.build().execute();
int currentlyOpenRequests = openRequests.incrementAndGet();
try {
log.debug("Currently open requests including {}:{}", exchange, currentlyOpenRequests);
Object plcWriteResponse = completableFuture.get();
if (exchange.getPattern().isOutCapable()) {
Message out = exchange.getOut();
out.copyFrom(exchange.getIn());
out.setBody(plcWriteResponse);
} else {
in.setBody(plcWriteResponse);
}
} finally {
int openRequestsAfterFinish = openRequests.decrementAndGet();
log.trace("Open Requests after {}:{}", exchange, openRequestsAfterFinish);
}
}
use of org.apache.plc4x.java.api.exceptions.PlcInvalidFieldException in project plc4x by apache.
the class DirectAdsField method of.
public static DirectAdsField of(String address) {
Matcher matcher = RESOURCE_ADDRESS_PATTERN.matcher(address);
if (!matcher.matches()) {
throw new PlcInvalidFieldException(address, RESOURCE_ADDRESS_PATTERN, "{indexGroup}/{indexOffset}:{adsDataType}([numberOfElements])?");
}
String indexGroupStringHex = matcher.group("indexGroupHex");
String indexGroupString = matcher.group("indexGroup");
String indexOffsetStringHex = matcher.group("indexOffsetHex");
String indexOffsetString = matcher.group("indexOffset");
long indexGroup;
if (indexGroupStringHex != null) {
indexGroup = Long.parseLong(indexGroupStringHex, 16);
} else {
indexGroup = Long.parseLong(indexGroupString);
}
long indexOffset;
if (indexOffsetStringHex != null) {
indexOffset = Long.parseLong(indexOffsetStringHex, 16);
} else {
indexOffset = Long.parseLong(indexOffsetString);
}
String adsDataTypeString = matcher.group("adsDataType");
AdsDataType adsDataType = AdsDataType.valueOf(adsDataTypeString);
String numberOfElementsString = matcher.group("numberOfElements");
Integer numberOfElements = numberOfElementsString != null ? Integer.valueOf(numberOfElementsString) : null;
return new DirectAdsField(indexGroup, indexOffset, adsDataType, numberOfElements);
}
Aggregations