diff --git a/utils/collectd/Makefile b/utils/collectd/Makefile index 71dee4285..fea646dd9 100644 --- a/utils/collectd/Makefile +++ b/utils/collectd/Makefile @@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=collectd PKG_VERSION:=5.8.1 -PKG_RELEASE:=3 +PKG_RELEASE:=4 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2 PKG_SOURCE_URL:=https://collectd.org/files/ \ diff --git a/utils/collectd/patches/051-Add-scale-and-shift-to-modbus-plugin.patch b/utils/collectd/patches/051-Add-scale-and-shift-to-modbus-plugin.patch new file mode 100644 index 000000000..f95df9d56 --- /dev/null +++ b/utils/collectd/patches/051-Add-scale-and-shift-to-modbus-plugin.patch @@ -0,0 +1,81 @@ +From eeabc41e703f39cae0ad7eb8a596045a5a2f25b4 Mon Sep 17 00:00:00 2001 +From: cekstam +Date: Tue, 27 Mar 2018 13:15:28 +0200 +Subject: [PATCH 1/3] Add scale and shift to modbus plugin + +Adding a Scale and Shift parameter to the modbus plugin in order to correct amplifed data +--- + src/collectd.conf.pod | 10 ++++++++++ + src/modbus.c | 18 ++++++++++++++---- + 2 files changed, 24 insertions(+), 4 deletions(-) + +--- a/src/collectd.conf.pod ++++ b/src/collectd.conf.pod +@@ -4169,6 +4169,16 @@ supported. + Sets the type instance to use when dispatching the value to I. If + unset, an empty string (no type instance) is used. + ++=item B I ++ ++The values taken from collectd are multiplied by I. The field is optional ++and the default is B<1.0>. ++ ++=item B I ++ ++I is added to values from collectd after they have been multiplied by ++B value. The field is optional and the default value is B<0.0>. ++ + =back + + =item EB IE blocks +--- a/src/modbus.c ++++ b/src/modbus.c +@@ -105,6 +105,8 @@ struct mb_data_s /* {{{ */ + mb_mreg_type_t modbus_register_type; + char type[DATA_MAX_NAME_LEN]; + char instance[DATA_MAX_NAME_LEN]; ++ double scale; ++ double shift; + + mb_data_t *next; + }; /* }}} */ +@@ -395,13 +397,13 @@ static int mb_init_connection(mb_host_t + #define CAST_TO_VALUE_T(ds, vt, raw) \ + do { \ + if ((ds)->ds[0].type == DS_TYPE_COUNTER) \ +- (vt).counter = (counter_t)(raw); \ ++ (vt).counter = (((counter_t)(raw) * ds[0].scale) + ds[0].shift); \ + else if ((ds)->ds[0].type == DS_TYPE_GAUGE) \ +- (vt).gauge = (gauge_t)(raw); \ ++ (vt).gauge = (((gauge_t)(raw) * ds[0].scale) + ds[0].shift); \ + else if ((ds)->ds[0].type == DS_TYPE_DERIVE) \ +- (vt).derive = (derive_t)(raw); \ ++ (vt).derive = (((derive_t)(raw) * ds[0].scale) + ds[0].shift); \ + else /* if (ds->ds[0].type == DS_TYPE_ABSOLUTE) */ \ +- (vt).absolute = (absolute_t)(raw); \ ++ (vt).absolute = (((absolute_t)(raw) * ds[0].scale) + ds[0].shift); \ + } while (0) + + static int mb_read_data(mb_host_t *host, mb_slave_t *slave, /* {{{ */ +@@ -723,6 +725,8 @@ static int mb_config_add_data(oconfig_it + data.name = NULL; + data.register_type = REG_TYPE_UINT16; + data.next = NULL; ++ data.scale = 1; ++ data.shift = 0; + + status = cf_util_get_string(ci, &data.name); + if (status != 0) +@@ -736,6 +740,12 @@ static int mb_config_add_data(oconfig_it + else if (strcasecmp("Instance", child->key) == 0) + status = cf_util_get_string_buffer(child, data.instance, + sizeof(data.instance)); ++ else if (strcasecmp("Scale", child->key) == 0) ++ status = cf_util_get_string_buffer(child, data.scale, ++ sizeof(data.scale)); ++ else if (strcasecmp("Shift", child->key) == 0) ++ status = cf_util_get_string_buffer(child, data.shift, ++ sizeof(data.shift)); + else if (strcasecmp("RegisterBase", child->key) == 0) + status = cf_util_get_int(child, &data.register_base); + else if (strcasecmp("RegisterType", child->key) == 0) { diff --git a/utils/collectd/patches/052-correcting-all-the-wrongs.patch b/utils/collectd/patches/052-correcting-all-the-wrongs.patch new file mode 100644 index 000000000..b56fe3d9a --- /dev/null +++ b/utils/collectd/patches/052-correcting-all-the-wrongs.patch @@ -0,0 +1,120 @@ +From e596496f5c783f4bba85c4d559502c98e4050465 Mon Sep 17 00:00:00 2001 +From: cekstam +Date: Tue, 27 Mar 2018 14:11:52 +0200 +Subject: [PATCH 2/3] correcting all the wrongs + +, data->scale, data->shift +--- + src/modbus.c | 32 +++++++++++++++----------------- + 1 file changed, 15 insertions(+), 17 deletions(-) + +--- a/src/modbus.c ++++ b/src/modbus.c +@@ -394,16 +394,16 @@ static int mb_init_connection(mb_host_t + } /* }}} int mb_init_connection */ + #endif /* !LEGACY_LIBMODBUS */ + +-#define CAST_TO_VALUE_T(ds, vt, raw) \ ++#define CAST_TO_VALUE_T(ds, vt, raw, scale, shift) \ + do { \ + if ((ds)->ds[0].type == DS_TYPE_COUNTER) \ +- (vt).counter = (((counter_t)(raw) * ds[0].scale) + ds[0].shift); \ ++ (vt).counter = (((counter_t)(raw) * scale) + shift); \ + else if ((ds)->ds[0].type == DS_TYPE_GAUGE) \ +- (vt).gauge = (((gauge_t)(raw) * ds[0].scale) + ds[0].shift); \ ++ (vt).gauge = (((gauge_t)(raw) * scale) + shift); \ + else if ((ds)->ds[0].type == DS_TYPE_DERIVE) \ +- (vt).derive = (((derive_t)(raw) * ds[0].scale) + ds[0].shift); \ ++ (vt).derive = (((derive_t)(raw) * scale) + shift); \ + else /* if (ds->ds[0].type == DS_TYPE_ABSOLUTE) */ \ +- (vt).absolute = (((absolute_t)(raw) * ds[0].scale) + ds[0].shift); \ ++ (vt).absolute = (((absolute_t)(raw) * scale) + shift); \ + } while (0) + + static int mb_read_data(mb_host_t *host, mb_slave_t *slave, /* {{{ */ +@@ -532,7 +532,7 @@ static int mb_read_data(mb_host_t *host, + "Returned float value is %g", + (double)float_value); + +- CAST_TO_VALUE_T(ds, vt, float_value); ++ 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_FLOAT_CDAB) { + float float_value; +@@ -543,7 +543,7 @@ static int mb_read_data(mb_host_t *host, + "Returned float value is %g", + (double)float_value); + +- CAST_TO_VALUE_T(ds, vt, float_value); ++ 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_INT32) { + union { +@@ -557,7 +557,7 @@ static int mb_read_data(mb_host_t *host, + "Returned int32 value is %" PRIi32, + v.i32); + +- CAST_TO_VALUE_T(ds, vt, v.i32); ++ CAST_TO_VALUE_T(ds, vt, v.i32, data->scale, data->shift); + mb_submit(host, slave, data, vt); + } else if (data->register_type == REG_TYPE_INT32_CDAB) { + union { +@@ -571,7 +571,7 @@ static int mb_read_data(mb_host_t *host, + "Returned int32 value is %" PRIi32, + v.i32); + +- CAST_TO_VALUE_T(ds, vt, v.i32); ++ CAST_TO_VALUE_T(ds, vt, v.i32, data->scale, data->shift); + mb_submit(host, slave, data, vt); + } else if (data->register_type == REG_TYPE_INT16) { + union { +@@ -586,7 +586,7 @@ static int mb_read_data(mb_host_t *host, + "Returned int16 value is %" PRIi16, + v.i16); + +- CAST_TO_VALUE_T(ds, vt, v.i16); ++ CAST_TO_VALUE_T(ds, vt, v.i16, data->scale, data->shift); + mb_submit(host, slave, data, vt); + } else if (data->register_type == REG_TYPE_UINT32) { + uint32_t v32; +@@ -597,7 +597,7 @@ static int mb_read_data(mb_host_t *host, + "Returned uint32 value is %" PRIu32, + v32); + +- CAST_TO_VALUE_T(ds, vt, v32); ++ CAST_TO_VALUE_T(ds, vt, v32, data->scale, data->shift); + mb_submit(host, slave, data, vt); + } else if (data->register_type == REG_TYPE_UINT32_CDAB) { + uint32_t v32; +@@ -608,7 +608,7 @@ static int mb_read_data(mb_host_t *host, + "Returned uint32 value is %" PRIu32, + v32); + +- CAST_TO_VALUE_T(ds, vt, v32); ++ CAST_TO_VALUE_T(ds, vt, v32, data->scale, data->shift); + mb_submit(host, slave, data, vt); + } else /* if (data->register_type == REG_TYPE_UINT16) */ + { +@@ -618,7 +618,7 @@ static int mb_read_data(mb_host_t *host, + "Returned uint16 value is %" PRIu16, + values[0]); + +- CAST_TO_VALUE_T(ds, vt, values[0]); ++ CAST_TO_VALUE_T(ds, vt, values[0], data->scale, data->shift); + mb_submit(host, slave, data, vt); + } + +@@ -741,11 +741,9 @@ static int mb_config_add_data(oconfig_it + status = cf_util_get_string_buffer(child, data.instance, + sizeof(data.instance)); + else if (strcasecmp("Scale", child->key) == 0) +- status = cf_util_get_string_buffer(child, data.scale, +- sizeof(data.scale)); ++ status = cf_util_get_double(child, &data.scale); + else if (strcasecmp("Shift", child->key) == 0) +- status = cf_util_get_string_buffer(child, data.shift, +- sizeof(data.shift)); ++ status = cf_util_get_double(child, &data.shift); + else if (strcasecmp("RegisterBase", child->key) == 0) + status = cf_util_get_int(child, &data.register_base); + else if (strcasecmp("RegisterType", child->key) == 0) { diff --git a/utils/collectd/patches/053-Add-support-for-RS485-to-modbus-plugin.patch b/utils/collectd/patches/053-Add-support-for-RS485-to-modbus-plugin.patch new file mode 100644 index 000000000..752689ed2 --- /dev/null +++ b/utils/collectd/patches/053-Add-support-for-RS485-to-modbus-plugin.patch @@ -0,0 +1,114 @@ +From a00ab52931a587cf29c53a945e9295b4d7fe41ba Mon Sep 17 00:00:00 2001 +From: Daniel Golle +Date: Thu, 28 Mar 2019 01:52:04 +0100 +Subject: [PATCH] Add support for RS485 to modbus plugin + +Allow setting up RS485 mode for Modbus-RTU +--- + src/collectd.conf.pod | 6 +++++ + src/modbus.c | 55 +++++++++++++++++++++++++++++++++++++++---- + 2 files changed, 57 insertions(+), 4 deletions(-) + +--- a/src/collectd.conf.pod ++++ b/src/collectd.conf.pod +@@ -4234,6 +4234,12 @@ For Modbus/RTU, specifies the path to th + For Modbus/RTU, specifies the baud rate of the serial device. + Note, connections currently support only 8/N/1. + ++=item B I ++ ++For Modbus/RTU, specifies the type of the serial device. ++RS232, RS422 and RS485 are supported. Defaults to RS232. ++Available only on Linux systems with libmodbus>=2.9.4. ++ + =item B I + + Sets the interval (in seconds) in which the values will be collected from this +--- a/src/modbus.c ++++ b/src/modbus.c +@@ -95,6 +95,12 @@ enum mb_conntype_e /* {{{ */ + MBCONN_RTU }; /* }}} */ + typedef enum mb_conntype_e mb_conntype_t; + ++enum mb_uarttype_e /* {{{ */ ++{ UARTTYPE_RS232, ++ UARTTYPE_RS422, ++ UARTTYPE_RS485 }; /* }}} */ ++typedef enum mb_uarttype_e mb_uarttype_t; ++ + struct mb_data_s; + typedef struct mb_data_s mb_data_t; + struct mb_data_s /* {{{ */ +@@ -124,8 +130,9 @@ struct mb_host_s /* {{{ */ + char host[DATA_MAX_NAME_LEN]; + char node[NI_MAXHOST]; /* TCP hostname or RTU serial device */ + /* char service[NI_MAXSERV]; */ +- int port; /* for Modbus/TCP */ +- int baudrate; /* for Modbus/RTU */ ++ int port; /* for Modbus/TCP */ ++ int baudrate; /* for Modbus/RTU */ ++ mb_uarttype_t uarttype; /* UART type for Modbus/RTU */ + mb_conntype_t conntype; + cdtime_t interval; + +@@ -390,6 +397,22 @@ static int mb_init_connection(mb_host_t + return status; + } + ++#if defined(linux) && LIBMODBUS_VERSION_CHECK(2, 9, 4) ++ switch (host->uarttype) { ++ case UARTTYPE_RS485: ++ if (modbus_rtu_set_serial_mode(host->connection, MODBUS_RTU_RS485)) ++ DEBUG("Modbus plugin: Setting RS485 mode failed."); ++ break; ++ case UARTTYPE_RS422: ++ /* libmodbus doesn't say anything about full-duplex symmetric RS422 UART */ ++ break; ++ case UARTTYPE_RS232: ++ break; ++ default: ++ DEBUG("Modbus plugin: Invalid UART type!."); ++ } ++#endif /* defined(linux) && LIBMODBUS_VERSION_CHECK(2, 9, 4) */ ++ + return 0; + } /* }}} int mb_init_connection */ + #endif /* !LEGACY_LIBMODBUS */ +@@ -951,11 +974,35 @@ static int mb_config_add_host(oconfig_it + status = -1; + } else if (strcasecmp("Device", child->key) == 0) { + status = cf_util_get_string_buffer(child, host->node, sizeof(host->node)); +- if (status == 0) ++ if (status == 0) { + host->conntype = MBCONN_RTU; ++ host->uarttype = UARTTYPE_RS232; ++ } + } else if (strcasecmp("Baudrate", child->key) == 0) + status = cf_util_get_int(child, &host->baudrate); +- else if (strcasecmp("Interval", child->key) == 0) ++ else if (strcasecmp("UARTType", child->key) == 0) { ++#if defined(linux) && !LEGACY_LIBMODBUS && LIBMODBUS_VERSION_CHECK(2, 9, 4) ++ char buffer[NI_MAXHOST]; ++ status = cf_util_get_string_buffer(child, buffer, sizeof(buffer)); ++ if (status != 0) ++ break; ++ if (strncmp(buffer, "RS485", 6) == 0) ++ host->uarttype = UARTTYPE_RS485; ++ else if (strncmp(buffer, "RS422", 6) == 0) ++ host->uarttype = UARTTYPE_RS422; ++ else if (strncmp(buffer, "RS232", 6) == 0) ++ host->uarttype = UARTTYPE_RS232; ++ else { ++ ERROR("Modbus plugin: The UARTType \"%s\" is unknown.", buffer); ++ status = -1; ++ break; ++ } ++#else ++ ERROR("Modbus plugin: Option `UARTType' not supported. Please " ++ "upgrade libmodbus to at least 2.9.4"); ++ return -1; ++#endif ++ } else if (strcasecmp("Interval", child->key) == 0) + status = cf_util_get_cdtime(child, &host->interval); + else if (strcasecmp("Slave", child->key) == 0) + /* Don't set status: Gracefully continue if a slave fails. */