Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lumina thinks my iMac G5 has a battery #765

Open
outpaddling opened this issue May 30, 2021 · 3 comments
Open

Lumina thinks my iMac G5 has a battery #765

outpaddling opened this issue May 30, 2021 · 3 comments

Comments

@outpaddling
Copy link
Contributor

Just installed Lumina on an iMac G5 via desktop-installer. Works just about perfectly, except for thinking that the system should have a battery and stunning me with the gulag firing squad drum roll every time I log in.

imac-g5

"sysctl -a | grep batt" shows nothing, so I'm wondering how Lumina determines that a system has a battery?

@outpaddling
Copy link
Contributor Author

outpaddling commented Feb 17, 2022

I dug into the code and discovered that battery monitoring is implemented by shelling out an apm command. Biggest problem here is that apm does not exist on powerpc, arm, or riscv. It's also an inefficient way to get battery info and has been superseded by the ACPI interface.

The patches below should work on any platform and perform better.

src-cpp/framework-OSInterface-FreeBSD.cpp does not appear to be used anymore, but I patched it just in case.

I was also getting intermittent false alarms about low battery with the apm implementation when the system was under heavy load and I'm hoping this will eliminate those as well. I'll report back if the false alarms continue.

--- ../src-cpp/framework-OSInterface-FreeBSD.cpp.orig   2021-12-25 20:33:45.000000000 -0600
+++ ../src-cpp/framework-OSInterface-FreeBSD.cpp        2022-02-17 08:14:20.413578000 -0600
@@ -21,24 +21,34 @@
 bool OSInterface::OS_batteryAvailable(){
   static int bat_avail = -1; //this will not change during a single session - keep later calls fast
   if(bat_avail < 0){
-    int val = getCmdOutput("apm -l").join("").toInt();
-    bat_avail = ((val >= 0 && val <= 100) ? 1 : 0 );
+    bat_avail = (sysctlbyname("hw.acpi.battery.life", &life, &len, NULL, 0) == 0);
   }
   return (bat_avail==1);
 }
 
 float OSInterface::OS_batteryCharge(){
-  int charge = getCmdOutput("apm -l").join("").toInt();
-  if(charge > 100){ charge = -1; } //invalid charge
-  return charge;
+  int life;
+  if ( (sysctlbyname("hw.acpi.battery.life", &life, &len, NULL, 0) != 0) ||
+       (life > 100) )
+    life = -1
+  return life;
 }
 
 bool OSInterface::OS_batteryCharging(){
-  return (getCmdOutput("apm -a").join("").simplified() == "1");
+  if ( (sysctlbyname("hw.acpi.battery.state", &state, &len, NULL, 0) == 0) &&
+       (state == ACPI_BATT_STAT_CHARGING) )
+    return true;
+  else
+    return false;
 }
 
 double OSInterface::OS_batterySecondsLeft(){ //Returns: estimated number of seconds remaining
-  return getCmdOutput("apm -t").join("").toDouble();
+  int min, sec;
+  if ( sysctlbyname("hw.acpi.battery.time", &min, &len, NULL, 0) == 0 )
+    sec = min * 60;
+  else
+    sec = -1
+  return sec;
 }
 
 // = Volume =
...skipping...
--- libLumina/LuminaOS-FreeBSD.cpp.orig 2021-12-26 02:33:45 UTC
+++ libLumina/LuminaOS-FreeBSD.cpp
@@ -9,6 +9,7 @@
 #include <unistd.h>
 #include <sys/types.h>
 #include <sys/sysctl.h>
+#include <dev/acpica/acpiio.h>
 
 #include <QDebug>
 //can't read xbrightness settings - assume invalid until set
@@ -289,31 +290,52 @@ void LOS::systemSuspend(){
 }
 
 //Battery Availability
+// apm command is not available on powerpc or arm
 bool LOS::hasBattery(){
   static int hasbat = -1;
+  int        life;
+  size_t     len = sizeof(life);
   if(hasbat < 0 ){
-    int val = batteryCharge();
-    if(val >= 0 && val <= 100){ hasbat = 1; }
-    else{ hasbat = 0; }
+    if ( sysctlbyname("hw.acpi.battery.life", &life, &len, NULL, 0) == 0 )
+      hasbat = 1;
+    else
+      hasbat = 0;
   }
   return (hasbat==1);
 }
 
 //Battery Charge Level
+// apm command is not available on powerpc or arm
 int LOS::batteryCharge(){ //Returns: percent charge (0-100), anything outside that range is counted as an error
-  int charge = LUtils::getCmdOutput("apm -l").join("").toInt();
-  if(charge > 100){ charge = -1; } //invalid charge
-  return charge;
+  int    life; // sysctl name
+  size_t len = sizeof(life);
+  if ( (sysctlbyname("hw.acpi.battery.life", &life, &len, NULL, 0) != 0) ||
+       (life > 100) )
+     life = -1; //invalid charge
+  return life;
 }
 
 //Battery Charging State
+// apm command is not available on powerpc or arm
 bool LOS::batteryIsCharging(){
-  return (LUtils::getCmdOutput("apm -a").join("").simplified() == "1");
+  int   state;
+  size_t len = sizeof(state);
+  if ( (sysctlbyname("hw.acpi.battery.state", &state, &len, NULL, 0) == 0) &&
+       (state == ACPI_BATT_STAT_CHARGING) )
+    return true;
+  else
+    return false;
 }
 
 //Battery Time Remaining
+// apm command is not available on powerpc or arm
 int LOS::batterySecondsLeft(){ //Returns: estimated number of seconds remaining
-  return LUtils::getCmdOutput("apm -t").join("").toInt();
+  int   min;
+  size_t len = sizeof(min);
+  if ( sysctlbyname("hw.acpi.battery.time", &min, &len, NULL, 0) == 0 )
+    return min * 60;
+  else
+    return -1;
 }
 
 //File Checksums

@outpaddling
Copy link
Contributor Author

Also relates to #349.

@outpaddling
Copy link
Contributor Author

FYI, this seems to have eliminated the minor CPU spikes (usually to around 3%) I had always seen under "top". Since reinstalling with these patches, the CPU stays consistently at a small fraction of a percent.

The patched 1.6.2 port is here, BTW:
https://github.com/outpaddling/freebsd-ports-wip/tree/master/lumina-core

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant