Older ThinkPads had built-in accelerometers so they could detect falls and protect the hard disk. It’s really easy to get access to the accelerometer data in Linux: just install tp_smapi and then load the hdaps module with sudo modprobe hdaps (or add it to the list of modules to be loaded at boot in /etc/modules or /etc/modules-load.d/modules.conf). You should then be able to get the accelerometer output from the file /sys/devices/platform/hdaps/position, which will contain a single line of the form (<roll>,<pitch>)\n where roll and pitch are numbers. If the only acceleration of your ThinkPad is due to gravity you can work out the roll and pitch angles from these. On my x220, holding the keyboard dead level (i.e. in a plane perpendicular to the direction of gravity) gives readings of (505, 505), and the individual readings run from about 360 to 650 as the angle varies from -90 to 90 degrees.

A fun thing to do with the accelerometer is to use it to control your computer through gestures. I will show you how to write a very short Python script so that if you tilt the ThinkPad left or right, you move to the previous or next workspace (in i3wm, but it will adapt to your preferred window manager). There are some (old) more complex scripts linked here.

First we will write a generator to return the content of the accelerometer data file:

def follow(file):
    while True:
        file.seek(0)
        line = file.readline()
        yield line

This lets us get the accelerometer readings in a for loop. Now all we need to do is look for a roll to the left or the right and send the appropriate key event. The easiest way I know to do this is using xdotool. I have i3wm set up so that ctrl+alt+Right and ctrl+alt+Left move to the next and previous workspaces, and to simulate pressing these keys we just run xdotool key ctrl+alt+Right or xdotool key ctrl+alt+Left. We’ll also need to debounce by pausing briefly after a left or right tilt is detected so that the same tilt doesn’t send lots of key events, which we can do using the sleep method in the standard library’s time module.

import os   # for sending system commands
import time # for waiting a fixed amount of time

thresh = 15 # experiment to get a good tilt threshold
with open('/sys/devices/platform/hdaps/position') as f:
    lines = follow(f)
    for line in lines: # "(<roll>,<pitch>)\n"
        roll, pitch = map(int, line[1:-2].split(","))
        if roll > 505 + thresh: # roll right
            os.popen("xdotool key ctrl+alt+Right")
            time.sleep(0.5) # avoid generating multiple events from the same tilt
        elif roll < 505 - thresh: # roll left
            os.popen("xdotool key ctrl+alt+Left")
            time.sleep(0.5)
        time.sleep(0.2) # experiment for a good value

That’s it!