User Tools

Site Tools


doc:howto:hardware.button
The Wiki is getting migrated to a new server, edits are disabled until further notice.

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
doc:howto:hardware.button [2013/01/17 20:02]
veoxwmt
doc:howto:hardware.button [2016/05/31 00:43] (current)
sshambar [procd buttons]
Line 1: Line 1:
 +====== Attach functions to a push button ======
 +There several ways for controlling buttons in OpenWrt.
 +  * [[#​procd_buttons| buttons using procd]]
 +  * [[#​Hotplug_Buttons|Hotplug buttons]], using the hotplug daemon or procd in compatibility mode (hotplug itself was phased out with r36003).
 +  * [[#​HID_buttons|HID buttons]], using ///​dev/​input/​event//​ with an application like triggerhappy.
  
 +
 +
 +| {{:​meta:​icons:​tango:​dialog-information.png?​nolink}} | **Kernel configuration**\\ If a target platform is known to support buttons, appropriate kernel modules are selected by default.\\ If a platform is not known to support buttons, you are required to install various kernel modules yourself such as ''​diag'',​ ''​input-gpio-buttons'',​ ''​gpio-button-hotplug'',​ and others.\\ However, installing various modules will not necessarily yield a successful result. |
 +
 +===== procd buttons =====
 +native button handling in procd is handled by scripts in '''/​etc/​rc.button/​*'''​
 +
 +These scripts receive the **same** environment as older style hotplug buttons received. ​ However, the script files have to be named after the button. ​ I am unaware of a way of getting the button name.  (Other than using hotplug compatible scripts with procd ;)
 +
 +^ Button Action ^ Script Environment ^ Script return value    ^
 +| Press         | ACTION="​pressed" ​  | Seconds before "​timeout"​ |
 +| Held "​timeout"​ seconds | ACTION="​timeout"​ SEEN="<​timeout secs>"​ | n/a |
 +| Release<​sup>​1</​sup> ​    | ACTION="​released"​ SEEN="<​seconds held>"​ | n/a |
 +
 +1 - "​released"​ action is sent on release even if "​timeout"​ has been sent.
 +===== Hotplug Buttons =====
 +|  {{:​meta:​icons:​tango:​48px-outdated.svg.png?​nolink}} | Note that after the introduction of **''​[[doc:​techref:​procd]]''​** into OpenWrt in [[https://​dev.openwrt.org/​changeset/​37132|r37132]] the package ''​hotplug2''​ has been removed from the default packages. ​ However at the time of writing, [[https://​dev.openwrt.org/​changeset/​37336|r37336:​ procd: make old button hotplug rules work until all packages are migrated]] is still in effect. ​ See also [[#​procd.buttons]] |
 +| FIXME | Please read the articles [[doc/​howto/​wifitoggle]],​ [[/​toh/​tp-link/​tl-wr741nd#​buttons]] and [[toh/​linksys/​nslu2/​nslu2.hardware.button]] and eventually merge them into this one article ​ |
 +
 +==== Preliminary steps ====
 +
 +The first step is to find out the internal name of the button you want to use: some images use generic names such as ''​BTN_1'',​ ''​BTN_2'',​ others have more specific ones like ''​reset'',​ ''​wps'',​ etc. Run the following:
 +
 +<code bash>
 +# mkdir -p /​etc/​hotplug.d/​button
 +</​code>​
 +
 +Create the file ''/​etc/​hotplug.d/​button/​buttons''​ with your favorite text editor, paste the following:
 +
 +<code bash>
 +#!/bin/sh
 +logger the button was $BUTTON and the action was $ACTION ​
 +</​code>​
 +
 +Save and exit. Now press the button you want to use, then run ''​logread''​.
 +
 +<code bash>
 +Jan 1 00:01:15 OpenWrt user.notice root: BTN_1   
 +Jan 1 00:01:15 OpenWrt user.notice root: pressed ​  
 +Jan 1 00:01:16 OpenWrt user.notice root: BTN_1    ​
 +Jan 1 00:01:16 OpenWrt user.notice root: released ​
 +</​code>​
 +
 +''​BTN_1''​ is the name of the button you want to use. If you want or need to use another button, replace every instance of ''​BTN_1''​ in the rest of this document with the correct text. From now on, there are several possible approaches: the first uses the ''​00-button''​ script from the ''​atheros''​ target, the other a simpler shell script.
 +
 +**notice**
 +
 +If you want to run programs from hotplug'​s scripts you need to be sure ''​PATH''​ and the like are initialized properly, scripts invoked by hotplug only have a default env. Especially if you install stuff into nonstandard locations like /​opt/​usr/​bin. It's possible by adding ''​. /​etc/​profile''​ after ''#​!/​bin/​sh''​
 +
 +<code bash>
 +#!/bin/sh
 +. /​etc/​profile
 +</​code>​
 +
 +==== Using Atheros'​ 00-button + UCI ====
 +If you've installed the full version of ''​wget'',​ run the following:
 +
 +<code bash>
 +# wget -O /​etc/​hotplug.d/​button/​00-button https://​dev.openwrt.org/​export/​36332/​trunk/​target/​linux/​atheros/​base-files/​etc/​hotplug.d/​button/​00-button
 +</​code>​
 +
 +If you only have ''​wget-nossl''​ and don't want to or can't upgrade, create ''/​etc/​hotplug.d/​button/​00-button''​ with your favorite editor, then paste the following:
 +
 +<code bash>
 +#!/bin/sh
 +. /​lib/​functions.sh
 +do_button () {
 +        local button
 +        local action
 +        local handler
 +        local min
 +        local max
 +
 +        config_get button $1 button
 +        config_get action $1 action
 +        config_get handler $1 handler
 +        config_get min $1 min
 +        config_get max $1 max
 +
 +        [ "​$ACTION"​ = "​$action"​ -a "​$BUTTON"​ = "​$button"​ -a -n "​$handler"​ ] && {
 +                [ -z "​$min"​ -o -z "​$max"​ ] && eval $handler
 +                [ -n "​$min"​ -a -n "​$max"​ ] && {
 +                        [ $min -le $SEEN -a $max -ge $SEEN ] && eval $handler
 +                }
 +        }
 +}
 +
 +config_load system
 +config_foreach do_button button
 +</​code>​
 +
 +Please note that after r34793 /​etc/​functions.sh -> /​lib/​functions.sh so if you are using an old version change it!
 +
 +Save and exit, then issue these commands:
 +
 +<code bash>
 +uci add system button ​   ​
 +uci set system.@button[-1].button=BTN_1
 +uci set system.@button[-1].action=pressed
 +uci set system.@button[-1].handler='​logger BTN_1 pressed'​
 +uci commit system ​
 +</​code>​
 +
 +''​button''​ is the name as the button, ''​action''​ is the event (two values: ''​pressed''​ and ''​released''​),​ handler contains the command line to be run when the event is detected (can be a script as well).
 +
 +You may need to reboot the router the make the change effective (mine would work with the simple shell script just fine but wouldn'​t budge when using the 00-button script --- //Frex 2011/03/25 22:29//). If this works, you can change the handler to something more useful, and add more button handlers.
 +
 +=== Examples ===
 +
 +**Example 1:** //Toggle Wi-Fi radio with a button press//
 +
 +<code bash>
 +uci add system button ​   ​
 +uci set system.@button[-1].button=wps ​   ​
 +uci set system.@button[-1].action=pressed
 +uci set system.@button[-1].handler='​uci set wireless.@wifi-device[0].disabled=1 && wifi'
 +uci commit system ​
 +</​code>​
 +
 +**Example 2:** //Assign two different functions to the same button: short press VS long press. This relies on tracking the //​released//​ event rather than the //pressed// event.//
 +
 +<code bash>
 +uci add system button
 +uci set system.@button[-1].button=BTN_1
 +uci set system.@button[-1].action=released
 +uci set system.@button[-1].handler='​logger timed pressed: 0-3s'
 +uci set system.@button[-1].min=0
 +uci set system.@button[-1].max=3
 +uci add system button
 +uci set system.@button[-1].button=BTN_1
 +uci set system.@button[-1].action=released
 +uci set system.@button[-1].handler='​logger timed pressed: 8-10s'
 +uci set system.@button[-1].min=8
 +uci set system.@button[-1].max=10
 +uci commit system ​
 +</​code>​
 +
 +**Example 3:** //Unmount USB storage using a long-ish press//
 +<code bash>
 +uci add system button
 +uci set system.@button[-1].button=BTN_1
 +uci set system.@button[-1].action=released
 +uci set system.@button[-1].handler="​for i in \$(mount | awk '/​dev\/​sd[b-z]/​ { print \$1}'​);​ do umount \$i; done"
 +uci set system.@button[-1].min=5
 +uci set system.@button[-1].max=10
 +uci commit system ​
 +</​code>​
 +
 +**Example 4:** //Restore defaults//
 +<code bash>
 +config button
 +        option button ​  reset
 +        option action ​  ​released
 +        option handler ​ "​firstboot && reboot"​
 +        option min              5
 +        option max             30
 +</​code>​
 +
 +**Example 5:** //Toggle Wi-Fi using a script//
 +<code bash>
 +config button
 +        option button ​  wps
 +        option action ​  ​released
 +        option handler ​ "/​usr/​bin/​wifionoff"​
 +        option min      0
 +        option max      3
 +</​code>​
 +
 +You'll have to create the file ''/​usr/​bin/​wifionoff''​ and paste this:
 +<code bash>
 +#!/bin/sh
 +SW=$(uci -q get wireless.@wifi-device[0].disabled)
 +[ "​$SW"​ == "​1"​ ] && uci set wireless.@wifi-device[0].disabled=0
 +[ "​$SW"​ == "​1"​ ] || uci set wireless.@wifi-device[0].disabled=1
 +wifi
 +</​code>​
 +
 +Another option for wifionoff is this script (doesn'​t store the state in uci, so it remains what is set in the configuration)
 +You can also call this script eg. from cron, to switch off your wifi at night.
 +<code bash>
 +#!/bin/sh
 +STATEFILE="/​tmp/​wifionoff.state"​
 +
 +if [ $# -eq 1 ]; then
 +  case $1 in
 +    "​up"​|"​on"​)
 +      STATE=off
 +      ;;
 +    "​down"​|"​off"​)
 +      STATE=on
 +      ;;
 +  esac
 +else
 +  if [ ! -e ${STATEFILE} ]; then
 +    STATE=on
 +  else
 +    . ${STATEFILE}
 +  fi
 +fi
 +if [ -z ${STATE} ]; then
 +  STATE=on
 +fi
 +
 +if [ ${STATE} == "​on"​ ]; then
 +  /sbin/wifi down
 +  STATE=off
 +else
 +  /sbin/wifi up
 +  STATE=on
 +fi
 +  ​
 +echo "​STATE=${STATE}"​ > ${STATEFILE}
 +</​code>​
 +
 +**Example 6:** //Set transmission-daemon alt-speed, enable or disable.Short press will activate alt-speed or longer press will deactivate alt-speed and also turns on qss led about speed status on tl-wr1043nd//​
 +
 +Edit your alt-speed limits from transmission-daemon , //​settings.json//​ file.To execute script, you need to install //​transmission-remote//​ package from opkg.
 +<code bash>
 +uci add system button ​   ​
 +uci set system.@button[-1].button=BTN_1
 +uci set system.@button[-1].action=pressed
 +uci set system.@button[-1].handler='​transmission-remote -as'
 +uci add system button ​   ​
 +uci set system.@button[-1].button=BTN_1
 +uci set system.@button[-1].action=pressed
 +uci set system.@button[-1].handler='​echo 1 > /​sys/​class/​leds/​tl-wr1043nd:​green:​qss/​brightness'​
 +uci add system button
 +uci set system.@button[-1].button=BTN_1
 +uci set system.@button[-1].action=released
 +uci set system.@button[-1].handler='​transmission-remote -AS'
 +uci set system.@button[-1].min=1
 +uci set system.@button[-1].max=4
 +uci add system button
 +uci set system.@button[-1].button=BTN_1
 +uci set system.@button[-1].action=released
 +uci set system.@button[-1].handler='​echo 0 > /​sys/​class/​leds/​tl-wr1043nd:​green:​qss/​brightness'​
 +uci set system.@button[-1].min=1
 +uci set system.@button[-1].max=4
 +uci commit system
 +</​code>​
 +
 +==== Leftovers from a previous version ====
 +
 +FIXME
 +
 +<code bash>
 +mkdir -p /​etc/​hotplug.d/​button
 +touch /​etc/​hotplug.d/​button/​00-button
 +</​code>​
 +
 +<code bash>
 +if [ "​$ACTION"​ = "​pressed"​ ]; then
 +    if [ "​$BUTTON"​ = "​BTN_0"​ ]; then BTN_0
 +    elif [ "​$BUTTON"​ = "​BTN_1"​ ]; then BTN_1
 +    fi 
 +fi 
 +</​code>​
 +
 +<code bash>
 +mkdir -p /​etc/​hotplug.d/​button
 +wget -O /​etc/​hotplug.d/​button/​00-button http://​dev.openwrt.org/​export/​21216/​trunk/​target/​linux/​atheros/​base-files/​etc/​hotplug.d/​button/​00-button ​
 +wget -O http://​dev.openwrt.org/​export/​21216/​trunk/​target/​linux/​atheros/​base-files/​etc/​hotplug.d/​button/​00-button
 +</​code>​
 +
 +<code bash>
 +#!/bin/sh
 +[ "​$BUTTON"​ = "​BTN_1"​ ] && [ "​$ACTION"​ = "​pressed"​ ] && {
 +SW=$(uci get wireless.@wifi-device[0].disabled)
 +[ $SW == '​0'​ ] && uci set wireless.@wifi-device[0].disabled=1
 +[ $SW == '​0'​ ] || uci set wireless.@wifi-device[0].disabled=0
 +wifi
 +}
 +</​code>​
 +
 +==== WR1043ND ====
 +If you decide to use the ''​wifitoggle''​ package, you will need to change a few things on the default configuration. The following will work and make the QSS led blink "​slowly"​ when wifi is on:
 +
 +<code bash>
 +uci show wifitoggle
 +uci set wifitoggle.@wifitoggle[0]=wifitoggle
 +uci set wifitoggle.@wifitoggle[0].led_enable_trigger=timer
 +uci set wifitoggle.@wifitoggle[0].persistent=1
 +uci set wifitoggle.@wifitoggle[0].button=BTN_1
 +uci set wifitoggle.@wifitoggle[0].led_sysfs=tl-wr1043nd:​green:​qss
 +uci set wifitoggle.@wifitoggle[0].led_enable_delayon=2000
 +uci set wifitoggle.@wifitoggle[0].led_disable_default=1
 +uci set wifitoggle.@wifitoggle[0].led_enable_delayoff=3000
 +uci set wifitoggle.@wifitoggle[0].timer=0
 +</​code>​
 +
 +:!: //You can probably get similar behaviour with [[doc:​uci:​system#​wifi.activity|phy0tpt]] trigger.//
 +===== HID buttons =====
 +
 +==== triggerhappy ====
 +To manage the router buttons and also other **HID buttons** (i.e pad buttons or keys of an usb device) we can use an application like triggerhappy.
 +=== Installation ===
 +  - Install the **triggerhappy** package and the **kmod-hid** kernel module
 +  - list your available buttons: execute<​code bash>thd --dump /​dev/​input/​event*</​code>​press your buttons \\ ''​EV_KEY ​ KEY_WPS_BUTTON ​ 1       /​dev/​input/​event0
 +# KEY_WPS_BUTTON ​       1       ​command
 +EV_KEY ​ KEY_WPS_BUTTON ​ 0       /​dev/​input/​event0
 +# KEY_WPS_BUTTON ​       0       ​command
 +EV_KEY ​ KEY_VOLUMEDOWN ​ 1       /​dev/​input/​event1
 +# KEY_VOLUMEDOWN ​       1       ​command
 +EV_KEY ​ KEY_VOLUMEDOWN ​ 0       /​dev/​input/​event1
 +# KEY_VOLUMEDOWN ​       0       ​command''​
 +  - Now associate your buttons to commands or scripts \\ //path /​etc/​triggerhappy/​triggers.d/​example.conf//​ <code bash>​KEY_WPS_BUTTON 1 /​etc/​mywifiscript.sh
 +KEY_VOLUMEUP 1 amixer -q set Speaker 3%+
 +KEY_VOLUMEDOWN 1 amixer -q set Speaker 3%-</​code>​
 +  - run triggerhappy \\ <code bash>/​etc/​init.d/​triggerhappy start</​code>​
 +  - enable triggerhappy permanently\\ <code bash>/​etc/​init.d/​triggerhappy enable</​code>​
 +
 +==== Notes ====
 +  * triggerhappy repeats commands twice: see bug https://​dev.openwrt.org/​ticket/​14995
 +  * kernel modules: ​ **kmod-hid** and **kmod-hid-generic** both should be installed\\ The kmod-hid-generic kernel module must be installed for buttons on USB devices such as USB sound cards to work in OpenWrt trunk. Only then the /​dev/​input/​event0 node for the buttons was created on the DIR-505 router with attached USB sound card. <​code>​
 +[   ​31.720000] input: C-Media USB Headphone Set   as /​devices/​platform/​ehci-platform/​usb1/​1-1/​1-1:​1.3/​input/​input0
 +[   ​31.760000] hid-generic 0003:​0D8C:​000C.0001:​ input,​hidraw0:​ USB HID v1.00 Device [C-Media USB Headphone Set  ] on usb-ehci-platform-1/​input3
 +[   ​31.800000] usbcore: registered new interface driver usbhid
 +[   ​31.800000] usbhid: USB HID core driver
 +</​code>​This is also noted in https://​dev.openwrt.org/​ticket/​12631
 +
 +==== cmdpad ====
 +Another simpler application to manage buttons.