python-keyboardleds 0.3.3 documentation

python-keyboardleds 0.3.3 documentation

Contents

API

class keyboardleds.LedKit(device_path)
Parameters:device_path – path to a device: either a terminal (/dev/tty or /dev/ttyN) or an input device /dev/input/eventN).
caps_lock

A Led instance for the Caps Lock key.

scroll_lock

A Led instance for the Scroll Lock key.

num_lock

A Led instance for the Num Lock key.

class keyboardleds.Led

Users are not supposed to instantiate this class themselves. Instead, they should use LedKit.caps_lock, LedKit.scroll_lock and LedKit.num_lock attributes.

get()

Return true if the led is turned on.

Return type:bool
Raises:NotImplementedError if the underlying device is not a terminal
set()

Turn the led on.

reset()

Turn the led off.

toggle()

True the led on if it was off; turn if off otherwise.

Raises:NotImplementedError if the underlying device is not a terminal

Example

import argparse
import glob
import grp
import os
import pwd
import re
import subprocess
import time

import keyboardleds


def drop_privileges():
    uid = pwd.getpwnam('nobody').pw_uid
    gid = grp.getgrnam('nogroup').gr_gid
    os.setgid(gid)
    os.setuid(uid)


def main(options):
    event_device = glob.glob('/dev/input/by-path/*-event-kbd')[0]
    ledkit = keyboardleds.LedKit(event_device)
    drop_privileges()
    led = getattr(ledkit, options.led.replace('-', '_'))
    temperature_re = re.compile('^ +temp[0-9]+_input: ([0-9.]+)$')
    try:
        while True:
            alert = False
            sensors = subprocess.Popen(
                ['sensors', '-u'],
                stdout=subprocess.PIPE
            )
            for line in sensors.stdout:
                line = line.rstrip()
                line = line.decode('ASCII', 'replace')  # make Python 3.X happy
                match = temperature_re.match(line)
                if match is not None:
                    temperature = match.group(1)
                    temperature = float(temperature)
                    if (options.temperature_limit < temperature
                            < options.bogus_temperature_limit):
                        alert = True
            sensors.wait()
            if alert:
                i = 0
                while i * options.blink_period < options.poll_period:
                    if i & 1 == 0:
                        led.set()
                    else:
                        led.reset()
                    time.sleep(options.blink_period)
                    i += 1
                led.reset()
            else:
                time.sleep(options.poll_period)
    finally:
        led.reset()


def parse_args():
    led_names = list(t + '-lock' for t in ('caps', 'num', 'scroll'))

    class default:
        temperature_limit = 75.0
        bogus_temperature_limit = 200.0
        poll_period = 5.0
        blink_period = 0.2

    ap = argparse.ArgumentParser()
    ap.add_argument('-t', '--temperature-limit', metavar='<temp>', type=float,
        default=default.temperature_limit,
        help='temperatures above this limit will trigger the alert (default: {0:.0f} deg C)'.format(default.temperature_limit),
    )
    ap.add_argument('--bogus-temperature-limit', metavar='<temp>', type=float,
        default=default.bogus_temperature_limit,
        help='temperatures above this limit will be consider bogus, and thus ignored (default: {0:.0f} deg C)'.format(default.bogus_temperature_limit),
    )
    ap.add_argument('--led', choices=led_names, default=led_names[0],
        help='keyboard LED to use',
    )
    ap.add_argument('--poll-period', metavar='<time>', type=float,
        default=default.poll_period,
        help='how often to poll sensors (default: {0:.1f} s)'.format(default.poll_period),
    )
    ap.add_argument('--blink-period', metavar='<time>', type=float,
        default=default.blink_period,
        help='how often to blink when alert is on (default: {0:.1f} s)'.format(default.blink_period),
    )
    return ap.parse_args()

if __name__ == '__main__':
    options = parse_args()
    main(options)

# vim:ts=4 sw=4 et

Contents