]> git.basschouten.com Git - openhab-addons.git/blob
0261bc1e50813a656e6e20604ea7316d5e644009
[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.nibeheatpump.internal.message;
14
15 import java.util.ArrayList;
16 import java.util.List;
17
18 import org.openhab.binding.nibeheatpump.internal.NibeHeatPumpException;
19 import org.openhab.binding.nibeheatpump.internal.protocol.NibeHeatPumpProtocol;
20
21 /**
22  * The {@link ModbusDataReadOutMessage} implements Nibe data read out message.
23  *
24  * @author Pauli Anttila - Initial contribution
25  */
26 public class ModbusDataReadOutMessage extends NibeHeatPumpBaseMessage {
27
28     private List<ModbusValue> values = new ArrayList<>();
29
30     private ModbusDataReadOutMessage(MessageBuilder builder) {
31         super.msgType = MessageType.MODBUS_DATA_READ_OUT_MSG;
32         this.values = builder.values;
33     }
34
35     public ModbusDataReadOutMessage(byte[] data) throws NibeHeatPumpException {
36         encodeMessage(data);
37     }
38
39     public List<ModbusValue> getValues() {
40         return values;
41     }
42
43     @Override
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];
48
49             values.clear();
50
51             try {
52                 for (int i = NibeHeatPumpProtocol.RES_OFFS_DATA; i < (msglen - 1); i += 4) {
53
54                     int id = ((rawMessage[i + 1] & 0xFF) << 8 | (rawMessage[i + 0] & 0xFF));
55                     int value = (rawMessage[i + 3] & 0xFF) << 8 | (rawMessage[i + 2] & 0xFF);
56
57                     if (id != 0xFFFF) {
58                         values.add(new ModbusValue(id, value));
59                     }
60                 }
61             } catch (ArrayIndexOutOfBoundsException e) {
62                 throw new NibeHeatPumpException("Error occurred during data parsing", e);
63             }
64         } else {
65             throw new NibeHeatPumpException("Not Modbus data readout message");
66         }
67     }
68
69     @Override
70     public byte[] decodeMessage() {
71         byte datalen = (byte) (values.size() * 4);
72         byte msglen = (byte) (NibeHeatPumpProtocol.RES_HEADER_LEN + datalen + NibeHeatPumpProtocol.PDU_CHECKSUM_LEN);
73
74         byte[] data = new byte[msglen];
75
76         data[0] = NibeHeatPumpProtocol.FRAME_START_CHAR_RES;
77         data[1] = 0x00;
78         data[2] = NibeHeatPumpProtocol.ADR_MODBUS40;
79         data[3] = NibeHeatPumpProtocol.CMD_MODBUS_DATA_MSG;
80         data[4] = datalen;
81
82         int i = NibeHeatPumpProtocol.RES_OFFS_DATA;
83
84         for (ModbusValue value : values) {
85
86             int coildAddress = value.getCoilAddress();
87             int val = value.getValue();
88
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);
93             i += 4;
94         }
95
96         data[msglen - 1] = NibeHeatPumpProtocol.calculateChecksum(data, 2, msglen);
97         return data;
98     }
99
100     @Override
101     public String toString() {
102         String str = super.toString();
103         str += ", Values: ";
104         str += values.toString();
105         return str;
106     }
107
108     public static class MessageBuilder {
109         private List<ModbusValue> values = new ArrayList<>();
110
111         public MessageBuilder values(List<ModbusValue> values) {
112             this.values = values;
113             return this;
114         }
115
116         public MessageBuilder value(ModbusValue value) {
117             this.values.add(value);
118             return this;
119         }
120
121         public MessageBuilder value(int coilAddress, int value) {
122             this.values.add(new ModbusValue(coilAddress, value));
123             return this;
124         }
125
126         public ModbusDataReadOutMessage build() {
127             return new ModbusDataReadOutMessage(this);
128         }
129     }
130 }