Working WiFi switch with scripting

Discussion in 'Linux' started by yodersj, Aug 26, 2008.

  1. yodersj

    yodersj

    Joined:
    Aug 21, 2008
    Messages:
    72
    Likes Received:
    0
    Location:
    NC
    Caveats:
    • I am a Fedora user, but this should be fairly generic across all distros. I'm able to read most things posted here and translate where necessary (and wouldn't be as far as I am without some of the posts here).[/*:m:1ibbuksd]
    • These instructions assume you have wifi working and fairly stable. Now you're just ready to use the hardware switch on the laptop so you can save some power drain when not using wifi (my powertop shows ~0.5 difference).[/*:m:1ibbuksd]

    Much of this was gleaned from two scripts, rm_driver.sh and add_driver.sh, that came with the Acer Linpus install as well as the .XHkeys file in the Linpus default 'user' home directory. It's been tweaked to my liking, adjust to suit your situation as needed.

    Requirements:
    1) A program to trap specific keycodes and execute a specific program when a specific keycode is seen. The Acer Linpus is using xhkeys. I've chosen, for now, to use xhotkeys.
    2) Might need rights and knowledge to edit the sudoers file. Depends on how your distro is setup.
    3) Knowledge of how to create/save a file to '/usr/local/bin/'. This isn't intended to be a full how-to and you could create the files in a place where your regular user account has rights to do so (ala '~/bin/').
    4) Adjust paths to any commands shown to match where they are on your system.

    Basic steps:
    1) Create the "turn off" and "turn on" scripts in the '/usr/local/bin/' directory. Let's pretend we call them the same as on the Acer Linpus install:
    • "turn off": /usr/local/bin/rm_driver.sh[/*:m:1ibbuksd]
    • "turn on": /usr/local/bin/add_driver.sh[/*:m:1ibbuksd]

    2) Make them executable:
    Code:
    sudo chmod 0755 /usr/local/bin/rm_driver.sh
    sudo chmod 0755 /usr/local/bin/add_driver.sh
    3) Test them by hand in a terminal with your normal account:
    Code:
    /usr/local/bin/rm_driver.sh
    /usr/local/bin/add_driver.sh
    4) Debug as necessary. If you have to type in a password when running the 'sudo' command at any time from when you first login, see below for some example ways to setup the sudoers file. You could do a quick and dirty '[user] ALL=(ALL) NOPASSWD: ALL' for debugging purposes only. I don't recommend leaving it that way, though.

    5) Once you can run the scripts by hand without any errors and the wifi is correctly stopped and started, you can now setup your chosen "hotkey" program. The keycodes that should be trapped are 234 for the "off" script and 233 for the "on" script. When I setup xhotkeys I:
    • Ran, in a terminal, 'xhotkeys -c' to get the configuration screen.[/*:m:1ibbuksd]
    • In the configuration screen I clicked on the "Add" button.[/*:m:1ibbuksd]
    • In the "Add" window I typed the name (for example "Wifi-Off"). Then I clicked on the "Change Hotk" button and moved the wifi switch (in this case I knew wifi was on, so the code generated was for the off command). Lastly in the "Command" box I typed in the full path to the script I wanted executed (again, for the off example of /usr/local/bin/rm_driver.sh).[/*:m:1ibbuksd]
    • The "Test command" button won't do anything unless the xhotkey daemon is running. You could start this in another terminal window by typing only 'xhotkey'. Leave the window running the daemon open to see if there are any errors when testing.[/*:m:1ibbuksd]
    • Repeat for the "on" script and trapping the "on" code.[/*:m:1ibbuksd]

    6) Once everything is debugged, locked down, and confirmed working with your "hotkey" program then set it to run when you login to X-Windows and enjoy.

    The "turn off" script:
    Code:
    #!/bin/sh
    # Disable the wireless drivers
    #
    # Requires sudo rights to the following commands
    RMOD=/sbin/rmmod
    IFCFG=/sbin/ifconfig
    WLANCFG=/usr/bin/wlanconfig
    
    # Sudo rights not required for the following commands
    SDO=/usr/bin/sudo
    LMOD=/sbin/lsmod
    GRP=/bin/grep
    AWK=/usr/bin/awk
    
    ###################
    $SDO $IFCFG ath0 down
    sleep 1
    $SDO $WLANCFG ath0 destroy
    # New order
    $SDO $RMOD ath_pci
    sleep 1
    for d in `$LMOD | $GRP ^wlan_ | $AWK '{print $1}'`; do
      $SDO $RMOD $d
    done
    sleep 1
    for d in `$LMOD | $GRP ^ath_ | $AWK '{print $1}'`; do
      $SDO $RMOD $d
    done
    $SDO $RMOD wlan
    
    exit 0
    The "turn on" script:
    Code:
    #!/bin/sh
    # Enable wireless drivers
    #
    # Requires sudo rights to the following commands
    MODP=/sbin/modprobe
    SYSCT=/sbin/sysctl
    IFCFG=/sbin/ifconfig
    
    # Sudo rights not required for the following commands
    SDO=/usr/bin/sudo
    
    ###################
    # Load the driver
    $SDO $MODP ath_pci
    # Turn the LED back on
    $SDO $SYSCT -q -w dev.wifi0.softled=1
    $SDO $SYSCT -q -w dev.wifi0.ledpin=3
    # Bring the interface up
    $SDO $IFCFG ath0 up
    
    exit 0
    Locked down sudoers settings example (replace [user] with the account you login as):
    Code:
    Cmnd_Alias ATHDIFCFG = /sbin/ifconfig ath0 down
    Cmnd_Alias ATHDWLANCFG = /usr/bin/wlanconfig ath0 destroy
    Cmnd_Alias ATHDRMODW1 = /sbin/rmmod wlan_*
    Cmnd_Alias ATHDRMODA = /sbin/rmmod ath_*
    Cmnd_Alias ATHDRMODW2 = /sbin/rmmod wlan
    Cmnd_Alias ATHUMODP = /sbin/modprobe ath_pci
    Cmnd_Alias ATHUSYSCTL1 = /sbin/sysctl -q -w dev.wifi0.softled\=1
    Cmnd_Alias ATHUSYSCTL2 = /sbin/sysctl -q -w dev.wifi0.ledpin\=3
    Cmnd_Alias ATHUIFCFG = /sbin/ifconfig ath0 up
    [user]   ALL = NOPASSWD: ATHDIFCFG, ATHDWLANCFG, ATHDRMODW1, ATHDRMODA, ATHDRMODW2, ATHUMODP, ATHUSYSCTL1, ATHUSYSCTL2, ATHUIFCFG
    Semi-locked down sudoers example settings (replace [user] with the account you login as):
    Code:
    Cmnd_Alias MODP = /sbin/modprobe
    Cmnd_Alias SYSCT = /sbin/sysctl
    Cmnd_Alias IFCFG = /sbin/ifconfig
    Cmnd_Alias RMOD = /sbin/rmmod
    Cmnd_Alias WLANCFG = /usr/bin/wlanconfig
    [user]   ALL = NOPASSWD: MODP, SYSCT, IFCFG, RMOD, WLANCFG
     
    yodersj, Aug 26, 2008
    #1
  2. yodersj

    tomo88

    Joined:
    Aug 20, 2008
    Messages:
    27
    Likes Received:
    0
    Wow thanks, this looks great, I just installed Ubuntu on my A110 and unfortunately the switch is useless and would be real good for power saving purposes.

    Unfortunately I've been using Linux for only a week (that is, since I got my aspire) so I wouldn't have a clue on how to do this haha, but i'll try read up and learn how cuz it looks real useful.

    Thanks again
     
    tomo88, Aug 26, 2008
    #2
  3. yodersj

    qball

    Joined:
    Aug 14, 2008
    Messages:
    42
    Likes Received:
    0
    The switch always kills the wifi (for me). it also causes the powerusage to drop.
    But I agree, this is a nice script.
    Now if we could manage to turn on/off the wifi led (left one) on the aspire.
     
    qball, Aug 26, 2008
    #3
  4. yodersj

    tomo88

    Joined:
    Aug 20, 2008
    Messages:
    27
    Likes Received:
    0
    so just by flickin it with the stock ubuntu install it kills it? awsome.

    when the computer starts up tho, is the wireless already on or still in the current status it was during shutdown (be it on or off)?
     
    tomo88, Aug 26, 2008
    #4
  5. yodersj

    mvincent99

    Joined:
    Aug 25, 2008
    Messages:
    1
    Likes Received:
    0
    You indicated that you are a fedora user, Which version of fedora are you using ... I am trying F8 ... any comments on using these scipts.
     
    mvincent99, Aug 27, 2008
    #5
  6. yodersj

    yodersj

    Joined:
    Aug 21, 2008
    Messages:
    72
    Likes Received:
    0
    Location:
    NC
    F8 w/ KDE. Working on making a custom live cd,
     
    yodersj, Aug 28, 2008
    #6
  7. yodersj

    spinnekopje

    Joined:
    Aug 13, 2008
    Messages:
    83
    Likes Received:
    0
    These scripts look very interesting, although I still need to take a look at my sudoers file (it keeps asking a passwd). Can that be something with the autologin I use or did I forget to run a certain command (I just rebooted)?

    There is one more thing that would make it very interesting to use: make an OSD notice when switching and let the nm_applet immediatly know that the wireless is switched on/off.
     
    spinnekopje, Aug 30, 2008
    #7
  8. yodersj

    ags

    Joined:
    Jul 22, 2008
    Messages:
    34
    Likes Received:
    0
    Have a look at this post http://www.aspireoneuser.com/forum/viewtopic.php?f=28&t=2191 which gets the OSD going.

    Having looked at this I can say a bit more: The OSD and the wifi control scripts are in the 'linpus-hotkey rpm'. The OSD is controlled by Xhotkeys and a small binary 'hotkey-splash', but the wifi scripts are not. In one of the boot-up rc files the wifi switch is set with 'xsetkeycodes' to 158/159, so somewhere else in the system the keycodes 158 and 159 are trapped and the wifi scripts in the 'linpus-hotkey rpm' must be run.

    It would be easy to have the wifi script call the binary 'hotkey-splash' for the OSD. Indeed this was what Linpus originally did, you can see it commented out in either add_driver.sh or rm_driver.sh (can't recall which).

    Linpus has the same problem with delay in nm_applet, so I guess they weren't able to fix it either.
     
    ags, Aug 30, 2008
    #8
  9. yodersj

    spinnekopje

    Joined:
    Aug 13, 2008
    Messages:
    83
    Likes Received:
    0
    The Linpus didn't run long enough to test that, but I wonder whether it is possible to control the nm_applet from a script. Otherwise I would like to add a call that does the same as right-click - disable wireless on the nm_applet (or whatever it is called in English, mine is in Dutch).

    It seems to me that it should work instantly, certainly if combined with the scripts from this thread... However I didn't find any information about changing options for the nm_applet from the command line.
     
    spinnekopje, Sep 3, 2008
    #9
  10. yodersj

    ags

    Joined:
    Jul 22, 2008
    Messages:
    34
    Likes Received:
    0
    Thanks for the great script. I've spent several days playing around with it and hopefully made some improvements.

    I finally realised that although Linpus have included add_driver.sh and rm_driver.sh in their distribution, they don't actually use them! Also the source rpm's don't match what it is the final computer! Alas, the Linpus scripts are red herrings...

    The two scripts are replaced with a single script that accepts a command line option of either 'off' or 'on'.

    Code:
    #!/bin/sh
    PATH=/bin:/sbin:/usr/bin:/usr/local/bin
    
    if [ "x$1" = "x" ]; then
      echo "No off|on command given"
      exit 1
    fi
    
    case $1 in
    
      off)
        # Disable the wireless drivers
        # keycode 234
    
        # basic command : notify-send -t 3000 -u normal "message"
        notify-send -i /usr/share/pixmaps/splash/splash_wifi_off.png \
                    --hint=int:'x':340 -h int:'y':200 \
                    -u normal -t 1000 " "
    
        # tell Network-Manager the network is down
        dbus-send --system --type=signal \
                  --dest=org.freedesktop.NetworkManager \
                  /org/freedesktop/NetworkManager \
                  org.freedesktop.NetworkManager.setWirelessEnabled \
                  boolean:false
    
        sleep 1
    
        wlanconfig ath0 destroy
        rmmod ath_pci
    
        ;;
    
      on)
    
        # Enable wireless drivers
        # keycode 233
    
        notify-send -i /usr/share/pixmaps/splash/splash_wifi_on.png \                                       
                    --hint=int:'x':340 -h int:'y':200 -u normal  \
                    -t 1000 " "
    
        # load the drivers
        modprobe ath_pci
        modprobe wlan_scan_sta
    
        # turn the LED back on
        sysctl -q -w dev.wifi0.softled=1
        sysctl -q -w dev.wifi0.ledpin=3
    
        sleep 1
    
        # tell Network-Manager the network is up
        dbus-send --system --type=signal \
                  --dest=org.freedesktop.NetworkManager \
                  /org/freedesktop/NetworkManager \
                  org.freedesktop.NetworkManager.setWirelessEnabled \
                  boolean:true
    
        ;;
    
      *)
         echo "Unknown command"
         exit 1
         ;;
    esac
    
    exit 0
    
    Now to get this script working you need to apt-get a couple of packages:
    Code:
    sudo apt-get install libnotify-bin libnotify1
    
    In my case one of these packages was already installed.

    You also need to have appropriate graphics installed in the path given in the two libnotify commands. In my case I just used the Linpus graphics as found in the OneLinux package. This gives a nice OSD just like Linpus.

    Details of libnotify are in this eeuser forum thread

    We also prod the network manager via dbus when the state changes. Finding the D-BUS specification for network manager is not easy, they seem to have gone out of there way to make it hard. A reference is in this gnome mail list message.

    The libnotify and dbus-send commands really are all one line!

    Finally, the script needs to be run as root. I did this by adding the script name to /etc/sudoers. You should edit sudoers with the command visudo, however this uses the vi editor - which is not for the unfamiliar. An easier approach is to use nano:
    Code:
    sudo env EDITOR=nano visudo
    
    When saving the file saved will be 'sudoers.tmp' (until visudo checks the syntax).

    I added the following:
    Code:
    Cmnd_Alias WIFI=/usr/local/bin/wifi_switch.sh
    asimpson ALL=NOPASSWD: WIFI
    
    The NOPASSWD line must be the last line in the file as commands are read top to bottom, and later commands overwrite the earlier.

    Use the switch in your keybindings with either:
    sudo wifi_switch.sh off
    sudo wifi_switch.sh on
    (No password required)

    That's it. Enjoy!
     
    ags, Sep 5, 2008
    #10
  11. yodersj

    yodersj

    Joined:
    Aug 21, 2008
    Messages:
    72
    Likes Received:
    0
    Location:
    NC
    Code:
    Alas, the Linpus scripts are red herrings...
    Many thanks. I've now switched my scripts over, though I had to add the 'ifdown ath0' and 'rmmod wlan_scan_sta' to the down or my NetworkManager would just revive itself. I'm also still using specific sudo calls rather than allowing sudo to the script itself. In fact I also made two more for the brightness and touchpad calls. I'm now 'splashd' and 'hotkey_splash' free.

    aa1-brightness.sh [down|up]:
    Code:
    #!/bin/sh
    PATH=/bin:/sbin:/usr/bin:/usr/local/bin
    
    NFSEND=/usr/bin/notify-send
    # Where icons are kept
    PICPATH=/usr/local/share/pixmaps/aa1
    
    # Text to display
    DOWNTH="Brightness down"
    DOWNTB="The LCD monitor brightness has been reduced"
    UPTH="Brightness up"
    UPTB="The LCD monitor brightness has been increased."
    
    if [ "x$1" = "x" ]; then
      echo "No up|down command given"
      exit 1
    fi
    
    case $1 in
    
      down)
        # Display brightness down alert
        # keycode 239
    
        # basic command : notify-send -t 3000 -u normal "message"
        $NFSEND -i $PICPATH/splash_brightness_down.png \
                -u normal -t 1000 "$DOWNTH" "$DOWNTB"
    
        ;;
    
      up)
    
        # Display brightness up alert
        # keycode 123
    
        # Display message
        $NFSEND -i $PICPATH/splash_brightness_up.png \
                -t 1000 "$UPTH" "$UPTB"
    
        ;;
    
      *)
         echo "Unknown command"
         exit 1
         ;;
    esac
    aa1-touchpad.sh [off|on]:
    Code:
    #!/bin/sh
    PATH=/bin:/sbin:/usr/bin:/usr/local/bin
    
    NFSEND=/usr/bin/notify-send
    # Where icons are kept
    PICPATH=/usr/local/share/pixmaps/aa1
    
    # Text to display
    OFFTH="Touchpad off"
    OFFTB="The touchpad has been turned off"
    ONTH="Touchpad on"
    ONTB="The touchpad has been turned on."
    
    if [ "x$1" = "x" ]; then
      echo "No on|off command given"
      exit 1
    fi
    
    case $1 in
    
      off)
        # Display touchpad off alert
        # keycode 192
    
        # basic command : notify-send -t 3000 -u normal "message"
        $NFSEND -i $PICPATH/splash_touchpad_off.png \
                -u normal -t 1000 "$OFFTH" "$OFFTB"
    
        ;;
    
      up)
    
        # Display touchpad on alert
        # keycode 191
    
        # Display message
        $NFSEND -i $PICPATH/splash_touchpad_on.png \
                -t 1000 "$ONTH" "$ONTB"
    
        ;;
    
      *)
         echo "Unknown command"
         exit 1
         ;;
    esac
    Do note the above does not position the icon in the middle of the screen, so adjust as needed. Of course one could just combine all three scripts into one, with adjustment to the case calls. Now I just need to see if the lvdsvga.sh script needs any tweaks, other than switching to use libnotify.
     
    yodersj, Sep 7, 2008
    #11
  12. yodersj

    yodersj

    Joined:
    Aug 21, 2008
    Messages:
    72
    Likes Received:
    0
    Location:
    NC
    Here's my version of the AA1 Linpus' lvdsvga.sh script. This is what is triggered by Fn+F5 (keycode 248) and walks through the various vga on/off + lcd on/off combinations.

    I placed mine in '/usr/local/bin/aa1-lvdsvga.sh':
    Code:
    #!/bin/sh
    
    # Switch between VGA and LCD
    # See here for additional things that can be done with xrandr
    # [url]http://www.thinkwiki.org/wiki/Xorg_RandR_1.2[/url]
    
    XRANDR=/usr/bin/xrandr
    NFSEND=/usr/bin/notify-send
    PICPATH=/usr/local/share/pixmaps/aa1
    STATUSFLAG=/tmp/.lvdsvga_flag
    SHOWTIME=5000
    VGASTATUS=
    LASTSTATUS=
    CURRENTSTATUS=
    
    # Text to display
    VGATH="VGA on"
    VGATB="The VGA connector has been activated and the LCD deactivated"
    LCDTH="LCD on"
    LCDTB="The LCD has been activated and the VGA connector deactivated"
    LVTH="VGA + LCD"
    LVTB="Both LCD and VGA are now activated"
    NVGATH="No VGA connection"
    NVGATB="Unable to detect a monitor connected to the VGA adaptor. Please check the connections and that the monitor is on."
    
    # Has a status been recorded?
    if [ ! -e $STATUSFLAG ]; then
            LASTSTATUS="0"
    else
            LASTSTATUS="`cat $STATUSFLAG`"
    fi
    
    # Is a VGA monitor connected?
    $XRANDR |grep -q "^VGA disconnected"
    VGASTATUS=$?
    if [ $VGASTATUS == 0 ]; then
            $NFSEND -i $PICPATH/splash_vga.png \
                    -u normal -t $SHOWTIME "$NVGATH" "$NVGATB"
            $XRANDR --output VGA --off --output LVDS --auto
            CURRENTSTATUS=0
            echo $CURRENTSTATUS > $STATUSFLAG
            exit
    fi
    
    # First time, enable both LCD and VGA
    if [ "$LASTSTATUS" == "0"  ]; then
            $NFSEND -i $PICPATH/splash_lvds_vga.png \
                    -u normal -t $SHOWTIME "$LVTH" "$LVTB"
            $XRANDR --auto
            CURRENTSTATUS=1
            echo $CURRENTSTATUS > $STATUSFLAG
    fi
    
    # Second time, switch LCD off and VGA on
    if [ "$LASTSTATUS" == "1"  ]; then
            $NFSEND -i $PICPATH/splash_vga_only.png \
                    -u normal -t $SHOWTME "$VGATH" "$VGATB"
            $XRANDR --output LVDS --off --output VGA --auto
            CURRENTSTATUS=2
            echo $CURRENTSTATUS > $STATUSFLAG
    fi
    
    # Third time, switch VGA off and LCD on
    if [ "$LASTSTATUS" == "2"  ]; then
            $NFSEND -i $PICPATH/splash_lvds_only.png \
                    -u normal -t $SHOWTIME "$LCDTH" "$LCDTB"
            $XRANDR --output VGA --off --output LVDS --auto
            CURRENTSTATUS=0
            echo $CURRENTSTATUS > $STATUSFLAG
    fi
    
    exit 0
    The way it has been done you can add your own "status" setups, rather than just the three shown above.
     
    yodersj, Sep 13, 2008
    #12
  13. yodersj

    Casao

    Joined:
    Aug 9, 2008
    Messages:
    28
    Likes Received:
    0
    Hey guys, I'm really digging these scripts, thanks for putting them out there.

    Question though - can you go back and explain exactly how to bind the wifi switch - specifically in ubuntu if possible? I tried running xhotkeys -c, telling it to grab input and flicking the switch, however, this doesn't work for me. Can anyone explain exactly how to do this?

    Thanks
     
    Casao, Sep 16, 2008
    #13
  14. yodersj

    ags

    Joined:
    Jul 22, 2008
    Messages:
    34
    Likes Received:
    0
    Well, I must admit I tried xhotkeys and I couldn't make it work. I read all the documentation and I was still confused. In the end I just installed xbindkeys from the Ubuntu repository and I found that much easier to use.

    The following command prints out a default configuration file to the screen:

    Code:
    xbindkeys --defaults
    
    You can save the file as a your own template like this:

    Code:
    xbindkeys --defaults > $HOME/.xbindkeysrc
    
    The leading '.' means it a hidden file, so you won't see it in a file listing unless you enable viewing of hidden files.

    There's a good article on configuring at this link http://www.debian-administration.org/articles/52 The article explains it better than I can.

    To check that I had the right keys, I used xev, though I see that xbindkeys can do it too. With xev, a little white box appears. You have to put the mouse pointer in the box, then push the keys (xev also records mouse movements).

    Finally, since I'm using Xubuntu, I put xbindkeys into my startup programs. This makes xbindkeys functional each time we start up.
     
    ags, Sep 17, 2008
    #14
  15. yodersj

    Casao

    Joined:
    Aug 9, 2008
    Messages:
    28
    Likes Received:
    0
    Thanks for this, it'll be helpful. I ended up figuring out how to get xhotkeys to work (key codes were 233 and 234 and I had an example to play around with), I managed to tie it in with Syco's OSD from one of the other posts and editted it to use Splashd, which you might want to consider - it looks a lot nicer/cleaner than using libnotify. Just displays the image in the center like Linpus did.
     
    Casao, Sep 17, 2008
    #15
Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.