From: Anthony Vickers Date: Fri, 2 Feb 2018 15:36:14 +0000 (+0000) Subject: Add support for Modbus 64 bit vals and update docs X-Git-Url: https://git.verplant.org/?a=commitdiff_plain;h=a4bb32fe599ea4ddab39a5994ee478675da18cc2;p=collectd.git Add support for Modbus 64 bit vals and update docs Add support for reading Int64 and Uint64 from four 16 bit registers. Update config document to explain new feature added. --- diff --git a/src/collectd.conf.pod b/src/collectd.conf.pod index e9715126..cfe4a28c 100644 --- a/src/collectd.conf.pod +++ b/src/collectd.conf.pod @@ -4128,7 +4128,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 +=item 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, @@ -4140,7 +4140,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. +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. =item B B|B diff --git a/src/modbus.c b/src/modbus.c index daa3c028..4266b73d 100644 --- a/src/modbus.c +++ b/src/modbus.c @@ -80,6 +80,8 @@ enum mb_register_type_e /* {{{ */ REG_TYPE_UINT16, REG_TYPE_UINT32, REG_TYPE_UINT32_CDAB, + REG_TYPE_UINT64, + REG_TYPE_INT64, REG_TYPE_FLOAT, REG_TYPE_FLOAT_CDAB }; /* }}} */ @@ -406,7 +408,7 @@ static int mb_init_connection(mb_host_t *host) /* {{{ */ static int mb_read_data(mb_host_t *host, mb_slave_t *slave, /* {{{ */ mb_data_t *data) { - uint16_t values[2] = {0}; + uint16_t values[4] = {0}; int values_num; const data_set_t *ds; int status = 0; @@ -431,11 +433,13 @@ static int mb_read_data(mb_host_t *host, mb_slave_t *slave, /* {{{ */ (data->register_type != REG_TYPE_INT32) && (data->register_type != REG_TYPE_INT32_CDAB) && (data->register_type != REG_TYPE_UINT32) && + (data->register_type != REG_TYPE_INT64) && + (data->register_type != REG_TYPE_UINT64) && (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 " - "is not UINT32.", + "is not UINT32 OR UINT64.", data->type, DS_TYPE_TO_STRING(ds->ds[0].type)); } @@ -446,6 +450,9 @@ static int mb_read_data(mb_host_t *host, mb_slave_t *slave, /* {{{ */ (data->register_type == REG_TYPE_FLOAT) || (data->register_type == REG_TYPE_FLOAT_CDAB)) values_num = 2; + else if ((data->register_type == REG_TYPE_UINT64) || + (data->register_type == REG_TYPE_INT64)) + values_num = 4; else values_num = 1; @@ -608,6 +615,33 @@ static int mb_read_data(mb_host_t *host, mb_slave_t *slave, /* {{{ */ CAST_TO_VALUE_T(ds, vt, v32); mb_submit(host, slave, data, vt); + } else if (data->register_type == REG_TYPE_UINT64) { + uint64_t v64; + value_t vt; + + v64 = (((uint64_t)values[0]) << 48) | (((uint64_t)values[1]) << 32) | + (((uint64_t)values[2]) << 16) | (((uint64_t)values[3])); + DEBUG("Modbus plugin: mb_read_data: " + "Returned uint64 value is %" PRIu64, + v64); + + CAST_TO_VALUE_T(ds, vt, v64); + mb_submit(host, slave, data, vt); + } else if (data->register_type == REG_TYPE_INT64) { + union { + uint64_t u64; + int64_t i64; + } v; + value_t vt; + + v.u64 = (((uint64_t)values[0]) << 48) | (((uint64_t)values[1]) << 32) | + (((uint64_t)values[2]) << 16) | ((uint64_t)values[3]); + DEBUG("Modbus plugin: mb_read_data: " + "Returned uint64 value is %" PRIi64, + v.i64); + + CAST_TO_VALUE_T(ds, vt, v.i64); + mb_submit(host, slave, data, vt); } else /* if (data->register_type == REG_TYPE_UINT16) */ { value_t vt; @@ -759,6 +793,10 @@ static int mb_config_add_data(oconfig_item_t *ci) /* {{{ */ data.register_type = REG_TYPE_FLOAT; else if (strcasecmp("FloatLE", tmp) == 0) data.register_type = REG_TYPE_FLOAT_CDAB; + else if (strcasecmp("Uint64", tmp) == 0) + data.register_type = REG_TYPE_UINT64; + else if (strcasecmp("Int64", tmp) == 0) + data.register_type = REG_TYPE_INT64; else { ERROR("Modbus plugin: The register type \"%s\" is unknown.", tmp); status = -1;