Code

modbus plugin: Implement signed integer register types.
authorFlorian Forster <octo@noris.net>
Wed, 5 Jan 2011 16:36:12 +0000 (17:36 +0100)
committerFlorian Forster <octo@noris.net>
Wed, 5 Jan 2011 16:36:12 +0000 (17:36 +0100)
Signed-off-by: Florian Forster <octo@noris.net>
src/collectd.conf.pod
src/modbus.c

index b63f486ba0cb984e1375a475d064947b8f762668..e91730eb0ba12aff2d5784f56975f4eff77fa300 100644 (file)
@@ -1933,11 +1933,11 @@ 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<Uint16>|B<Uint32>|B<Float>
+=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<Uint32>
-or B<Float>, two 16E<nbsp>bit registers will be read and the data is combined
-into one value. Defaults to B<Uint16>.
+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<Type> I<Type>
 
index 17396edfbef1dec4eaaf51eb023e17590a1194db..a14ccedb291433d3ea9b76391f7e1b8f1e249c55 100644 (file)
@@ -1,6 +1,6 @@
 /**
  * collectd - src/modbus.c
- * Copyright (C) 2010  noris network AG
+ * Copyright (C) 2010,2011  noris network AG
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the
@@ -68,6 +68,8 @@
  */
 enum mb_register_type_e /* {{{ */
 {
+  REG_TYPE_INT16,
+  REG_TYPE_INT32,
   REG_TYPE_UINT16,
   REG_TYPE_UINT32,
   REG_TYPE_FLOAT
@@ -410,6 +412,7 @@ 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))
   {
     NOTICE ("Modbus plugin: The data source of type \"%s\" is %s, not gauge. "
@@ -418,7 +421,8 @@ static int mb_read_data (mb_host_t *host, mb_slave_t *slave, /* {{{ */
   }
 
   memset (values, 0, sizeof (values));
-  if ((data->register_type == REG_TYPE_UINT32)
+  if ((data->register_type == REG_TYPE_INT32)
+      || (data->register_type == REG_TYPE_UINT32)
       || (data->register_type == REG_TYPE_FLOAT))
     values_num = 2;
   else
@@ -501,12 +505,47 @@ static int mb_read_data (mb_host_t *host, mb_slave_t *slave, /* {{{ */
     CAST_TO_VALUE_T (ds, vt, float_value);
     mb_submit (host, slave, data, vt);
   }
+  else if (data->register_type == REG_TYPE_INT32)
+  {
+    union
+    {
+      uint32_t u32;
+      int32_t  i32;
+    } v;
+    value_t vt;
+
+    v.u32 = (((uint32_t) values[0]) << 16)
+      | ((uint32_t) values[1]);
+    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)
+  {
+    union
+    {
+      uint16_t u16;
+      int16_t  i16;
+    } v;
+    value_t vt;
+
+    v.u16 = values[0];
+
+    DEBUG ("Modbus plugin: mb_read_data: "
+        "Returned int16 value is %"PRIi16, v.i16);
+
+    CAST_TO_VALUE_T (ds, vt, v.i16);
+    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];
+    v32 = (((uint32_t) values[0]) << 16)
+      | ((uint32_t) values[1]);
     DEBUG ("Modbus plugin: mb_read_data: "
         "Returned uint32 value is %"PRIu32, v32);
 
@@ -662,6 +701,10 @@ static int mb_config_add_data (oconfig_item_t *ci) /* {{{ */
       status = cf_util_get_string_buffer (child, tmp, sizeof (tmp));
       if (status != 0)
         /* do nothing */;
+      else if (strcasecmp ("Int16", tmp) == 0)
+        data.register_type = REG_TYPE_INT16;
+      else if (strcasecmp ("Int32", tmp) == 0)
+        data.register_type = REG_TYPE_INT32;
       else if (strcasecmp ("Uint16", tmp) == 0)
         data.register_type = REG_TYPE_UINT16;
       else if (strcasecmp ("Uint32", tmp) == 0)