@@ -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}
0 commit comments