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).
- 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