Search in sources :

Example 1 with PlcRuntimeException

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);
    }
}
Also used : PlcRuntimeException(org.apache.plc4x.java.api.exceptions.PlcRuntimeException) SerializationException(org.apache.plc4x.java.spi.generation.SerializationException) CANOpenPayload(org.apache.plc4x.java.canopen.readwrite.CANOpenPayload) WriteBufferByteBased(org.apache.plc4x.java.spi.generation.WriteBufferByteBased)

Example 2 with PlcRuntimeException

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);
    }
}
Also used : DocumentBuilderFactory(javax.xml.parsers.DocumentBuilderFactory) HashMap(java.util.HashMap) Element(org.w3c.dom.Element) Document(org.w3c.dom.Document) Attr(org.w3c.dom.Attr) SAXException(org.xml.sax.SAXException) Function(org.apache.plc4x.java.knxnetip.ets5.model.Function) GroupAddress(org.apache.plc4x.java.knxnetip.ets5.model.GroupAddress) ParserConfigurationException(javax.xml.parsers.ParserConfigurationException) FileHeader(net.lingala.zip4j.model.FileHeader) Path(java.nio.file.Path) PlcRuntimeException(org.apache.plc4x.java.api.exceptions.PlcRuntimeException) KnxDatapointType(org.apache.plc4x.java.knxnetip.readwrite.KnxDatapointType) NodeList(org.w3c.dom.NodeList) IOException(java.io.IOException) TreeMap(java.util.TreeMap) Ets5Model(org.apache.plc4x.java.knxnetip.ets5.model.Ets5Model) ZipFile(net.lingala.zip4j.ZipFile) DocumentBuilder(javax.xml.parsers.DocumentBuilder) AddressType(org.apache.plc4x.java.knxnetip.ets5.model.AddressType) File(java.io.File) ZipFile(net.lingala.zip4j.ZipFile)

Example 3 with PlcRuntimeException

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;
}
Also used : PlcRuntimeException(org.apache.plc4x.java.api.exceptions.PlcRuntimeException) EipField(org.apache.plc4x.java.eip.readwrite.field.EipField) PlcResponseCode(org.apache.plc4x.java.api.types.PlcResponseCode) ReadBuffer(org.apache.plc4x.java.spi.generation.ReadBuffer) ReadBufferByteBased(org.apache.plc4x.java.spi.generation.ReadBufferByteBased) ParseException(org.apache.plc4x.java.spi.generation.ParseException)

Example 4 with PlcRuntimeException

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();
}
Also used : PlcRuntimeException(org.apache.plc4x.java.api.exceptions.PlcRuntimeException) PlcRuntimeException(org.apache.plc4x.java.api.exceptions.PlcRuntimeException)

Example 5 with PlcRuntimeException

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;
}
Also used : PlcRuntimeException(org.apache.plc4x.java.api.exceptions.PlcRuntimeException) PlcField(org.apache.plc4x.java.api.model.PlcField) DefaultPlcSubscriptionField(org.apache.plc4x.java.spi.model.DefaultPlcSubscriptionField) PlcInvalidFieldException(org.apache.plc4x.java.api.exceptions.PlcInvalidFieldException) FirmataFieldDigital(org.apache.plc4x.java.firmata.readwrite.field.FirmataFieldDigital) FirmataFieldAnalog(org.apache.plc4x.java.firmata.readwrite.field.FirmataFieldAnalog)

Aggregations

PlcRuntimeException (org.apache.plc4x.java.api.exceptions.PlcRuntimeException)83 BigInteger (java.math.BigInteger)17 PlcConnectionException (org.apache.plc4x.java.api.exceptions.PlcConnectionException)10 CompletableFuture (java.util.concurrent.CompletableFuture)8 PlcResponseCode (org.apache.plc4x.java.api.types.PlcResponseCode)8 PlcValue (org.apache.plc4x.java.api.value.PlcValue)8 ResponseItem (org.apache.plc4x.java.spi.messages.utils.ResponseItem)8 IOException (java.io.IOException)7 Duration (java.time.Duration)7 PlcField (org.apache.plc4x.java.api.model.PlcField)7 ConversationContext (org.apache.plc4x.java.spi.ConversationContext)7 TimeoutException (java.util.concurrent.TimeoutException)6 Matcher (java.util.regex.Matcher)6 PlcConnection (org.apache.plc4x.java.api.PlcConnection)6 org.apache.plc4x.java.api.messages (org.apache.plc4x.java.api.messages)6 DefaultPlcSubscriptionField (org.apache.plc4x.java.spi.model.DefaultPlcSubscriptionField)6 PlcList (org.apache.plc4x.java.spi.values.PlcList)6 File (java.io.File)5 ArrayList (java.util.ArrayList)5 List (java.util.List)5