Adding support for CDAB endian 32-bit modbus polls
authorPJ Bostley <pbostley@gmail.com>
Sat, 20 Jan 2018 23:39:36 +0000 (16:39 -0700)
committerPJ Bostley <pbostley@gmail.com>
Sat, 20 Jan 2018 23:39:36 +0000 (16:39 -0700)
src/modbus.c

index 31f0c2d..daa3c02 100644 (file)
 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
@@ -523,6 +532,17 @@ 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_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) {
     union {
       uint32_t u32;
@@ -537,6 +557,20 @@ static int mb_read_data(mb_host_t *host, mb_slave_t *slave, /* {{{ */
 
     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) {
     union {
       uint16_t u16;
@@ -563,6 +597,17 @@ static int mb_read_data(mb_host_t *host, mb_slave_t *slave, /* {{{ */
 
     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) */
   {
     value_t vt;
@@ -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;