Wemo
WeMo in Domoticz
Background
While WeMo is not supported as a core device in Domoticz, there are some good python libraries (we will use Ouimeaux) available that let you get control of the WeMo from your domoticz Please note that while Switches work fine, I have had to use a few workarounds to get the motion sensor to work - Feel free to suggest a better method if you can
Setting up your WeMo device
The guide assumes that you have the WeMo devices setup on your network and you can control them through the official iOS/Android app already Please obtain the IP addresses of your WeMo devices and note them down It would be a good idea to reserve the current IPs for the WeMos on your router as the IP will be hardcoded in the following scripts
Creating Dummy Switches
To create a virtual switch, you first have to create a virtual hardware device.
Go to Setup > Hardware. Type in a name say Dummy1, choose 'Dummy (Does nothing, use for virtual switches only)' from the drop-down. Leave 'Data timeout' disabled. Click on 'Add'
Creating a virtual switch
To create a virtual switch, go to the 'Switches' tab. Click the 'Manual Light/Switch' button in the upper left corner. Choose the dummy hardware from the drop-down. Enter a name ('WeMo Switch'). Switch type 'On/off'. Type 'X10'. For 'House code' and 'Unit code', choose some random, doesn't really matter. As 'Main Device'. It is advisable to make the switch 'protected', so the switch can only be operated by the detection script and not by you, by accidentally clicking on it
Setting up your WeMo Switch
This is fairly straight forward process
1) Create a dummy switch for each of your WeMo devices
2) While you can use Ouimeaux to control switches, I found it to be a bit of an overkill so I settled for a script written by a gentleman here - [1]
3) Get the script - Its a good idea to keep all scripts nested under the defined folder so
mkdir /home/pi/domoticz/scripts/wemo
cd /home/pi/domoticz/scripts/wemo
wget http://moderntoil.com/file_attachments/wemo_control.sh
4) Create a on and off script
nano wemo_on.sh
#!/bin/sh
/home/pi/domoticz/scripts/wemo/wemo_control.sh YOUR_SWITCH_IP ON
nano wemo_off.sh
#!/bin/sh
/home/pi/domoticz/scripts/wemo/wemo_control.sh YOUR_SWITCH_IP OFF
5) Make the scripts executable chmod +x wemo_on.sh
, chmod +x wemo_off.sh
and chmod +x wemo_control.sh
6) Link the On/off scripts to the dummy switch on/off actions
That should be it
WeMo Sensor
As always , create a dummy switch, name it whatever you like, say motion switch and note its idx value from the devices tab
You will need to install Ouimeaux next (All credit to Ian McCracken)
1) ouimeaux requires Python header files to build some dependencies: sudo apt-get install python-setuptools python-dev
2) install by easy_install ouimeaux
3) check if Ouimeaux can find all your devices: wemo list
Make a note of the motion sensors you found listed here , let's say you found 1 called WeMo Motion
4) The original code contains a code snippet for probing a sensor periodically and echo the output on screen, I have modified it to trigger a JSON-call to the idx of the dummy switch we created
Save this as motion_watch.py under /home/pi/domoticz/scripts/wemo
#!/usr/bin/env python
import argparse
import sys
import requests
from ouimeaux.environment import Environment
from ouimeaux.utils import matcher
from ouimeaux.signals import receiver, statechange, devicefound
def mainloop(name):
matches = matcher(name)
@receiver(devicefound)
def found(sender, **kwargs):
if matches(sender.name):
print "Found device:", sender.name
@receiver(statechange)
def motion(sender, **kwargs):
if matches(sender.name):
r= requests.get("http://YOUR_DOMOTICZ_IP:PORT/json.htm?type=command¶m=switchlight&idx=DUMMY_SWITCH_IDX&switchcmd={state}&level=0".format(
sender.name, state="On" if kwargs.get('state') else "Off"))
print (r.url)
env = Environment(with_cache=False)
try:
env.start()
env.discover(10)
env.wait()
except (KeyboardInterrupt, SystemExit):
print "Goodbye!"
sys.exit(0)
if __name__ == "__main__":
parser = argparse.ArgumentParser("Motion notifier")
parser.add_argument("name", metavar="NAME",
help="Name (fuzzy matchable)"
" of the Motion to detect")
args = parser.parse_args()
mainloop(args.name)
Please replace http://192.168.0.100/8080 with the IP/port of your domoticz and the idx with your dummy switch id in the code above
6) Create another script under /home/pi/domoticz/scripts/wemo called run_sensor.sh
#!/bin/sh
sudo python /home/pi/ouimeaux/ouimeaux/examples/motion2.py "Wemo Motion"
7) chmod +x run_sensor.sh
8) Open crontab editor to Add script to crontab to check every 5 minutes if its running and to start it if it isn't running: crontab -e
9) add the following line
*/5 * * * * pgrep run_sensor.sh > /dev/null || /home/pi/domoticz/scripts/wemo/run_sensor.sh
10) That's it - Your dummy sensor should now turn on when it detects motion
Handling Power outages
While this worked well for me, I had an issue with power outages I live in India where unplanned outages are relatively common and while the domoticz server runs off a UPS, the motion sensor doesn't. Thus each time there would be a power cycle, the Domoticz server would lose connection with the sensor and the script would keep running without any output Even if the domoticz sensor was not a UPS, WeMo devices take quite some time to boot and establish connection and the initial script would have executed without having found a WeMo
I have implemented an odd workaround for this but would be happy to see alternate suggestions
The method I use is to ping the WeMo sensor IP once every 1 minute and grep the output to do nothing if ping is returned else kill and restart the run_sensor script
1) Create script $ cd/home/pi/domoticz/scripts/wemo
nano check_sensor_online.sh
#!/bin/bash
ping -c1 192.168.0.9 2>&1 | grep ttl > /dev/null
if [ $? -eq 1 ]
then
sudo kill $(ps aux | grep 'python /home/pi/ouimeaux/ouimeaux/examples/motion2.py' | awk '{print $2}')
fi
3) chmod +x check_sensor_online.sh
4) add to crontab to run every 1 minute
Open crontab editor: crontab -e
and add
*/1 * * * * /home/pi/domoticz/scripts/check_wemo_online.sh
I understand this is far from an ideal implementation but it seems to be working well for me