[nibeheatpump] Support 16-bit addressing (#13752)
* [nibeheatpump] Support for 16-bit addressing Signed-off-by: Pauli Anttila <pauli.anttila@gmail.com>
This commit is contained in:
@@ -24,6 +24,7 @@
|
|||||||
* 3.7.2022 v4.00 Send messages to IP address received from the UDP messages
|
* 3.7.2022 v4.00 Send messages to IP address received from the UDP messages
|
||||||
* 13.7.2022 v4.01 Fixed target IP address issue
|
* 13.7.2022 v4.01 Fixed target IP address issue
|
||||||
* 29.7.2022 v5.00 New configuration model and PRODINo ESP32 Ethernet v1 support with OTA update
|
* 29.7.2022 v5.00 New configuration model and PRODINo ESP32 Ethernet v1 support with OTA update
|
||||||
|
* 19.11.2022 v5.10 Support 16-bit addressing.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define VERSION "5.00"
|
#define VERSION "5.00"
|
||||||
|
|||||||
@@ -279,12 +279,6 @@ int NibeGw::checkNibeMessage(const byte* const data, byte len)
|
|||||||
if (data[0] != 0x5C)
|
if (data[0] != 0x5C)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (len >= 2)
|
|
||||||
{
|
|
||||||
if (data[1] != 0x00)
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (len >= 6)
|
if (len >= 6)
|
||||||
{
|
{
|
||||||
int datalen = data[4];
|
int datalen = data[4];
|
||||||
@@ -295,7 +289,7 @@ int NibeGw::checkNibeMessage(const byte* const data, byte len)
|
|||||||
byte checksum = 0;
|
byte checksum = 0;
|
||||||
|
|
||||||
// calculate XOR checksum
|
// calculate XOR checksum
|
||||||
for (int i = 2; i < (datalen + 5); i++)
|
for (int i = 1; i < (datalen + 5); i++)
|
||||||
checksum ^= data[i];
|
checksum ^= data[i];
|
||||||
|
|
||||||
byte msg_checksum = data[datalen + 5];
|
byte msg_checksum = data[datalen + 5];
|
||||||
|
|||||||
@@ -13,15 +13,16 @@
|
|||||||
* ----------------------------------------------------------------------------
|
* ----------------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
* Frame format:
|
* Frame format:
|
||||||
* +----+----+------+-----+-----+----+----+-----+
|
* +----+------+------+-----+-----+----+----+-----+
|
||||||
* | 5C | 00 | ADDR | CMD | LEN | DATA | CHK |
|
* | 5C | ADDR | ADDR | CMD | LEN | DATA | CHK |
|
||||||
* +----+----+------+-----+-----+----+----+-----+
|
* +----+------+------+-----+-----+----+----+-----+
|
||||||
* |------------ CHK -----------|
|
*
|
||||||
|
* |------------ CHK ------------------|
|
||||||
*
|
*
|
||||||
* Address:
|
* Address:
|
||||||
* 0x16 = SMS40
|
* 0x0016 = SMS40
|
||||||
* 0x19 = RMU40
|
* 0x0019 = RMU40
|
||||||
* 0x20 = MODBUS40
|
* 0x0020 = MODBUS40
|
||||||
*
|
*
|
||||||
* Checksum: XOR
|
* Checksum: XOR
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
*
|
*
|
||||||
* ----------------------------------------------------------------------------
|
* ----------------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
* This application listening data from Nibe F1145/F1245/F1155/F1255 heat pumps (RS485 bus)
|
* This application listening data from various Nibe heat pumps (RS485 bus)
|
||||||
* and send valid frames to configurable IP/port address by UDP packets.
|
* and send valid frames to configurable IP/port address by UDP packets.
|
||||||
* Application also acknowledge the valid packets to heat pump.
|
* Application also acknowledge the valid packets to heat pump.
|
||||||
*
|
*
|
||||||
@@ -21,18 +21,18 @@
|
|||||||
* MODBUS module support should be turned ON from the heat pump.
|
* MODBUS module support should be turned ON from the heat pump.
|
||||||
*
|
*
|
||||||
* Frame format:
|
* Frame format:
|
||||||
* +----+----+------+-----+-----+----+----+-----+
|
* +----+------+------+-----+-----+----+----+-----+
|
||||||
* | 5C | 00 | ADDR | CMD | LEN | DATA | CHK |
|
* | 5C | ADDR | ADDR | CMD | LEN | DATA | CHK |
|
||||||
* +----+----+------+-----+-----+----+----+-----+
|
* +----+------+------+-----+-----+----+----+-----+
|
||||||
*
|
*
|
||||||
* |------------ CHK -----------|
|
* |------------ CHK ------------------|
|
||||||
*
|
*
|
||||||
* Address:
|
* Address:
|
||||||
* 0x16 = SMS40
|
* 0x0016 = SMS40
|
||||||
* 0x19 = RMU40
|
* 0x0019 = RMU40
|
||||||
* 0x20 = MODBUS40
|
* 0x0020 = MODBUS40
|
||||||
*
|
*
|
||||||
* Checksum: XOR
|
* Checksum: XOR
|
||||||
*
|
*
|
||||||
* When valid data is received (checksum ok),
|
* When valid data is received (checksum ok),
|
||||||
* ACK (0x06) should be sent to the heat pump.
|
* ACK (0x06) should be sent to the heat pump.
|
||||||
@@ -56,6 +56,7 @@
|
|||||||
* 30.6.2015 v1.21 Some fixes.
|
* 30.6.2015 v1.21 Some fixes.
|
||||||
* 20.2.2017 v1.22 Separated read and write token support.
|
* 20.2.2017 v1.22 Separated read and write token support.
|
||||||
* 7.2.2021 v1.23 Fixed compile error in RasPi.
|
* 7.2.2021 v1.23 Fixed compile error in RasPi.
|
||||||
|
* 19.11.2022 v1.30 Support 16-bit addressing.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
@@ -273,12 +274,6 @@ int checkMessage(const unsigned char* const data, int len)
|
|||||||
if (data[0] != 0x5C)
|
if (data[0] != 0x5C)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (len >= 2)
|
|
||||||
{
|
|
||||||
if (data[1] != 0x00)
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (len >= 6)
|
if (len >= 6)
|
||||||
{
|
{
|
||||||
int datalen = data[4];
|
int datalen = data[4];
|
||||||
@@ -289,7 +284,7 @@ int checkMessage(const unsigned char* const data, int len)
|
|||||||
unsigned char calc_checksum = 0;
|
unsigned char calc_checksum = 0;
|
||||||
|
|
||||||
// calculate XOR checksum
|
// calculate XOR checksum
|
||||||
for(int i = 2; i < (datalen + 5); i++)
|
for(int i = 1; i < (datalen + 5); i++)
|
||||||
calc_checksum ^= data[i];
|
calc_checksum ^= data[i];
|
||||||
|
|
||||||
unsigned char msg_checksum = data[datalen + 5];
|
unsigned char msg_checksum = data[datalen + 5];
|
||||||
|
|||||||
@@ -148,12 +148,6 @@ public enum NibeHeatPumpProtocolStates implements NibeHeatPumpProtocolState {
|
|||||||
return msgStatus.INVALID;
|
return msgStatus.INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (len >= 2) {
|
|
||||||
if (!(byteBuffer.get(1) == 0x00)) {
|
|
||||||
return msgStatus.INVALID;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (len >= 6) {
|
if (len >= 6) {
|
||||||
int datalen = byteBuffer.get(NibeHeatPumpProtocol.RES_OFFS_LEN);
|
int datalen = byteBuffer.get(NibeHeatPumpProtocol.RES_OFFS_LEN);
|
||||||
|
|
||||||
@@ -164,7 +158,7 @@ public enum NibeHeatPumpProtocolStates implements NibeHeatPumpProtocolState {
|
|||||||
|
|
||||||
// calculate XOR checksum
|
// calculate XOR checksum
|
||||||
byte calcChecksum = 0;
|
byte calcChecksum = 0;
|
||||||
for (int i = 2; i < (datalen + 5); i++) {
|
for (int i = 1; i < (datalen + 5); i++) {
|
||||||
calcChecksum ^= byteBuffer.get(i);
|
calcChecksum ^= byteBuffer.get(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -109,7 +109,9 @@ public class NibeHeatPumpProtocolTest {
|
|||||||
// MODBUS40 data read out, special len, acknowledge should be send
|
// MODBUS40 data read out, special len, acknowledge should be send
|
||||||
+ "5C00206852449C2500489CFE004C9CF2004E9CD4014D9CFB014F9C2500509C3700519C0D01529C5C5C01569C3200C9AF000001A80C01FDA712FAFAA9070098A95C5C1BFFFF0000A0A9D102FFFF00009CA9B412FFFF00007F"
|
+ "5C00206852449C2500489CFE004C9CF2004E9CD4014D9CFB014F9C2500509C3700519C0D01529C5C5C01569C3200C9AF000001A80C01FDA712FAFAA9070098A95C5C1BFFFF0000A0A9D102FFFF00009CA9B412FFFF00007F"
|
||||||
// MODBUS40 data read out, special checksum, acknowledge should be send
|
// MODBUS40 data read out, special checksum, acknowledge should be send
|
||||||
+ "5C00206850449C2600489CF6004C9CF1004E9CD6014D9C0C024F9C4500509C3F00519CF100529C0401569CD500C9AF000001A80C01FDA799FAFAA9020098A91A1BFFFF0000A0A9CA02FFFF00009CA99212FFFF0000C5";
|
+ "5C00206850449C2600489CF6004C9CF1004E9CD6014D9C0C024F9C4500509C3F00519CF100529C0401569CD500C9AF000001A80C01FDA799FAFAA9020098A91A1BFFFF0000A0A9CA02FFFF00009CA99212FFFF0000C5"
|
||||||
|
// 16-bit address (e.g. model F2120 heatpumps), acknowledge should be send
|
||||||
|
+ "5C41C9F7007F";
|
||||||
//@formatter:on
|
//@formatter:on
|
||||||
|
|
||||||
// create byte data from hex string
|
// create byte data from hex string
|
||||||
@@ -125,11 +127,11 @@ public class NibeHeatPumpProtocolTest {
|
|||||||
|
|
||||||
// test results
|
// test results
|
||||||
|
|
||||||
assertEquals(7, ackRequestCount);
|
assertEquals(8, ackRequestCount);
|
||||||
assertEquals(2, nakRequestCount);
|
assertEquals(2, nakRequestCount);
|
||||||
assertEquals(1, sendWriteMsgCount);
|
assertEquals(1, sendWriteMsgCount);
|
||||||
assertEquals(1, sendReadMsgCount);
|
assertEquals(1, sendReadMsgCount);
|
||||||
assertEquals(7, receivedMsgs.size());
|
assertEquals(8, receivedMsgs.size());
|
||||||
|
|
||||||
String expect;
|
String expect;
|
||||||
|
|
||||||
@@ -153,5 +155,8 @@ public class NibeHeatPumpProtocolTest {
|
|||||||
|
|
||||||
expect = "5C00206850449C2600489CF6004C9CF1004E9CD6014D9C0C024F9C4500509C3F00519CF100529C0401569CD500C9AF000001A80C01FDA799FAFAA9020098A91A1BFFFF0000A0A9CA02FFFF00009CA99212FFFF0000C5";
|
expect = "5C00206850449C2600489CF6004C9CF1004E9CD6014D9C0C024F9C4500509C3F00519CF100529C0401569CD500C9AF000001A80C01FDA799FAFAA9020098A91A1BFFFF0000A0A9CA02FFFF00009CA99212FFFF0000C5";
|
||||||
assertArrayEquals(HexUtils.hexToBytes(expect), receivedMsgs.get(6));
|
assertArrayEquals(HexUtils.hexToBytes(expect), receivedMsgs.get(6));
|
||||||
|
|
||||||
|
expect = "5C41C9F7007F";
|
||||||
|
assertArrayEquals(HexUtils.hexToBytes(expect), receivedMsgs.get(7));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user