diff --git a/README.md b/README.md index bbcfbbf..60c612d 100644 --- a/README.md +++ b/README.md @@ -95,28 +95,25 @@ and some optional params can be provided as well: * **datatype(optional):** provide datatype as single char: `b` - for MODBUS_BIT - `i` - for MODBUS_INTEGER (unsigned) - `s` - for MODBUS_SIGNED_INT (NOTE: in Zabbix use 'Type of information' Numeric(float) ) - `l` - for MODBUS_LONG, 32bit + `i` - for MODBUS_INTEGER, 16bit (unsigned) + `s` - for MODBUS_SIGNED_INT, 16bit (NOTE: in Zabbix use 'Type of information' Numeric(float) ) + `l` - for MODBUS_LONG, 32bit (unsigned) `f` - for MODBUS_FLOAT, 32bit - - There is also experimental support added for 64bit Modbus datatypes: - `S` - for MODBUS_SIGNED_INT64 (NOTE: in Zabbix use 'Type of information' Numeric(float) ) - `I` - for MODBUS_INT64 (unsigned) (NOTE: in Zabbix use 'Type of information' Numeric(unsigned) ) - `d` - for MODBUS_FLOAT64, 64 bit + `S` - for MODBUS_SIGNED_INT32, 32bit (NOTE: in Zabbix use 'Type of information' Numeric(float) ) + `I` - for MODBUS_UINT64, 64bit (unsigned) (NOTE: in Zabbix use 'Type of information' Numeric(unsigned) ) + `d` - for MODBUS_FLOAT64, 64bit otherwise, defaults will be used: MODBUS_BIT if modbus function 1 or 2. MODBUS_INTEGER if modbus_function 3 or 4. - - Please also note Zabbix datatypes constraints when working with 64bit: - https://www.zabbix.com/documentation/3.4/manual/config/items * **endianness(optional):** - Modbus endianness(word swap) for long and float 32bit/64bit datatypes: - 0 - for MODBUS_16BIT_LE (16 bit little endian) - 1 - for MODBUS_16BIT_BE (16 bit big endian) - default is BE + Modbus endianness for 32bit/64bit datatypes: + 0 - for MODBUS_MLE_CDAB (Mid-Little Endian (CDAB)) + 1 - for MODBUS_BE_ABCD (Big Endian (ABCD)) + 2 - for MODBUS_MBE_BADC (Mid-Big Endian (BADC)) + 3 - for MODBUS_LE_DCBA (Little Endian (DCBA)) + Default is BE(1). Normaly, you don't need to change this. * **first_reg(optional):** Modbus addressing scheme diff --git a/src/modbus.c b/src/modbus.c index a485cb6..ed6a0e2 100644 --- a/src/modbus.c +++ b/src/modbus.c @@ -28,6 +28,8 @@ #include #include +#include + #define MODBUS_READ_COIL_1 1 #define MODBUS_READ_DINPUTS_2 2 #define MODBUS_READ_H_REGISTERS_3 3 @@ -38,12 +40,32 @@ #define MODBUS_SIGNED_INT 's' #define MODBUS_LONG 'l' #define MODBUS_FLOAT 'f' -#define MODBUS_SIGNED_INT64 'S' -#define MODBUS_INT64 'I' +#define MODBUS_SIGNED_INT32 'S' +#define MODBUS_UINT64 'I' #define MODBUS_FLOAT64 'd' -#define MODBUS_16BIT_LE 0 -#define MODBUS_16BIT_BE 1 +#define MODBUS_GET_BE_32BIT(tab_int16, index) (((uint32_t)tab_int16[(index)]) << 16) | tab_int16[(index) + 1] +#define MODBUS_GET_MLE_32BIT(tab_int16, index) (((uint32_t)tab_int16[(index) + 1]) << 16) | tab_int16[(index)] +#define MODBUS_GET_MBE_32BIT(tab_int16, index) (((uint32_t)bswap_16(tab_int16[(index)])) << 16) | bswap_16(tab_int16[(index) + 1]) +#define MODBUS_GET_LE_32BIT(tab_int16, index) (((uint32_t)bswap_16(tab_int16[(index) + 1])) << 16) | bswap_16(tab_int16[(index)]) + + +#define MODBUS_GET_BE_64BIT(tab_int16, index) (((uint64_t)tab_int16[index]) << 48) | (((uint64_t)tab_int16[index + 1]) << 32) | (((uint64_t)tab_int16[index + 2]) << 16) | tab_int16[index + 3] +#define MODBUS_GET_MLE_64BIT(tab_int16, index) (((uint64_t)tab_int16[index + 3]) << 48) | (((uint64_t)tab_int16[index + 2]) << 32) | (((uint64_t)tab_int16[index + 1]) << 16) | tab_int16[index] +#define MODBUS_GET_MBE_64BIT(tab_int16, index) (((uint64_t)bswap_16(tab_int16[index])) << 48) \ + | (((uint64_t)bswap_16(tab_int16[index + 1])) << 32) \ + | (((uint64_t)bswap_16(tab_int16[index + 2])) << 16) \ + | bswap_16(tab_int16[index + 3]) +#define MODBUS_GET_LE_64BIT(tab_int16, index) (((uint64_t)bswap_16(tab_int16[index + 3])) << 48) \ + | (((uint64_t)bswap_16(tab_int16[index + 2])) << 32) \ + | (((uint64_t)bswap_16(tab_int16[index + 1])) << 16) \ + | bswap_16(tab_int16[index]) + + +#define MODBUS_MLE_CDAB 0 //Mid-Little Endian (CDAB) +#define MODBUS_BE_ABCD 1 //Big Endian (ABCD) +#define MODBUS_MBE_BADC 2 //Mid-Big Endian (BADC) +#define MODBUS_LE_DCBA 3 //Little Endian (DCBA) #define MODBUS_PDU_ADDRESS_0 0 #define MODBUS_PROTOCOL_ADDRESS_1 1 @@ -144,17 +166,6 @@ unsigned long hash(unsigned char *str) return hash; } -/* Get a float from 8 bytes (Modbus) with swapped words (GH EF CD AB) */ -double modbus_get_double(const uint16_t *src) -{ - double d; - uint64_t i; - - i = (((uint64_t)src[3]) << 48) + (((uint64_t)src[2]) << 32) + (((uint64_t)src[1]) << 16) + src[0]; - memcpy(&d, &i, sizeof(double)); - - return d; -} /****************************************************************************** * * @@ -254,7 +265,7 @@ int zbx_modbus_read_registers(AGENT_REQUEST *request, AGENT_RESULT *result) } char datatype; - int end = MODBUS_16BIT_BE; // endianness LE(0) BE(1) default BE + int end = MODBUS_BE_ABCD; // endianness LE(0) BE(1) MBE(2) MLE(3) default BE if (request->nparam > 4) { //optional params provided param5 = get_rparam(request, 4); //datatype @@ -265,12 +276,15 @@ int zbx_modbus_read_registers(AGENT_REQUEST *request, AGENT_RESULT *result) } datatype = *param5; // set datatype - param6 = get_rparam(request, 5); //16 endiannes + param6 = get_rparam(request, 5); //32-64bit endiannes if(param6) { //endianness to use errno = 0; end = strtol(param6,&endptr, 0); - if ( (end != MODBUS_16BIT_LE && end != MODBUS_16BIT_BE) || + if ( (end != MODBUS_LE_DCBA && + end != MODBUS_BE_ABCD && + end != MODBUS_MBE_BADC && + end != MODBUS_MLE_CDAB ) || (errno!=0 || *endptr != '\0') ) { SET_MSG_RESULT(result, strdup("Check endiannes used")); modbus_free(ctx); @@ -314,9 +328,10 @@ int zbx_modbus_read_registers(AGENT_REQUEST *request, AGENT_RESULT *result) uint16_t tab_reg[64];//temp vars uint8_t tab_reg_bits[64]; + int regs_to_read = 1; - if (datatype == MODBUS_FLOAT || datatype == MODBUS_LONG) { regs_to_read=2;} - else if (datatype == MODBUS_SIGNED_INT64 || datatype == MODBUS_INT64 || datatype == MODBUS_FLOAT64) { regs_to_read=4;} + if (datatype == MODBUS_FLOAT || datatype == MODBUS_LONG || datatype == MODBUS_SIGNED_INT32) { regs_to_read=2;} + else if (datatype == MODBUS_UINT64 || datatype == MODBUS_FLOAT64) { regs_to_read=4;} @@ -378,79 +393,122 @@ int zbx_modbus_read_registers(AGENT_REQUEST *request, AGENT_RESULT *result) //use float type in zabbix item SET_DBL_RESULT(result, (int16_t) tab_reg[0]); break; - + float f; + uint32_t i; case MODBUS_FLOAT: - if (end == MODBUS_16BIT_LE) { - temp_arr[0] = tab_reg[0]; - temp_arr[1] = tab_reg[1]; - } else if (end == MODBUS_16BIT_BE) { - temp_arr[0] = tab_reg[1]; - temp_arr[1] = tab_reg[0]; + switch( end ) + { + case MODBUS_LE_DCBA: + i = MODBUS_GET_LE_32BIT(tab_reg, 0); + break; + case MODBUS_BE_ABCD: + i = MODBUS_GET_BE_32BIT(tab_reg, 0); + break; + case MODBUS_MBE_BADC: + i = MODBUS_GET_MBE_32BIT(tab_reg, 0); + break; + case MODBUS_MLE_CDAB: + i = MODBUS_GET_MLE_32BIT(tab_reg, 0); + break; + default: + return SYSINFO_RET_FAIL; + break; } - SET_DBL_RESULT(result, modbus_get_float(temp_arr)); + memcpy(&f, &i, sizeof(float)); + SET_DBL_RESULT(result, f); break; case MODBUS_LONG: - //MODBUS_GET_INT32_FROM_INT16 is doing BIG_ENDIAN for register pair, so inverse registers (sort of hack) - if (end == MODBUS_16BIT_LE) {//word swap - temp_arr[0] = tab_reg[1]; - temp_arr[1] = tab_reg[0]; - } else if (end == MODBUS_16BIT_BE) { - temp_arr[0] = tab_reg[0]; - temp_arr[1] = tab_reg[1]; - } - SET_UI64_RESULT(result, MODBUS_GET_INT32_FROM_INT16(temp_arr, 0)); - break; - case MODBUS_SIGNED_INT64: - if (end == MODBUS_16BIT_LE) { - temp_arr[0] = tab_reg[3]; - temp_arr[1] = tab_reg[2]; - temp_arr[2] = tab_reg[1]; - temp_arr[3] = tab_reg[0]; - } - if (end == MODBUS_16BIT_BE) { - temp_arr[0] = tab_reg[0]; - temp_arr[1] = tab_reg[1]; - temp_arr[2] = tab_reg[2]; - temp_arr[3] = tab_reg[3]; + switch( end ) + { + case MODBUS_LE_DCBA: + SET_UI64_RESULT(result, (uint32_t)MODBUS_GET_LE_32BIT(tab_reg, 0)); + break; + case MODBUS_BE_ABCD: + SET_UI64_RESULT(result, (uint32_t)MODBUS_GET_BE_32BIT(tab_reg, 0)); + break; + case MODBUS_MBE_BADC: + SET_UI64_RESULT(result, (uint32_t)MODBUS_GET_MBE_32BIT(tab_reg, 0)); + break; + case MODBUS_MLE_CDAB: + SET_UI64_RESULT(result, (uint32_t)MODBUS_GET_MLE_32BIT(tab_reg, 0)); + break; + default: + return SYSINFO_RET_FAIL; + break; } - SET_DBL_RESULT(result, ((int64_t)MODBUS_GET_INT64_FROM_INT16(temp_arr,0))); - break; + break; - case MODBUS_INT64: - //INT64 - if (end == MODBUS_16BIT_LE) { - temp_arr[0] = tab_reg[3]; - temp_arr[1] = tab_reg[2]; - temp_arr[2] = tab_reg[1]; - temp_arr[3] = tab_reg[0]; + case MODBUS_SIGNED_INT32: + switch( end ) + { + case MODBUS_BE_ABCD: + temp_arr[0] = tab_reg[0]; + temp_arr[1] = tab_reg[1]; + break; + case MODBUS_LE_DCBA: + temp_arr[0] = bswap_16(tab_reg[1]); + temp_arr[1] = bswap_16(tab_reg[0]); + break; + case MODBUS_MBE_BADC: + temp_arr[0] = bswap_16(tab_reg[0]); + temp_arr[1] = bswap_16(tab_reg[1]); + break; + case MODBUS_MLE_CDAB: + temp_arr[0] = tab_reg[1]; + temp_arr[1] = tab_reg[0]; + break; + default: + return SYSINFO_RET_FAIL; + break; } - if (end == MODBUS_16BIT_BE) { - temp_arr[0] = tab_reg[0]; - temp_arr[1] = tab_reg[1]; - temp_arr[2] = tab_reg[2]; - temp_arr[3] = tab_reg[3]; + SET_DBL_RESULT(result, ((int32_t)MODBUS_GET_INT32_FROM_INT16(temp_arr,0))); + break; + case MODBUS_UINT64: + switch( end ) + { + case MODBUS_LE_DCBA: + SET_UI64_RESULT(result, ((uint64_t)MODBUS_GET_LE_64BIT(tab_reg,0))); + break; + case MODBUS_BE_ABCD: + SET_UI64_RESULT(result, ((uint64_t)MODBUS_GET_BE_64BIT(tab_reg,0))); + break; + case MODBUS_MBE_BADC: + SET_UI64_RESULT(result, ((uint64_t)MODBUS_GET_MBE_64BIT(tab_reg,0))); + break; + case MODBUS_MLE_CDAB: + SET_UI64_RESULT(result, ((uint64_t)MODBUS_GET_MLE_64BIT(tab_reg,0))); + break; + default: + return SYSINFO_RET_FAIL; + break; } + break; - SET_UI64_RESULT(result, ((uint64_t)MODBUS_GET_INT64_FROM_INT16(temp_arr,0))); - break; - + double d; + uint64_t i64; case MODBUS_FLOAT64: - - if (end == MODBUS_16BIT_LE) { - temp_arr[0] = tab_reg[3]; - temp_arr[1] = tab_reg[2]; - temp_arr[2] = tab_reg[1]; - temp_arr[3] = tab_reg[0]; - } - if (end == MODBUS_16BIT_BE) { - temp_arr[0] = tab_reg[0]; - temp_arr[1] = tab_reg[1]; - temp_arr[2] = tab_reg[2]; - temp_arr[3] = tab_reg[3]; + switch( end ) + { + case MODBUS_LE_DCBA: + i64 = MODBUS_GET_LE_64BIT(tab_reg, 0); + break; + case MODBUS_BE_ABCD: + i64 = MODBUS_GET_BE_64BIT(tab_reg, 0); + break; + case MODBUS_MBE_BADC: + i64 = MODBUS_GET_MBE_64BIT(tab_reg, 0); + break; + case MODBUS_MLE_CDAB: + i64 = MODBUS_GET_MLE_64BIT(tab_reg, 0); + break; + default: + return SYSINFO_RET_FAIL; + break; } - SET_DBL_RESULT(result, modbus_get_double(temp_arr)); + memcpy(&d, &i64, sizeof(double)); + SET_DBL_RESULT(result, d); break; default : diff --git a/tests/README.md b/tests/README.md index 57ba732..e63ef5f 100644 --- a/tests/README.md +++ b/tests/README.md @@ -15,5 +15,5 @@ ## Run local You can run tests local: 1. Build libzbxmodbus `./configure --enable-zabbix-3.2 && make` -2. Build and run the rest with docker-compose `export ZBX_VERSION=3.4.12 ; pushd tests/docker && docker-compose up -d --force-recreate ; popd` +2. Build and run the rest with docker-compose `export ZBX_VERSION=3.4.12 ; pushd tests/docker && docker-compose build && docker-compose up -d --force-recreate ; popd` 3. Run sample test from shell `docker exec docker_zabbix-agent-modbus_1 sh -c "zabbix_get -s localhost -k modbus_read[172.16.238.2:5020,1,2,3,i,1,1]"` diff --git a/tests/docker/modbus-server/app.py b/tests/docker/modbus-server/app.py index 2bf49d6..219acc0 100644 --- a/tests/docker/modbus-server/app.py +++ b/tests/docker/modbus-server/app.py @@ -89,14 +89,47 @@ def run_server(modbus_type,port): #block = ModbusSequentialDataBlock(0x00, [16]*0xff) block = ModbusSparseDataBlock({ + #this block is to test 32bits + 1:0xC28F,#PDU0 - BE + 2:0xC20D, + + 3:0x8FC2,#PDU2 - MBE + 4:0x0DC2, + + 5:0xC20D,#PDU4 - MLE + 6:0xC28F, + + 7:0x0DC2,#PDU6 - LE + 8:0x8FC2, + + # test int32 + 13:0xFFFF,#PDU12 + 14:0xFDCE, - 1:0xC28F,#PDU0 - 2:0xC20D,#PDU1 + # this block is to test 64bits + #BE + 15:0xBFBF,#PDU14 + 16:0x9A6B, + 17:0x50B0, + 18:0xF27C, + + #LE + 19:0x7CF2,#PDU18 + 20:0xB050, + 21:0x6B9A, + 22:0xBFBF, + + #MLE + 23:0xF27C,#PDU22 + 24:0x50B0, + 25:0x9A6B, + 26:0xBFBF, - 11:0xFFFF,#PDU10 - 12:0xFFFF, - 13:0xFFFF, - 14:0xFDCE + #MBE + 27:0xBFBF,#PDU26 + 28:0x6B9A, + 29:0xB050, + 30:0x7CF2 }) store = ModbusSlaveContext(di=block, co=block, hr=block, ir=block) diff --git a/tests/test_modbus.py b/tests/test_modbus.py index d1a712f..4736553 100644 --- a/tests/test_modbus.py +++ b/tests/test_modbus.py @@ -6,76 +6,83 @@ class ModbusTestCase(unittest.TestCase): host = "172.16.238.2:5020" - - # test holding_registers03.mbs set - # 16bit, all tests are PDU (start from 0 address) - # signed int + # 16bit, all tests are PDU (start from 0 address) + # INT16,Big Endian def test_modbus_datatype_signed_0(self): key = "modbus_read["+self.host+",1,0,3,s]" self.assertEqual(zabbix_get(key),'-15729.000000') - # signed int + # INT16,Big Endian def test_modbus_datatype_signed_1(self): key = "modbus_read["+self.host+",1,1,3,s]" self.assertEqual(zabbix_get(key),'-15859.000000') - # unsigned int + # UINT16,Big Endian def test_modbus_datatype_unsigned_0(self): key = "modbus_read["+self.host+",1,0,3,i]" self.assertEqual(zabbix_get(key),'49807') - # unsigned int + # UINT16,Big Endian def test_modbus_datatype_unsigned_1(self): key = "modbus_read["+self.host+",1,1,3,i]" self.assertEqual(zabbix_get(key),'49677') - # 32bit - # float,BigEndian (ABCD) + # 32bit. + # Float. In 32bit float we are looking for "-71.879005" + # Big Endian (ABCD) def test_modbus_datatype_float_32bit_be_abcd_0(self): key = "modbus_read["+self.host+",1,0,3,f]" self.assertEqual(zabbix_get(key),'-71.879005') - # float,(LittleEndian with Wordswap),(CDAB) - def test_modbus_datatype_float_32bit_le_cdab_0(self): - key = "modbus_read["+self.host+",1,0,3,f,0]" - self.assertEqual(zabbix_get(key),'-35.439999') - - #IMPLEMENT: - #float (LittleEndian)(DCBA) - @unittest.skip("implement this first") + # Little Endian with Wordswap or Mid-Little Endian (CDAB) + def test_modbus_datatype_float_32bit_mle_cdab_0(self): + key = "modbus_read["+self.host+",1,4,3,f,0]" + self.assertEqual(zabbix_get(key),'-71.879005') + # Big Endian with WordSwap or Mid-Big Endian (BADC) + def test_modbus_datatype_float_32bit_mbe_badc_0(self): + key = "modbus_read["+self.host+",1,2,3,f,2]" + self.assertEqual(zabbix_get(key),'-71.879005') + # Little Endian (DCBA) def test_modbus_datatype_float_32bit_le_dcba_0(self): - key = "modbus_read["+self.host+",1,0,3,f,0]" - self.assertEqual(zabbix_get(key),'1.19907815e-30') - #IMPLEMENT: - # float (Big Endian with WordSwap) Mid-Big Endian (BADC) - @unittest.skip("implement this first") - def test_modbus_datatype_float_32bit_be_badc_0(self): - key = "modbus_read["+self.host+",1,0,3,f]" - self.assertEqual(zabbix_get(key),'-1.91351763e-29') + key = "modbus_read["+self.host+",1,6,3,f,3]" + self.assertEqual(zabbix_get(key),'-71.879005') - - # 32bit unsigned integers(long): - # long,BigEndian (ABCD) - @unittest.skip("Seems to be broken 32bit long") + # UINT32,unsigned,long: + # Big Endian (ABCD) def test_modbus_datatype_long_32bit_be_abcd_0(self): key = "modbus_read["+self.host+",1,0,3,l]" self.assertEqual(zabbix_get(key),'3264201229') - # long,(LittleEndian with Wordswap),(CDAB) - @unittest.skip("Seems to be broken with 32bit long") - def test_modbus_datatype_long_32bit_le_cdab_0(self): + # Mid-Little Endian (CDAB) + def test_modbus_datatype_long_32bit_mle_cdab_0(self): key = "modbus_read["+self.host+",1,0,3,l,0]" self.assertEqual(zabbix_get(key),'3255681679') - #IMPLEMENT: - # long (LittleEndian)(DCBA) - @unittest.skip("implement this first") + # Little Endian (DCBA) def test_modbus_datatype_long_32bit_le_dcba_0(self): - key = "modbus_read["+self.host+",1,0,3,l,0]" - self.assertEqual(zabbix_get(key),'230854594') - #IMPLEMENT: - # long (Big Endian with WordSwap) Mid-Big Endian (BADC) - @unittest.skip("implement this first") - def test_modbus_datatype_long_32bit_be_badc_0(self): - key = "modbus_read["+self.host+",1,0,3,l]" - self.assertEqual(zabbix_get(key),'2411859394') + key = "modbus_read["+self.host+",1,0,3,l,3]" + self.assertEqual(zabbix_get(key),'230854594') + # Mid-Big Endian (BADC) + def test_modbus_datatype_long_32bit_mbe_badc_0(self): + key = "modbus_read["+self.host+",1,0,3,l,2]" + self.assertEqual(zabbix_get(key),'2411859394') + + # INT32(Signed) + # Big Endian (ABCD) + def test_modbus_datatype_int32_be_0(self): + key = "modbus_read["+self.host+",1,12,3,S]" + self.assertEqual(zabbix_get(key),'-562.000000') + # Mid-Little Endian (CDAB) + def test_modbus_datatype_int32_mle_0(self): + key = "modbus_read["+self.host+",1,12,3,S,0]" + self.assertEqual(zabbix_get(key),'-36765697.000000') + + # Little Endian (DCAB) + def test_modbus_datatype_int32_le_0(self): + key = "modbus_read["+self.host+",1,12,3,S,3]" + self.assertEqual(zabbix_get(key),'-822214657.000000') + # Mid-Big Endian (BADC) + def test_modbus_datatype_int32_mbe_0(self): + key = "modbus_read["+self.host+",1,12,3,S,2]" + self.assertEqual(zabbix_get(key),'-12547.000000') + if __name__ == '__main__': diff --git a/tests/test_modbus_64bit.py b/tests/test_modbus_64bit.py index 1cefb98..96f7158 100644 --- a/tests/test_modbus_64bit.py +++ b/tests/test_modbus_64bit.py @@ -5,32 +5,72 @@ class Modbus64BitTestCase(unittest.TestCase): host = "172.16.238.2:5020" + + # INT64(Signed) NOT IMLEMENTED + # Big Endian + @unittest.skip("Implement first") + def test_modbus_datatype_int64_64bit_be_0(self): + key = "modbus_read["+self.host+",1,14,3,X]" + self.assertEqual(zabbix_get(key),'-4629812106207628676') + # Mid-Little Endian + @unittest.skip("Implement first") + def test_modbus_datatype_int64_64bit_mle_0(self): + key = "modbus_read["+self.host+",1,22,3,X,0]" + self.assertEqual(zabbix_get(key),'-4629812106207628676') + + # Little Endian + @unittest.skip("Implement first") + def test_modbus_datatype_int64_64bit_le_0(self): + key = "modbus_read["+self.host+",1,18,3,X,3]" + self.assertEqual(zabbix_get(key),'-4629812106207628676') + + # Mid-Big Endian + @unittest.skip("Implement first") + def test_modbus_datatype_int64_64bit_mbe_0(self): + key = "modbus_read["+self.host+",1,26,3,X,2]" + self.assertEqual(zabbix_get(key),'-4629812106207628676') + + #UNSIGNED INT64 + # Big Endian + def test_modbus_datatype_uint64_64bit_be_0(self): + key = "modbus_read["+self.host+",1,14,3,I]" + self.assertEqual(zabbix_get(key),'13816931967501922940') + # Mid-Little Endian + def test_modbus_datatype_uint64_64bit_mle_0(self): + key = "modbus_read["+self.host+",1,22,3,I,0]" + self.assertEqual(zabbix_get(key),'13816931967501922940') + + # Little Endian + def test_modbus_datatype_uint64_64bit_le_0(self): + key = "modbus_read["+self.host+",1,18,3,I,3]" + self.assertEqual(zabbix_get(key),'13816931967501922940') + + # Mid-Big Endian + def test_modbus_datatype_uint64_64bit_mbe_0(self): + key = "modbus_read["+self.host+",1,26,3,I,2]" + self.assertEqual(zabbix_get(key),'13816931967501922940') + + + # FLOAT64(double) + # Big Endian + def test_modbus_datatype_double_64bit_be_0(self): + key = "modbus_read["+self.host+",1,14,3,d]" + self.assertEqual(zabbix_get(key),'-0.123450') + # Mid-Little Endian + def test_modbus_datatype_double_64bit_mle_0(self): + key = "modbus_read["+self.host+",1,22,3,d,0]" + self.assertEqual(zabbix_get(key),'-0.123450') + + # Little Endian + def test_modbus_datatype_double_64bit_le_0(self): + key = "modbus_read["+self.host+",1,18,3,d,3]" + self.assertEqual(zabbix_get(key),'-0.123450') + + # Mid-Big Endian + def test_modbus_datatype_double_64bit_mbe_0(self): + key = "modbus_read["+self.host+",1,26,3,d,2]" + self.assertEqual(zabbix_get(key),'-0.123450') - #64bit signed - #https://github.com/v-zhuravlev/libzbxmodbus/issues/28#issuecomment-390718491 - # 64bit signed integers(long): - # long,BigEndian - # testing for value 0xFFFFFFFFFFFFFDCE - def test_modbus_datatype_long_64bit_be_0(self): - key = "modbus_read["+self.host+",1,10,3,S]" - self.assertEqual(zabbix_get(key),'-562.000000') - # 64int signed,(LittleEndian with Wordswap),(CDAB) - def test_modbus_datatype_long_64bit_le_cdab_0(self): - key = "modbus_read["+self.host+",1,10,3,S,0]" - self.assertEqual(zabbix_get(key),'-157907461934678016.000000') - - #IMPLEMENT: - # 64int signed (LittleEndian)(DCBA) - @unittest.skip("implement this first") - def test_modbus_datatype_long_64bit_le_dcba_0(self): - key = "modbus_read["+self.host+",1,10,3,S,0]" - self.assertEqual(zabbix_get(key),'-3531385057811890177') - #IMPLEMENT: - # 64int signed (Big Endian with WordSwap) Mid-Big Endian (BADC) - @unittest.skip("implement this first") - def test_modbus_datatype_long_64bit_be_badc_0(self): - key = "modbus_read["+self.host+",1,10,3,S]" - self.assertEqual(zabbix_get(key),'-12547') if __name__ == '__main__': diff --git a/tests/test_modbus_errors.py b/tests/test_modbus_errors.py index c49c5f3..5484518 100644 --- a/tests/test_modbus_errors.py +++ b/tests/test_modbus_errors.py @@ -45,7 +45,7 @@ def test_bad_PDU_flag_string(self): def test_bad_LE_flag_integer(self): - key = "modbus_read_registers["+self.host+",3,14,3,l,2,0]" + key = "modbus_read_registers["+self.host+",3,14,3,l,5,0]" self.assertEqual(zabbix_get(key),'ZBX_NOTSUPPORTED: Check endiannes used') def test_bad_LE_flag_string(self): @@ -68,10 +68,10 @@ def test_bad_register_string(self): self.assertEqual(zabbix_get(key),'ZBX_NOTSUPPORTED: Check register to read') def test_bad_slaveid_integer(self): - key = "modbus_read_registers["+self.host+",5000,14,3,l,1,0]" + key = "modbus_read_registers["+self.host+",5000,99,3,l,1,0]" self.assertEqual(zabbix_get(key),'ZBX_NOTSUPPORTED: Illegal data address') def test_bad_slaveid_string(self): - key = "modbus_read_registers["+self.host+",bad,14,3,l,1,0]" + key = "modbus_read_registers["+self.host+",bad,1,3,l,1,0]" self.assertEqual(zabbix_get(key),'ZBX_NOTSUPPORTED: Check slaveid parameter')