]> git.basschouten.com Git - openhab-addons.git/blob
3a90e48973e9d9fcb67db10283b5beeccbcffc40
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2021 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;
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         values = parseMessage(data);
46     }
47
48     @Override
49     public byte[] decodeMessage() {
50         return createDataReadOutPdu(values);
51     }
52
53     private byte[] createDataReadOutPdu(List<ModbusValue> values) {
54         byte datalen = (byte) (values.size() * 4);
55         byte msglen = (byte) (6 + datalen);
56
57         byte[] data = new byte[msglen];
58
59         data[0] = NibeHeatPumpProtocol.FRAME_START_CHAR_FROM_NIBE;
60         data[1] = 0x00;
61         data[2] = NibeHeatPumpProtocol.ADR_MODBUS40;
62         data[3] = NibeHeatPumpProtocol.CMD_MODBUS_DATA_MSG;
63         data[4] = datalen;
64
65         int i = NibeHeatPumpProtocol.OFFSET_DATA;
66
67         for (ModbusValue value : values) {
68
69             int coildAddress = value.getCoilAddress();
70             int val = value.getValue();
71
72             data[i + 0] = (byte) (coildAddress & 0xFF);
73             data[i + 1] = (byte) ((coildAddress >> 8) & 0xFF);
74             data[i + 2] = (byte) (val & 0xFF);
75             data[i + 3] = (byte) ((val >> 8) & 0xFF);
76             i += 4;
77         }
78
79         data[msglen - 1] = NibeHeatPumpProtocol.calculateChecksum(data, 2, msglen);
80
81         return data;
82     }
83
84     @Override
85     public String toString() {
86         String str = super.toString();
87         str += ", Values: ";
88         str += values.toString();
89         return str;
90     }
91
92     private List<ModbusValue> parseMessage(byte[] data) throws NibeHeatPumpException {
93         if (NibeHeatPumpProtocol.isModbus40DataReadOut(data)) {
94             super.encodeMessage(data);
95             final int msglen = 5 + rawMessage[NibeHeatPumpProtocol.OFFSET_LEN];
96
97             List<ModbusValue> vals = new ArrayList<>();
98
99             try {
100                 for (int i = NibeHeatPumpProtocol.OFFSET_DATA; i < (msglen - 1); i += 4) {
101
102                     int id = ((rawMessage[i + 1] & 0xFF) << 8 | (rawMessage[i + 0] & 0xFF));
103                     int value = (rawMessage[i + 3] & 0xFF) << 8 | (rawMessage[i + 2] & 0xFF);
104
105                     if (id != 0xFFFF) {
106                         vals.add(new ModbusValue(id, value));
107                     }
108                 }
109             } catch (ArrayIndexOutOfBoundsException e) {
110                 throw new NibeHeatPumpException("Error occurred during data parsing", e);
111             }
112
113             return vals;
114
115         } else {
116             throw new NibeHeatPumpException("Not Modbus data readout message");
117         }
118     }
119
120     public static class MessageBuilder {
121         private List<ModbusValue> values = new ArrayList<>();
122
123         public MessageBuilder values(List<ModbusValue> values) {
124             this.values = values;
125             return this;
126         }
127
128         public MessageBuilder value(ModbusValue value) {
129             this.values.add(value);
130             return this;
131         }
132
133         public MessageBuilder value(int coilAddress, int value) {
134             this.values.add(new ModbusValue(coilAddress, value));
135             return this;
136         }
137
138         public ModbusDataReadOutMessage build() {
139             return new ModbusDataReadOutMessage(this);
140         }
141     }
142 }