2

I've created a Python program in Linux that would blink the NumLock LED. The code is shown below:

import fcntl
import os
import time

# Define variables for keyboard and NUM_LOCK LED
KDSETLED = 0x4B32
NUM_LED = 0x02

# Open the "keyboard console" for LED toggling
console_fd = os.open('/dev/console', os.O_NOCTTY)

def blink(tme, cnt):
    secs = tme/cnt
    for i in range(cnt):
        fcntl.ioctl(console_fd, KDSETLED, 0)
        time.sleep(secs)
        fcntl.ioctl(console_fd, KDSETLED, NUM_LED)
        if i < cnt - 1:
            time.sleep(secs)

blink(0.5,1)

If it looks vaguly familiar, it's because it came from a similar post here.

It blinks correctly for one of my Power Up! USB Numeric Keypad (Part No.: G54-41403). However, while the program does run without any errors, the LEDs do not blink for my older keyboards (I've also verified that the NUM LOCK does properly). The older keyboards are a Targus Numeric Keypad with USB Hub (Model PAUK10U note that I couldn't find my older model online), and a Rlip Ergonomic Keypad KNP-180.

I checked the Python module python-keyboardleds (link here), and I found that the program accesses the keyboard directly. Specifically, while I access it through /dev/console, the program accesses it through the /dev/input/by-path/. I tried changing the code so that I open the first keyboard on the list, and the same results occurred as before (where there were no errors, and the LED didn't blink on the other keyboard models). The code I made is shown below:

#LEDToggle.py

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

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

def parse_args():
    led_names = list(t + '-lock' for t in ('caps', 'num', 'scroll'))
    ap = argparse.ArgumentParser()
    ap.add_argument('--led', choices=led_names, default=led_names[1],
    help='keyboard LED to use',
    )
    return ap.parse_args()

def blink(tme, cnt):
    secs = tme/cnt
    options = parse_args()
    event_device = glob.glob('/dev/input/by-path/*-event-kbd')[0]
    ledkit = keyboardleds.LedKit(event_device)
    drop_privileges()
    #led = getattr(ledkit, 'num-lock')
    led = getattr(ledkit, options.led.replace('-', '_'))
    for i in range(cnt):
        led.reset()
        print "off"
        time.sleep(secs)
        led.set()
        print "on"
        if i < cnt - 1:
            time.sleep(secs)

blink(5,5)

After research, I suspected that some keyboards are not being called correctly when accessing the /dev/console. When I look into /dev/input/by-path/, I find that the working keyboard is named platform-bcm2708_usb-usb-0:1.3:1.0-event-kbd. Then when I try to connect one of the two non-working keyboards, they have the same name.

I've also tried using the setleds commands in the kernel, as well as calling both the console and tty7 to communicate with the keyboard. Both of these did the same thing; they worked on the Power Up! keyboard and (without any errors) didn't blink on the other two keyboards.

I feel like I am not communicating with these older keyboards correctly. Other than from what I tried, is there any other way to toggle the keyboard LEDs?

Community
  • 1
  • 1
user2125538
  • 147
  • 2
  • 4
  • 15
  • Did you ask this exact same question last week, under a different username? If not, someone else definitely did, so search for that. (Although IIRC, it never got answered, because I suggested the OP take a look at python-keyboardleds, and he said he'd do that and come back later.) – abarnert Mar 25 '13 at 21:48
  • @abarnert This is the same user that posted this question as last week. I am admittedly new to using this, but I felt the previous question I asked last week was changed so much from the original question, that reposing the revised question would make the problem more clear. I was not intentionally trying to violate any rules, or upset anyone in the process – user2125538 Mar 25 '13 at 21:58
  • @abarnert I did try using the `python-keyboardleds` module, and the results were the same. – user2125538 Mar 25 '13 at 21:59
  • It's fine to ask a new question, but it's usually worth linking to the previous one, if for no other reason than to stop someone from closing your new one as a dup. Also, it's probably better to use one account than to create a new one for each question, if for no other reason than to get to the nominal 5 rep or whatever it takes to get to the basic features. – abarnert Mar 25 '13 at 22:17
  • @abarnert Good to know. I'll remember that advice for next time. I actually am using the same account as before. I'm not sure why it would change on me. Either way, thanks for the advice. But going back to the topic, is there another approach for accessing the LEDs on a keyboard? – user2125538 Mar 25 '13 at 22:24
  • You're already using the approach that the linux generic console driver provides. If there were any workaround appropriate to your distro/version/etc., `setleds` would be using it. There are almost certainly no custom drivers for these devices (since they're advertised as Windows-only, and "no-driver-needed plug&play"). So, if there _is_ a way to access the LEDs, you'd have to drop down below the level of the console driver to do it. – abarnert Mar 25 '13 at 22:27

1 Answers1

1

If setleds doesn't work, most likely the problem is that your two old keyboards just don't have programatically-accessible LEDs—or, if they do, they've not accessible through the linux console drivers.

The fact that these are keypads, which are intended to be used along with full keyboards (which usually already have their own LEDs) might have made that seem like a reasonable design decision.

Unless you want to try to communicate with the keyboards directly at the USB level, I think you're done.

abarnert
  • 354,177
  • 51
  • 601
  • 671