Sysfs issues with battery.el in emacs

Hi everyone,

I noticed that battery.el (battery, display-battery-mode) in Emacs is nonfunctional on the pocket reform (displaying N/A for all values) despite sysfs exposing correct battery metrics in /sys/class/power_supply/BAT0.

The cause of this seems to be that the detection logic in battery.el seems to rely on what value POWER_SUPPLY_PRESENT holds in uevent, but as it doesn’t exist the detection logic fails. I’m not sure if this is an issue with how the battery is exposed to sysfs or a bug in battery.el by assuming that POWER_SUPPLY_PRESENT is a given?

I came up with a few lines of an advice function to bend the detection logic of battery-linux-sysfs in battery.el to check for "POWER_SUPPLY_NAMEinstead ofPOWER_SUPPLY_PRESENT` which isn’t ideal but allows me to calculate load and remaining time values:

(defun mnt-battery-detection (orig-fun &rest args)
  "Override battery detection in `battery-linux-sysfs` to use POWER_SUPPLY_NAME."
	(let ((battery-detected nil))
    (dolist (dir (battery--find-linux-sysfs-batteries))
      (with-temp-buffer
        (ignore-errors
          (insert-file-contents (expand-file-name "uevent" dir) nil nil nil t))
        (goto-char (point-min))
        (when (re-search-forward "POWER_SUPPLY_NAME=\\(.*\\)" nil t)
          (setq battery-detected t))))
    (if battery-detected
	(apply orig-fun args)
      '((?L . "N/A") (?B . "N/A") (?p . "N/A")))))

(advice-add 'battery-linux-sysfs :around #'mnt-battery-detection)

I don’t know enough on sysfs and how uevent is composed to make an educated guess whether that’s expected behavior. Maybe the workaround is helpful for folks who came across the same detection issue in battery.el.

Cheers!

1 Like

Me neither but @nanocodebug wrote it and might know more. :slight_smile:

I think I used an existing battery implementation at the time as a reference, what properties a battery module implements are all over the place.

In this case adding POWER_SUPPLY_PROP_PRESENT (presumably always set to 1, as I don’t think there is a way to dynamically detect this with the current data sent from the system controller) in the mntreform battery module would satisfy emacs.

From the different battery meter programs in various DEs I’ve examined - many of them all have a long list of logic for handling what properties batteries expose or not. emacs might be focused on the POWER_SUPPLY_PROP_PRESENT because of systems that have multiple swappable batteries.

2 Likes

Would that look somewhat like this?

--- a/lpc/reform2_lpc.c
+++ b/lpc/reform2_lpc.c
@@ -84,6 +84,7 @@ static enum power_supply_property bat_props[] = {
        POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
        POWER_SUPPLY_PROP_CHARGE_NOW,
        POWER_SUPPLY_PROP_CHARGE_EMPTY,
+       POWER_SUPPLY_PROP_PRESENT,
 };
 
 static struct power_supply_desc bat_desc = {
@@ -529,6 +530,10 @@ static int get_bat_property(struct power_supply *psy,
                val->intval = (buffer[2] | buffer[3] << 8) * 1000;
                break;
 
+       case POWER_SUPPLY_PROP_PRESENT:
+               val->intval = 1;
+               break;
+
        default:
                val->intval = POWER_SUPPLY_CHARGE_TYPE_NONE;
                ret = -EINVAL;
3 Likes

:smiley: yes it would look exactly like that

4 Likes

@theesm could you try building the lpc module with above patch and see if that fixes the issue for you? Thanks!

1 Like

Sure thing! I was away from computers for a few days, but will probably be able to do so either today or tomorrow and report back!