battery plugin: Add StateFS backend.
authorRinigus <rinigus.git@gmail.com>
Thu, 8 Sep 2016 06:18:53 +0000 (08:18 +0200)
committerFlorian Forster <octo@collectd.org>
Thu, 8 Sep 2016 06:20:47 +0000 (08:20 +0200)
Pull-Request: #1795

Squashed commit of the following:

commit 8f4841f381a59e1f1afd3101f93d84079866e8fa
Author: rinigus <rinigus.git@gmail.com>
Date:   Wed Sep 7 11:10:27 2016 +0300

    battery plugin, statefs backend: use power to report values

commit bab1a17ca6d6b2a21c64eb7c5a2b0cdb658f50bc
Author: Rinigus <rinigus.git@gmail.com>
Date:   Tue Sep 6 23:53:51 2016 +0300

    battery plugin, statefs backend: adjusting type names and small corrections

commit 6428720c330f7773f3e335c8426edb9d2f8f3139
Author: Rinigus <rinigus.git@gmail.com>
Date:   Sat Sep 3 12:15:19 2016 +0300

    battery statefs backend: cleanup

commit 6039a12774d3933a88bcc4612c92699d3a816f97
Author: Rinigus <rinigus.git@gmail.com>
Date:   Sat Sep 3 07:45:45 2016 +0300

    battery plugin: clang-format for statefs backend

commit 55ec4952dbc5643af335ca9d9802df438bf4a006
Author: Rinigus <rinigus.git@gmail.com>
Date:   Sat Sep 3 07:37:52 2016 +0300

    battery plugin: adjusting read_statefs call

commit 4a41e8f1b88f58ef09b0c8702e752d9d8f793e38
Author: Rinigus <rinigus.git@gmail.com>
Date:   Fri Sep 2 23:43:49 2016 +0300

    battery: statefs backend saves as battery plugin

commit bbc25d26663cb727b884e3931e6a909a71dac160
Author: Rinigus <rinigus.git@gmail.com>
Date:   Fri Sep 2 23:19:56 2016 +0300

    battery_statefs: define read function for statefs backend

commit 352cf7d9c2146e0960b8b688dfafcbdd54a789f1
Author: Rinigus <rinigus.git@gmail.com>
Date:   Thu Sep 1 23:36:35 2016 +0300

    battery_statefs: incorporating into battery plugin

commit 65e9d416c028d919efc2d901b782bb465c82f56b
Merge: c9eca12 bb98f71
Author: Rinigus <rinigus.git@gmail.com>
Date:   Thu Sep 1 23:08:36 2016 +0300

    battery_statefs: merge updates from upstream

commit c9eca127455571e8adf1f5c5f4290e56b793040b
Merge: a6b4c85 6cf7955
Author: Rinigus <rinigus.git@gmail.com>
Date:   Sun Jul 24 14:29:57 2016 +0300

    fix configure.ac

commit a6b4c851ae3e257faad417737065aacba1db9303
Author: Rinigus <rinigus.git@gmail.com>
Date:   Mon Jul 18 23:51:44 2016 +0300

    return statements

commit d31678bb5b3d9707063986ace17e5d7ba03976b5
Author: Rinigus <rinigus.git@gmail.com>
Date:   Mon Jul 18 23:46:19 2016 +0300

    changes suggested by @rubenk

commit 56785979aa49319a0a4622ff7ece0cc1ad1fd9a6
Author: Rinigus <rinigus.git@gmail.com>
Date:   Mon Jul 18 23:40:51 2016 +0300

    changes suggested by @rubenk

commit 6cbf0d03a9404f560d346ea770e06e38ed11206f
Author: Rinigus <rinigus.git@gmail.com>
Date:   Fri Jul 15 10:03:58 2016 +0300

    statefs_battery config

src/Makefile.am
src/battery.c
src/battery_statefs.c [new file with mode: 0644]
src/collectd.conf.in
src/collectd.conf.pod
src/types.db

index bc5f429..b76e43c 100644 (file)
@@ -213,7 +213,7 @@ endif
 
 if BUILD_PLUGIN_BATTERY
 pkglib_LTLIBRARIES += battery.la
-battery_la_SOURCES = battery.c
+battery_la_SOURCES = battery.c battery_statefs.c
 battery_la_LDFLAGS = $(PLUGIN_LDFLAGS)
 if BUILD_WITH_LIBIOKIT
 battery_la_LDFLAGS += -framework IOKit
index a084319..3e6d7bd 100644 (file)
 # define SYSFS_FACTOR 0.000001
 #endif /* KERNEL_LINUX */
 
+int battery_read_statefs (void); /* defined in battery_statefs; used by StateFS backend */
+
 static _Bool report_percent = 0;
 static _Bool report_degraded = 0;
+static _Bool query_statefs = 0;
 
 static void battery_submit2 (char const *plugin_instance, /* {{{ */
                char const *type, char const *type_instance, gauge_t value)
@@ -359,6 +362,9 @@ static int battery_read (void) /* {{{ */
        gauge_t capacity_full = NAN; /* Total capacity */
        gauge_t capacity_design = NAN; /* Full design capacity */
 
+       if (query_statefs)
+               return battery_read_statefs ();
+
 #if HAVE_IOKIT_PS_IOPOWERSOURCES_H
        get_via_io_power_sources (&charge_rel, &current, &voltage);
 #endif
@@ -778,6 +784,9 @@ static int battery_read (void) /* {{{ */
 {
        int status;
 
+       if (query_statefs)
+               return battery_read_statefs ();
+
        DEBUG ("battery plugin: Trying sysfs ...");
        status = read_sysfs ();
        if (status == 0)
@@ -808,6 +817,8 @@ static int battery_config (oconfig_item_t *ci)
                        cf_util_get_boolean (child, &report_percent);
                else if (strcasecmp ("ReportDegraded", child->key) == 0)
                        cf_util_get_boolean (child, &report_degraded);
+               else if (strcasecmp ("QueryStateFS", child->key) == 0)
+                       cf_util_get_boolean (child, &query_statefs);
                else
                        WARNING ("battery plugin: Ignoring unknown "
                                        "configuration option \"%s\".",
diff --git a/src/battery_statefs.c b/src/battery_statefs.c
new file mode 100644 (file)
index 0000000..53730ed
--- /dev/null
@@ -0,0 +1,140 @@
+/**
+ * collectd - src/statefs_battery.c
+ * Copyright (C) 2016 rinigus
+ *
+ *
+The MIT License (MIT)
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+ * Authors:
+ *   rinigus <http://github.com/rinigus>
+
+ Battery stats are collected from StateFS Battery namespace. Reported
+ units are as follows:
+
+ capacity %
+ charge %
+ current A
+ energy Wh
+ power W
+ temperature C
+ timefull and timelow seconds
+ voltage V
+
+ Provider at
+ https://git.merproject.org/mer-core/statefs-providers/blob/master/src/power_udev/provider_power_udev.cpp
+
+ **/
+
+#include "collectd.h"
+#include "common.h"
+#include "plugin.h"
+
+#include <stdio.h>
+
+#define STATEFS_ROOT "/run/state/namespaces/Battery/"
+#define BUFFER_SIZE 512
+
+static int submitted_this_run = 0;
+
+static void battery_submit(const char *type, gauge_t value,
+                           const char *type_instance) {
+  value_t values[1];
+  value_list_t vl = VALUE_LIST_INIT;
+
+  values[0].gauge = value;
+
+  vl.values = values;
+  vl.values_len = 1;
+  sstrncpy(vl.host, hostname_g, sizeof(vl.host));
+  sstrncpy(vl.plugin, "battery", sizeof(vl.plugin));
+  /* statefs supports 1 battery at present */
+  sstrncpy(vl.plugin_instance, "0", sizeof(vl.plugin_instance));
+  sstrncpy(vl.type, type, sizeof(vl.type));
+  if (type_instance != NULL)
+    sstrncpy(vl.type_instance, type_instance, sizeof(vl.type_instance));
+  plugin_dispatch_values(&vl);
+
+  submitted_this_run++;
+}
+
+static _Bool getvalue(const char *fname, gauge_t *value) {
+  FILE *fh;
+  char buffer[BUFFER_SIZE];
+
+  if ((fh = fopen(fname, "r")) == NULL) {
+    WARNING("battery plugin: cannot open StateFS file %s", fname);
+    return (0);
+  }
+
+  if (fgets(buffer, STATIC_ARRAY_SIZE(buffer), fh) == NULL) {
+    fclose(fh);
+    return (0); // empty file
+  }
+
+  (*value) = atof(buffer);
+
+  fclose(fh);
+
+  return (1);
+}
+
+/* cannot be static, is referred to from battery.c */
+int battery_read_statefs(void) {
+  gauge_t value = NAN;
+
+  submitted_this_run = 0;
+
+  if (getvalue(STATEFS_ROOT "ChargePercentage", &value))
+    battery_submit("charge", value, NULL);
+  // Use capacity as a charge estimate if ChargePercentage is not available
+  else if (getvalue(STATEFS_ROOT "Capacity", &value))
+    battery_submit("charge", value, NULL);
+
+  if (getvalue(STATEFS_ROOT "Current", &value))
+    battery_submit("current", value * 1e-6, NULL); // from uA to A
+
+  if (getvalue(STATEFS_ROOT "Energy", &value))
+    battery_submit("energy_wh", value * 1e-6, NULL); // from uWh to Wh
+
+  if (getvalue(STATEFS_ROOT "Power", &value))
+    battery_submit("power", value * 1e-6, NULL); // from uW to W
+
+  if (getvalue(STATEFS_ROOT "Temperature", &value))
+    battery_submit("temperature", value * 0.1, NULL); // from 10xC to C
+
+  if (getvalue(STATEFS_ROOT "TimeUntilFull", &value))
+    battery_submit("duration", value, "full");
+
+  if (getvalue(STATEFS_ROOT "TimeUntilLow", &value))
+    battery_submit("duration", value, "low");
+
+  if (getvalue(STATEFS_ROOT "Voltage", &value))
+    battery_submit("voltage", value * 1e-6, NULL); // from uV to V
+
+  if (submitted_this_run == 0) {
+    ERROR("battery plugin: statefs backend: none of the statistics are "
+          "available");
+    return (-1);
+  }
+
+  return (0);
+}
index 16b6648..0fc13dc 100644 (file)
 #<Plugin "battery">
 #  ValuesPercentage false
 #  ReportDegraded false
+#  QueryStateFS false
 #</Plugin>
 
 #<Plugin "bind">
index 2919099..0fa74d5 100644 (file)
@@ -1108,6 +1108,13 @@ When set to B<true>, the battery plugin will report three values: B<charged>
 and "remaining capacity") and B<degraded> (difference between "design capacity"
 and "last full capacity").
 
+=item B<QueryStateFS> B<false>|B<true>
+
+When set to B<true>, the battery plugin will only read statistics
+related to battery performance as exposed by StateFS at
+/run/state. StateFS is used in Mer-based Sailfish OS, for
+example.
+
 =back
 
 =head2 Plugin C<bind>
index 093df15..6ec7812 100644 (file)
@@ -74,6 +74,8 @@ duration                seconds:GAUGE:0:U
 email_check             value:GAUGE:0:U
 email_count             value:GAUGE:0:U
 email_size              value:GAUGE:0:U
+energy                  value:GAUGE:U:U
+energy_wh               value:GAUGE:U:U
 entropy                 value:GAUGE:0:4294967295
 evicted_keys            value:DERIVE:0:U
 expired_keys            value:DERIVE:0:U