use of org.apache.plc4x.java.api.exceptions.PlcRuntimeException in project plc4x by apache.
the class CANOpenFrameDataHandler method toCAN.
@Override
public Message toCAN(CANOpenFrame frame) {
try {
CANOpenPayload payload = frame.getPayload();
WriteBufferByteBased buffer = new WriteBufferByteBased(payload.getLengthInBytes(), ByteOrder.LITTLE_ENDIAN);
payload.serialize(buffer);
return builder.get().withId(frame.getService().getMin() + frame.getNodeId()).withData(buffer.getData()).create();
} catch (SerializationException e) {
throw new PlcRuntimeException(e);
}
}
use of org.apache.plc4x.java.api.exceptions.PlcRuntimeException in project plc4x by apache.
the class Ets5Parser method parse.
public Ets5Model parse(File knxprojFile, String password) {
try {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_SCHEMA, "");
DocumentBuilder builder = factory.newDocumentBuilder();
XPathFactory xPathFactory = XPathFactory.newInstance();
XPath xPath = xPathFactory.newXPath();
try (ZipFile zipFile = new ZipFile(knxprojFile)) {
// //////////////////////////////////////////////////////////////////////////////
// File containing the information on the type of encoding used for group addresses.
// //////////////////////////////////////////////////////////////////////////////
Document projectHeaderDoc;
Document projectDoc;
String projectNumber = this.getProjectNumber(zipFile);
FileHeader projectFileHeader = zipFile.getFileHeader(projectNumber + "/project.xml");
if (projectFileHeader == null) {
// This is the case of a knxproj file which is password-protected
final FileHeader encryptedProjectFileHeader = zipFile.getFileHeader(projectNumber + ".zip");
if (encryptedProjectFileHeader == null) {
throw new PlcRuntimeException(String.format("Error accessing project header file. Project file '%s/project.xml' and '%s.zip' don't exist.", projectNumber, projectNumber));
}
// Dump the encrypted zip to a temp file.
Path tempDir = Files.createTempDirectory(null);
zipFile.extractFile(projectNumber + ".zip", tempDir.toFile().getAbsolutePath());
File tempFile = new File(tempDir.toFile(), projectNumber + ".zip");
// Unzip the archive inside the archive.
try (ZipFile projectZipFile = new ZipFile(tempFile, password.toCharArray())) {
final FileHeader compressedProjectFileHeader = projectZipFile.getFileHeader("project.xml");
if (compressedProjectFileHeader == null) {
throw new PlcRuntimeException(String.format("Error accessing project header file: Project file 'project.xml' inside '%s.zip'.", projectNumber));
}
projectHeaderDoc = builder.parse(projectZipFile.getInputStream(compressedProjectFileHeader));
FileHeader projectFileFileHeader = projectZipFile.getFileHeader("0.xml");
if (projectFileFileHeader == null) {
throw new PlcRuntimeException("Error accessing project file.");
}
projectDoc = builder.parse(projectZipFile.getInputStream(projectFileFileHeader));
}
} else {
projectHeaderDoc = builder.parse(zipFile.getInputStream(projectFileHeader));
FileHeader projectFileFileHeader = zipFile.getFileHeader(projectNumber + "/0.xml");
if (projectFileFileHeader == null) {
throw new PlcRuntimeException("Error accessing project file.");
}
projectDoc = builder.parse(zipFile.getInputStream(projectFileFileHeader));
}
final XPathExpression xpathGroupAddressStyle = xPath.compile("/KNX/Project/ProjectInformation/@GroupAddressStyle");
Attr groupAddressStyle = (Attr) xpathGroupAddressStyle.evaluate(projectHeaderDoc, XPathConstants.NODE);
byte groupAddressStyleCode = getGroupAddressLevel(groupAddressStyle.getTextContent());
// //////////////////////////////////////////////////////////////////////////////
// General information on the type of encoding and the value ranges.
// //////////////////////////////////////////////////////////////////////////////
FileHeader knxMasterDataFileFileHeader = zipFile.getFileHeader("knx_master.xml");
if (knxMasterDataFileFileHeader == null) {
throw new PlcRuntimeException("Error accessing KNX master file.");
}
Document knxMasterDoc = builder.parse(zipFile.getInputStream(knxMasterDataFileFileHeader));
final XPathExpression xpathDatapointSubtype = xPath.compile("//DatapointSubtype");
NodeList datapointSubtypeNodes = (NodeList) xpathDatapointSubtype.evaluate(knxMasterDoc, XPathConstants.NODESET);
// Build an index of the internal data-types.
Map<String, KnxDatapointType> knxDatapointTypeMap = new TreeMap<>();
for (KnxDatapointType value : KnxDatapointType.values()) {
knxDatapointTypeMap.put(value.getDatapointMainType().getNumber() + "#" + value.getNumber(), value);
}
Map<String, AddressType> addressTypes = new HashMap<>();
for (int i = 0; i < datapointSubtypeNodes.getLength(); i++) {
final Element datapointSubtypeNode = (Element) datapointSubtypeNodes.item(i);
final String id = datapointSubtypeNode.getAttribute("Id");
final int subType = Integer.parseInt(datapointSubtypeNode.getAttribute("Number"));
final int mainType = Integer.parseInt(((Element) datapointSubtypeNode.getParentNode().getParentNode()).getAttribute("Number"));
final String name = datapointSubtypeNode.getAttribute("Text");
addressTypes.put(id, new AddressType(id, mainType, subType, name));
}
// //////////////////////////////////////////////////////////////////////////////
// File containing all the information about group addresses used, their names, types etc.
// //////////////////////////////////////////////////////////////////////////////
final Map<String, String> topologyNames = new HashMap<>();
final XPathExpression topology = xPath.compile("//Topology");
final Element topologyElement = (Element) topology.evaluate(projectDoc, XPathConstants.NODE);
final NodeList areas = topologyElement.getElementsByTagName("Area");
for (int a = 0; a < areas.getLength(); a++) {
final Element areaNode = (Element) areas.item(a);
final String curAreaAddress = areaNode.getAttribute("Address");
topologyNames.put(curAreaAddress, areaNode.getAttribute("Name"));
final NodeList lines = areaNode.getElementsByTagName("Line");
for (int l = 0; l < lines.getLength(); l++) {
final Element lineNode = (Element) lines.item(l);
final String curLineAddress = curAreaAddress + "/" + lineNode.getAttribute("Address");
topologyNames.put(curLineAddress, lineNode.getAttribute("Name"));
}
}
final Map<String, Function> groupAddressRefs = new HashMap<>();
final XPathExpression xpathGroupAddressRef = xPath.compile("//GroupAddressRef");
NodeList groupAddressRefNodes = (NodeList) xpathGroupAddressRef.evaluate(projectDoc, XPathConstants.NODESET);
for (int i = 0; i < groupAddressRefNodes.getLength(); i++) {
final Element groupAddressRefNode = (Element) groupAddressRefNodes.item(i);
final String refId = groupAddressRefNode.getAttribute("RefId");
final Element functionNode = (Element) groupAddressRefNode.getParentNode();
final String functionName = functionNode.getAttribute("Name");
// Function Type information is stored in knx_master.xml (//FunctionType[@id='functionTypeId']
final String functionTypeId = functionNode.getAttribute("Type");
final Element spaceNode = (Element) functionNode.getParentNode();
final String spaceName = spaceNode.getAttribute("Name");
final Function function = new Function(refId, functionName, functionTypeId, spaceName);
groupAddressRefs.put(refId, function);
}
final XPathExpression xpathGroupAddresses = xPath.compile("//GroupAddress");
NodeList groupAddressNodes = (NodeList) xpathGroupAddresses.evaluate(projectDoc, XPathConstants.NODESET);
Map<String, GroupAddress> groupAddresses = new HashMap<>();
for (int i = 0; i < groupAddressNodes.getLength(); i++) {
final Element groupAddressNode = (Element) groupAddressNodes.item(i);
final String id = groupAddressNode.getAttribute("Id");
final Function function = groupAddressRefs.get(id);
final int addressInt = Integer.parseInt(groupAddressNode.getAttribute("Address"));
final String knxGroupAddress = Ets5Model.parseGroupAddress(groupAddressStyleCode, addressInt);
final String name = groupAddressNode.getAttribute("Name");
final String typeString = groupAddressNode.getAttribute("DatapointType");
final AddressType addressType = addressTypes.get(typeString);
if (addressType != null) {
// Lookup the driver internal data-type.
final KnxDatapointType datapointType = knxDatapointTypeMap.get(addressType.getMainType() + "#" + addressType.getSubType());
GroupAddress groupAddress = new GroupAddress(knxGroupAddress, name, datapointType, function);
groupAddresses.put(knxGroupAddress, groupAddress);
}
}
return new Ets5Model(groupAddressStyleCode, groupAddresses, topologyNames);
}
} catch (IOException | ParserConfigurationException | SAXException | XPathExpressionException e) {
// Zip and Xml Stuff
throw new PlcRuntimeException(e);
}
}
use of org.apache.plc4x.java.api.exceptions.PlcRuntimeException in project plc4x by apache.
the class EipProtocolLogic method decodeWriteResponse.
private PlcResponse decodeWriteResponse(CipService p, PlcWriteRequest writeRequest) {
Map<String, PlcResponseCode> responses = new HashMap<>();
if (p instanceof CipWriteResponse) {
CipWriteResponse resp = (CipWriteResponse) p;
String fieldName = writeRequest.getFieldNames().iterator().next();
EipField field = (EipField) writeRequest.getField(fieldName);
responses.put(fieldName, decodeResponseCode(resp.getStatus()));
return new DefaultPlcWriteResponse(writeRequest, responses);
} else if (p instanceof MultipleServiceResponse) {
MultipleServiceResponse resp = (MultipleServiceResponse) p;
int nb = resp.getServiceNb();
List<CipService> arr = new ArrayList<>(nb);
ReadBufferByteBased read = new ReadBufferByteBased(resp.getServicesData());
int total = (int) read.getTotalBytes();
for (int i = 0; i < nb; i++) {
int length = 0;
int offset = resp.getOffsets().get(i);
if (offset == nb - 1) {
// Get the rest if last
length = total - offset;
} else {
// Calculate length with offsets
length = resp.getOffsets().get(i + 1) - offset;
}
ReadBuffer serviceBuf = new ReadBufferByteBased(read.getBytes(offset, length), org.apache.plc4x.java.spi.generation.ByteOrder.LITTLE_ENDIAN);
CipService service = null;
try {
service = CipService.staticParse(read, length);
arr.add(service);
} catch (ParseException e) {
throw new PlcRuntimeException(e);
}
}
Services services = new Services(nb, resp.getOffsets(), arr, -1);
Iterator<String> it = writeRequest.getFieldNames().iterator();
for (int i = 0; i < nb && it.hasNext(); i++) {
String fieldName = it.next();
EipField field = (EipField) writeRequest.getField(fieldName);
PlcValue plcValue = null;
if (services.getServices().get(i) instanceof CipWriteResponse) {
CipWriteResponse writeResponse = (CipWriteResponse) services.getServices().get(i);
PlcResponseCode code = decodeResponseCode(writeResponse.getStatus());
responses.put(fieldName, code);
}
}
return new DefaultPlcWriteResponse(writeRequest, responses);
}
return null;
}
use of org.apache.plc4x.java.api.exceptions.PlcRuntimeException in project plc4x by apache.
the class KnxNetIpProtocolLogic method toKnxAddressData.
protected byte[] toKnxAddressData(KnxNetIpField field) {
WriteBufferByteBased address = new WriteBufferByteBased(2);
try {
switch(knxNetIpDriverContext.getGroupAddressType()) {
case 3:
address.writeUnsignedShort(5, Short.parseShort(field.getMainGroup()));
address.writeUnsignedByte(3, Byte.parseByte(field.getMiddleGroup()));
address.writeUnsignedShort(8, Short.parseShort(field.getSubGroup()));
break;
case 2:
address.writeUnsignedShort(5, Short.parseShort(field.getMainGroup()));
address.writeUnsignedShort(11, Short.parseShort(field.getSubGroup()));
break;
case 1:
address.writeUnsignedShort(16, Short.parseShort(field.getSubGroup()));
break;
}
} catch (Exception e) {
throw new PlcRuntimeException("Error converting field into knx address data.", e);
}
return address.getData();
}
use of org.apache.plc4x.java.api.exceptions.PlcRuntimeException 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;
}
Aggregations