|
|
- From 6028f89df95b12219d735b277863f83e9f5ee9e9 Mon Sep 17 00:00:00 2001
- From: PJ Bostley <pbostley@gmail.com>
- Date: Sat, 20 Jan 2018 16:39:36 -0700
- Subject: [PATCH 1/2] Adding support for CDAB endian 32-bit modbus polls
-
- ---
- src/modbus.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
- 1 file changed, 56 insertions(+), 5 deletions(-)
-
- diff --git a/src/modbus.c b/src/modbus.c
- index 31f0c2da81..daa3c028f5 100644
- --- a/src/modbus.c
- +++ b/src/modbus.c
- @@ -76,9 +76,13 @@
- enum mb_register_type_e /* {{{ */
- { REG_TYPE_INT16,
- REG_TYPE_INT32,
- + REG_TYPE_INT32_CDAB,
- REG_TYPE_UINT16,
- REG_TYPE_UINT32,
- - REG_TYPE_FLOAT }; /* }}} */
- + REG_TYPE_UINT32_CDAB,
- + REG_TYPE_FLOAT,
- + REG_TYPE_FLOAT_CDAB }; /* }}} */
- +
- enum mb_mreg_type_e /* {{{ */
- { MREG_HOLDING,
- MREG_INPUT }; /* }}} */
- @@ -425,7 +429,9 @@ static int mb_read_data(mb_host_t *host, mb_slave_t *slave, /* {{{ */
-
- if ((ds->ds[0].type != DS_TYPE_GAUGE) &&
- (data->register_type != REG_TYPE_INT32) &&
- - (data->register_type != REG_TYPE_UINT32)) {
- + (data->register_type != REG_TYPE_INT32_CDAB) &&
- + (data->register_type != REG_TYPE_UINT32) &&
- + (data->register_type != REG_TYPE_UINT32_CDAB)) {
- NOTICE(
- "Modbus plugin: The data source of type \"%s\" is %s, not gauge. "
- "This will most likely result in problems, because the register type "
- @@ -434,8 +440,11 @@ static int mb_read_data(mb_host_t *host, mb_slave_t *slave, /* {{{ */
- }
-
- if ((data->register_type == REG_TYPE_INT32) ||
- + (data->register_type == REG_TYPE_INT32_CDAB) ||
- (data->register_type == REG_TYPE_UINT32) ||
- - (data->register_type == REG_TYPE_FLOAT))
- + (data->register_type == REG_TYPE_UINT32_CDAB) ||
- + (data->register_type == REG_TYPE_FLOAT) ||
- + (data->register_type == REG_TYPE_FLOAT_CDAB))
- values_num = 2;
- else
- values_num = 1;
- @@ -496,8 +505,8 @@ static int mb_read_data(mb_host_t *host, mb_slave_t *slave, /* {{{ */
- }
- if (status != values_num) {
- ERROR("Modbus plugin: modbus read function (%s/%s) failed. "
- - " status = %i, values_num = %i. Giving up.",
- - host->host, host->node, status, values_num);
- + " status = %i, start_addr = %i, values_num = %i. Giving up.",
- + host->host, host->node, status, data->register_base, values_num);
- #if LEGACY_LIBMODBUS
- modbus_close(&host->connection);
- #else
- @@ -521,6 +530,17 @@ static int mb_read_data(mb_host_t *host, mb_slave_t *slave, /* {{{ */
- "Returned float value is %g",
- (double)float_value);
-
- + CAST_TO_VALUE_T(ds, vt, float_value);
- + mb_submit(host, slave, data, vt);
- + } else if (data->register_type == REG_TYPE_FLOAT_CDAB) {
- + float float_value;
- + value_t vt;
- +
- + float_value = mb_register_to_float(values[1], values[0]);
- + DEBUG("Modbus plugin: mb_read_data: "
- + "Returned float value is %g",
- + (double)float_value);
- +
- CAST_TO_VALUE_T(ds, vt, float_value);
- mb_submit(host, slave, data, vt);
- } else if (data->register_type == REG_TYPE_INT32) {
- @@ -535,6 +555,20 @@ static int mb_read_data(mb_host_t *host, mb_slave_t *slave, /* {{{ */
- "Returned int32 value is %" PRIi32,
- v.i32);
-
- + CAST_TO_VALUE_T(ds, vt, v.i32);
- + mb_submit(host, slave, data, vt);
- + } else if (data->register_type == REG_TYPE_INT32_CDAB) {
- + union {
- + uint32_t u32;
- + int32_t i32;
- + } v;
- + value_t vt;
- +
- + v.u32 = (((uint32_t)values[1]) << 16) | ((uint32_t)values[0]);
- + DEBUG("Modbus plugin: mb_read_data: "
- + "Returned int32 value is %" PRIi32,
- + v.i32);
- +
- CAST_TO_VALUE_T(ds, vt, v.i32);
- mb_submit(host, slave, data, vt);
- } else if (data->register_type == REG_TYPE_INT16) {
- @@ -561,6 +595,17 @@ static int mb_read_data(mb_host_t *host, mb_slave_t *slave, /* {{{ */
- "Returned uint32 value is %" PRIu32,
- v32);
-
- + CAST_TO_VALUE_T(ds, vt, v32);
- + mb_submit(host, slave, data, vt);
- + } else if (data->register_type == REG_TYPE_UINT32_CDAB) {
- + uint32_t v32;
- + value_t vt;
- +
- + v32 = (((uint32_t)values[1]) << 16) | ((uint32_t)values[0]);
- + DEBUG("Modbus plugin: mb_read_data: "
- + "Returned uint32 value is %" PRIu32,
- + v32);
- +
- CAST_TO_VALUE_T(ds, vt, v32);
- mb_submit(host, slave, data, vt);
- } else /* if (data->register_type == REG_TYPE_UINT16) */
- @@ -702,12 +747,18 @@ static int mb_config_add_data(oconfig_item_t *ci) /* {{{ */
- data.register_type = REG_TYPE_INT16;
- else if (strcasecmp("Int32", tmp) == 0)
- data.register_type = REG_TYPE_INT32;
- + else if (strcasecmp("Int32LE", tmp) == 0)
- + data.register_type = REG_TYPE_INT32_CDAB;
- else if (strcasecmp("Uint16", tmp) == 0)
- data.register_type = REG_TYPE_UINT16;
- else if (strcasecmp("Uint32", tmp) == 0)
- data.register_type = REG_TYPE_UINT32;
- + else if (strcasecmp("Uint32LE", tmp) == 0)
- + data.register_type = REG_TYPE_UINT32_CDAB;
- else if (strcasecmp("Float", tmp) == 0)
- data.register_type = REG_TYPE_FLOAT;
- + else if (strcasecmp("FloatLE", tmp) == 0)
- + data.register_type = REG_TYPE_FLOAT_CDAB;
- else {
- ERROR("Modbus plugin: The register type \"%s\" is unknown.", tmp);
- status = -1;
-
- From 67afd2685892e69ababb489f48b9033ab5908f4d Mon Sep 17 00:00:00 2001
- From: PJ Bostley <pbostley@gmail.com>
- Date: Tue, 23 Jan 2018 15:33:23 -0700
- Subject: [PATCH 2/2] Adding documentation for the Modbus little endian modes
- where 32 bit values have thier registers swapped
-
- ---
- src/collectd.conf.pod | 18 +++++++++++++-----
- 1 file changed, 13 insertions(+), 5 deletions(-)
-
- diff --git a/src/collectd.conf.pod b/src/collectd.conf.pod
- index dfd785a2c8..e9715126e6 100644
- --- a/src/collectd.conf.pod
- +++ b/src/collectd.conf.pod
- @@ -4139,11 +4139,19 @@ Configures the base register to read from the device. If the option
- B<RegisterType> has been set to B<Uint32> or B<Float>, this and the next
- register will be read (the register number is increased by one).
-
- -=item B<RegisterType> B<Int16>|B<Int32>|B<Uint16>|B<Uint32>|B<Float>
- -
- -Specifies what kind of data is returned by the device. If the type is B<Int32>,
- -B<Uint32> or B<Float>, two 16E<nbsp>bit registers will be read and the data is
- -combined into one value. Defaults to B<Uint16>.
- +=item B<RegisterType> B<Int16>|B<Int32>|B<Uint16>|B<Uint32>|B<Float>|B<Int32LE>|B<Uint32LE>|B<FloatLE>
- +
- +Specifies what kind of data is returned by the device. This defaults to
- +B<Uint16>. If the type is B<Int32>, B<Int32LE>, B<Uint32>, B<Uint32LE>,
- +B<Float> or B<FloatLE>, two 16E<nbsp>bit registers at B<RegisterBase>
- +and B<RegisterBase+1> will be read and the data is combined into one
- +32E<nbsp>value. For B<Int32>, B<Uint32> and B<Float> the most significant
- +16E<nbsp>bits are in the register at B<RegisterBase> and the least
- +significant 16E<nbsp>bits are in the register at B<RegisterBase+1>.
- +For B<Int32LE>, B<Uint32LE>, or B<Float32LE>, the high and low order
- +registers are swapped with the most significant 16E<nbsp>bits in
- +the B<RegisterBase+1> and the least significant 16E<nbsp>bits in
- +B<RegisterBase>.
-
- =item B<RegisterCmd> B<ReadHolding>|B<ReadInput>
-
|