X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Fmodbus.c;h=0a4f40ca035397e3eb5f3827bc098a97c1f4dd58;hb=7c9d772c992647fcba64a96800c146eb9f1647f8;hp=cf8b0b29849bf73e7b7550c09df5547e6a2b4dc8;hpb=938897a27dc7f5a68c81a4e3dae78b99bd5ad841;p=collectd.git diff --git a/src/modbus.c b/src/modbus.c index cf8b0b29..0a4f40ca 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_INT64, + REG_TYPE_UINT64, REG_TYPE_FLOAT, REG_TYPE_FLOAT_CDAB }; /* }}} */ @@ -127,7 +129,6 @@ struct mb_host_s /* {{{ */ int port; /* for Modbus/TCP */ int baudrate; /* for Modbus/RTU */ mb_conntype_t conntype; - cdtime_t interval; mb_slave_t *slaves; size_t slaves_num; @@ -137,7 +138,7 @@ struct mb_host_s /* {{{ */ #else modbus_t *connection; #endif - _Bool is_connected; + bool is_connected; }; /* }}} */ typedef struct mb_host_s mb_host_t; @@ -154,7 +155,7 @@ struct mb_data_group_s /* {{{ */ /* * Global variables */ -static mb_data_t *data_definitions = NULL; +static mb_data_t *data_definitions; /* * Functions @@ -250,15 +251,11 @@ static int mb_submit(mb_host_t *host, mb_slave_t *slave, /* {{{ */ if ((host == NULL) || (slave == NULL) || (data == NULL)) return EINVAL; - if (host->interval == 0) - host->interval = plugin_get_interval(); - if (slave->instance[0] == 0) snprintf(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)); @@ -334,7 +331,7 @@ static int mb_init_connection(mb_host_t *host) /* {{{ */ return status; } - host->is_connected = 1; + host->is_connected = true; return 0; } /* }}} int mb_init_connection */ /* #endif LEGACY_LIBMODBUS */ @@ -394,21 +391,21 @@ static int mb_init_connection(mb_host_t *host) /* {{{ */ } /* }}} 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, /* {{{ */ 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; @@ -433,11 +430,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_UINT32_CDAB)) { + (data->register_type != REG_TYPE_UINT32_CDAB) && + (data->register_type != REG_TYPE_INT64) && + (data->register_type != REG_TYPE_UINT64)) { 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)); } @@ -448,6 +447,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_INT64) || + (data->register_type == REG_TYPE_UINT64)) + values_num = 4; else values_num = 1; @@ -467,7 +469,7 @@ static int mb_read_data(mb_host_t *host, mb_slave_t *slave, /* {{{ */ if (status != 0) { ERROR("Modbus plugin: mb_init_connection (%s/%s) failed. ", host->host, host->node); - host->is_connected = 0; + host->is_connected = false; host->connection = NULL; return -1; } @@ -532,7 +534,7 @@ 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); + 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 +545,7 @@ 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); + 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 +559,7 @@ 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); + 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 +573,7 @@ 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); + 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 +588,7 @@ static int mb_read_data(mb_host_t *host, mb_slave_t *slave, /* {{{ */ "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 +599,7 @@ 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); + 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 +610,34 @@ 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); + CAST_TO_VALUE_T(ds, vt, v32, data->scale, data->shift); + 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, data->scale, data->shift); + 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, data->scale, data->shift); mb_submit(host, slave, data, vt); } else /* if (data->register_type == REG_TYPE_UINT16) */ { @@ -618,7 +647,7 @@ static int mb_read_data(mb_host_t *host, mb_slave_t *slave, /* {{{ */ "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 +770,9 @@ static int mb_config_add_data(oconfig_item_t *ci) /* {{{ */ 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) { @@ -769,6 +796,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; @@ -916,6 +947,7 @@ static int mb_config_add_slave(mb_host_t *host, oconfig_item_t *ci) /* {{{ */ static int mb_config_add_host(oconfig_item_t *ci) /* {{{ */ { + cdtime_t interval = 0; mb_host_t *host; int status; @@ -956,7 +988,7 @@ static int mb_config_add_host(oconfig_item_t *ci) /* {{{ */ } 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); + status = cf_util_get_cdtime(child, &interval); else if (strcasecmp("Slave", child->key) == 0) /* Don't set status: Gracefully continue if a slave fails. */ mb_config_add_slave(host, child); @@ -997,7 +1029,7 @@ static int mb_config_add_host(oconfig_item_t *ci) /* {{{ */ plugin_register_complex_read(/* group = */ NULL, name, /* callback = */ mb_read, - /* interval = */ host->interval, + /* interval = */ interval, &(user_data_t){ .data = host, .free_func = host_free, });