2 * Copyright (c) 2010-2023 Contributors to the openHAB project
4 * See the NOTICE file(s) distributed with this work for additional
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
11 * SPDX-License-Identifier: EPL-2.0
13 package org.openhab.binding.modbus.e3dc.internal.modbus;
15 import static org.openhab.binding.modbus.e3dc.internal.modbus.E3DCModbusConstans.*;
17 import java.util.Arrays;
18 import java.util.Optional;
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;
33 * The {@link Parser} class receives callbacks from modbus poller
35 * @author Bernd Weymann - Initial contribution
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;
44 private int counter = 0;
45 private long maxDuration = Long.MIN_VALUE;
46 private long minDuration = Long.MAX_VALUE;
47 private long avgDuration = 0;
49 public Parser(DataType type) {
51 if (type.equals(DataType.INFO)) {
52 size = INFO_REG_SIZE * 2;
53 bArray = new byte[size];
55 size = (REGISTER_LENGTH - INFO_REG_SIZE) * 2;
56 bArray = new byte[size];
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());
66 long duration = System.currentTimeMillis() - startTime;
67 avgDuration += duration;
68 minDuration = Math.min(minDuration, duration);
69 maxDuration = Math.max(maxDuration, duration);
71 if (counter % MEASURE_COUNT == 0) {
72 logger.debug("Min {} Max {} Avg {}", minDuration, maxDuration, avgDuration / MEASURE_COUNT);
74 minDuration = Long.MAX_VALUE;
75 maxDuration = Long.MIN_VALUE;
78 logger.warn("Modbus read result doesn't return expected registers");
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);
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)));
111 logger.warn("Wrong Block requested. Request is {} but type is {}", type, callbackType);
112 return Optional.empty();
116 public String toString() {
117 StringBuilder sb = new StringBuilder();
118 sb.append(this.getClass().getName()).append(":").append(callbackType);
119 return sb.toString();