X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Fmodbus.c;h=40b6c57a36bfe39eab361032de7c56b74c0a9c7f;hb=491712ab7dd36eb58fba23942f5edf4b76b50361;hp=52e6bd8972f8c4c029e4f870dc4172cdcdf4dedd;hpb=d86f0d115cc8e8d80167b65a24aa6ee7404bc766;p=collectd.git diff --git a/src/modbus.c b/src/modbus.c index 52e6bd89..40b6c57a 100644 --- a/src/modbus.c +++ b/src/modbus.c @@ -24,8 +24,18 @@ #include "plugin.h" #include "configfile.h" +#include + #include +#ifndef MODBUS_TCP_DEFAULT_PORT +# ifdef MODBUS_TCP_PORT +# define MODBUS_TCP_DEFAULT_PORT MODBUS_TCP_PORT +# else +# define MODBUS_TCP_DEFAULT_PORT 502 +# endif +#endif + /* * * RegisterBase 1234 @@ -49,17 +59,17 @@ /* * Data structures */ -enum mb_register_type_e +enum mb_register_type_e /* {{{ */ { REG_TYPE_UINT16, REG_TYPE_UINT32, REG_TYPE_FLOAT -}; +}; /* }}} */ typedef enum mb_register_type_e mb_register_type_t; struct mb_data_s; typedef struct mb_data_s mb_data_t; -struct mb_data_s +struct mb_data_s /* {{{ */ { char *name; int register_base; @@ -68,17 +78,17 @@ struct mb_data_s char instance[DATA_MAX_NAME_LEN]; mb_data_t *next; -}; +}; /* }}} */ -struct mb_slave_s +struct mb_slave_s /* {{{ */ { int id; char instance[DATA_MAX_NAME_LEN]; mb_data_t *collect; -}; +}; /* }}} */ typedef struct mb_slave_s mb_slave_t; -struct mb_host_s +struct mb_host_s /* {{{ */ { char host[DATA_MAX_NAME_LEN]; char node[NI_MAXHOST]; @@ -92,18 +102,18 @@ struct mb_host_s modbus_param_t connection; _Bool is_connected; _Bool have_reconnected; -}; +}; /* }}} */ typedef struct mb_host_s mb_host_t; struct mb_data_group_s; typedef struct mb_data_group_s mb_data_group_t; -struct mb_data_group_s +struct mb_data_group_s /* {{{ */ { mb_data_t *registers; size_t registers_num; mb_data_group_t *next; -}; +}; /* }}} */ /* * Global variables @@ -204,6 +214,33 @@ static int data_copy_by_name (mb_data_t **dst, mb_data_t *src, /* {{{ */ /* Read functions */ +static int mb_submit (mb_host_t *host, mb_slave_t *slave, /* {{{ */ + mb_data_t *data, value_t value) +{ + value_list_t vl = VALUE_LIST_INIT; + + if ((host == NULL) || (slave == NULL) || (data == NULL)) + return (EINVAL); + + if (host->interval <= 0) + host->interval = interval_g; + + if (slave->instance[0] == 0) + ssnprintf (slave->instance, sizeof (slave->instance), "slave_%i", + slave->id); + + vl.values = &value; + vl.values_len = 1; + vl.interval = host->interval; + sstrncpy (vl.host, host->host, sizeof (vl.host)); + sstrncpy (vl.plugin, "modbus", sizeof (vl.plugin)); + sstrncpy (vl.plugin_instance, slave->instance, sizeof (vl.plugin_instance)); + sstrncpy (vl.type, data->type, sizeof (vl.type)); + sstrncpy (vl.type_instance, data->instance, sizeof (vl.type_instance)); + + return (plugin_dispatch_values (&vl)); +} /* }}} int mb_submit */ + static float mb_register_to_float (uint16_t hi, uint16_t lo) /* {{{ */ { union @@ -270,6 +307,17 @@ static int mb_init_connection (mb_host_t *host) /* {{{ */ return (0); } /* }}} int mb_init_connection */ +#define CAST_TO_VALUE_T(ds,vt,raw) do { \ + if ((ds)->ds[0].type == DS_TYPE_COUNTER) \ + (vt).counter = (counter_t) (raw); \ + else if ((ds)->ds[0].type == DS_TYPE_GAUGE) \ + (vt).gauge = (gauge_t) (raw); \ + else if ((ds)->ds[0].type == DS_TYPE_DERIVE) \ + (vt).derive = (derive_t) (raw); \ + else /* if (ds->ds[0].type == DS_TYPE_ABSOLUTE) */ \ + (vt).absolute = (absolute_t) (raw); \ +} while (0) + static int mb_read_data (mb_host_t *host, mb_slave_t *slave, /* {{{ */ mb_data_t *data) { @@ -297,6 +345,14 @@ static int mb_read_data (mb_host_t *host, mb_slave_t *slave, /* {{{ */ return (-1); } + if ((ds->ds[0].type != DS_TYPE_GAUGE) + && (data->register_type != REG_TYPE_UINT32)) + { + 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.", data->type, DS_TYPE_TO_STRING (ds->ds[0].type)); + } + memset (values, 0, sizeof (values)); if ((data->register_type == REG_TYPE_UINT32) || (data->register_type == REG_TYPE_FLOAT)) @@ -347,11 +403,37 @@ static int mb_read_data (mb_host_t *host, mb_slave_t *slave, /* {{{ */ if (data->register_type == REG_TYPE_FLOAT) { - float value; + float float_value; + value_t vt; + + float_value = mb_register_to_float (values[0], values[1]); + 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_UINT32) + { + uint32_t v32; + value_t vt; + + v32 = (values[0] << 16) | values[1]; + 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) */ + { + value_t vt; - value = mb_register_to_float (values[0], values[1]); DEBUG ("Modbus plugin: mb_read_data: " - "Returned float value is %g", (double) value); + "Returned uint16 value is %"PRIu16, values[0]); + + CAST_TO_VALUE_T (ds, vt, values[0]); + mb_submit (host, slave, data, vt); } return (0); @@ -724,9 +806,8 @@ static int mb_config_add_host (oconfig_item_t *ci) /* {{{ */ else interval.tv_sec = 0; - plugin_register_complex_read (name, mb_read, - (interval.tv_sec > 0) ? &interval : NULL, - &ud); + plugin_register_complex_read (/* group = */ NULL, name, + mb_read, (interval.tv_sec > 0) ? &interval : NULL, &ud); } else { @@ -760,47 +841,6 @@ static int mb_config (oconfig_item_t *ci) /* {{{ */ /* ========= */ -#if 0 -static int foo (void) /* {{{ */ -{ - int status; - uint16_t values[2]; - int values_num; - - if (dev == NULL) - return (EINVAL); - - printf ("mb_read (addr = %i, float = %s);\n", register_addr, - is_float ? "true" : "false"); - - memset (values, 0, sizeof (values)); - if (is_float) - values_num = 2; - else - values_num = 1; - - status = read_holding_registers (dev->connection, - /* slave = */ 1, /* start_addr = */ register_addr, - /* num_registers = */ values_num, /* buffer = */ values); - printf ("read_coil_status returned with status %i\n", status); - if (status <= 0) - return (EAGAIN); - - if (is_float) - { - float value = mb_register_to_float (values[0], values[1]); - printf ("read_coil_status returned value %g (hi %#"PRIx16", lo %#"PRIx16")\n", - value, values[0], values[1]); - } - else - { - printf ("read_coil_status returned value %"PRIu16"\n", values[0]); - } - - return (0); -} /* }}} int foo */ -#endif - static int mb_shutdown (void) /* {{{ */ { data_free_all (data_definitions);