* 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
* 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"
if (data[0] != 0x5C)
return -1;
- if (len >= 2)
- {
- if (data[1] != 0x00)
- return -1;
- }
-
if (len >= 6)
{
int datalen = data[4];
byte checksum = 0;
// calculate XOR checksum
- for (int i = 2; i < (datalen + 5); i++)
+ for (int i = 1; i < (datalen + 5); i++)
checksum ^= data[i];
byte msg_checksum = data[datalen + 5];
* ----------------------------------------------------------------------------
*
* Frame format:
- * +----+----+------+-----+-----+----+----+-----+
- * | 5C | 00 | ADDR | CMD | LEN | DATA | CHK |
- * +----+----+------+-----+-----+----+----+-----+
- * |------------ CHK -----------|
+ * +----+------+------+-----+-----+----+----+-----+
+ * | 5C | ADDR | ADDR | CMD | LEN | DATA | CHK |
+ * +----+------+------+-----+-----+----+----+-----+
+ *
+ * |------------ CHK ------------------|
*
* Address:
- * 0x16 = SMS40
- * 0x19 = RMU40
- * 0x20 = MODBUS40
+ * 0x0016 = SMS40
+ * 0x0019 = RMU40
+ * 0x0020 = MODBUS40
*
* Checksum: XOR
*
*
* ----------------------------------------------------------------------------
*
- * 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.
* Application also acknowledge the valid packets to heat pump.
*
* MODBUS module support should be turned ON from the heat pump.
*
* Frame format:
- * +----+----+------+-----+-----+----+----+-----+
- * | 5C | 00 | ADDR | CMD | LEN | DATA | CHK |
- * +----+----+------+-----+-----+----+----+-----+
+ * +----+------+------+-----+-----+----+----+-----+
+ * | 5C | ADDR | ADDR | CMD | LEN | DATA | CHK |
+ * +----+------+------+-----+-----+----+----+-----+
*
- * |------------ CHK -----------|
+ * |------------ CHK ------------------|
*
- * Address:
- * 0x16 = SMS40
- * 0x19 = RMU40
- * 0x20 = MODBUS40
+ * Address:
+ * 0x0016 = SMS40
+ * 0x0019 = RMU40
+ * 0x0020 = MODBUS40
*
- * Checksum: XOR
+ * Checksum: XOR
*
* When valid data is received (checksum ok),
* ACK (0x06) should be sent to the heat pump.
* 30.6.2015 v1.21 Some fixes.
* 20.2.2017 v1.22 Separated read and write token support.
* 7.2.2021 v1.23 Fixed compile error in RasPi.
+ * 19.11.2022 v1.30 Support 16-bit addressing.
*/
#include <signal.h>
if (data[0] != 0x5C)
return -1;
- if (len >= 2)
- {
- if (data[1] != 0x00)
- return -1;
- }
-
if (len >= 6)
{
int datalen = data[4];
unsigned char calc_checksum = 0;
// calculate XOR checksum
- for(int i = 2; i < (datalen + 5); i++)
+ for(int i = 1; i < (datalen + 5); i++)
calc_checksum ^= data[i];
unsigned char msg_checksum = data[datalen + 5];
return msgStatus.INVALID;
}
- if (len >= 2) {
- if (!(byteBuffer.get(1) == 0x00)) {
- return msgStatus.INVALID;
- }
- }
-
if (len >= 6) {
int datalen = byteBuffer.get(NibeHeatPumpProtocol.RES_OFFS_LEN);
// calculate XOR checksum
byte calcChecksum = 0;
- for (int i = 2; i < (datalen + 5); i++) {
+ for (int i = 1; i < (datalen + 5); i++) {
calcChecksum ^= byteBuffer.get(i);
}
// MODBUS40 data read out, special len, acknowledge should be send
+ "5C00206852449C2500489CFE004C9CF2004E9CD4014D9CFB014F9C2500509C3700519C0D01529C5C5C01569C3200C9AF000001A80C01FDA712FAFAA9070098A95C5C1BFFFF0000A0A9D102FFFF00009CA9B412FFFF00007F"
// 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
// create byte data from hex string
// test results
- assertEquals(7, ackRequestCount);
+ assertEquals(8, ackRequestCount);
assertEquals(2, nakRequestCount);
assertEquals(1, sendWriteMsgCount);
assertEquals(1, sendReadMsgCount);
- assertEquals(7, receivedMsgs.size());
+ assertEquals(8, receivedMsgs.size());
String expect;
expect = "5C00206850449C2600489CF6004C9CF1004E9CD6014D9C0C024F9C4500509C3F00519CF100529C0401569CD500C9AF000001A80C01FDA799FAFAA9020098A91A1BFFFF0000A0A9CA02FFFF00009CA99212FFFF0000C5";
assertArrayEquals(HexUtils.hexToBytes(expect), receivedMsgs.get(6));
+
+ expect = "5C41C9F7007F";
+ assertArrayEquals(HexUtils.hexToBytes(expect), receivedMsgs.get(7));
}
}