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