diff --git a/ksysguardd/Linux/acpi.h b/ksysguardd/Linux/acpi.h --- a/ksysguardd/Linux/acpi.h +++ b/ksysguardd/Linux/acpi.h @@ -28,8 +28,14 @@ void printSysBatteryChargeInfo(const char *cmd); void printSysBatteryChargeDesign(const char *cmd); void printSysBatteryChargeDesignInfo(const char *cmd); +void printSysBatteryEnergy(const char *cmd); +void printSysBatteryEnergyInfo(const char *cmd); +void printSysBatteryEnergyDesign(const char *cmd); +void printSysBatteryEnergyDesignInfo(const char *cmd); void printSysBatteryRate(const char *cmd); void printSysBatteryRateInfo(const char *cmd); +void printSysBatteryRatePower(const char *cmd); +void printSysBatteryRatePowerInfo(const char *cmd); void readTypeFile(const char *fileFormat, int number, char *buffer, int bufferSize); static int getSysFileValue(const char *class, const char *group, int value, const char *file); diff --git a/ksysguardd/Linux/acpi.c b/ksysguardd/Linux/acpi.c --- a/ksysguardd/Linux/acpi.c +++ b/ksysguardd/Linux/acpi.c @@ -3,6 +3,7 @@ Copyright (c) 2003 Stephan Uhlmann Copyright (c) 2005 Sirtaj Singh Kang -- Battery fixes and Thermal + Copyright (c) 2020 Jose Jorge -- Add energy sensor This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public @@ -51,58 +52,80 @@ /************ ACPI Battery **********/ -void registerBatteryCharge(int number, struct SensorModul *sm) +void registerBatteryCharge(const char *name, int number, struct SensorModul *sm) { - char name[ ACPIFILENAMELENGTHMAX ]; - readTypeFile("/sys/class/power_supply/BAT%d/type", number, name, sizeof(name)); - char sensorName [ ACPIFILENAMELENGTHMAX ]; snprintf(sensorName, sizeof(sensorName), "acpi/Battery/%d-%s/Charge", number, name); - registerMonitor(sensorName, "integer", printSysBatteryCharge, + registerMonitor(sensorName, "float", printSysBatteryCharge, printSysBatteryChargeInfo, sm); } -void registerBatteryChargeDesign(int number, struct SensorModul *sm) +void registerBatteryChargeDesign(const char *name, int number, struct SensorModul *sm) { - char name[ ACPIFILENAMELENGTHMAX ]; - readTypeFile("/sys/class/power_supply/BAT%d/type", number, name, sizeof(name)); - char sensorName [ ACPIFILENAMELENGTHMAX ]; snprintf(sensorName, sizeof(sensorName), "acpi/Battery/%d-%s/ChargeDesign", number, name); - registerMonitor(sensorName, "integer", printSysBatteryChargeDesign, + registerMonitor(sensorName, "float", printSysBatteryChargeDesign, printSysBatteryChargeDesignInfo, sm); } -void registerBatteryRate(int number, struct SensorModul *sm) +void registerBatteryEnergy(const char *name, int number, struct SensorModul *sm) { - char name[ ACPIFILENAMELENGTHMAX ]; - readTypeFile("/sys/class/power_supply/BAT%d/type", number, name, sizeof(name)); + char sensorName [ ACPIFILENAMELENGTHMAX ]; + snprintf(sensorName, sizeof(sensorName), "acpi/Battery/%d-%s/Energy", number, name); + registerMonitor(sensorName, "float", printSysBatteryEnergy, + printSysBatteryEnergyInfo, sm); +} + +void registerBatteryEnergyDesign(const char *name, int number, struct SensorModul *sm) +{ + char sensorName [ ACPIFILENAMELENGTHMAX ]; + snprintf(sensorName, sizeof(sensorName), "acpi/Battery/%d-%s/EnergyDesign", number, name); + + registerMonitor(sensorName, "float", printSysBatteryEnergyDesign, + printSysBatteryEnergyDesignInfo, sm); +} + +void registerBatteryRate(const char *name, int number, struct SensorModul *sm) +{ char sensorName [ ACPIFILENAMELENGTHMAX ]; snprintf(sensorName, sizeof(sensorName), "acpi/Battery/%d-%s/Rate", number, name); registerMonitor(sensorName, "integer", printSysBatteryRate, printSysBatteryRateInfo, sm); } +void registerBatteryRatePower(const char *name, int number, struct SensorModul *sm) +{ + char sensorName [ ACPIFILENAMELENGTHMAX ]; + snprintf(sensorName, sizeof(sensorName), "acpi/Battery/%d-%s/RatePower", number, name); + + registerMonitor(sensorName, "integer", printSysBatteryRatePower, + printSysBatteryRatePowerInfo, sm); +} + void initAcpiBattery( struct SensorModul* sm ) { DIR *d; struct dirent *de; - char s[ ACPIFILENAMELENGTHMAX ]; + char name[ ACPIFILENAMELENGTHMAX ]; d = opendir("/sys/class/power_supply/"); if (d != NULL) { while ( (de = readdir(d)) != NULL ) { if (!de->d_name || de->d_name[0] == '.') continue; if (strncmp( de->d_name, "BAT", sizeof("BAT")-1) == 0) { int number = atoi(de->d_name + (sizeof("BAT")-1)); - registerBatteryCharge(number, sm); - registerBatteryChargeDesign(number, sm); - registerBatteryRate(number, sm); + readTypeFile("/sys/class/power_supply/BAT%d/type", number, name, sizeof(name)); + registerBatteryCharge(name, number, sm); + registerBatteryChargeDesign(name, number, sm); + registerBatteryEnergy(name, number, sm); + registerBatteryEnergyDesign(name, number, sm); + registerBatteryRate(name, number, sm); + registerBatteryRatePower(name, number, sm); } } closedir( d ); @@ -119,16 +142,16 @@ int charge = getSysFileValue("power_supply", "BAT", zone, "charge_now"); int maximum = getSysFileValue("power_supply", "BAT", zone, "charge_full"); - int state = 0; + float state = 0; if ( maximum > 0) { - state = charge * 100 / maximum; + state = charge/((float)maximum/100);/* to get 0.1% changes */ } if (state > 100) { state = 100; /* prevent insane numbers with bad hardware */ } else if (state < 0) { state = 0; /* prevent insane numbers with bad hardware */ } - output( "%d\n", state); + output( "%f\n", state); } void printSysBatteryChargeInfo(const char *cmd) @@ -151,16 +174,16 @@ int charge = getSysFileValue("power_supply", "BAT", zone, "charge_now"); int maximum = getSysFileValue("power_supply", "BAT", zone, "charge_full_design"); - int state = 0; + float state = 0; if (maximum > 0) { - state = charge * 100 / maximum; + state = charge/((float)maximum/100);/* to get 0.1% changes */ } if (state > 100) { state = 100; /* prevent insane numbers with bad hardware */ } else if (state < 0) { state = 0; /* prevent insane numbers with bad hardware */ } - output( "%d\n", state); + output( "%f\n", state); } void printSysBatteryChargeDesignInfo(const char *cmd) @@ -173,6 +196,70 @@ } } +void printSysBatteryEnergy(const char *cmd) +{ + int zone = 0; + if (sscanf(cmd, "acpi/Battery/%d", &zone) <= 0) { + output("-1\n"); + return; + } + + int charge = getSysFileValue("power_supply", "BAT", zone, "energy_now"); + int maximum = getSysFileValue("power_supply", "BAT", zone, "energy_full"); + float state = 0; + if ( maximum > 0) { + state = charge/((float)maximum/100);/* to get 0.1% changes */ + } + if (state > 100) { + state = 100; /* prevent insane numbers with bad hardware */ + } else if (state < 0) { + state = 0; /* prevent insane numbers with bad hardware */ + } + output( "%f\n", state); +} + +void printSysBatteryEnergyInfo(const char *cmd) +{ + char name [ 200 ]; + if (sscanf(cmd, "acpi/Battery/%199[^/]", name) > 0) { + output( "%s energy\t0\t100\t%%\n", name); + } else { + output( "Current energy\t0\t100\t%%\n"); + } +} + +void printSysBatteryEnergyDesign(const char *cmd) +{ + int zone = 0; + if (sscanf(cmd, "acpi/Battery/%d", &zone) <= 0) { + output("-1\n"); + return; + } + + int charge = getSysFileValue("power_supply", "BAT", zone, "energy_now"); + int maximum = getSysFileValue("power_supply", "BAT", zone, "energy_full_design"); + float state = 0; + if (maximum > 0) { + state = charge/((float)maximum/100);/* to get 0.1% changes */ + } + if (state > 100) { + state = 100; /* prevent insane numbers with bad hardware */ + } else if (state < 0) { + state = 0; /* prevent insane numbers with bad hardware */ + } + output( "%f\n", state); +} + +void printSysBatteryEnergyDesignInfo(const char *cmd) +{ + char name [ 200 ]; + if (sscanf(cmd, "acpi/Battery/%199[^/]", name) > 0) { + output( "%s energy (by design)\t0\t100\t%%\n", name); + } else { + output( "Current energy (by design)\t0\t100\t%%\n"); + } +} + void printSysBatteryRate(const char *cmd) { int zone = 0; @@ -194,6 +281,27 @@ } } +void printSysBatteryRatePower(const char *cmd) +{ + int zone = 0; + if (sscanf(cmd, "acpi/Battery/%d", &zone) <= 0) { + output("-1\n"); + return; + } + + output( "%d\n", getSysFileValue("power_supply", "BAT", zone, "power_now") / 1000); +} + +void printSysBatteryRatePowerInfo(const char *cmd) +{ + char name [ 200 ]; + if (sscanf(cmd, "acpi/Battery/%199[^/]", name) > 0) { + output( "%s rate\t0\t0\tmA\n", name); + } else { + output( "Current power rate\t0\t0\tmA\n"); + } +} + /************** ACPI Thermal *****************/ @@ -339,12 +447,7 @@ snprintf(th_file, sizeof(th_file), "/sys/class/%s/%s%d/%s", className, group, value, file); int fd = open(th_file, O_RDONLY); if (fd < 0) { - if (!shownError) - print_error( "Cannot open file \'%s\'!\n" - "Load the thermal ACPI kernel module or\n" - "compile it into your kernel.\n", th_file ); - shownError = 1; - return -1; + return -1;/* ignore failures, as sys files disappear when battery is removed */ } int read_bytes = read( fd, input_buf, sizeof(input_buf) - 1 ); if ( read_bytes == sizeof(input_buf) - 1 ) {