flak rss random

backlight battery indicator

The last few models of Thinkpads are sadly devoid of indicators. How do you tell if caps lock is on? Type something and see if it matches expectations. If it happens to be the lock screen, loltastic. More importantly, how do you know if AC power has accidentally been disconnected and the battery is running low? The red dot on the opposite side of the lid isn’t much use.

It’s possible to use some sort of desktop environment status bar, but I prefer a low thrills environment. I don’t need a big honking battery icon distracting me. Accordingly, I have only a small (text) battery display in the corner. It’s there when I need it, but unobtrusive. The only problem is if I think I’m plugged into the wall, but I’m not, I won’t be checking battery and may not notice even as the situation grows dire.

A more obvious alert system is to blink the screen and even keyboard backlights. It’s somewhat distracting (that’s good) if I’m trying to hurriedly finish a task, but far less impeding than some popup alert.

Every minute we check the apm status. If unplugged and low on battery, we turn the screen down (not off) and the keyboard backlight up for three seconds to draw attention to the system. Then we reset it.

#include <sys/ioctl.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#include <machine/apmvar.h>
#include <dev/wscons/wsconsio.h>

int
main(int argc, char **argv)
{
        struct apm_power_info info;
        struct wsdisplay_param disp;
        struct wskbd_backlight kb;
        int apmfd, consfd, kbfd;
        int dispval, kbval;


        apmfd = open("/dev/apm", O_RDONLY);
        consfd = open("/dev/ttyC0", O_RDWR);
        kbfd = open("/dev/wskbd0", O_RDWR);

        while (1) {
                ioctl(apmfd, APM_IOC_GETPOWER, &info);
                if (info.ac_state == 0 &&
                    info.battery_life < 15) {
                        disp.param = WSDISPLAYIO_PARAM_BRIGHTNESS;
                        ioctl(consfd, WSDISPLAYIO_GETPARAM, &disp);
                        dispval = disp.curval;
                        disp.curval = disp.minval;
                        ioctl(consfd, WSDISPLAYIO_SETPARAM, &disp);

                        ioctl(kbfd, WSKBDIO_GETBACKLIGHT, &kb);
                        kbval = kb.curval;
                        kb.curval = kb.max;
                        ioctl(kbfd, WSKBDIO_SETBACKLIGHT, &kb);

                        sleep(3);

                        disp.curval = dispval;
                        ioctl(consfd, WSDISPLAYIO_SETPARAM, &disp);
                        kb.curval = kbval;
                        ioctl(kbfd, WSKBDIO_SETBACKLIGHT, &kb);
                }
                sleep(60);
        }
        return 0;
}

Should work on most newer laptops.

Previous adventures in backlighting.

Posted 28 Aug 2016 02:43 by tedu Updated: 09 Sep 2016 21:02