Switch wifi on/off with LED brightness button

Hi!

I’d like to switch my wifi on and off directly at the router itself. As it already has a hardware button (the LED brightness button) I’d like to change its purpose (no need for dimming LEDs with a button in my case).

There is already a thread trying the same (Wifi/LTE button for off/on) but there was no solution coming up and it was closed some years ago.

I tried my luck with the help from https://openwrt.org/docs/guide-user/hardware/hardware.button but I was not able to catch pushes on the LED brightness button so far.

Does anyone know if it would be theoretically possible to reprogramm the use of this button (or expand it with something like a long press) and maybe even has an idea on how to accomplish that? I’m running Turris OS 4.0.3 at the moment.

Thanks a lot in advance!

1 Like

I’m guessing Turris Omnia? You can use rainbow get intensity, poll it regularly and check for change in brightness and react to it by setting brightness back to normal level and executing whatever you need.

nemluvi se tu neco o koze a voze?

2 Likes

Yes, Turris Omnia.

Reacting to a change to the LED brightness is a great idea. I try tinkering around with inotifywait and /etc/rainbow.magic

Will update if I’ll find a solution.

Once upon time @Tangero mentioned that bright control could be reprogrammed to do exactly this… unfortunately he did neither offer more hints nor he made this idea actually work.

I figured out a simple solution based on the idea of @miska:

Add the following to a script, for example /etc/toggle-wifi-button.sh

#!/bin/sh

#-------------------------------------------------------------------------------
# This script toggles wifi within 60 seconds, when the led brightness button is
# pressed.
#
# How this works:
# /usr/bin/rainbow_button_sync.sh runs every minute and writes the actual led
# brightness intensity into /etc/rainbow.magic
#
# When a change to /etc/rainbow.magic gets detected, wifi is toggled.
#
# inotifywait must be installed on the router (opkg install inotifywait).
#-------------------------------------------------------------------------------

observe_rainbow() {
  # detect changes to /etc/rainbow.magic
	inotifywait -qq -e modify /etc/rainbow.magic
}

get_wifi_status() {
	if [[ $(ubus call network.wireless status | jsonfilter -e "@.radio0.up") = "false" ]];
	then
		#wifi is disabled
		disabled=1
	else
		#wifi is enabled
		disabled=0
	fi
}

toggle_wifi() {
	get_wifi_status
	if [ $disabled = 1 ]
	then
		# enable wifi
		wifi up > /dev/null 2>&1
	else
		# disable wifi
		wifi down > /dev/null 2>&1
	fi
}

while observe_rainbow; do
  toggle_wifi
done

Run the script in the background (and add this to /etc/rc.local if you want it to run after a reboot):

/etc/toggle-wifi-button.sh &

This script is very basic and I’m happy for inputs of any sort. Also there is room for many improvements like setting led-brightness back to the normal value, toggle wifi immediately and so on.

Last but not least it would be much nicer to not rely on the /etc/rainbow.magic file and react on pushes to the brightness button directly.

5 Likes

you can also use the i2c-bus to set the button to user mode and grab up to 7 continous button presses. here is an example python3 script, you have to also install python3-smbus (opkg)

use it with caution, as the i2c mcu interface lets you also restart your device and power off usb and so on - if you are not carefull and send wrong commands.

if you ctrl-c the script the default (dimming) mode is restored.

from smbus import SMBus
import atexit
import time

#i2c-1
bus = SMBus(1)

#MCU address
address = 0x2A

@atexit.register
def button_default_mode():
    bus.write_word_data(address, 2, 0x4000)

def button_user_mode():
    bus.write_word_data(address, 2, 0x4040)

def get_button_press_count():
    return bus.read_word_data(address, 1) >> 13

if __name__ == "__main__":
    button_user_mode()
    while True:
        print(get_button_press_count())
        time.sleep(3)
2 Likes

Hi,
thanks for sharing your solution - I used your script to define my own wifi toggling script.
The difference is, that I’m checking directly the intensity of the leds like miska described it so that the toggling is done in 3 seconds…
I also visualize the actual state of wifi on the usr2 led (green / red).
There is one thing that isn’t really nice: pressing the button the intensity decreases and then returns to the value I’ve preset in the script - but for me this isn’t a real problem :slight_smile: .

Would be interesting if my solution by checking every 3 seconds for a change increases the CPU load - honestly I can’t see a very big increase…

#!/bin/sh

#--------------------------------------------------------------------------------------------------------------------
# Script to toggle wifi and visualize state on led usr2
#
# Initial idea and work: klempner - https://forum.test.turris.cz/t/switch-wifi-on-off-with-led-brightness-button/11902/6
# Modified so that the toggling of wifi is done in some seconds (idea: miska from the Turris Team)
# The script first checks the actual intensity of the leds and compares the value with the previous value.
# If the value has changed, toggle wifi, set the color of led usr2 and also reset the intensity of the leds
#
# Script is saved under /usr/bin/ and inserted in rc.local to start when the router starts
#--------------------------------------------------------------------------------------------------------------------

get_wifi_status() {
        if [[ $(ubus call network.wireless status | jsonfilter -e "@.radio0.up") = "false" ]];
        then
                #wifi is disabled
                wifi_disabled=1
        else
                #wifi is enabled
                wifi_disabled=0
        fi
}

toggle_wifi() {
        get_wifi_status
        if [ $wifi_disabled = 1 ]
        then
                # enable wifi
                wifi up > /dev/null 2>&1
                rainbow usr2 green enable
        else
                # disable wifi
                wifi down > /dev/null 2>&1
                rainbow usr2 red enable
        fi
}

#--- Startup ---

# Wait for the system to initialize
sleep 20

# Get actual intensity and save into the variable for the previous value to omit a toggling of wifi on startup
PREV_INTENSITY=$(rainbow get intensity)

#Get wifi state to initalize usr2 led on system start
get_wifi_status

#Set led color according to wifi state during startup
if [ $wifi_disabled = 1 ]
then
        rainbow usr2 red enable
else
        rainbow usr2 green enable
fi


# --- Continuous checking ---

while true; do
  ACT_INTENSITY=$(rainbow get intensity)

  #echo "ACT = $ACT_INTENSITY - PREV = $PREV_INTENSITY"

  if [ "$ACT_INTENSITY" != "$PREV_INTENSITY" ]; then
        toggle_wifi
        rainbow intensity $PREV_INTENSITY
  fi

  sleep 3

done
1 Like

Hi,

I don’t know if anybody is using my script but as with Turris OS 6.0 the rainbow command can’t get the brightness anymore I have modified it a bit.
One question because I’m not really sure about it: is it a problem if i write directly to the file /sys/class/leds/rgb:power/device/brightness? Looking at the source code of rainbow it did not seems to be critical, but I’m really not sure…

Here is the new version:
#!/bin/sh

#--------------------------------------------------------------------------------------------------------------------
# Script to toggle wifi and visualize state on led "indicator-2" - For OS Version >= Turris OS 6.0
#
# Initial idea and work: klempner - https://forum.test.turris.cz/t/switch-wifi-on-off-with-led-brightness-button/11902/6
# Modified so that the toggling of wifi is done in some seconds (idea: miska from the Turris Team)
# The script first checks the actual intensity of the leds and compares the value with the previous value.
# If the value has changed, toggle wifi, set the color of led "indicator-2" and also reset the intensity of the leds 
#
# Script is inserted in rc.local to start when the router starts
#--------------------------------------------------------------------------------------------------------------------

get_wifi_status() {
	if [[ $(ubus call network.wireless status | jsonfilter -e "@.radio0.up") = "false" ]];
	then
		#wifi is disabled
		wifi_disabled=1
	else
		#wifi is enabled
		wifi_disabled=0
	fi
}

toggle_wifi() {
	get_wifi_status
	if [ $wifi_disabled = 1 ]
	then
		# enable wifi
		wifi up > /dev/null 2>&1
		rainbow indicator-2 green enable
	else
		# disable wifi
		wifi down > /dev/null 2>&1
		rainbow indicator-2 red enable
	fi
}

#--- Startup ---

# Wait for the system to initialize
sleep 20

# Get actual intensity and save into the variable for the previous value to omit a toggling of wifi on startup
PREV_INTENSITY=$(cat /sys/class/leds/rgb:power/device/brightness)

#Get wifi state to initalize indicator-2 led on system start
get_wifi_status

#Set led color according to wifi state during startup
if [ $wifi_disabled = 1 ]
then
	rainbow indicator-2 red enable
else
	rainbow indicator-2 green enable
fi


# --- Continuous checking ---

while true; do
  ACT_INTENSITY=$(cat /sys/class/leds/rgb:power/device/brightness)

  if [ "$ACT_INTENSITY" != "$PREV_INTENSITY" ]; then
  	toggle_wifi
	echo $PREV_INTENSITY > "/sys/class/leds/rgb:power/device/brightness"
  fi

  sleep 3

done
1 Like