Skip to content

Commit 422d5f3

Browse files
committed
Fetch the current power consumption
1 parent 67dd282 commit 422d5f3

12 files changed

Lines changed: 206 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: 38 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,31 @@ 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) == 0 &&
471+
(bst->state & ACPI_BATT_STAT_CHARGING) != 0)
472+
batteryPower = -batteryPower;
473+
474+
totalPower += batteryPower;
475+
haveTotalPower = true;
442476
}
443477

444478
close(fd);
@@ -451,4 +485,8 @@ void Platform_getBattery(BatteryInfo* info) {
451485
info->energyCurr = (double) totalRemain / 1000000.0;
452486
info->energyFull = (double) totalFull / 1000000.0;
453487
}
488+
489+
if (haveTotalPower) {
490+
info->powerCurr = (double) totalPower / 1000000.0;
491+
}
454492
}

freebsd/Platform.c

Lines changed: 28 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,25 @@ 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+
totalPower += batteryPower;
499+
haveTotalPower = true;
500+
}
477501
}
478502

479503
close(fd);
@@ -486,4 +510,8 @@ void Platform_getBattery(BatteryInfo* info) {
486510
info->energyCurr = (double) totalRemain / 1000000.0;
487511
info->energyFull = (double) totalFull / 1000000.0;
488512
}
513+
514+
if (haveTotalPower) {
515+
info->powerCurr = (double) totalPower / 1000000.0;
516+
}
489517
}

linux/Platform.c

Lines changed: 38 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,9 @@ 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+
922933
const char* line;
923934

924935
char* buf = buffer;
@@ -969,6 +980,18 @@ static void Platform_Battery_getSysData(BatteryInfo* info) {
969980
haveBatteryVoltage = 2;
970981
continue;
971982
}
983+
984+
if (String_eq(field, "CURRENT_NOW")) {
985+
batteryCurrent = val;
986+
haveBatteryCurrent = true;
987+
continue;
988+
}
989+
990+
if (String_eq(field, "POWER_NOW")) {
991+
batteryPower += val;
992+
haveBatteryPower = true;
993+
continue;
994+
}
972995
}
973996

974997
if (haveBatteryLevel) {
@@ -998,6 +1021,16 @@ static void Platform_Battery_getSysData(BatteryInfo* info) {
9981021
totalFull += batteryEnergyFull;
9991022
totalRemain += batteryEnergyCurr > batteryEnergyFull ? batteryEnergyFull : batteryEnergyCurr;
10001023
}
1024+
1025+
if (!haveBatteryPower && haveBatteryCurrent && haveBatteryVoltage) {
1026+
batteryPower = (batteryCurrent * batteryVoltage) / 1000000;
1027+
haveBatteryPower = true;
1028+
}
1029+
1030+
if (haveBatteryPower) {
1031+
totalPower += batteryPower;
1032+
havePower = true;
1033+
}
10011034
} else if (type == AC) {
10021035
if (info->ac != AC_ERROR)
10031036
goto next;
@@ -1026,6 +1059,10 @@ static void Platform_Battery_getSysData(BatteryInfo* info) {
10261059
info->energyCurr = (double) totalRemain / 1000000.0;
10271060
info->energyFull = (double) totalFull / 1000000.0;
10281061
}
1062+
1063+
if (havePower) {
1064+
info->powerCurr = (double) totalPower / 1000000.0;
1065+
}
10291066
}
10301067

10311068
void Platform_getBattery(BatteryInfo* info) {
@@ -1039,6 +1076,7 @@ void Platform_getBattery(BatteryInfo* info) {
10391076
Platform_Battery_cache = (BatteryInfo) {
10401077
.ac = AC_ERROR,
10411078
.percent = NAN,
1079+
.powerCurr = NAN,
10421080
.energyCurr = NAN,
10431081
.energyFull = NAN,
10441082
};

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 += batteryDischargeRate - batteryChargeRate;
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)