| /* |
| * 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 "extech.h" |
| #include "power_supply.h" |
| #include "sysfs.h" |
| #include "../parameters/parameters.h" |
| #include "../lib.h" |
| |
| #include <string> |
| #include <sys/types.h> |
| #include <dirent.h> |
| #include <stdio.h> |
| #include <fstream> |
| #include <unistd.h> |
| |
| double min_power = 50000.0; |
| |
| void power_meter::start_measurement(void) |
| { |
| } |
| |
| |
| void power_meter::end_measurement(void) |
| { |
| } |
| |
| |
| double power_meter::joules_consumed(void) |
| { |
| return 0.0; |
| } |
| |
| double power_meter::time_left(void) |
| { |
| double cap, rate; |
| double left; |
| |
| cap = dev_capacity(); |
| rate = joules_consumed(); |
| |
| if (cap < 0.001) |
| return 0.0; |
| |
| left = cap / rate; |
| |
| return left; |
| } |
| |
| |
| vector<class power_meter *> power_meters; |
| |
| void start_power_measurement(void) |
| { |
| unsigned int i; |
| for (i = 0; i < power_meters.size(); i++) |
| power_meters[i]->start_measurement(); |
| } |
| void end_power_measurement(void) |
| { |
| unsigned int i; |
| for (i = 0; i < power_meters.size(); i++) |
| power_meters[i]->end_measurement(); |
| } |
| |
| double global_joules_consumed(void) |
| { |
| double total = 0.0; |
| unsigned int i; |
| for (i = 0; i < power_meters.size(); i++) |
| total += power_meters[i]->joules_consumed(); |
| |
| all_results.power = total; |
| if (total < min_power && total > 0.01) |
| min_power = total; |
| return total; |
| } |
| |
| double global_time_left(void) |
| { |
| double total = 0.0; |
| unsigned int i; |
| for (i = 0; i < power_meters.size(); i++) |
| total += power_meters[i]->time_left(); |
| |
| return total; |
| } |
| |
| void sysfs_power_meters_callback(const char *d_name) |
| { |
| std::string type = read_sysfs_string("/sys/class/power_supply/%s/type", d_name); |
| |
| if (type != "Battery" && type != "UPS") |
| return; |
| |
| class sysfs_power_meter *meter; |
| meter = new(std::nothrow) class sysfs_power_meter(d_name); |
| if (meter) |
| power_meters.push_back(meter); |
| } |
| |
| void acpi_power_meters_callback(const char *d_name) |
| { |
| class acpi_power_meter *meter; |
| meter = new(std::nothrow) class acpi_power_meter(d_name); |
| if (meter) |
| power_meters.push_back(meter); |
| } |
| |
| void power_supply_callback(const char *d_name) |
| { |
| char filename[4096]; |
| char line[4096]; |
| ifstream file; |
| bool discharging = false; |
| |
| sprintf(filename, "/sys/class/power_supply/%s/uevent", d_name); |
| file.open(filename, ios::in); |
| if (!file) |
| return; |
| |
| while (file) { |
| file.getline(line, 4096); |
| |
| if (strstr(line, "POWER_SUPPLY_STATUS") && strstr(line, "Discharging")) |
| discharging = true; |
| } |
| file.close(); |
| |
| if (!discharging) |
| return; |
| |
| class power_supply *power; |
| power = new(std::nothrow) class power_supply(d_name); |
| if (power) |
| power_meters.push_back(power); |
| } |
| |
| void detect_power_meters(void) |
| { |
| process_directory("/sys/class/power_supply", sysfs_power_meters_callback); |
| if (power_meters.size() == 0) { |
| process_directory("/proc/acpi/battery", acpi_power_meters_callback); |
| } |
| } |
| |
| void extech_power_meter(const char *devnode) |
| { |
| class extech_power_meter *meter; |
| |
| meter = new class extech_power_meter(devnode); |
| |
| power_meters.push_back(meter); |
| } |