Shell Script To Control Belkin WeMo’s

It’s no surprise I’m a huge fan of home automation and tech toys, and I recently picked up a pair of Belkin WeMo’s.

You **have** to set them up with the app they supply for smartphones, but after that I hoped I could find a way to control them directly. Belkin has collected quite a few negative reviews for these devices, and it’s a shame, because the hardware seems real solid.  It’s their current apps that leave a LOT to be desired.  Clearly the issues they’re having getting the app side right are driving down the reviews.  Fortunately, I could care less how the app experience is, since I only needed it to initially deploy the devices, and planned from the get-go to write my own code to control them.

Numerous folks have written tools to control some of the functions of these, but everything I came across was dependent on other libraries, was incomplete, or didn’t work when I tested it.  I like plain-old vanilla shell scripts that I can just run from any local machine, and I’ve hacked up various XML snippets I’ve found and just rely on curl for the following script that I put together:

#!/bin/sh
#
# WeMo Control Script
#
# Usage: ./wemo_control IP_ADDRESS ON/OFF/GETSTATE/GETSIGNALSTRENGTH/GETFRIENDLYNAME
#
#

IP=$1
COMMAND=$2

PORTTEST=$(curl -s $IP:49152 | grep “404″)

if [ "$PORTTEST" = "" ]
then
PORT=49153
else
PORT=49152
fi

if [ "$1" = "" ]
then
echo “Usage: ./wemo_control IP_ADDRESS ON/OFF/GETSTATE/GETSIGNALSTRENGTH/GETFRIENDLYNAME”
else

if [ "$2" = "GETSTATE" ]

then

curl -0 -A ” -X POST -H ‘Accept: ‘ -H ‘Content-type: text/xml; charset=”utf-8″‘ -H “SOAPACTION: \”urn:Belkin:service:basicevent:1#GetBinaryState\”" –data ‘<?xml version=”1.0″ encoding=”utf-8″?><s:Envelope xmlns:s=”http://schemas.xmlsoap.org/soap/envelope/” s:encodingStyle=”http://schemas.xmlsoap.org/soap/encoding/”><s:Body><u:GetBinaryState xmlns:u=”urn:Belkin:service:basicevent:1″><BinaryState>1</BinaryState></u:GetBinaryState></s:Body></s:Envelope>’ -s http://$IP:$PORT/upnp/control/basicevent1 |
grep “<BinaryState”  | cut -d”>” -f2 | cut -d “<” -f1 | sed ’s/0/OFF/g’ | sed ’s/1/ON/g’

elif [ "$2" = "ON" ]

then

curl -0 -A ” -X POST -H ‘Accept: ‘ -H ‘Content-type: text/xml; charset=”utf-8″‘ -H “SOAPACTION: \”urn:Belkin:service:basicevent:1#SetBinaryState\”" –data ‘<?xml version=”1.0″ encoding=”utf-8″?><s:Envelope xmlns:s=”http://schemas.xmlsoap.org/soap/envelope/” s:encodingStyle=”http://schemas.xmlsoap.org/soap/encoding/”><s:Body><u:SetBinaryState xmlns:u=”urn:Belkin:service:basicevent:1″><BinaryState>1</BinaryState></u:SetBinaryState></s:Body></s:Envelope>’ -s http://$IP:$PORT/upnp/control/basicevent1 |
grep “<BinaryState”  | cut -d”>” -f2 | cut -d “<” -f1

elif [ "$2" = "OFF" ]

then

curl -0 -A ” -X POST -H ‘Accept: ‘ -H ‘Content-type: text/xml; charset=”utf-8″‘ -H “SOAPACTION: \”urn:Belkin:service:basicevent:1#SetBinaryState\”" –data ‘<?xml version=”1.0″ encoding=”utf-8″?><s:Envelope xmlns:s=”http://schemas.xmlsoap.org/soap/envelope/” s:encodingStyle=”http://schemas.xmlsoap.org/soap/encoding/”><s:Body><u:SetBinaryState xmlns:u=”urn:Belkin:service:basicevent:1″><BinaryState>0</BinaryState></u:SetBinaryState></s:Body></s:Envelope>’ -s http://$IP:$PORT/upnp/control/basicevent1 |
grep “<BinaryState”  | cut -d”>” -f2 | cut -d “<” -f1

elif [ "$2" = "GETSIGNALSTRENGTH" ]

then

curl -0 -A ” -X POST -H ‘Accept: ‘ -H ‘Content-type: text/xml; charset=”utf-8″‘ -H “SOAPACTION: \”urn:Belkin:service:basicevent:1#GetSignalStrength\”" –data ‘<?xml version=”1.0″ encoding=”utf-8″?><s:Envelope xmlns:s=”http://schemas.xmlsoap.org/soap/envelope/” s:encodingStyle=”http://schemas.xmlsoap.org/soap/encoding/”><s:Body><u:GetSignalStrength xmlns:u=”urn:Belkin:service:basicevent:1″><GetSignalStrength>0</GetSignalStrength></u:GetSignalStrength></s:Body></s:Envelope>’ -s http://$IP:$PORT/upnp/control/basicevent1 |
grep “<SignalStrength”  | cut -d”>” -f2 | cut -d “<” -f1

elif [ "$2" = "GETFRIENDLYNAME" ]

then

curl -0 -A ” -X POST -H ‘Accept: ‘ -H ‘Content-type: text/xml; charset=”utf-8″‘ -H “SOAPACTION: \”urn:Belkin:service:basicevent:1#ChangeFriendlyName\”" –data ‘<?xml version=”1.0″ encoding=”utf-8″?><s:Envelope xmlns:s=”http://schemas.xmlsoap.org/soap/envelope/” s:encodingStyle=”http://schemas.xmlsoap.org/soap/encoding/”><s:Body><u:ChangeFriendlyName xmlns:u=”urn:Belkin:service:basicevent:1″><FriendlyName>Pool Filter</FriendlyName></u:ChangeFriendlyName></s:Body></s:Envelope>’ -s http://$IP:$PORT/upnp/control/basicevent1 |
grep “<FriendlyName”  | cut -d”>” -f2 | cut -d “<” -f1

else

echo “COMMAND NOT RECOGNIZED”
echo “”
echo “Usage: ./wemo_control IP_ADDRESS ON/OFF/GETSTATE/GETSIGNALSTRENGTH/GETFRIENDLYNAME”
echo “”

fi

fi

Copy/Paste or download here: wemo_control.sh

Usage is:   ./wemo_control IP_ADDRESS ON/OFF/GETSTATE/GETSIGNALSTRENGTH/GETFRIENDLYNAME and the functions are pretty self-explanatory.

The usual disclaimer applies.  I don’t write code for a living and there’s probably gross inefficiencies and poor syntax, but it WORKS.

Enjoy :P

  • Karim Aissa Baccouche

    August 11th, 2013

    Hi! I’ve been looking for a way to control my new Wemo with this kind of solution. I found this page but for a reason your code did not work. I get a ./wemob.sh: 23: ./wemob.sh: Syntax error: redirection unexpected -error constantly when trying to make it work. :(

  • Rich

    August 12th, 2013

    Hi Karim. Based on the line number, I think it’s a word wrap issue from the copy/paste. Make sure when you grab the code there’s aren’t extra lines due to lines being too long and wrapping.

  • Karim Aissa Baccouche

    August 12th, 2013

    I’m still at a beginner stage what it comes to scripting. I kindly ask you, if there is any possibility, would it be possible for you to provide the readers to a “raw” file?
    Nice website by the way.

  • Rich

    August 13th, 2013

    Hi Karim. I added a direct download of the script from the site under the code block.

  • Karim Aissa Baccouche

    August 13th, 2013

    Ouah! Thank you Rich for your help! It works like the “toilets of a train”, a finnish expression that means that it works perfectly. Now, I can really start playing around with this peace of hardware.

  • Rich

    August 14th, 2013

    Hi Karim. VERY glad to hear it’s working for you now.

  • Mike Mylenbusch

    August 15th, 2013

    Not sure if you’ve tested with the latest firmware, but your CURL command didn’t work for me. Here’s an updated version that works.

    curl -0 –silent -A “CyberGarage-HTTP/1.0″ -H ‘Accept: ‘ -H ‘Content-type: text/xml; charset=”utf-8″‘ -H “SOAPACTION: \”urn:Belkin:service:basicevent:1#GetBinaryState\”" -H “Content-Length: 299″ –data ‘1′ http://$IP:$PORT/upnp/control/basicevent1 | grep “” -f2 | cut -d “<" -f1 | sed 's/0/OFF/g' | sed 's/1/ON/g'

  • Miljbee

    August 16th, 2013

    Here is what I found using packet capture on android.
    This request turns on my wall switch.

    POST /upnp/control/basicevent1 HTTP/1.0
    Content-Type: text/xml; charset=”utf-8″
    HOST: 192.168.1.120
    Content-Length: 334
    SOAPACTION: “urn:Belkin:service:basicevent:1#SetBinaryState”

    1

    You can get the corresponding C# code here :
    https://docs.google.com/uc?export=download&id=0B3RTucUBY2bwVFZsYU5teUNEVEk

  • Rob

    November 6th, 2013

    Any idea how to turn this into an applescript? I’m on a Mac, and I’m struggling to figure out how to use the scripts posted above.

    Compared to Philips Hue, WeMo is really frustrating, which is odd since it’s so much simpler of a device.

  • wgscott

    December 7th, 2013

    Hi Rob:

    Your can run the shell script from an applescript using the “do shell script” Applescript command. Everything else you would type on a the command-line goes between quotes after the do shell script Applescript command.

  • ceemjay

    January 20th, 2014

    I have just started a forum for people who are interested in directly accessing and controlling a WeMo and as a place to collate and store relevant information.

    Do please take a look and contribute as you are able.

  • ceemjay

    January 20th, 2014

    Forgot to say a big thank you to Rich for his work — I have used this to create a simple web page to turn on and off a WeMo, Happy to share with anyone who is interested,

    Would be particularly keen to hear from anyone who has successfully downloaded the rules (program).

  • ceemjay

    January 25th, 2014

    Should have added that I have setup a forum http://wemo.forumatic.com/ for the WeMo do please take a look and contribute to increase the knowledge of the community

  • Rob

    May 21st, 2014

    Every time I run this script, it stalls for a few minutes before finally returning a result of “”

    I’m guessing the issue is the port. I’m on OSX. How can I figure out what port my WeMo is using?

  • Donald Burr

    July 14th, 2014

    Great script! I’ve modified it a bit, and have added some new features as well as fixed some bugs.

    * auto detection of the port works much better now. For some reason, instead of returning a 404 when using an incorrect port, my WeMo would just sit there and not respond until curl eventually times out (this is possibly a change they made in a newer firmware?) I changed the call to curl to enforce a timeout of 1 second (if your wemo takes longer than that to respond, it’s probably seriously messed up)
    * added an option so that you can force the port to use by specifying the IP address as “IP_ADDRESS:PORT” (e.g. 192.168.24.40:49153)
    * commands no longer need to be entered in all uppercase
    * GETSTATE will cause the shell script to exit with status code 0 if the wemo is off, or 1 if the wemo is on – useful for when this script is called from other scripts
    * There was a typo in GETFRIENDLYNAME; you were actually using SetFriendlyName in the actual command and so were always setting the WeMo’s friendly name to “Pool Filter”.

    You can download the updated script here:

    https://dl.dropboxusercontent.com/u/169813/wemo.gz

  • Rich

    July 14th, 2014

    Great work, thanks!

  • Milton

    July 14th, 2014

    Excuse my English ..
    In addition to the options ON / OFF / GetState / GETSIGNALSTRENGTH / GETFRIENDLYNAME
    Should exister an option to Reboot, this is for the case that the WIFI is connected to Wemo .. do not you think?

    Regards, Milton

  • Tom Painter

    July 21st, 2014

    this is great!
    Can’t believe how bad the app is! even the new one.
    this solved a huge problem for me
    thanks to everyone involved.
    Tom

  • York

    August 7th, 2014

    Donald, thanks for make the script available. I tried it and it worked well. But later when I tried again, it doesn’t respond. In the meantime I can still use the Android app to see the state and control WeMo. I have two WeMo switches. One may work but the other doesn’t. I haven’t found out why. Sometimes they both works. I can always ping them.

    The firmware version is WeMo_US_2.00.4494.PVT, same for both WeMo switches.

    Any idea why this happens?

  • Jonathan Greenblatt

    August 24th, 2014

    Your script worked great for a while then the port magically changed to one outside the range you had. I think you need to modify your script to take the http url without the path and add a discovery script to find devices. Below is the discovery script, if you would like the discover script and the modified control script I can email that for you to post here. You need to install gssdp-discover for this to work, gssdp-discove comes with the linux repo. Here is the script:

    #!/bin/bash
    function getName {
    curl -0 -A ” -X POST -H ‘Accept: ‘ -H ‘Content-type: text/xml; charset=”utf-8″‘ -H “SOAPACTION: \”urn:Belkin:service:basicevent:1#GetFriendlyName\”" –data ” -s $1/upnp/control/basicevent1 | grep “” -f2 | cut -d “<" -f1
    }

    gssdp-discover -n 2 -t urn:Belkin:service:basicevent:1 | egrep " Location: " | while read a b c; do
    url=${b%/*}
    name="`getName ${url}`"
    echo ${url} ${name}
    done

  • Jonathan Greenblatt

    August 24th, 2014

    The script did not paste correctly above due to HTTP tags but you get the idea with the gssdp-discover which I combined with friendly name query from your script. As I said I can email the two scripts.

  • Dan

    September 4th, 2014

    Has anyone tested this code with a Wemo Light Switch?

    Thanks.

  • Dan

    September 14th, 2014

    I’ve confirmed that the same code that’s used to control Wemo Switches also works for Wemo Light Switches.

  • Dash

    September 19th, 2014

    Hi Jonathan,
    I am doing a project using the WeMo Insight. So I was using the curl script on moderntoil.com.
    Hence can I request you to email me the discover script and the modified control script so that it can ease my work a lot.

    Thanks

    Regards,
    Dash

  • Dash

    September 19th, 2014

    Forgot to mention my mail id is arnabdash92@yahoo.com

  • Roberto

    September 24th, 2014

    Great work man!
    I’ve just bought a Wemo and i’m looking for a script that controls it from my raspberry.

    I will use it!

  • Mirx

    November 20th, 2014

    Awesome script, i was playing around with it recently, but just after the last update in the last week or so, my wemo seems to have stopped responding to calls from this script or curl calls. Any one else experience the same?

  • Rob

    November 21st, 2014

    Mirx, I wonder if that’s why I’m having trouble too. I was coming here to ask for help.

    I’ve downloaded the script (as well as Donald Burr’s script from a few comments above) and moved them to usr/local/bin on my Mac. I don’t know if it matters, but I made sure the script has 755 permissions. I then typed the following into terminal with no effect:

    /usr/local/bin/wemo http://10.0.1.7 ON

    Nothing happens. I know the IP address is correct. I specifically assigned it in order to prevent it from changing. I know my WeMo works. I can trigger it on & off with my iPhone or with the WeMo Toolbar Mac app I found on the web. Also, if I mistype the command (OFFG instead of OFF, for example), I a COMMAND NOT RECOGNIZED error, which tells me the script is functioning. But none of the commands are working.

    Am I missing something here?

  • Rich

    November 21st, 2014

    Rob, at least with my version of the script, you dont’ specify “http”. It’s just the IP address. So, in your example it would be:

    /usr/local/bin/./wemo_control 10.0.1.7 ON

  • Rob

    November 21st, 2014

    If I enter /usr/local/bin/wemo 10.0.1.7 ON in Terminal (without the http://), it stalls for quite a while before eventually returning as if it did nothing (or, if I enter a mistyped command such as ONG instead of ON, it stalls for quite a while before returning with COMMAND NOT RECOGNIZED.

  • Rob

    November 21st, 2014

    I mention the part about mistyping a command in order to show that the script is obviously installed and seems to be functioning.

  • Rob

    November 21st, 2014

    Ah, forget it. I installed Ouimeaux, and it works like a charm.

  • Jack Lawry

    December 5th, 2014

    I have modified this script and uploaded it here:
    http://www.codedpixel.co.uk/wemo/wemo_control.sh.zip

    This adds additional port lookups as explained on another forum post http://wemo.forumatic.com/viewtopic.php?f=2&t=5 – Note: I have set this to use 49154 first as this is the port my switch is now using and if first it runs much faster – there is a comment you can uncomment if you want to check the port yours is using – just search for this line “# echo “INFO: Connected to” $1″:”$PORT.” and remove the #

    I have also added the additional function to “TOGGLE” so if the switch is OFF it turns ON and if ON it turns it OFF.

    Hope this helps someone :-)

  • Jide

    December 26th, 2014

    Hey,
    Has anyone had any luck using the new wemo long press feature in the light switch? I can’t seem to find the section of the SOAP api that controls/detects when it is pressed.

    Thanks!

  • Rob

    March 2nd, 2015

    I’m having an issue with this script. Every time I run it, the device accumulates a FIN_WAIT_2 state that I see when I run netstat. Every call to the script generates a persistent connection that just hangs, waiting to be closed. From reading about the FIN_WAIT_2 state, it seems that it’s waiting for a signal (ACK?) to come back. Could someone amend the script to clean up the leftovers on the device?

  • Wagner

    June 1st, 2015

    First Thanks to everyone who put this tool together.

    I have modified this script to fix the PORT parameter not working and add support for WeMo Link LED Bulbs.
    http://guino.home.insightbb.com/wemo_control.sh

    Hope it helps someone out there!

  • Victor

    July 30th, 2015

    Thank you for the script. I have also modified your script and made the following changes:

    - Lower case options
    - Fixed the get name option
    - Changed the output of on|off
    - Added a network scan for devices that displays IP and name

    The script can be found here – https://github.com/mississaugalug/bash/blob/master/Scripts/Networking/wemo_control.sh

  • AK

    August 24th, 2015

    Loving the work you folk have done for controlling our wemo’s. I wish I had the coding skills many of you have. Any chance of someone providing some code or editing existing an existing script to obtain the status of a Wemo Maker sensor (triggered/not triggered)?

  • Michael Rogers

    August 27th, 2015

    It looks like the newest firmware (2.00.9399) breaks the script, hanging on the PORTTEST line. Hard-coding the port number (49153 for me) gets it working again.

  • Vincenzo

    September 16th, 2015

    Hi Michael, could you post your working script somewhere because I’m not that good in coding.
    TIA

  • Hightitude

    September 29th, 2015

    Great job guys!! Appreciate the work.

  • cpuwiz22

    October 4th, 2015

    @Michael Rogers
    I’m using Victor’s script and…
    I added a time out and that seemed to fix it (-y 1)

    PORTTEST=$(curl -s -y 1 “$IP”:49152 | grep “404″)

    that way if it can’t find it- times out goes to next

  • TaskerUser112

    October 13th, 2015

    Thank you for the modified script, Donald Burr. In case there are others that want to use Tasker to control their Wemo device, I’d like to share how I got this script to work. I only have one Wemo light switch, and so I changed the script to use the port that I know is used. Then I was able to use Tasker in Android to set my own custom rules, by using the “Run Shell” task with the command:

    sh /sdcard/Download/wemo_control.sh 192.168.1.12 ON

    This is the only way I got Tasker to function with Wemo in a way that is consistent and immediate.

  • JM

    December 10th, 2015

    Anyone having luck with this script on .98xx series firmware? I just get “Unknown option”.

  • DaveJ

    April 14th, 2016

    I use Wagner’s script (June 1 2015) and it works perfectly with a Wemo Switch (Original not Insight). My firmware version listed in the Wemo app is WeMo_WW_2.00.10062.PVT-OWR-SNS”

  • ex

    May 23rd, 2016

    Just got a WeMo Switch Insight today, this still seem to work for that model. (Assume it’s a newer version/hav had some firmware updates.)

    Using mine as a bandaid solution for a host that randomly dies and need hard reboots now and then.

  • Wayne Manion

    September 14th, 2016

    This works perfectly with my WeMo Insight.

  • Mike

    January 21st, 2017

    Thanks for this! I’m using it with ha-bridge, now I can control my mix of hue, wemo, and x10 lights with Hue apps.

  • Song

    February 23rd, 2017

    I haven’t yet bought a WEMO insight.

    I was planning on buying one and using “wemo_control.sh” to control it and measure power consumption watt-hour through it. If it works, I would like to try designing a smartphone app for it.

    So my question is… Would a standard WEMO insight off the shelf work fine with this shell? If not, Is there a particular model number that this shell works on?

    Thanks.

  • Larry

    June 15th, 2017

    I am able to connect to the Wemo and get the state, signal strength, and name. Does anyone know how I would go about getting the Power usage in watts? I would love to be able to request from the Wemo how much energy is currently being used at this moment.

    Thank you.

  • Vincent

    August 17th, 2017

    Does anyone knows what is the request to get the power consumption of a wimo insight ?
    thanks

  • Shed Denizen

    November 16th, 2018

    Ancient tech now, but FWIW, here’s yet more bash to make a WeMo to MQTT bridge: https://shedlabsblog.wordpress.com/2018/11/14/wemo-smart-plug-to-mqtt/

  • Lehi

    November 21st, 2018

    It is 11/21/2018 and this script is working great for me, thank you for it!

  • Soynerdito

    November 25th, 2018

    This script worked very well on my esp8266 emulating a wemo device. Had to change the port to the actual port I am using. Apart of that, well done my friend. Great post and thread comments.
    And the c# implementation, have to look into it. need a few mods for my liking, but thanks also it is a great start.

  • dedelajoie

    December 16th, 2018

    I found a simple -though ugly- way to get power consumption over a wemo insight switch

    this is a simple modification of rich’s script

    just add before the “else” something like :
    elif [ "$2" = "GETPOWER" ]

    then

    res=`curl -0 -A ” -X POST -H ‘Accept: ‘ -H ‘Content-type: text/xml; charset=”utf-8″‘ -H “SOAPACTION: \”urn:Belkin:service:insight:1#GetInsightParams\”" –data ‘ ‘ -s http://$IP:$PORT/upnp/control/insight1 | grep “” | cut -d”>” -f2|cut -d”|” -f9`
    Power=$(($res/60000))
    echo $Power

    I wanted to get the GetPower Property which is mentionned here and there but I never managed to get it working.

    I found an alternate solution which is to get the InsightParams from the wemo insight API. the result is a string which looks like that : 1|1544988731|3|38049|456580|1209600|361|1430400|657939175|7107245804.000000|8000

    I was able to identify the meaning of some -not all- fields

    field 1 : 1 is the position of the switch (1-ON |0-OFF)

    field 2 : 1544988731 is the date in secondes since 1970/01/01

    field 3 : unknown

    field 4 : 38049 Today’s activity in sec

    field 5 : 456580 Total activity in sec

    field 6 : 1209600 unknown

    field 7 : 361 unknown

    field 8 : unknown

    field 9 : 657939175 Energy Today that’s our consumption ! (on mwh -> to be divided by 60000 to get the Energy Today

    field 10 : 7107245804 Total Engery (since when? )

    field 11 : unknown

    then the only thing to do is to get the InsightParam, get the field n# 9 and divide it by 60000

    I’d like to say thank you to rich for his brillant inspiration.

  • No trackbacks yet