]> git.itanic.dy.fi Git - rrdd/commitdiff
onewire_parser: Add support for temperature offsets
authorTimo Kokkonen <timo.t.kokkonen@iki.fi>
Mon, 2 Jul 2012 18:55:24 +0000 (21:55 +0300)
committerTimo Kokkonen <timo.t.kokkonen@iki.fi>
Mon, 2 Jul 2012 18:55:24 +0000 (21:55 +0300)
Some temperature sensors may have a significant systematic error
offset on their readings. This patch makes it possible to define an
offset value that is added to the raw value before the result is
stored in the rrd database.

From now on it is assumed that each onewire path never contains white
space. If there is a white space within the server path, it is
expected that each string that is separated with white space contains
an option that is used to control the readout of the values returned
or available from the server.

At the moment only one option is supported; temperature offset. The
option string must contain "offset=" following a decimal number. The
offset value is added to the number read from the server.

Signed-off-by: Timo Kokkonen <timo.t.kokkonen@iki.fi>
onewire_parser.c

index 32414a13ed1142cb12454aacb80a1e6848f585be..e5d37ea082044a419dbce03437b605d3b9f824dd 100644 (file)
@@ -5,6 +5,44 @@
 #include "debug.h"
 #include "string.h"
 
+int parse_opts(const char *str, char *ow_path, size_t pathlen, double *offset)
+{
+       char *endptr;
+       const char *start_str = str;
+       const char offset_str[] = "offset=";
+
+       if (!offset)
+               return 0;
+
+       /*
+        * Skip the onewire path entry. Options begin after the first
+        * white space
+        */
+       for (; *str; str++)
+               if (isspace(*str))
+                       break;
+
+       /* Copy the onewire path without options */
+       strncpy(ow_path, start_str, pathlen);
+       ow_path[str - start_str] = '\0';
+
+       /* Get the next non-space, which is where the argument begins */
+       for (; *str; str++)
+               if (!isspace(*str))
+                       break;
+
+       if (strncmp(str, offset_str, sizeof(offset_str) - 1))
+               return 0;
+       str += sizeof(offset_str) - 1;
+
+       *offset = strtod(str, &endptr);
+
+       if (str != endptr)
+               return 1;
+
+       return 0;
+}
+
 int onewire_parser(char *rrd_data, const char **parser_data)
 {
        OWNET_HANDLE h;
@@ -32,6 +70,10 @@ int onewire_parser(char *rrd_data, const char **parser_data)
        }
 
        while (parser_data[i]) {
+               double offset = 0, data;
+               char *endptr;
+               char ow_path[1024];
+
                if (!strcmp("U", parser_data[i])) {
 undefined:
                        ret = snprintf(rrd_data, max_str, "U");
@@ -40,8 +82,11 @@ undefined:
                        goto next;
                }
 
-               pr_info("Reading data for entry %s\n", parser_data[i]);
-               ret = OWNET_read(h, parser_data[i], &tmp);
+               parse_opts(parser_data[i], ow_path, sizeof(ow_path), &offset);
+
+               pr_info("Reading data for entry %s with offset of %.2f\n",
+                       ow_path, offset);
+               ret = OWNET_read(h, ow_path, &tmp);
                if (ret < 0) {
                        pr_err("Failed to read entry %s\n", parser_data[i]);
                        goto undefined;
@@ -52,7 +97,16 @@ undefined:
                free(tmp);
                buf[ret] = 0;
 
-               ret = snprintf(rrd_data, max_str, "%s", buf);
+               data = strtod(buf, &endptr);
+
+               if (endptr == buf) {
+                       pr_err("Failed to parse data %s\n", buf);
+                       goto undefined;
+               }
+
+               data += offset;
+
+               ret = snprintf(rrd_data, max_str, "%f", data);
                max_str -= ret;
                rrd_data += ret;