From 806091e395886da83acf2435e90648bdf2cf2ed5 Mon Sep 17 00:00:00 2001 From: Rinigus Date: Thu, 8 Sep 2016 08:18:53 +0200 Subject: [PATCH] battery plugin: Add StateFS backend. Pull-Request: #1795 Squashed commit of the following: commit 8f4841f381a59e1f1afd3101f93d84079866e8fa Author: rinigus Date: Wed Sep 7 11:10:27 2016 +0300 battery plugin, statefs backend: use power to report values commit bab1a17ca6d6b2a21c64eb7c5a2b0cdb658f50bc Author: Rinigus Date: Tue Sep 6 23:53:51 2016 +0300 battery plugin, statefs backend: adjusting type names and small corrections commit 6428720c330f7773f3e335c8426edb9d2f8f3139 Author: Rinigus Date: Sat Sep 3 12:15:19 2016 +0300 battery statefs backend: cleanup commit 6039a12774d3933a88bcc4612c92699d3a816f97 Author: Rinigus Date: Sat Sep 3 07:45:45 2016 +0300 battery plugin: clang-format for statefs backend commit 55ec4952dbc5643af335ca9d9802df438bf4a006 Author: Rinigus Date: Sat Sep 3 07:37:52 2016 +0300 battery plugin: adjusting read_statefs call commit 4a41e8f1b88f58ef09b0c8702e752d9d8f793e38 Author: Rinigus Date: Fri Sep 2 23:43:49 2016 +0300 battery: statefs backend saves as battery plugin commit bbc25d26663cb727b884e3931e6a909a71dac160 Author: Rinigus Date: Fri Sep 2 23:19:56 2016 +0300 battery_statefs: define read function for statefs backend commit 352cf7d9c2146e0960b8b688dfafcbdd54a789f1 Author: Rinigus Date: Thu Sep 1 23:36:35 2016 +0300 battery_statefs: incorporating into battery plugin commit 65e9d416c028d919efc2d901b782bb465c82f56b Merge: c9eca12 bb98f71 Author: Rinigus Date: Thu Sep 1 23:08:36 2016 +0300 battery_statefs: merge updates from upstream commit c9eca127455571e8adf1f5c5f4290e56b793040b Merge: a6b4c85 6cf7955 Author: Rinigus Date: Sun Jul 24 14:29:57 2016 +0300 fix configure.ac commit a6b4c851ae3e257faad417737065aacba1db9303 Author: Rinigus Date: Mon Jul 18 23:51:44 2016 +0300 return statements commit d31678bb5b3d9707063986ace17e5d7ba03976b5 Author: Rinigus Date: Mon Jul 18 23:46:19 2016 +0300 changes suggested by @rubenk commit 56785979aa49319a0a4622ff7ece0cc1ad1fd9a6 Author: Rinigus Date: Mon Jul 18 23:40:51 2016 +0300 changes suggested by @rubenk commit 6cbf0d03a9404f560d346ea770e06e38ed11206f Author: Rinigus Date: Fri Jul 15 10:03:58 2016 +0300 statefs_battery config --- src/Makefile.am | 2 +- src/battery.c | 11 ++++ src/battery_statefs.c | 140 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/collectd.conf.in | 1 + src/collectd.conf.pod | 7 +++ src/types.db | 2 + 6 files changed, 162 insertions(+), 1 deletion(-) create mode 100644 src/battery_statefs.c diff --git a/src/Makefile.am b/src/Makefile.am index bc5f4294..b76e43cd 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -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 diff --git a/src/battery.c b/src/battery.c index a0843196..3e6d7bda 100644 --- a/src/battery.c +++ b/src/battery.c @@ -69,8 +69,11 @@ # 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, ¤t, &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 index 00000000..53730ed0 --- /dev/null +++ b/src/battery_statefs.c @@ -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 + + 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 + +#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); +} diff --git a/src/collectd.conf.in b/src/collectd.conf.in index 16b66482..0fc13dcc 100644 --- a/src/collectd.conf.in +++ b/src/collectd.conf.in @@ -300,6 +300,7 @@ # # ValuesPercentage false # ReportDegraded false +# QueryStateFS false # # diff --git a/src/collectd.conf.pod b/src/collectd.conf.pod index 29190995..0fa74d54 100644 --- a/src/collectd.conf.pod +++ b/src/collectd.conf.pod @@ -1108,6 +1108,13 @@ When set to B, the battery plugin will report three values: B and "remaining capacity") and B (difference between "design capacity" and "last full capacity"). +=item B B|B + +When set to B, 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 diff --git a/src/types.db b/src/types.db index 093df15a..6ec78128 100644 --- a/src/types.db +++ b/src/types.db @@ -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 -- 2.11.0