X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Fmodbus.c;h=c04b308d81728e74f4621737b64fb394eb47430d;hb=3307054b6ab46b51fdda4f528e72d119e9de3071;hp=701406dbe73ffb6b5733a0b089a93374801dbcff;hpb=391db29c68e197ae19af1d77fd2e330b78fbc6f2;p=collectd.git diff --git a/src/modbus.c b/src/modbus.c index 701406db..c04b308d 100644 --- a/src/modbus.c +++ b/src/modbus.c @@ -27,7 +27,7 @@ #include -#include +#include #ifndef LIBMODBUS_VERSION_CHECK /* Assume version 2.0.3 */ @@ -47,15 +47,19 @@ /* * * RegisterBase 1234 + * RegisterCmd ReadHolding * RegisterType float * Type gauge - * ModbusRegisterType holding * Instance "..." * * * * Address "addr" * Port "1234" + * # Or: + * # Device "/dev/ttyUSB0" + * # Baudrate 38400 + * # (Assumes 8N1) * Interval 60 * * @@ -84,6 +88,14 @@ enum mb_mreg_type_e /* {{{ */ typedef enum mb_register_type_e mb_register_type_t; typedef enum mb_mreg_type_e mb_mreg_type_t; +/* TCP or RTU depending on what is specified in host config block */ +enum mb_conntype_e /* {{{ */ +{ + MBCONN_TCP, + MBCONN_RTU +}; /* }}} */ +typedef enum mb_conntype_e mb_conntype_t; + struct mb_data_s; typedef struct mb_data_s mb_data_t; struct mb_data_s /* {{{ */ @@ -109,9 +121,11 @@ typedef struct mb_slave_s mb_slave_t; struct mb_host_s /* {{{ */ { char host[DATA_MAX_NAME_LEN]; - char node[NI_MAXHOST]; + char node[NI_MAXHOST]; /* TCP hostname or RTU serial device */ /* char service[NI_MAXSERV]; */ - int port; + int port; /* for Modbus/TCP */ + int baudrate; /* for Modbus/RTU */ + mb_conntype_t conntype; cdtime_t interval; mb_slave_t *slaves; @@ -296,26 +310,40 @@ static int mb_init_connection (mb_host_t *host) /* {{{ */ if (host == NULL) return (EINVAL); +#if COLLECT_DEBUG modbus_set_debug (&host->connection, 1); +#endif /* We'll do the error handling ourselves. */ modbus_set_error_handling (&host->connection, NOP_ON_ERROR); - if ((host->port < 1) || (host->port > 65535)) - host->port = MODBUS_TCP_DEFAULT_PORT; + if (host->conntype == MBCONN_TCP) + { + if ((host->port < 1) || (host->port > 65535)) + host->port = MODBUS_TCP_DEFAULT_PORT; + + DEBUG ("Modbus plugin: Trying to connect to \"%s\", port %i.", + host->node, host->port); - DEBUG ("Modbus plugin: Trying to connect to \"%s\", port %i.", - host->node, host->port); + modbus_init_tcp (&host->connection, + /* host = */ host->node, + /* port = */ host->port); + } + else /* MBCONN_RTU */ + { + DEBUG ("Modbus plugin: Trying to connect to \"%s\".", host->node); - modbus_init_tcp (&host->connection, - /* host = */ host->node, - /* port = */ host->port); + modbus_init_rtu (&host->connection, + /* device = */ host->node, + /* baudrate = */ host->baudrate, + 'N', 8, 1, 0); + } status = modbus_connect (&host->connection); if (status != 0) { ERROR ("Modbus plugin: modbus_connect (%s, %i) failed with status %i.", - host->node, host->port, status); + host->node, host->port ? host->port : host->baudrate, status); return (status); } @@ -336,20 +364,37 @@ static int mb_init_connection (mb_host_t *host) /* {{{ */ if (host->connection != NULL) return (0); - if ((host->port < 1) || (host->port > 65535)) - host->port = MODBUS_TCP_DEFAULT_PORT; + if (host->conntype == MBCONN_TCP) + { + if ((host->port < 1) || (host->port > 65535)) + host->port = MODBUS_TCP_DEFAULT_PORT; - DEBUG ("Modbus plugin: Trying to connect to \"%s\", port %i.", - host->node, host->port); + DEBUG ("Modbus plugin: Trying to connect to \"%s\", port %i.", + host->node, host->port); - host->connection = modbus_new_tcp (host->node, host->port); - if (host->connection == NULL) + host->connection = modbus_new_tcp (host->node, host->port); + if (host->connection == NULL) + { + ERROR ("Modbus plugin: Creating new Modbus/TCP object failed."); + return (-1); + } + } + else { - ERROR ("Modbus plugin: Creating new Modbus/TCP object failed."); - return (-1); + DEBUG ("Modbus plugin: Trying to connect to \"%s\", baudrate %i.", + host->node, host->baudrate); + + host->connection = modbus_new_rtu (host->node, host->baudrate, 'N', 8, 1); + if (host->connection == NULL) + { + ERROR ("Modbus plugin: Creating new Modbus/RTU object failed."); + return (-1); + } } +#if COLLECT_DEBUG modbus_set_debug (host->connection, 1); +#endif /* We'll do the error handling ourselves. */ modbus_set_error_recovery (host->connection, 0); @@ -358,7 +403,7 @@ static int mb_init_connection (mb_host_t *host) /* {{{ */ if (status != 0) { ERROR ("Modbus plugin: modbus_connect (%s, %i) failed with status %i.", - host->node, host->port, status); + host->node, host->port ? host->port : host->baudrate, status); modbus_free (host->connection); host->connection = NULL; return (status); @@ -385,7 +430,7 @@ static int mb_read_data (mb_host_t *host, mb_slave_t *slave, /* {{{ */ uint16_t values[2]; int values_num; const data_set_t *ds; - int status; + int status = 0; if ((host == NULL) || (slave == NULL) || (data == NULL)) return (EINVAL); @@ -422,12 +467,11 @@ static int mb_read_data (mb_host_t *host, mb_slave_t *slave, /* {{{ */ else values_num = 1; - status = 0; if (host->connection == NULL) { status = EBADF; } - else + else if (host->conntype == MBCONN_TCP) { struct sockaddr sockaddr; socklen_t saddrlen = sizeof (sockaddr); @@ -487,8 +531,9 @@ static int mb_read_data (mb_host_t *host, mb_slave_t *slave, /* {{{ */ } if (status != values_num) { - ERROR ("Modbus plugin: modbus_read_registers (%s/%s) failed. status = %i, values_num = %i " - "Giving up.", host->host, host->node, 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); #if LEGACY_LIBMODBUS modbus_close (&host->connection); #else @@ -691,7 +736,6 @@ static int mb_config_add_data (oconfig_item_t *ci) /* {{{ */ for (i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; - status = 0; if (strcasecmp ("Type", child->key) == 0) status = cf_util_get_string_buffer (child, @@ -723,25 +767,27 @@ static int mb_config_add_data (oconfig_item_t *ci) /* {{{ */ status = -1; } } - else if (strcasecmp ("ModbusRegisterType", child->key) == 0) + else if (strcasecmp ("RegisterCmd", child->key) == 0) { - #if LEGACY_LIBMODBUS - ERROR("Modbus plugin: ModbusRegisterType parameter can not be used with your libmodbus version"); - #else - char tmp[16]; - status = cf_util_get_string_buffer (child, tmp, sizeof (tmp)); - if (status != 0) - /* do nothing */; - else if (strcasecmp ("holding", tmp) == 0) - data.modbus_register_type = MREG_HOLDING; - else if (strcasecmp ("input", tmp) == 0) - data.modbus_register_type = MREG_INPUT; - else - { - ERROR ("Modbus plugin: The modbus_register_type \"%s\" is unknown.", tmp); - status = -1; - } - #endif +#if LEGACY_LIBMODBUS + ERROR("Modbus plugin: RegisterCmd parameter can not be used " + "with your libmodbus version"); +#else + char tmp[16]; + status = cf_util_get_string_buffer (child, tmp, sizeof (tmp)); + if (status != 0) + /* do nothing */; + else if (strcasecmp ("ReadHolding", tmp) == 0) + data.modbus_register_type = MREG_HOLDING; + else if (strcasecmp ("ReadInput", tmp) == 0) + data.modbus_register_type = MREG_INPUT; + else + { + ERROR ("Modbus plugin: The modbus_register_type \"%s\" is unknown.", + tmp); + status = -1; + } +#endif } else { @@ -850,7 +896,6 @@ static int mb_config_add_slave (mb_host_t *host, oconfig_item_t *ci) /* {{{ */ for (i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; - status = 0; if (strcasecmp ("Instance", child->key) == 0) status = cf_util_get_string_buffer (child, @@ -901,9 +946,15 @@ static int mb_config_add_host (oconfig_item_t *ci) /* {{{ */ status = cf_util_get_string_buffer (ci, host->host, sizeof (host->host)); if (status != 0) + { + sfree (host); return (status); + } if (host->host[0] == 0) + { + sfree (host); return (EINVAL); + } for (i = 0; i < ci->children_num; i++) { @@ -916,6 +967,8 @@ static int mb_config_add_host (oconfig_item_t *ci) /* {{{ */ status = cf_util_get_string_buffer (child, buffer, sizeof (buffer)); if (status == 0) status = mb_config_set_host_address (host, buffer); + if (status == 0) + host->conntype = MBCONN_TCP; } else if (strcasecmp ("Port", child->key) == 0) { @@ -923,6 +976,14 @@ static int mb_config_add_host (oconfig_item_t *ci) /* {{{ */ if (host->port <= 0) status = -1; } + else if (strcasecmp ("Device", child->key) == 0) + { + status = cf_util_get_string_buffer (child, host->node, sizeof (host->node)); + if (status == 0) + host->conntype = MBCONN_RTU; + } + else if (strcasecmp ("Baudrate", child->key) == 0) + status = cf_util_get_int(child, &host->baudrate); else if (strcasecmp ("Interval", child->key) == 0) status = cf_util_get_cdtime (child, &host->interval); else if (strcasecmp ("Slave", child->key) == 0) @@ -939,9 +1000,22 @@ static int mb_config_add_host (oconfig_item_t *ci) /* {{{ */ } /* for (i = 0; i < ci->children_num; i++) */ assert (host->host[0] != 0); - if (host->host[0] == 0) + if (host->node[0] == 0) { - ERROR ("Modbus plugin: Data block \"%s\": No type has been specified.", + ERROR ("Modbus plugin: Data block \"%s\": No address or device has been specified.", + host->host); + status = -1; + } + if (host->conntype == MBCONN_RTU && !host->baudrate) + { + ERROR ("Modbus plugin: Data block \"%s\": No serial baudrate has been specified.", + host->host); + status = -1; + } + if ((host->conntype == MBCONN_TCP && host->baudrate) || + (host->conntype == MBCONN_RTU && host->port)) + { + ERROR ("Modbus plugin: Data block \"%s\": You've mixed up RTU and TCP options.", host->host); status = -1; }