From: Simon Peeters Date: Wed, 8 Jun 2022 09:53:25 +0000 (+0200) Subject: modbus: add support for double values (#4009) X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=83a3e93f0f5b38a591a7a1a26c1def8ef9b10f1b;p=thirdparty%2Fcollectd.git modbus: add support for double values (#4009) --- diff --git a/src/collectd.conf.pod b/src/collectd.conf.pod index cde4bd7ed..38519e8d2 100644 --- a/src/collectd.conf.pod +++ b/src/collectd.conf.pod @@ -5179,7 +5179,7 @@ Configures the base register to read from the device. If the option B has been set to B or B, this and the next register will be read (the register number is increased by one). -=item B B|B|B|B|B|B|B|B|B|B +=item B B|B|B|B|B|B|B|B|B|B|B Specifies what kind of data is returned by the device. This defaults to B. If the type is B, B, B, B, @@ -5191,10 +5191,10 @@ significant 16Ebits are in the register at B. For B, B, or B, the high and low order registers are swapped with the most significant 16Ebits in the B and the least significant 16Ebits in -B. If the type is B or B, four 16Ebit -registers at B, B, B and -B will be read and the data combined into one -64Evalue. +B. If the type is B, B or B, four +16Ebit registers at B, B, B +and B will be read and the data combined into one 64Ebit +value. =item B B|B diff --git a/src/modbus.c b/src/modbus.c index e36f3daea..068f73cea 100644 --- a/src/modbus.c +++ b/src/modbus.c @@ -83,7 +83,9 @@ enum mb_register_type_e /* {{{ */ REG_TYPE_INT64, REG_TYPE_UINT64, REG_TYPE_FLOAT, - REG_TYPE_FLOAT_CDAB }; /* }}} */ + REG_TYPE_FLOAT_CDAB, + REG_TYPE_DOUBLE, +}; /* }}} */ enum mb_mreg_type_e /* {{{ */ { MREG_HOLDING, @@ -296,6 +298,38 @@ static float mb_register_to_float(uint16_t hi, uint16_t lo) /* {{{ */ return conv.f; } /* }}} float mb_register_to_float */ +static double mb_register_to_double(uint16_t b0, uint16_t b1, uint16_t b2, + uint16_t b3) /* {{{ */ +{ + union { + uint8_t b[8]; + double d; + } conv; + +#if BYTE_ORDER == LITTLE_ENDIAN + /* little endian */ + conv.b[0] = b3 & 0x00ff; + conv.b[1] = (b3 >> 8) & 0x00ff; + conv.b[2] = b2 & 0x00ff; + conv.b[3] = (b2 >> 8) & 0x00ff; + conv.b[4] = b1 & 0x00ff; + conv.b[5] = (b1 >> 8) & 0x00ff; + conv.b[6] = b0 & 0x00ff; + conv.b[7] = (b0 >> 8) & 0x00ff; +#else + conv.b[7] = b3 & 0x00ff; + conv.b[6] = (b3 >> 8) & 0x00ff; + conv.b[5] = b2 & 0x00ff; + conv.b[4] = (b2 >> 8) & 0x00ff; + conv.b[3] = b1 & 0x00ff; + conv.b[2] = (b1 >> 8) & 0x00ff; + conv.b[1] = b0 & 0x00ff; + conv.b[0] = (b0 >> 8) & 0x00ff; +#endif + + return (conv.d); +} /* }}} double mb_register_to_double */ + #if LEGACY_LIBMODBUS /* Version 2.0.3 */ static int mb_init_connection(mb_host_t *host) /* {{{ */ @@ -341,7 +375,7 @@ static int mb_init_connection(mb_host_t *host) /* {{{ */ host->is_connected = true; return 0; } /* }}} int mb_init_connection */ - /* #endif LEGACY_LIBMODBUS */ +/* #endif LEGACY_LIBMODBUS */ #else /* if !LEGACY_LIBMODBUS */ /* Version 2.9.2 */ @@ -471,7 +505,8 @@ static int mb_read_data(mb_host_t *host, mb_slave_t *slave, /* {{{ */ (data->register_type == REG_TYPE_FLOAT_CDAB)) values_num = 2; else if ((data->register_type == REG_TYPE_INT64) || - (data->register_type == REG_TYPE_UINT64)) + (data->register_type == REG_TYPE_UINT64) || + (data->register_type == REG_TYPE_DOUBLE)) values_num = 4; else values_num = 1; @@ -570,6 +605,18 @@ static int mb_read_data(mb_host_t *host, mb_slave_t *slave, /* {{{ */ CAST_TO_VALUE_T(ds, vt, float_value, data->scale, data->shift); mb_submit(host, slave, data, vt); + } else if (data->register_type == REG_TYPE_DOUBLE) { + double double_value; + value_t vt; + + double_value = + mb_register_to_double(values[0], values[1], values[2], values[3]); + DEBUG("Modbus plugin: mb_read_data: " + "Returned double value is %g", + double_value); + + CAST_TO_VALUE_T(ds, vt, double_value, data->scale, data->shift); + mb_submit(host, slave, data, vt); } else if (data->register_type == REG_TYPE_INT32) { union { uint32_t u32; @@ -823,6 +870,8 @@ static int mb_config_add_data(oconfig_item_t *ci) /* {{{ */ data.register_type = REG_TYPE_UINT64; else if (strcasecmp("Int64", tmp) == 0) data.register_type = REG_TYPE_INT64; + else if (strcasecmp("Double", tmp) == 0) + data.register_type = REG_TYPE_DOUBLE; else { ERROR("Modbus plugin: The register type \"%s\" is unknown.", tmp); status = -1;