Sunday, November 29, 2015

Switch my wifi router off when not in use (WR703N TP-link)

Automatic wifi shutdown when idle on a small WRT router

The script below runs on my OpenWRT wifi router (a cheap but effective $20 TP-Link TL-WR703N, which I flashed with OpenWRT -- see the how to here).



It is configured as a wifi router, when switched on.

But when no one connects to it, it will blink its led for a while before it shuts down by itself. So it does not waste useless energy, it is more secure at home and we live in one less wifi network.




Here is the script, saved as ''/etc/init.d/wifi_idle_shutdown'':
''
#!/bin/sh /etc/rc.common

START=98

#
# Automatically shut down when WLAN0 is left unused (specially made for OpenWrt wifi relays)
# No shutdown occurs if there is a remote SSH conection to some 192.168.x.x
#

wifi_rx()
{
        # returns the RX byte count of WLAN0
        ifconfig | sed -e '/./{H;$!d;}' -e 'x;/wlan0/!d;' |sed -n '/RX bytes/s/[^0-9]*\([0-9]*\).*/\1/p'
}

led()
{
        # set the WR703N led state
        echo "$1" > /sys/class/leds/tp-link\:blue\:system/brightness
}

idle_check()
{
        delay_before_off=240 # 1200 for 20 minutes
        elapsed=0
        rxprev=`wifi_rx`
        while true; do

                led 1
                sleep 4
                if ! grep -q "ESTABL.*192\.168\..*sport=22" /proc/net/nf_conntrack; then
                        # No SSH connection - slowly blink and count time
                        led 0
                        sleep 1
                        elapsed=`expr $elapsed + 5`

                        # No shutdown will occur if an SSH connection exists with 192.168.0.100
                        if [ "$elapsed" -gt "$delay_before_off" ]; then
                                # After some time, check if wifi really was used
                                rxnew=`wifi_rx`
                                if [ "$rxnew" -eq "$rxprev" ]; then
                                        echo "Wifi idle suicide about to happen"
                                        # Notify the user we are goind to die
                                        s=0
                                        while [ `wifi_rx` -eq "$rxprev" ]; do
                                                led 0; sleep 1; led 1; sleep 1 # blink fast when in "end of life" mode
                                                s=`expr $s + 2`
                                                if [ "$s" -gt 480 ]; then
                                                        led 0
                                                        echo "Wifi idle suicide committed"
                                                        poweroff
                                                fi
                                        done
                                fi
                                rxprev=`wifi_rx`
                        fi
                fi
        done
}

start()
{
        echo "wifi_idle_shutdown started"
        idle_check &
}

stop()
{
        pid=`ps|egrep '[r]c.common.*wifi_idle_shutdown'|awk '{print $1}'`
        test -n "$pid" && kill $pid && echo "wifi_idle_shutdown stopped"
        for i in 1 2 3; do led 1; sleep 1; led 0; sleep 1; done
}
''

And you need to add this link so it runs when the router boots:
''
ln -s /etc/rc.d/init.d/wifi_idle_shutdown /etc/rc.d/S99wifi_idle_shutdown
''