1

I have a ThinkPad laptop with dual batteries, and I want to write an indicator app for GNOME which performs an action when the external battery is plugged/unplugged. To read these events I connect to the acpid socket, like so:

#!/usr/bin/env python3
import socket

ACPID_SOCKETFILE = "/var/run/acpid.socket"
RECV_SIZE = 4096

s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
s.connect(ACPID_SOCKETFILE)

try:
    while True:
        data = s.recv(RECV_SIZE)
        print(repr(data))
except:
    s.close()
    raise

And I get output like the following:

b'battery PNP0C0A:01 00000080 00000001\n'
b'battery PNP0C0A:01 00000080 00000001\n'
b'battery PNP0C0A:01 00000003 00000000\n'
b'battery PNP0C0A:01 00000003 00000000\n'
b'battery PNP0C0A:01 00000080 00000001\n'
b'battery PNP0C0A:01 00000080 00000001\n'
b'battery PNP0C0A:01 00000003 00000000\n'
b'battery PNP0C0A:01 00000003 00000000\n'
b'battery PNP0C0A:01 00000001 00000001\n'
b'battery PNP0C0A:01 00000001 00000001\n'
b'battery PNP0C0A:01 00000080 00000001\n'
b'battery PNP0C0A:01 00000080 00000001\n'
b'battery PNP0C0A:01 00000003 00000000\n'
b'battery PNP0C0A:01 00000003 00000000\n'

I figured that the fourth column is 1 if the battery is plugged in, and 0 if it is unplugged. But what exactly do the second and third columns mean? I've tried man acpid, but didn't find any useful information.

  • If you have made it this far then you're better off reading source code of acpid or v2 of acpid – gwillie Jul 27 '15 at 2:51
  • Thanks! I found where the messages are printed in netlink.c: snprintf(buf, sizeof(buf), "%s %s %08x %08x", event->device_class, event->bus_id, event->type, event->data);, but the source of event->type still eludes me... They do not appear to be generated by acpid itself. What would be a good place to find where these constants are defined? – Andrew Sun Jul 27 '15 at 3:19
1

The first column is the device class. The values come from the kernel drivers handling the respective ACPI devices. They are either of the form "class" (e.g. "battery") or "class/subclass" (e.g. "button/power").

The second column is the name the kernel uses for the device. There is a matching folders in /sys/bus/acpi/devices/ for every ACPI device. The general rule for these names is device type:instance number. As described in the kernel documentation, the device type is either

  1. a name assigned by the kernel, starting with LNX, for special devices described in the ACPI tables of your BIOS.
  2. a PnP HID (Plug & Play Hardware ID; a few are defined in section 5.6.7 of the ACPI specification and there are some lists on the internet) for other devices that have an HID assigned in the ACPI DSDT table.
  3. device for any other ACPI device.

The instance number is an incrementing counter to differentiate between different devices of the same type. For example, your primary battery is PNP0C0A:00 and your secondary one is PNP0C0A:01.

The third column is the event code or "Notification Value". They are defined in section 5.6.6 the ACPI specification. 00000001 means "Device Check" (device either appeared or disappeared), 00000003 "Eject Request" and 00000080 "Battery Status Changed".

The fourth column is a supplementary value generated by the kernel driver. The meaning of this column varies for any combination of event code, driver and device type. The Linux ACPI battery driver sets the value on the "Battery Status Changed" event to 1 for "present" and 0 for "not present".

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.