Skip to content

Commit b33c6c6

Browse files
committed
Fetch the current power consumption
1 parent eb0abdb commit b33c6c6

12 files changed

Lines changed: 212 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
@@ -686,6 +686,7 @@ void Platform_getBattery(BatteryInfo* info) {
686686
*info = (BatteryInfo) {
687687
.ac = AC_ERROR,
688688
.percent = NAN,
689+
.powerCurr = NAN,
689690
.energyCurr = NAN,
690691
.energyFull = NAN,
691692
};

dragonflybsd/Platform.c

Lines changed: 37 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>
@@ -367,6 +371,7 @@ void Platform_getBattery(BatteryInfo* info) {
367371
*info = (BatteryInfo) {
368372
.ac = AC_ERROR,
369373
.percent = NAN,
374+
.powerCurr = NAN,
370375
.energyCurr = NAN,
371376
.energyFull = NAN,
372377
};
@@ -393,9 +398,11 @@ void Platform_getBattery(BatteryInfo* info) {
393398

394399
bool haveTotalRemain = false;
395400
bool haveTotalFull = false;
401+
bool haveTotalPower = false;
396402

397403
int64_t totalRemain = 0;
398404
int64_t totalFull = 0;
405+
int64_t totalPower = 0;
399406

400407
for (int u = 0; u < units; u++) {
401408
union acpi_battery_ioctl_arg bifArg = { .unit = u };
@@ -411,9 +418,11 @@ void Platform_getBattery(BatteryInfo* info) {
411418

412419
bool haveBatteryEnergyCurr = false;
413420
bool haveBatteryEnergyFull = false;
421+
bool haveBatteryPower = false;
414422

415423
int64_t batteryEnergyCurr = 0;
416424
int64_t batteryEnergyFull = 0;
425+
int64_t batteryPower = 0;
417426

418427
if (bif->lfcap != ACPI_BATT_UNKNOWN && bst->cap != ACPI_BATT_UNKNOWN) {
419428
if (bif->units == ACPI_BIF_UNITS_MW) {
@@ -439,6 +448,30 @@ void Platform_getBattery(BatteryInfo* info) {
439448
totalFull += batteryEnergyFull;
440449
haveTotalFull = true;
441450
}
451+
452+
if (bst->rate == ACPI_BATT_UNKNOWN)
453+
continue;
454+
455+
if (bif->units == ACPI_BIF_UNITS_MW) {
456+
batteryPower = (int64_t) bst->rate * 1000;
457+
haveBatteryPower = true;
458+
} else {
459+
uint32_t batteryVoltage = (bst->volt != ACPI_BATT_UNKNOWN) ? bst->volt : bif->dvol;
460+
461+
if (batteryVoltage != ACPI_BATT_UNKNOWN && batteryVoltage != 0) {
462+
batteryPower = (int64_t) bst->rate * batteryVoltage;
463+
haveBatteryPower = true;
464+
}
465+
}
466+
467+
if (!haveBatteryPower)
468+
continue;
469+
470+
if (bst->state & ACPI_BATT_STAT_DISCHARG)
471+
batteryPower = -batteryPower;
472+
473+
totalPower += batteryPower;
474+
haveTotalPower = true;
442475
}
443476

444477
close(fd);
@@ -451,4 +484,8 @@ void Platform_getBattery(BatteryInfo* info) {
451484
info->energyCurr = (double) totalRemain / 1000000.0;
452485
info->energyFull = (double) totalFull / 1000000.0;
453486
}
487+
488+
if (haveTotalPower) {
489+
info->powerCurr = (double) totalPower / 1000000.0;
490+
}
454491
}

freebsd/Platform.c

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,7 @@ void Platform_getBattery(BatteryInfo* info) {
404404
*info = (BatteryInfo) {
405405
.ac = AC_ERROR,
406406
.percent = NAN,
407+
.powerCurr = NAN,
407408
.energyCurr = NAN,
408409
.energyFull = NAN,
409410
};
@@ -429,9 +430,11 @@ void Platform_getBattery(BatteryInfo* info) {
429430

430431
bool haveTotalRemain = false;
431432
bool haveTotalFull = false;
433+
bool haveTotalPower = false;
432434

433435
int64_t totalRemain = 0;
434436
int64_t totalFull = 0;
437+
int64_t totalPower = 0;
435438

436439
for (int u = 0; u < units; u++) {
437440
union acpi_battery_ioctl_arg bixArg = { .unit = u };
@@ -447,9 +450,11 @@ void Platform_getBattery(BatteryInfo* info) {
447450

448451
bool haveBatteryEnergyCurr = false;
449452
bool haveBatteryEnergyFull = false;
453+
bool haveBatteryPower = false;
450454

451455
int64_t batteryEnergyCurr = 0;
452456
int64_t batteryEnergyFull = 0;
457+
int64_t batteryPower = 0;
453458

454459
if (bix->lfcap != ACPI_BATT_UNKNOWN && bst->cap != ACPI_BATT_UNKNOWN) {
455460
if (bix->units == ACPI_BIX_UNITS_MW) {
@@ -474,6 +479,27 @@ void Platform_getBattery(BatteryInfo* info) {
474479
haveTotalRemain = true;
475480
haveTotalFull = true;
476481
}
482+
483+
if (bst->rate != ACPI_BATT_UNKNOWN && bst->rate > 0) {
484+
if (bix->units == ACPI_BIX_UNITS_MW) {
485+
batteryPower = (int64_t) bst->rate * 1000;
486+
haveBatteryPower = true;
487+
} else {
488+
uint32_t rateVoltage = (bst->volt != ACPI_BATT_UNKNOWN) ? bst->volt : bix->dvol;
489+
490+
if (rateVoltage != ACPI_BATT_UNKNOWN && rateVoltage != 0) {
491+
batteryPower = (int64_t) bst->rate * rateVoltage;
492+
haveBatteryPower = true;
493+
}
494+
}
495+
}
496+
497+
if (haveBatteryPower) {
498+
if (bst->state & ACPI_BATT_STAT_DISCHARG)
499+
batteryPower = -batteryPower;
500+
totalPower += batteryPower;
501+
haveTotalPower = true;
502+
}
477503
}
478504

479505
close(fd);
@@ -486,4 +512,8 @@ void Platform_getBattery(BatteryInfo* info) {
486512
info->energyCurr = (double) totalRemain / 1000000.0;
487513
info->energyFull = (double) totalFull / 1000000.0;
488514
}
515+
516+
if (haveTotalPower) {
517+
info->powerCurr = (double) totalPower / 1000000.0;
518+
}
489519
}

linux/Platform.c

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ static time_t Platform_Battery_cacheTime;
165165
static BatteryInfo Platform_Battery_cache = {
166166
.ac = AC_ERROR,
167167
.percent = NAN,
168+
.powerCurr = NAN,
168169
.energyCurr = NAN,
169170
.energyFull = NAN,
170171
};
@@ -849,6 +850,7 @@ static void Platform_Battery_getProcData(BatteryInfo* info) {
849850
static void Platform_Battery_getSysData(BatteryInfo* info) {
850851
info->percent = NAN;
851852
info->ac = AC_ERROR;
853+
info->powerCurr = NAN;
852854
info->energyCurr = NAN;
853855
info->energyFull = NAN;
854856

@@ -858,6 +860,9 @@ static void Platform_Battery_getSysData(BatteryInfo* info) {
858860

859861
uint64_t totalFull = 0;
860862
uint64_t totalRemain = 0;
863+
int64_t totalPower = 0;
864+
865+
bool havePower = false;
861866

862867
const struct dirent* dirEntry;
863868
while ((dirEntry = readdir(dir))) {
@@ -910,6 +915,9 @@ static void Platform_Battery_getSysData(BatteryInfo* info) {
910915
uint8_t haveBatteryVoltage = 0; // 0 = no, 1 = min_voltage, 2 = curr_voltage
911916
bool haveBatteryLevel = false;
912917

918+
bool haveBatteryCurrent = false;
919+
bool haveBatteryPower = false;
920+
913921
uint64_t batteryEnergyFull = 0;
914922
uint64_t batteryEnergyCurr = 0;
915923

@@ -919,6 +927,11 @@ static void Platform_Battery_getSysData(BatteryInfo* info) {
919927
uint64_t batteryVoltage = 0;
920928
uint64_t batteryLevel = 0;
921929

930+
int64_t batteryCurrent = 0;
931+
int64_t batteryPower = 0;
932+
933+
bool batteryIsDischarging = false;
934+
922935
const char* line;
923936

924937
char* buf = buffer;
@@ -975,6 +988,18 @@ static void Platform_Battery_getSysData(BatteryInfo* info) {
975988
haveBatteryVoltage = 2;
976989
continue;
977990
}
991+
992+
if (String_eq(field, "CURRENT_NOW")) {
993+
batteryCurrent = val;
994+
haveBatteryCurrent = true;
995+
continue;
996+
}
997+
998+
if (String_eq(field, "POWER_NOW")) {
999+
batteryPower += val;
1000+
haveBatteryPower = true;
1001+
continue;
1002+
}
9781003
}
9791004

9801005
if (haveBatteryLevel) {
@@ -1004,6 +1029,19 @@ static void Platform_Battery_getSysData(BatteryInfo* info) {
10041029
totalFull += batteryEnergyFull;
10051030
totalRemain += batteryEnergyCurr > batteryEnergyFull ? batteryEnergyFull : batteryEnergyCurr;
10061031
}
1032+
1033+
if (!haveBatteryPower && haveBatteryCurrent && haveBatteryVoltage) {
1034+
batteryPower = (batteryCurrent * batteryVoltage) / 1000000;
1035+
haveBatteryPower = true;
1036+
}
1037+
1038+
if (haveBatteryPower) {
1039+
if (batteryIsDischarging)
1040+
batteryPower = -batteryPower;
1041+
1042+
totalPower += batteryPower;
1043+
havePower = true;
1044+
}
10071045
} else if (type == AC) {
10081046
if (info->ac != AC_ERROR)
10091047
goto next;
@@ -1032,6 +1070,10 @@ static void Platform_Battery_getSysData(BatteryInfo* info) {
10321070
info->energyCurr = (double) totalRemain / 1000000.0;
10331071
info->energyFull = (double) totalFull / 1000000.0;
10341072
}
1073+
1074+
if (havePower) {
1075+
info->powerCurr = (double) totalPower / 1000000.0;
1076+
}
10351077
}
10361078

10371079
void Platform_getBattery(BatteryInfo* info) {
@@ -1045,6 +1087,7 @@ void Platform_getBattery(BatteryInfo* info) {
10451087
Platform_Battery_cache = (BatteryInfo) {
10461088
.ac = AC_ERROR,
10471089
.percent = NAN,
1090+
.powerCurr = NAN,
10481091
.energyCurr = NAN,
10491092
.energyFull = NAN,
10501093
};

netbsd/Platform.c

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -453,9 +453,13 @@ void Platform_getBattery(BatteryInfo* info) {
453453
intmax_t totalCharge = 0;
454454
intmax_t totalCapacity = 0;
455455

456+
bool havePower = false;
457+
intmax_t totalPower = 0;
458+
456459
*info = (BatteryInfo) {
457460
.ac = AC_ERROR,
458461
.percent = NAN,
462+
.powerCurr = NAN,
459463
.energyCurr = NAN,
460464
.energyFull = NAN,
461465
};
@@ -488,11 +492,17 @@ void Platform_getBattery(BatteryInfo* info) {
488492
intmax_t isConnected = 0;
489493
intmax_t curCharge = 0;
490494
intmax_t maxCharge = 0;
495+
intmax_t chargeRate = 0;
496+
intmax_t dischargeRate = 0;
491497
intmax_t voltage = 0;
492498
intmax_t designVoltage = 0;
493499

494500
bool haveCharge = false;
501+
bool haveChargeRate = false;
502+
bool haveDischargeRate = false;
495503
bool chargeIsAmpHours = false;
504+
bool chargeRateIsAmps = false;
505+
bool dischargeRateIsAmps = false;
496506

497507
while ((fields = prop_object_iterator_next(fieldsIter)) != NULL) {
498508
props = prop_dictionary_get(fields, "device-properties");
@@ -531,14 +541,29 @@ void Platform_getBattery(BatteryInfo* info) {
531541
haveCharge = true;
532542
chargeIsAmpHours = typeField != NULL &&
533543
prop_string_equals_string(typeField, "Ampere hour");
544+
} else if (prop_string_equals_string(descField, "charge rate")) {
545+
chargeRate = prop_number_signed_value(curValue);
546+
chargeRateIsAmps = typeField != NULL &&
547+
prop_string_equals_string(typeField, "Ampere");
548+
haveChargeRate = true;
549+
} else if (prop_string_equals_string(descField, "discharge rate")) {
550+
dischargeRate = prop_number_signed_value(curValue);
551+
dischargeRateIsAmps = typeField != NULL &&
552+
prop_string_equals_string(typeField, "Ampere");
553+
haveDischargeRate = true;
534554
}
535555
}
536556

537557
if (isBattery && isPresent) {
538558
intmax_t batteryVoltage = (voltage != 0) ? voltage : designVoltage;
539559

560+
bool haveBatteryChargeRate = false;
561+
bool haveBatteryDischargeRate = false;
562+
540563
bool haveBatteryCharge = false;
541564

565+
intmax_t batteryChargeRate = 0;
566+
intmax_t batteryDischargeRate = 0;
542567
intmax_t batteryCharge = 0;
543568
intmax_t batteryCapacity = 0;
544569

@@ -556,11 +581,39 @@ void Platform_getBattery(BatteryInfo* info) {
556581
}
557582
}
558583

584+
if (haveChargeRate) {
585+
if (chargeRateIsAmps) {
586+
if (batteryVoltage > 0) {
587+
batteryChargeRate = chargeRate * batteryVoltage / 1000000;
588+
haveBatteryChargeRate = true;
589+
}
590+
} else {
591+
batteryChargeRate = chargeRate;
592+
haveBatteryChargeRate = true;
593+
}
594+
}
595+
596+
if (haveDischargeRate) {
597+
if (dischargeRateIsAmps) {
598+
if (batteryVoltage > 0) {
599+
batteryDischargeRate = dischargeRate * batteryVoltage / 1000000;
600+
haveBatteryDischargeRate = true;
601+
}
602+
} else {
603+
batteryDischargeRate = dischargeRate;
604+
haveBatteryDischargeRate = true;
605+
}
606+
}
607+
559608
if (haveBatteryCharge) {
560609
totalCharge += batteryCharge;
561610
totalCapacity += batteryCapacity;
562611
}
563612

613+
if (haveBatteryChargeRate || haveBatteryDischargeRate) {
614+
totalPower += batteryChargeRate - batteryDischargeRate;
615+
havePower = true;
616+
}
564617
}
565618

566619
if (isACAdapter && info->ac != AC_PRESENT) {
@@ -577,6 +630,10 @@ void Platform_getBattery(BatteryInfo* info) {
577630
info->energyFull = (double) totalCapacity / 1000000.0;
578631
}
579632

633+
if (havePower) {
634+
info->powerCurr = (double) totalPower / 1000000.0;
635+
}
636+
580637
error:
581638
if (fd != -1)
582639
close(fd);

0 commit comments

Comments
 (0)