ouimeaux: Command line and Python API for WeMo hacking
I bought a bunch of Belkin WeMo Switches over Christmas, and while I appreciate that my lights now have IP addresses, controlling them can really only be done through the WeMo iPhone app, which (besides having a few understandable bugs) is slow to start up. More to the point, I had no way to hook the switches up to any other events beyond using IFTTT, which seems to have a one-switch limit.
Luckily, WeMo devices appear to provide a fairly complete SOAP API. Isaac Kelly posted a proof of concept discovering and controlling switches, so obviously more direct control was possible. Hacking together a decent library only took a couple of nights.
Thus: ouimeaux. It uses gevent for async I/O and the minimal UPnP functionality required (broadcasting M-SEARCH requests, listening for responses), and it uses requests to communicate directly with the devices. Service stubs are built on the fly and provide easy attribute access to actions (for example, switch.basicevent.SetBinaryState(BinaryState=1)
). There's also a handy explain()
method to print out all services, actions and arguments. The only useful things I had time to figure out how to do—turn switches on and off, get current switch state—I pulled up into methods on the switch object itself: switch.on(), switch.off(), switch.get_state()
. The documentation gives more details.
Once that was written, a simple command line script was straightforward. Installing the package will get you the wemo
script in your PATH. wemo list
to discover names of devices, wemo switch "Switch Name" on
to turn it on. Nothing else so far, but it's highly hackable.
I hope to explore the Motion API next, and provide the ability to listen to events from Motion devices. Firmware uploading is exposed too; might be possible to intercept and modify to get an SSH server running.
February 7, 2013 at 11:04 AM
I've been able to get Isaac's sample to work and looking through your code I'm looking forward to trying it as well. It looks great!
Have you been able to sort out the SOAP requests to get the WEMO onto another wireless network rather than having to access it through it's default 10.something address?
February 7, 2013 at 9:02 PM
There's a WiFiSetup service, looks like this:
WiFiSetup
---------
StopPair()
ConnectHomeNetwork(password, encrypt, ssid, auth, channel)
GetApList(ApList)
GetNetworkStatus(NetworkStatus)
CloseSetup()
I haven't gotten too deep in it yet, just done a scan with GetApList, which returns what you'd expect. What do you mean exactly, get it onto another wireless network?
February 9, 2013 at 11:04 AM
Thats the one I'm trying to sort out. Figuring out exactly what to pass to the ConnectHomeNetwork function. What I assume is:
Password - the password as a string
encrypt - "AES", "TKIP"
ssid - name of the network
auth - "Shared", "WPA2-Personal", etc. I'm less sure on this one.
channel - channel as a string "11"
February 9, 2013 at 11:06 AM
That would also be my assumption :) My plan is to fire up Wireshark at my next opportunity and try to fill out my knowledge about argument values.
February 22, 2013 at 2:42 AM
Hi Ian,
I have read your blog about hacking wemo switch. I am a Java developer, not knowing Python, so my plan was to communicate with device via upnp library (cling). But as always - there is some problem (in this particular case cling is too strict when it comes to specification, but at least it is opensource and I can use discovery mechanism which works pretty well and I have tested it already). Right now I am able to "discover" device and "proprietary parse" all the necessary xmls for device/service info. What I do not know (as I am newbie into upnp with no prior experience) is what the target = working SOAP request for switching on/off device - should look like. URL, http headers and http body (containing SOAP request).
Since you're already up and running it will be very helpful, if you could send me theese. I will substitute parts that are specific for your environment and after sucessfull proof of concept will write simple Java wrapper and make it available for others to play.
Thank you very much in advance and hope to hear from you soon.
T.
February 25, 2013 at 8:03 AM
Problem solved - for those facing the same problem - the SOAP request can be found here (in the discussion): http://www.mgalisa.com/?p=91
Hope this helps. T.
March 19, 2013 at 2:53 AM
Hey - been playing around with ouimeaux... being able to turn these switches on and off with a real computer is awesome -- almost like we're living in the future!
There's just one thing that's buggin' the crap out of me, and that's how to get any information out of the Wemo Motion device... any insight you may have on this would be greatly appreciated!
(the unnecessary backstory: want to be able to issue commands to Philips Hue lightbulbs after detecting motion with the WeMo motion)
April 3, 2013 at 3:27 PM
Hey,
I've made an REST API base on issackelly's job.
With that you can request your wemo easily via http GET command.
Feel free to contribute here :
https://github.com/canvin/wemo
April 3, 2013 at 3:27 PM
This comment has been removed by the author.
April 21, 2013 at 7:40 PM
Jayson: Check out the 0.2 release, which allows you to subscribe to motion events (as well as switch events).
May 29, 2013 at 4:31 PM
Hi Guys,
I was wondering if anyone out there has been able to use these findings to allow us to control these switches with Android and the app tasker?
May 29, 2013 at 4:32 PM
This comment has been removed by the author.
September 23, 2013 at 4:43 AM
Hello,
Great job ! Is there a way to make this work on a Mac ?
Best,
Franck
September 23, 2013 at 1:12 PM
It works on a Mac now. System Python will work fine. You'd need to install it with sudo if you don't use a virtualenv. Alternatively you could use Homebrew to install an updated Python and install ouimeaux into that.
But let's go with system Python. Like any normal Python package in PyPI, just do:
sudo easy_install ouimeaux
October 18, 2013 at 5:48 PM
I stumbled across the WeMo devices quite by accident and was really annoyed that they only had facilities for Apple. Then, they had a beta, and finally a released Android app. The problem is the Android app is terrible. Then I stumbled across your work.
Wow!
I only have one switch so far, but it's working just fine from my Raspberry Pi. Sure, I had to borrow a phone to set the darn switch up, but IT'S WORKING.
Thank you for this work. The wemo command line interface works well. Now, to build up some python code and get some real control.
April 17, 2014 at 11:06 PM
I could not get this to work on Mac OS X, so I tried running Ubuntu on VM and installing ouimeaux there. However, once I get to env.discover(seconds=5), it does not return anything. env.list_switches() also returns an empty list. Any idea why I cannot detect my Insight Switch? Could it be that I am running it from a VM?
April 17, 2014 at 11:16 PM
Yeah, if the VM is NATed, it won't work. The WeMo devices have to be able to contact the box running ouimeaux directly in order to respond to broadcasts and send events. Set up your VM to bridge to your interface, so it's on the same network as your host box (and, presumably, the WeMos).
April 19, 2014 at 5:13 PM
@I'm An Astronomer - Thank you. I have ouimeaux installed now.
Now here is another question... I was able to have the computer recognize the devices through the Environment part of the API. However, when I type into the python shell:
macbook.current_power
where I named my insight switch macbook, it gives the following output:
{'faultcode': 's:Client', 'faultstring': 'UPnPError', 'detail': '\n'}
Some googling indicates it is a problem having to do with newer firmware. Does anyone know what firmware version ouimeaux was designed for and if the Insight Switch firmware version can be changed? Or does anyone know a coding solution that would enable me to get the current power draw from my Insight Switch?
April 20, 2014 at 9:54 PM
@Melissa: The latest firmware indeed broke that call; indeed, several of the Insight calls don't work. However, GetInsightParams() has the info you want. I've got an open ticket to rewrite the exposed calls to use that: https://github.com/iancmcc/ouimeaux/issues/29
January 5, 2015 at 4:43 AM
This comment has been removed by the author.
January 5, 2015 at 4:44 AM
Nice information, valuable and excellent design, as share good stuff with good ideas and concepts, lots of great information and inspiration, both of which I need, thanks to offer such a helpful information here.
January 30, 2015 at 5:09 AM
Extraordinary post! Also mind boggling website! Extremely accommodating post! I must say. Basic & intriguing Wonderful work!
Visit : Online High School Diploma
February 19, 2015 at 2:18 PM
Hi there,
I'm very new to code & rpi, but I have had some wemo devices for a while now. I have just managed to get things running and can turn devices on / off etc from the command prompt on my rpi.
My question is though, is there a way to get ouimeaux to recognise my Wemo LED light bulbs?
February 19, 2015 at 5:12 PM
Check out the ongoing issue: https://github.com/iancmcc/ouimeaux/issues/51
April 30, 2015 at 2:55 AM
Really well created post i have got,