Skip to content

Commit 4d3bece

Browse files
committed
Fetch the current power consumption
1 parent 3da5be1 commit 4d3bece

11 files changed

Lines changed: 110 additions & 0 deletions

File tree

BatteryMeter.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ static void BatteryMeter_updateValues(Meter* this) {
2828
BatteryInfo info = {
2929
.ac = AC_ERROR,
3030
.percent = NAN,
31+
.powerCurr = NAN,
3132
.energyCurr = NAN,
3233
.energyFull = NAN,
3334
};

BatteryMeter.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ typedef struct BatteryInfo_ {
2222
ACPresence ac;
2323

2424
double percent; /* [0..100], NAN if unknown */
25+
double powerCurr; /* instantaneous power in W, NAN if unknown */
2526
double energyCurr; /* Wh, NAN if unknown */
2627
double energyFull; /* Wh, NAN if unknown */
2728
} BatteryInfo;

darwin/Platform.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -679,6 +679,7 @@ void Platform_getBattery(BatteryInfo* info) {
679679
*info = (BatteryInfo) {
680680
.ac = AC_ERROR,
681681
.percent = NAN,
682+
.powerCurr = NAN,
682683
.energyCurr = NAN,
683684
.energyFull = NAN,
684685
};

dragonflybsd/Platform.c

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,13 @@ in the source distribution for its full text.
1212

1313
#include <devstat.h>
1414
#include <errno.h>
15+
#include <fcntl.h>
1516
#include <ifaddrs.h>
1617
#include <math.h>
1718
#include <time.h>
19+
#include <unistd.h>
20+
#include <dev/acpica/acpiio.h>
21+
#include <sys/ioctl.h>
1822
#include <sys/resource.h>
1923
#include <sys/socket.h>
2024
#include <sys/sysctl.h>
@@ -368,6 +372,7 @@ void Platform_getBattery(BatteryInfo* info) {
368372
*info = (BatteryInfo) {
369373
.ac = AC_ERROR,
370374
.percent = NAN,
375+
.powerCurr = NAN,
371376
.energyCurr = NAN,
372377
.energyFull = NAN,
373378
};
@@ -381,4 +386,59 @@ void Platform_getBattery(BatteryInfo* info) {
381386
size_t acline_len = sizeof(acline);
382387
if (sysctlbyname("hw.acpi.acline", &acline, &acline_len, NULL, 0) != -1)
383388
info->ac = (acline == 0) ? AC_ABSENT : AC_PRESENT;
389+
390+
int units = 0;
391+
int fd = open("/dev/acpi", O_RDONLY | O_CLOEXEC);
392+
if (fd == -1)
393+
return;
394+
395+
if (ioctl(fd, ACPIIO_BATT_GET_UNITS, &units) == -1 || units <= 0) {
396+
close(fd);
397+
return;
398+
}
399+
400+
double totalPower = 0.0;
401+
bool hasPower = false;
402+
403+
for (int u = 0; u < units; u++) {
404+
union acpi_battery_ioctl_arg bifArg = { .unit = u };
405+
if (ioctl(fd, ACPIIO_BATT_GET_BIF, &bifArg) == -1)
406+
continue;
407+
408+
union acpi_battery_ioctl_arg bstArg = { .unit = u };
409+
if (ioctl(fd, ACPIIO_BATT_GET_BST, &bstArg) == -1)
410+
continue;
411+
412+
const struct acpi_bif* bif = &bifArg.bif;
413+
const struct acpi_bst* bst = &bstArg.bst;
414+
415+
if (bst->rate == ACPI_BATT_UNKNOWN)
416+
continue;
417+
418+
double rate = NAN;
419+
420+
if (bif->units == ACPI_BIF_UNITS_MW) {
421+
rate = bst->rate / 1000.0;
422+
} else {
423+
uint32_t voltMV = (bst->volt != ACPI_BATT_UNKNOWN) ? bst->volt : bif->dvol;
424+
425+
if (voltMV != ACPI_BATT_UNKNOWN && voltMV != 0)
426+
rate = bst->rate * (double)voltMV / 1e6;
427+
}
428+
429+
if (!isNonnegative(rate))
430+
continue;
431+
432+
if ((bst->state & ACPI_BATT_STAT_DISCHARG) == 0 &&
433+
(bst->state & ACPI_BATT_STAT_CHARGING) != 0)
434+
rate = -rate;
435+
436+
totalPower += rate;
437+
hasPower = true;
438+
}
439+
440+
close(fd);
441+
442+
if (hasPower)
443+
info->powerCurr = totalPower;
384444
}

freebsd/Platform.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,7 @@ void Platform_getBattery(BatteryInfo* info) {
405405
*info = (BatteryInfo) {
406406
.ac = AC_ERROR,
407407
.percent = NAN,
408+
.powerCurr = NAN,
408409
.energyCurr = NAN,
409410
.energyFull = NAN,
410411
};
@@ -430,6 +431,7 @@ void Platform_getBattery(BatteryInfo* info) {
430431

431432
double totalRemain = 0.0;
432433
double totalFull = 0.0;
434+
double totalPower = 0.0;
433435

434436
for (int u = 0; u < units; u++) {
435437
union acpi_battery_ioctl_arg bixArg = { .unit = u };
@@ -466,6 +468,17 @@ void Platform_getBattery(BatteryInfo* info) {
466468
totalRemain += remain;
467469
totalFull += full;
468470
}
471+
472+
if (bst->rate != ACPI_BATT_UNKNOWN && bst->rate > 0) {
473+
if (bix->units == ACPI_BIX_UNITS_MW) {
474+
totalPower += bst->rate / 1000.0;
475+
} else {
476+
uint32_t rateVoltMV = (bst->volt != ACPI_BATT_UNKNOWN) ? bst->volt : bix->dvol;
477+
478+
if (rateVoltMV != ACPI_BATT_UNKNOWN && rateVoltMV != 0)
479+
totalPower += bst->rate * (double)rateVoltMV / 1e6;
480+
}
481+
}
469482
}
470483

471484
close(fd);
@@ -474,4 +487,6 @@ void Platform_getBattery(BatteryInfo* info) {
474487
info->energyCurr = totalRemain;
475488
info->energyFull = totalFull;
476489
}
490+
if (totalPower > 0.0)
491+
info->powerCurr = totalPower;
477492
}

linux/Platform.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,7 @@ static time_t Platform_Battery_cacheTime;
166166
static BatteryInfo Platform_Battery_cache = {
167167
.ac = AC_ERROR,
168168
.percent = NAN,
169+
.powerCurr = NAN,
169170
.energyCurr = NAN,
170171
.energyFull = NAN,
171172
};
@@ -850,6 +851,7 @@ static void Platform_Battery_getProcData(BatteryInfo* info) {
850851
static void Platform_Battery_getSysData(BatteryInfo* info) {
851852
info->percent = NAN;
852853
info->ac = AC_ERROR;
854+
info->powerCurr = NAN;
853855
info->energyCurr = NAN;
854856
info->energyFull = NAN;
855857

@@ -859,6 +861,8 @@ static void Platform_Battery_getSysData(BatteryInfo* info) {
859861

860862
uint64_t totalFull = 0;
861863
uint64_t totalRemain = 0;
864+
int64_t totalPower = 0;
865+
bool hasPower = false;
862866

863867
const struct dirent* dirEntry;
864868
while ((dirEntry = readdir(dir))) {
@@ -937,6 +941,12 @@ static void Platform_Battery_getSysData(BatteryInfo* info) {
937941
break;
938942
continue;
939943
}
944+
945+
if (String_eq(field, "POWER_NOW")) {
946+
totalPower += val;
947+
hasPower = true;
948+
continue;
949+
}
940950
}
941951

942952
if (!now && full && isNonnegative(capacityLevel))
@@ -970,6 +980,8 @@ static void Platform_Battery_getSysData(BatteryInfo* info) {
970980
info->energyCurr = (double) totalRemain;
971981
info->energyFull = (double) totalFull;
972982
}
983+
if (hasPower)
984+
info->powerCurr = (double) totalPower;
973985
}
974986

975987
void Platform_getBattery(BatteryInfo* info) {
@@ -983,6 +995,7 @@ void Platform_getBattery(BatteryInfo* info) {
983995
Platform_Battery_cache = (BatteryInfo) {
984996
.ac = AC_ERROR,
985997
.percent = NAN,
998+
.powerCurr = NAN,
986999
.energyCurr = NAN,
9871000
.energyFull = NAN,
9881001
};

netbsd/Platform.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -457,6 +457,7 @@ void Platform_getBattery(BatteryInfo* info) {
457457
*info = (BatteryInfo) {
458458
.ac = AC_ERROR,
459459
.percent = NAN,
460+
.powerCurr = NAN,
460461
.energyCurr = NAN,
461462
.energyFull = NAN,
462463
};

openbsd/Platform.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,7 @@ void Platform_getBattery(BatteryInfo* info) {
384384
*info = (BatteryInfo) {
385385
.ac = AC_ERROR,
386386
.percent = NAN,
387+
.powerCurr = NAN,
387388
.energyCurr = NAN,
388389
.energyFull = NAN,
389390
};
@@ -410,6 +411,20 @@ void Platform_getBattery(BatteryInfo* info) {
410411
info->energyFull = last_full_capacity;
411412
}
412413
}
414+
415+
mib[3] = SENSOR_INTEGER;
416+
mib[4] = 0; /* "battery state" */
417+
int64_t batteryState = 0;
418+
if (sysctl(mib, 5, &s, &slen, NULL, 0) != -1)
419+
batteryState = s.value;
420+
421+
mib[3] = SENSOR_WATTS;
422+
mib[4] = 0; /* "rate" */
423+
if (sysctl(mib, 5, &s, &slen, NULL, 0) != -1) {
424+
info->powerCurr = (double)s.value / 1000000.0;
425+
if (batteryState & 0x02)
426+
info->powerCurr = -info->powerCurr;
427+
}
413428
}
414429

415430
found = findDevice("acpiac0", mib, &snsrdev, &sdlen);

pcp/Platform.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -853,6 +853,7 @@ void Platform_getBattery(BatteryInfo* info) {
853853
*info = (BatteryInfo) {
854854
.ac = AC_ERROR,
855855
.percent = NAN,
856+
.powerCurr = NAN,
856857
.energyCurr = NAN,
857858
.energyFull = NAN,
858859
};

solaris/Platform.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,7 @@ void Platform_getBattery(BatteryInfo* info) {
347347
*info = (BatteryInfo) {
348348
.ac = AC_ERROR,
349349
.percent = NAN,
350+
.powerCurr = NAN,
350351
.energyCurr = NAN,
351352
.energyFull = NAN,
352353
};

0 commit comments

Comments
 (0)