User Tools

Site Tools


doc:howto:hardware.button

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/07/03 10:46]
lorema
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.