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
andLedKit.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 sts=4 sw=4 et