summaryrefslogtreecommitdiffstats
path: root/src/measurement/acpi.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/measurement/acpi.cpp')
-rw-r--r--src/measurement/acpi.cpp213
1 files changed, 213 insertions, 0 deletions
diff --git a/src/measurement/acpi.cpp b/src/measurement/acpi.cpp
new file mode 100644
index 0000000..572852c
--- /dev/null
+++ b/src/measurement/acpi.cpp
@@ -0,0 +1,213 @@
+/*
+ * Copyright 2010, Intel Corporation
+ *
+ * This file is part of PowerTOP
+ *
+ * This program file is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program in a file named COPYING; if not, write to the
+ * Free Software Foundation, Inc,
+ * 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ * or just google for it.
+ *
+ * Authors:
+ * Arjan van de Ven <arjan@linux.intel.com>
+ */
+#include "measurement.h"
+#include "acpi.h"
+#include <iostream>
+#include <fstream>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
+#include "../lib.h"
+
+using namespace std;
+
+acpi_power_meter::acpi_power_meter(const char *acpi_name)
+{
+ rate = 0.0;
+ capacity = 0.0;
+ voltage = 0.0;
+ pt_strcpy(battery_name, acpi_name);
+}
+
+/*
+present: yes
+capacity state: ok
+charging state: discharging
+present rate: 8580 mW
+remaining capacity: 34110 mWh
+present voltage: 12001 mV
+*/
+
+void acpi_power_meter::measure(void)
+{
+ char filename[PATH_MAX];
+ char line[4096];
+ ifstream file;
+
+ double _rate = 0;
+ double _capacity = 0;
+ double _voltage = 0;
+
+ char rate_units[16];
+ char capacity_units[16];
+ char voltage_units[16];
+
+ rate_units[0] = 0;
+ capacity_units[0] = 0;
+ voltage_units[0] = 0;
+
+ rate = 0;
+ voltage = 0;
+ capacity = 0;
+
+ snprintf(filename, sizeof(filename), "/proc/acpi/battery/%s/state", battery_name);
+
+ file.open(filename, ios::in);
+ if (!file)
+ return;
+
+ while (file) {
+ char *c;
+ file.getline(line, sizeof(line));
+
+ if (strstr(line, "present:") && (strstr(line, "yes") == NULL)) {
+ return;
+ }
+ if (strstr(line, "charging state:") && (strstr(line, "discharging") == NULL)) {
+ return; /* not discharging */
+ }
+ if (strstr(line, "present rate:")) {
+ c = strchr(line, ':');
+ c++;
+ while (*c == ' ') c++;
+ _rate = strtoull(c, NULL, 10);
+ c = strchr(c, ' ');
+ if (c) {
+ c++;
+ pt_strcpy(rate_units, c);
+ } else {
+ _rate = 0;
+ strcpy(rate_units, "Unknown");
+ }
+
+ }
+ if (strstr(line, "remaining capacity:")) {
+ c = strchr(line, ':');
+ c++;
+ while (*c == ' ') c++;
+ _capacity = strtoull(c, NULL, 10);
+ c = strchr(c, ' ');
+ if (c) {
+ c++;
+ pt_strcpy(capacity_units, c);
+ } else {
+ _capacity = 0;
+ strcpy(capacity_units, "Unknown");
+ }
+ }
+ if (strstr(line, "present voltage:")) {
+ c = strchr(line, ':');
+ c++;
+ while (*c == ' ') c++;
+ _voltage = strtoull(c, NULL, 10);
+ c = strchr(c, ' ');
+ if (c) {
+ c++;
+ pt_strcpy(voltage_units, c);
+ } else {
+ _voltage = 0;
+ strcpy(voltage_units, "Unknown");
+ }
+ }
+ }
+ file.close();
+
+ /* BIOS report random crack-inspired units. Lets try to get to the Si-system units */
+
+ if (strcmp(voltage_units, "mV") == 0) {
+ _voltage = _voltage / 1000.0;
+ strcpy(voltage_units, "V");
+ }
+
+ if (strcmp(rate_units, "mW") == 0) {
+ _rate = _rate / 1000.0;
+ strcpy(rate_units, "W");
+ }
+
+ if (strcmp(rate_units, "mA") == 0) {
+ _rate = _rate / 1000.0;
+ strcpy(rate_units, "A");
+ }
+
+ if (strcmp(capacity_units, "mAh") == 0) {
+ _capacity = _capacity / 1000.0;
+ strcpy(capacity_units, "Ah");
+ }
+ if (strcmp(capacity_units, "mWh") == 0) {
+ _capacity = _capacity / 1000.0;
+ strcpy(capacity_units, "Wh");
+ }
+ if (strcmp(capacity_units, "Wh") == 0) {
+ _capacity = _capacity * 3600.0;
+ strcpy(capacity_units, "J");
+ }
+
+
+ if (strcmp(capacity_units, "Ah") == 0 && strcmp(voltage_units, "V") == 0) {
+ _capacity = _capacity * 3600.0 * _voltage;
+ strcpy(capacity_units, "J");
+ }
+
+ if (strcmp(rate_units, "A") == 0 && strcmp(voltage_units, "V")==0 ) {
+ _rate = _rate * _voltage;
+ strcpy(rate_units, "W");
+ }
+
+
+
+
+ if (strcmp(capacity_units, "J") == 0)
+ capacity = _capacity;
+ else
+ capacity = 0.0;
+
+ if (strcmp(rate_units, "W")==0)
+ rate = _rate;
+ else
+ rate = 0.0;
+
+ if (strcmp(voltage_units, "V")==0)
+ voltage = _voltage;
+ else
+ voltage = 0.0;
+}
+
+
+void acpi_power_meter::end_measurement(void)
+{
+ measure();
+}
+
+void acpi_power_meter::start_measurement(void)
+{
+ /* ACPI battery state is a lagging indication, lets only measure at the end */
+}
+
+
+double acpi_power_meter::power(void)
+{
+ return rate;
+}