]> git.basschouten.com Git - openhab-addons.git/blob
e8a257d18c28401b38d82e00b2a4d22428fbf0a8
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2023 Contributors to the openHAB project
3  *
4  * See the NOTICE file(s) distributed with this work for additional
5  * information.
6  *
7  * This program and the accompanying materials are made available under the
8  * terms of the Eclipse Public License 2.0 which is available at
9  * http://www.eclipse.org/legal/epl-2.0
10  *
11  * SPDX-License-Identifier: EPL-2.0
12  */
13 package org.openhab.binding.gce.internal.model;
14
15 import java.util.regex.Pattern;
16
17 import org.eclipse.jdt.annotation.NonNullByDefault;
18 import org.openhab.binding.gce.internal.handler.Ipx800DeviceConnector;
19 import org.openhab.binding.gce.internal.handler.Ipx800EventListener;
20 import org.slf4j.Logger;
21 import org.slf4j.LoggerFactory;
22
23 /**
24  * This class handles message translation to and from the IPX.
25  *
26  * @author GaĆ«l L'hopital - Initial contribution
27  */
28 @NonNullByDefault
29 public class M2MMessageParser {
30     private static final String IO_DESCRIPTOR = "(\\d{32})";
31     private static final Pattern IO_PATTERN = Pattern.compile(IO_DESCRIPTOR);
32     private static final Pattern VALIDATION_PATTERN = Pattern
33             .compile("I=" + IO_DESCRIPTOR + "&O=" + IO_DESCRIPTOR + "&([AC]\\d{1,2}=\\d+&)*[^I]*");
34
35     private final Logger logger = LoggerFactory.getLogger(M2MMessageParser.class);
36     private final Ipx800DeviceConnector connector;
37     private final Ipx800EventListener listener;
38
39     private String expectedResponse = "";
40
41     public M2MMessageParser(Ipx800DeviceConnector connector, Ipx800EventListener listener) {
42         this.connector = connector;
43         this.listener = listener;
44         connector.setParser(this);
45     }
46
47     /**
48      *
49      * @param data
50      */
51     public void unsolicitedUpdate(String data) {
52         if (IO_PATTERN.matcher(data).matches()) {
53             PortDefinition portDefinition = PortDefinition.fromM2MCommand(expectedResponse);
54             decodeDataLine(portDefinition, data);
55         } else if (VALIDATION_PATTERN.matcher(data).matches()) {
56             for (String status : data.split("&")) {
57                 String statusPart[] = status.split("=");
58                 int portNumShift = 1;
59                 PortDefinition portDefinition = PortDefinition.fromPortName(statusPart[0].substring(0, 1));
60                 switch (portDefinition) {
61                     case CONTACT:
62                     case RELAY: {
63                         decodeDataLine(portDefinition, statusPart[1]);
64                         break;
65                     }
66                     case COUNTER:
67                         portNumShift = 0; // Align counters on 1 based array
68                     case ANALOG: {
69                         int portNumber = Integer.parseInt(statusPart[0].substring(1)) + portNumShift;
70                         setStatus(portDefinition.getPortName() + portNumber, Double.parseDouble(statusPart[1]));
71                     }
72                 }
73             }
74         } else if (!expectedResponse.isEmpty()) {
75             setStatus(expectedResponse, Double.parseDouble(data));
76         }
77
78         expectedResponse = "";
79     }
80
81     private void decodeDataLine(PortDefinition portDefinition, String data) {
82         for (int count = 0; count < data.length(); count++) {
83             setStatus(portDefinition.getPortName() + (count + 1), (double) data.charAt(count) - '0');
84         }
85     }
86
87     private void setStatus(String port, double value) {
88         logger.debug("Received {} : {}", port, value);
89         listener.dataReceived(port, value);
90     }
91
92     public void setExpectedResponse(String expectedResponse) {
93         if (expectedResponse.endsWith("s")) { // GetInputs or GetOutputs
94             this.expectedResponse = expectedResponse;
95         } else { // GetAnx or GetCountx
96             PortDefinition portType = PortDefinition.fromM2MCommand(expectedResponse);
97             this.expectedResponse = expectedResponse.replaceAll(portType.getM2mCommand(), portType.getPortName());
98         }
99     }
100
101     /**
102      * Set output of the device sending the corresponding command
103      *
104      * @param targetPort
105      * @param targetValue
106      */
107     public void setOutput(String targetPort, int targetValue, boolean pulse) {
108         logger.debug("Sending {} to {}", targetValue, targetPort);
109         String command = String.format("Set%02d%s%s", Integer.parseInt(targetPort), targetValue, pulse ? "p" : "");
110         connector.send(command);
111     }
112
113     /**
114      * Resets the counter value to 0
115      *
116      * @param targetCounter
117      */
118     public void resetCounter(int targetCounter) {
119         logger.debug("Resetting counter {} to 0", targetCounter);
120         connector.send(String.format("ResetCount%d", targetCounter));
121     }
122
123     public void errorOccurred(Exception e) {
124         logger.warn("Error received from connector : {}", e.getMessage());
125         listener.errorOccurred(e);
126     }
127
128     public void resetPLC() {
129         connector.send("Reset");
130     }
131 }