Nivel de carga y estado de salud de la batería de un portátil en GNU/linux

A día de hoy, cualquier combinación de distribución GNU/Linux y entorno de escritorio, por ligera y minimalista que sea, ofrece información del nivel de carga de la batería de un portátil, mostrando un porcentaje de energía disponible con respecto al total y en muchos casos una estimación del tiempo restante en función del tipo de uso que actualmente se está haciendo del sistema. Esta información suele aparecer en un indicador en la barra de estado y además en alguna sección del panel de control. Pero ¿en qué información se basan esos indicadores? ¿Cómo podemos acceder con mayor nivel de detalle a esa información para tener más conocimiento de ella o hacer nuestras propias mediciones?

UPower es un software que proporciona una capa de abstracción para la gestión de energía en equipos con GNU/Linux. Enumera orígenes de energía (baterías, fuentes de alimentación, …), mantiene estadísticas y datos históricos sobre ellos y notifica cuando se producen cambios de estado. Está compuesto de un demonio (upowerd), una API y un conjunto de de herramientas de línea de comandos. El demonio proporciona su funcionalidad a las aplicaciones a través del bus del sistema (mediante el servicio org.freedesktop.UPower, a través de D-Bus,). PolicyKit limita el acceso a la funcionalidad de UPower de iniciar el modo de hibernación o apagar el sistema operativo (freedesktop.upower.policy). El programa cliente de línea de comandos upower puede utilizarse para consultar y monitorizar la información sobre los dispositivos de suministro de energía del sistema. Los entornos de escritorio proporcionan herramientas gráficas para hacer uso de la funcionalidad de UPower, como GNOME Power Manager y Xfce Power Manager.

Vamos a centrarnos en un uso básico del comando upower. Podemos consultar los dispositivos de energía disponibles en el sistema con el comando upower -e o upower --enumerate. Nos mostrará la ruta de acceso a ellos, que luego utilizaremos para obtener más información de un dispositivo en concreto:

$ upower -e
/org/freedesktop/UPower/devices/line_power_AC
/org/freedesktop/UPower/devices/battery_BAT0
/org/freedesktop/UPower/devices/battery_BAT1
/org/freedesktop/UPower/devices/line_power_ucsi_source_psy_USBC000o001
/org/freedesktop/UPower/devices/DisplayDevice

La lista completa de parámetros de todos los dispositivos se puede obtener con upower -d o upower --dump:

$ upower -d
Device: /org/freedesktop/UPower/devices/line_power_AC
  native-path:          AC
  power supply:         yes
  updated:              mar 04 ene 2022 21:03:18 (1451 seconds ago)
  has history:          no
  has statistics:       no
  line-power
    warning-level:       none
    online:              no
    icon-name:          'ac-adapter-symbolic'

. . . 

Device: /org/freedesktop/UPower/devices/battery_BAT1
  native-path:          BAT1
  vendor:               Celxpert
  model:                01AV424
  serial:               4287
  power supply:         yes
  updated:              mar 04 ene 2022 21:27:19 (10 seconds ago)
  has history:          yes
  has statistics:       yes
  battery
    present:             yes
    rechargeable:        yes
    state:               discharging
    warning-level:       none
    energy:              12,57 Wh
    energy-empty:        0 Wh
    energy-full:         19,89 Wh
    energy-full-design:  24,05 Wh
    energy-rate:         4,424 W
    voltage:             11,259 V
    time to empty:       2,8 hours
    percentage:          62%
    capacity:            80,5405%
    technology:          lithium-polymer
    icon-name:          'battery-full-symbolic'
  History (charge):
    1641328039	62,000	discharging
  History (rate):
    1641328039	4,424	discharging

  . . .   

Podemos ver con el comando anterior la situación de carga de la batería con respecto al total que admite actualmente (percentaje: 62%) y la situación aproximada de la salud de la batería, diferenciando entre energy-full (la cantidad de energía que actualmente puede almacenar como máximo) y energy-full-design (la cantidad de energía que puede almacenar por diseño, es decir cuando está nueva).

En este caso se trata de un portátil con dos baterías. Podemos ver información de cada una de ellas con upower -i o upower --show-info seguido de la ruta del componente, que será la devuelta por el comando upower -e:

$ upower -i /org/freedesktop/UPower/devices/battery_BAT0
  native-path:          BAT0
  vendor:               LGC
  model:                01AV489
  serial:               1297
  power supply:         yes
  updated:              mar 04 ene 2022 21:27:19 (10 seconds ago)
  has history:          yes
  has statistics:       yes
  battery
    present:             yes
    rechargeable:        yes
    state:               fully-charged
    warning-level:       none
    energy:              17,24 Wh
    energy-empty:        0 Wh
    energy-full:         18,7 Wh
    energy-full-design:  23,94 Wh
    energy-rate:         1,408 W
    voltage:             12,731 V
    percentage:          100%
    capacity:            72,0134%
    technology:          lithium-polymer
    icon-name:          'battery-full-charged-symbolic'

$ $ upower -i /org/freedesktop/UPower/devices/battery_BAT1
  native-path:          BAT1
  vendor:               Celxpert
  model:                01AV424
  serial:               4287
  power supply:         yes
  updated:              mar 04 ene 2022 21:27:19 (10 seconds ago)
  has history:          yes
  has statistics:       yes
  battery
    present:             yes
    rechargeable:        yes
    state:               discharging
    warning-level:       none
    energy:              14,43 Wh
    energy-empty:        0 Wh
    energy-full:         20,04 Wh
    energy-full-design:  24,05 Wh
    energy-rate:         5,544 W
    voltage:             11,386 V
    time to empty:       2,6 hours
    percentage:          70%
    capacity:            79,7505%
    technology:          lithium-polymer
    icon-name:          'battery-full-symbolic'
  History (rate):
    1640122870	5,544	discharging

Sysfs es un sistema de archivos virtual que proporciona el núcleo de Linux y que exporta información sobre los dispositivos y sus controladores desde el modelo de dispositivos del núcleo hacia el espacio del usuario. Genera una estructura de directorios y archivos que representan los dispositivos en una jerarquía de directorios y cada uno de sus parámetros como un archivo cuyo contenido es el valor actual de dicho parámetro. Además de permitir consultar información de estos dispositivos, también permite modificar algunos de ellos.

Uno de los directorios que expone es /sys/class, que contiene cada clase de dispositivo registrada por el kernel. Las clases de dispositivo describen un tipo funcional de dispositivo, por ejemplo, dispositivos de entrada, dispositivos de red o dispositivos de bloques. Para el tema que nos interesa se puede conocer, por ejemplo, el estado de la batería de un portátil y el estado de la alimentación externa comprobando la información que contienen archivos almacenados dentro del directorio /sys/class/power_supply. Dependiendo del equipo habrá diferentes elementos, pero en el caso de un portátil existirá como mínimo el directorio /sys/class/power_supply/BAT0 que contendrá los parámetros de la batería principal.

$ ls  /sys/class/power_supply/
AC  BAT0  BAT1  ucsi-source-psy-USBC000:001

Si mostramos el directorio correspondiente a la batería 0 (BAT0), nos aparecerá un archivo por parámetro de la batería:

$ ls  /sys/class/power_supply/BAT0
alarm           charge_control_end_threshold    charge_stop_threshold  energy_full         hwmon3        power      serial_number  technology  voltage_min_design
capacity        charge_control_start_threshold  cycle_count            energy_full_design  manufacturer  power_now  status         type        voltage_now
capacity_level  charge_start_threshold          device                 energy_now          model_name    present    subsystem      uevent

Podemos consultar el valor de la carga actual (energy_now), carga total cuando está llena (energy_full) y carga total cuando está llena según su diseño original (energy_full_design), entre otros parámetros, mostrando el contenido de los archivos que se encuentran dentro de ese directorio:

$ cat /sys/class/power_supply/BAT0/status
Discharging

# cat /sys/class/power_supply/BAT0/capacity
70

$ cat /sys/class/power_supply/BAT0/energy_now
14320000

$ cat /sys/class/power_supply/BAT0/energy_full
20610000

$ cat /sys/class/power_supply/BAT0/energy_full_design
24050000

Las aplicaciones utilizan principalmente las llamadas al bus del sistema para obtener los datos que necesitan, pero nosotros de forma muy sencilla podemos obtener la información de la batería a través de estos dos medios: el comando upower o el sistema de archivos sysfs, y utilizarla directamente o a través de scripts.

Referencias