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.nibeheatpump.internal.message;
15 import java.util.ArrayList;
16 import java.util.List;
18 import org.openhab.binding.nibeheatpump.internal.NibeHeatPumpException;
19 import org.openhab.binding.nibeheatpump.internal.protocol.NibeHeatPumpProtocol;
22 * The {@link ModbusDataReadOutMessage} implements Nibe data read out message.
24 * @author Pauli Anttila - Initial contribution
26 public class ModbusDataReadOutMessage extends NibeHeatPumpBaseMessage {
28 private List<ModbusValue> values = new ArrayList<>();
30 private ModbusDataReadOutMessage(MessageBuilder builder) {
31 super.msgType = MessageType.MODBUS_DATA_READ_OUT_MSG;
32 this.values = builder.values;
35 public ModbusDataReadOutMessage(byte[] data) throws NibeHeatPumpException {
39 public List<ModbusValue> getValues() {
44 public void encodeMessage(byte[] data) throws NibeHeatPumpException {
45 if (NibeHeatPumpProtocol.isModbus40DataReadOut(data)) {
46 super.encodeMessage(data);
47 final int msglen = NibeHeatPumpProtocol.RES_HEADER_LEN + rawMessage[NibeHeatPumpProtocol.RES_OFFS_LEN];
52 for (int i = NibeHeatPumpProtocol.RES_OFFS_DATA; i < (msglen - 1); i += 4) {
54 int id = ((rawMessage[i + 1] & 0xFF) << 8 | (rawMessage[i + 0] & 0xFF));
55 int value = (rawMessage[i + 3] & 0xFF) << 8 | (rawMessage[i + 2] & 0xFF);
58 values.add(new ModbusValue(id, value));
61 } catch (ArrayIndexOutOfBoundsException e) {
62 throw new NibeHeatPumpException("Error occurred during data parsing", e);
65 throw new NibeHeatPumpException("Not Modbus data readout message");
70 public byte[] decodeMessage() {
71 byte datalen = (byte) (values.size() * 4);
72 byte msglen = (byte) (NibeHeatPumpProtocol.RES_HEADER_LEN + datalen + NibeHeatPumpProtocol.PDU_CHECKSUM_LEN);
74 byte[] data = new byte[msglen];
76 data[0] = NibeHeatPumpProtocol.FRAME_START_CHAR_RES;
78 data[2] = NibeHeatPumpProtocol.ADR_MODBUS40;
79 data[3] = NibeHeatPumpProtocol.CMD_MODBUS_DATA_MSG;
82 int i = NibeHeatPumpProtocol.RES_OFFS_DATA;
84 for (ModbusValue value : values) {
86 int coildAddress = value.getCoilAddress();
87 int val = value.getValue();
89 data[i + 0] = (byte) (coildAddress & 0xFF);
90 data[i + 1] = (byte) ((coildAddress >> 8) & 0xFF);
91 data[i + 2] = (byte) (val & 0xFF);
92 data[i + 3] = (byte) ((val >> 8) & 0xFF);
96 data[msglen - 1] = NibeHeatPumpProtocol.calculateChecksum(data, 2, msglen);
101 public String toString() {
102 String str = super.toString();
104 str += values.toString();
108 public static class MessageBuilder {
109 private List<ModbusValue> values = new ArrayList<>();
111 public MessageBuilder values(List<ModbusValue> values) {
112 this.values = values;
116 public MessageBuilder value(ModbusValue value) {
117 this.values.add(value);
121 public MessageBuilder value(int coilAddress, int value) {
122 this.values.add(new ModbusValue(coilAddress, value));
126 public ModbusDataReadOutMessage build() {
127 return new ModbusDataReadOutMessage(this);