many routers have one or more buttons and leds; if their default functions dont look good to you, you can change them with openwrt; in this article, we take a router with 1 button and 2 leds, and show how to control the leds with the button;

led

openwrt defines a few triggers for leds, so that, you can turn a led on and off in response to different events; our example has a very simple usage: we use the trigger none, which keeps the light in a constant state;

luci has builtin support for led config, so we can config leds right from the web interface:

  1. log into luci, select System -> LED Configuration;

  2. create 2 leds as follows:

    • Name: this is the user-friendly name of the led; you can set it to any valid name; in this example we set to led0 and led1;

    • LED Name: this is the name identifying a physical led; it typically consists of 3 fields: the hardware name, the color, and the designation, separated by colon; an example is tp-link:green:usb; this makes it easier to select the led we want to use;

    • Default State: this is a checkbox; tick it iff you want the led to be on by default; in our example, we turn on led0 and turn off led1 by default;

    • Trigger: this is the trigger that controls this led on and off; openwrt has defined a few triggers for you; for example, you can use led to indicate link establishment, network activity, etc.; our example uses the simplest trigger none, which always keeps a led in its default state;

  3. click Save & Apply to apply our changes; now led0 should be on and led1 should be off; and uci show system should give output:

    system.@led[0]=led
    system.@led[0].name='led0'
    system.@led[0].sysfs='xxx:xxx:xxx'
    system.@led[0].default='1'
    system.@led[0].trigger='none'
    system.@led[1]=led
    system.@led[1].name='led1'
    system.@led[1].sysfs='xxx:xxx:xxx'
    system.@led[1].default='0'
    system.@led[1].trigger='none'
    

button

openwrt natively supports button handler scripts in /etc/rc.button/; the script name must match the button name; in our example, it is a wps button; so we will create a file /etc/rc.button/wps with the following content (modified from a vanilla script /etc/rc.button/reset):

#!/bin/sh

[ "${ACTION}" = "released" ] || exit 0

. /lib/functions.sh

logger "$BUTTON pressed for $SEEN seconds"

if [ "$SEEN" -ge 2 ]
then
        uci set system.@led[0].default='1'
        uci set system.@led[1].default='0'
        uci commit
        /etc/init.d/led reload
else
        uci set system.@led[0].default='0'
        uci set system.@led[1].default='1'
        uci commit
        /etc/init.d/led reload
fi

return 0

in this script:

  • ACTION is button action;

  • BUTTON is button name;

  • SEEN is the time (in seconds) a button is pressed before it is released;

see doc for details;

test

now reboot the router and test led control with button; after router is powered on, led0 is on and led1 is off; if we press the button for a short time (< 2 seconds), then led0 is off and led1 is on; if we press the button for a long time (>= 2 seconds), then led0 is on and led1 is off; you can change the button handler script to do more than led control, of course;

finally, some routers have a slider, whose value can be read from gpio; when you power on the router, or press the button, you can check the slider value to, for example, use different configs; an example is here; there is a plethora of interesting things you can do here;