]> git.basschouten.com Git - openhab-addons.git/blob
e1524f44c4386cca0fddcd81bec5e6b06d974bb2
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2020 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.modbus.e3dc.internal.modbus;
14
15 import static org.openhab.binding.modbus.e3dc.internal.modbus.E3DCModbusConstans.*;
16
17 import java.util.Arrays;
18 import java.util.Optional;
19
20 import org.eclipse.jdt.annotation.NonNullByDefault;
21 import org.openhab.binding.modbus.e3dc.internal.dto.EmergencyBlock;
22 import org.openhab.binding.modbus.e3dc.internal.dto.InfoBlock;
23 import org.openhab.binding.modbus.e3dc.internal.dto.PowerBlock;
24 import org.openhab.binding.modbus.e3dc.internal.dto.StringBlock;
25 import org.openhab.binding.modbus.e3dc.internal.dto.WallboxArray;
26 import org.openhab.binding.modbus.e3dc.internal.modbus.Data.DataType;
27 import org.openhab.io.transport.modbus.AsyncModbusReadResult;
28 import org.openhab.io.transport.modbus.ModbusRegister;
29 import org.openhab.io.transport.modbus.ModbusRegisterArray;
30 import org.slf4j.Logger;
31 import org.slf4j.LoggerFactory;
32
33 /**
34  * The {@link InfoBlockCallback} class receives callbacks from modbus poller
35  *
36  * @author Bernd Weymann - Initial contribution
37  */
38 @NonNullByDefault
39 public class Parser {
40     private static final int MEASURE_COUNT = 100;
41     private final Logger logger = LoggerFactory.getLogger(Parser.class);
42     private DataType callbackType;
43     private byte[] bArray;
44     private int size;
45     private int counter = 0;
46     private long maxDuration = Long.MIN_VALUE;
47     private long minDuration = Long.MAX_VALUE;
48     private long avgDuration = 0;
49
50     public Parser(DataType type) {
51         callbackType = type;
52         if (type.equals(DataType.INFO)) {
53             size = INFO_REG_SIZE * 2;
54             bArray = new byte[size];
55         } else {
56             size = (REGISTER_LENGTH - INFO_REG_SIZE) * 2;
57             bArray = new byte[size];
58         }
59     }
60
61     public void handle(AsyncModbusReadResult result) {
62         byte[] newArray = new byte[size];
63         long startTime = System.currentTimeMillis();
64         Optional<ModbusRegisterArray> opt = result.getRegisters();
65         if (opt.isPresent()) {
66             ModbusRegisterArray registers = opt.get();
67             int i = 0;
68             for (ModbusRegister reg : registers) {
69                 System.arraycopy(reg.getBytes(), 0, newArray, i, 2);
70                 i += 2;
71             }
72             setArray(newArray);
73
74             long duration = System.currentTimeMillis() - startTime;
75             avgDuration += duration;
76             minDuration = Math.min(minDuration, duration);
77             maxDuration = Math.max(maxDuration, duration);
78             counter++;
79             if (counter % MEASURE_COUNT == 0) {
80                 logger.debug("Min {} Max {} Avg {}", minDuration, maxDuration, avgDuration / MEASURE_COUNT);
81                 avgDuration = 0;
82                 minDuration = Long.MAX_VALUE;
83                 maxDuration = Long.MIN_VALUE;
84             }
85         } else {
86             logger.warn("Modbus read result doesn't return expected registers");
87         }
88     }
89
90     public synchronized void setArray(byte[] b) {
91         if (b.length != size) {
92             logger.warn("Wrong byte size received. Should be {} but is {}. Data maybe corrupted!", size, b.length);
93         }
94         bArray = b.clone();
95     }
96
97     public Optional<Data> parse(DataType type) {
98         synchronized (bArray) {
99             if (type.equals(DataType.INFO) && callbackType.equals(DataType.INFO)) {
100                 return Optional.of(new InfoBlock(Arrays.copyOfRange(bArray, INFO_REG_START, INFO_REG_SIZE * 2)));
101             } else if (type.equals(DataType.POWER) && callbackType.equals(DataType.DATA)) {
102                 int start = (POWER_REG_START - INFO_REG_SIZE) * 2;
103                 int end = start + POWER_REG_SIZE * 2;
104                 return Optional.of(new PowerBlock(Arrays.copyOfRange(bArray, start, end)));
105             } else if (type.equals(DataType.EMERGENCY) && callbackType.equals(DataType.DATA)) {
106                 int start = (EMS_REG_START - INFO_REG_SIZE) * 2;
107                 int end = start + EMS_REG_SIZE * 2;
108                 return Optional.of(new EmergencyBlock(Arrays.copyOfRange(bArray, start, end)));
109             } else if (type.equals(DataType.WALLBOX) && callbackType.equals(DataType.DATA)) {
110                 int start = (WALLBOX_REG_START - INFO_REG_SIZE) * 2;
111                 int end = start + WALLBOX_REG_SIZE * 2;
112                 return Optional.of(new WallboxArray(Arrays.copyOfRange(bArray, start, end)));
113             } else if (type.equals(DataType.STRINGS) && callbackType.equals(DataType.DATA)) {
114                 int start = (STRINGS_REG_START - INFO_REG_SIZE) * 2;
115                 int end = start + STRINGS_REG_SIZE * 2;
116                 return Optional.of(new StringBlock(Arrays.copyOfRange(bArray, start, end)));
117             }
118         }
119         logger.warn("Wrong Block requested. Request is {} but type is {}", type, callbackType);
120         return Optional.empty();
121     }
122
123     @Override
124     public String toString() {
125         StringBuilder sb = new StringBuilder();
126         sb.append(this.getClass().getName()).append(":").append(callbackType);
127         return sb.toString();
128     }
129 }