Update collectd to version 5.9.0 * remove backported upstream patches (sensors, modbus) * remove lua patch that has been been implemented upstream (See collectd PR 3144) * refresh patches and accommodate into upstream path changes * place the 'stations' datatype for iwinfo in alpbetically correct place in types.db * add libmnl dependency to 'processes' plugin required for the new Linux process Delay Accounting capability. (Alternatively the capability & requirement might be patched away in Makefile.am, HAVE_LIBTASKSTATS from collectd_4ea7a572) * new plugins (disabled): ampq1, gpu_nvidia, pcie_errors, write_stackdriver, write_syslog compile-tested: ar71xx/WNDR3700 (all plugins) run-tested: ar71xx/WNDR3700 (selected plugins) Signed-off-by: Hannu Nyman <hannu.nyman@iki.fi>lilik-openwrt-22.03
@ -1,84 +0,0 @@ | |||
From d5a3c020d33cc33ee8049f54c7b4dffcd123bf83 Mon Sep 17 00:00:00 2001 | |||
From: Pavel Rochnyack <pavel2000@ngs.ru> | |||
Date: Mon, 3 Dec 2018 18:34:14 +0700 | |||
Subject: [PATCH] sensors: Removed checks for upper limit of | |||
SENSORS_API_VERSION | |||
That makes no more sense after lm-sensors got new maintainers. | |||
Closes: #3006 | |||
--- | |||
src/sensors.c | 17 ++++++----------- | |||
1 file changed, 6 insertions(+), 11 deletions(-) | |||
diff --git a/src/sensors.c b/src/sensors.c | |||
index f4ecda5e49..33982e061a 100644 | |||
--- a/src/sensors.c | |||
+++ b/src/sensors.c | |||
@@ -149,7 +149,7 @@ typedef struct featurelist { | |||
static char *conffile = SENSORS_CONF_PATH; | |||
/* #endif SENSORS_API_VERSION < 0x400 */ | |||
-#elif (SENSORS_API_VERSION >= 0x400) && (SENSORS_API_VERSION < 0x500) | |||
+#elif (SENSORS_API_VERSION >= 0x400) | |||
typedef struct featurelist { | |||
const sensors_chip_name *chip; | |||
const sensors_feature *feature; | |||
@@ -159,11 +159,6 @@ typedef struct featurelist { | |||
static char *conffile = NULL; | |||
static _Bool use_labels = 0; | |||
-/* #endif (SENSORS_API_VERSION >= 0x400) && (SENSORS_API_VERSION < 0x500) */ | |||
- | |||
-#else /* if SENSORS_API_VERSION >= 0x500 */ | |||
-#error "This version of libsensors is not supported yet. Please report this " \ | |||
- "as bug." | |||
#endif | |||
static featurelist_t *first_feature = NULL; | |||
@@ -223,7 +218,7 @@ static int sensors_config(const char *key, const char *value) { | |||
if (IS_TRUE(value)) | |||
ignorelist_set_invert(sensor_list, 0); | |||
} | |||
-#if (SENSORS_API_VERSION >= 0x400) && (SENSORS_API_VERSION < 0x500) | |||
+#if (SENSORS_API_VERSION >= 0x400) | |||
else if (strcasecmp(key, "UseLabels") == 0) { | |||
use_labels = IS_TRUE(value) ? 1 : 0; | |||
} | |||
@@ -353,7 +348,7 @@ static int sensors_load_conf(void) { | |||
} /* while sensors_get_detected_chips */ | |||
/* #endif SENSORS_API_VERSION < 0x400 */ | |||
-#elif (SENSORS_API_VERSION >= 0x400) && (SENSORS_API_VERSION < 0x500) | |||
+#elif (SENSORS_API_VERSION >= 0x400) | |||
chip_num = 0; | |||
while ((chip = sensors_get_detected_chips(NULL, &chip_num)) != NULL) { | |||
const sensors_feature *feature; | |||
@@ -410,7 +405,7 @@ static int sensors_load_conf(void) { | |||
} /* while (subfeature) */ | |||
} /* while (feature) */ | |||
} /* while (chip) */ | |||
-#endif /* (SENSORS_API_VERSION >= 0x400) && (SENSORS_API_VERSION < 0x500) */ | |||
+#endif /* (SENSORS_API_VERSION >= 0x400) */ | |||
if (first_feature == NULL) { | |||
sensors_cleanup(); | |||
@@ -485,7 +480,7 @@ static int sensors_read(void) { | |||
} /* for fl = first_feature .. NULL */ | |||
/* #endif SENSORS_API_VERSION < 0x400 */ | |||
-#elif (SENSORS_API_VERSION >= 0x400) && (SENSORS_API_VERSION < 0x500) | |||
+#elif (SENSORS_API_VERSION >= 0x400) | |||
for (featurelist_t *fl = first_feature; fl != NULL; fl = fl->next) { | |||
double value; | |||
int status; | |||
@@ -528,7 +523,7 @@ static int sensors_read(void) { | |||
sensors_submit(plugin_instance, type, type_instance, value); | |||
} /* for fl = first_feature .. NULL */ | |||
-#endif /* (SENSORS_API_VERSION >= 0x400) && (SENSORS_API_VERSION < 0x500) */ | |||
+#endif /* (SENSORS_API_VERSION >= 0x400) */ | |||
return 0; | |||
} /* int sensors_read */ | |||
@ -1,179 +0,0 @@ | |||
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> | |||
@ -1,81 +0,0 @@ | |||
From eeabc41e703f39cae0ad7eb8a596045a5a2f25b4 Mon Sep 17 00:00:00 2001 | |||
From: cekstam <christian.ekstam@gmail.com> | |||
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<collectd>. If | |||
unset, an empty string (no type instance) is used. | |||
+=item B<Scale> I<Value> | |||
+ | |||
+The values taken from collectd are multiplied by I<Value>. The field is optional | |||
+and the default is B<1.0>. | |||
+ | |||
+=item B<Shift> I<Value> | |||
+ | |||
+I<Value> is added to values from collectd after they have been multiplied by | |||
+B<Scale> value. The field is optional and the default value is B<0.0>. | |||
+ | |||
=back | |||
=item E<lt>B<Host> I<Name>E<gt> 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) { |
@ -1,120 +0,0 @@ | |||
From e596496f5c783f4bba85c4d559502c98e4050465 Mon Sep 17 00:00:00 2001 | |||
From: cekstam <christian.ekstam@gmail.com> | |||
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) { |
@ -1,114 +0,0 @@ | |||
From a00ab52931a587cf29c53a945e9295b4d7fe41ba Mon Sep 17 00:00:00 2001 | |||
From: Daniel Golle <daniel@makrotopia.org> | |||
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<UARTType> I<UARTType> | |||
+ | |||
+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<Interval> I<Interval> | |||
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. */ |
@ -1,42 +0,0 @@ | |||
--- a/src/lua.c | |||
+++ b/src/lua.c | |||
@@ -281,9 +281,6 @@ static int lua_cb_register_read(lua_Stat | |||
luaL_checktype(L, 1, LUA_TFUNCTION); | |||
- char function_name[DATA_MAX_NAME_LEN]; | |||
- snprintf(function_name, sizeof(function_name), "lua/%s", lua_tostring(L, 1)); | |||
- | |||
int callback_id = clua_store_callback(L, 1); | |||
if (callback_id < 0) | |||
return luaL_error(L, "%s", "Storing callback function failed"); | |||
@@ -298,6 +295,9 @@ static int lua_cb_register_read(lua_Stat | |||
if (cb == NULL) | |||
return luaL_error(L, "%s", "calloc failed"); | |||
+ char function_name[DATA_MAX_NAME_LEN]; | |||
+ snprintf(function_name, sizeof(function_name), "lua/%p", thread); | |||
+ | |||
cb->lua_state = thread; | |||
cb->callback_id = callback_id; | |||
cb->lua_function_name = strdup(function_name); | |||
@@ -325,9 +325,6 @@ static int lua_cb_register_write(lua_Sta | |||
luaL_checktype(L, 1, LUA_TFUNCTION); | |||
- char function_name[DATA_MAX_NAME_LEN] = ""; | |||
- snprintf(function_name, sizeof(function_name), "lua/%s", lua_tostring(L, 1)); | |||
- | |||
int callback_id = clua_store_callback(L, 1); | |||
if (callback_id < 0) | |||
return luaL_error(L, "%s", "Storing callback function failed"); | |||
@@ -342,6 +339,9 @@ static int lua_cb_register_write(lua_Sta | |||
if (cb == NULL) | |||
return luaL_error(L, "%s", "calloc failed"); | |||
+ char function_name[DATA_MAX_NAME_LEN] = ""; | |||
+ snprintf(function_name, sizeof(function_name), "lua/%p", thread); | |||
+ | |||
cb->lua_state = thread; | |||
cb->callback_id = callback_id; | |||
cb->lua_function_name = strdup(function_name); |