Close
0%
0%

MQTT Porchlight is an Intranet of Thing

Controlling a Wemo light switch with MQTT and Raspberry Pi

Similar projects worth following
Years ago I installed a Wemo WiFi-enabled switch to automatically turn our porch light on at dusk and off at 11pm. It is controlled via the Wemo app which I always found a bit wonky and recently decided to take back control of this functionality.

I have an MQTT broker running on a Raspberry Pi. To add the Wemo switch to the system I wrote a Python script that of basic functionality as well as scheduling to turn the light on and off automatically.

System Design:

There are three main parts to what I've set up:

  1. Raspberry Pi
  2. Wemo WiFi Switch
  3. Android phone

Both the broker and the client script for the switch are running on the Raspberry Pi. when the client script receives a command it changes the switch state (or reports back status). It is also responsible for the scheduled events like turning on at sunset.

MQTT Android App:

As recommended in Elliot's MQTT guide I'm using the "IoT MQTT Dashboard" Android app. It provides a basic interface that's really easy to setup - give it the IP, port, and topic and you can add a few different button types to sent custom messages.

The topic widget of 3 buttons are what I'm using now for basic control. The other widgets are some ideas I have for making the schedule user-settable. However, it seems like a web interface will end up being the best solution here as it'll be available to anyone on the network without installing an app. That's a project for another day.

Conclusion

It was fun throwing this together in an afternoon to learn a bit more about MQTT and it took me down the rabbit hole on Python libraries for scheduling and establishing sunrise and sunset times. I don't really have any other devices in my house that are on the network, but now that I have an MQTT broker I might pick up a current sensing clamp to add washer/dryer cycle-complete notifier. We'll see!

  • Tracking Sunset time in Python

    Mike Szczys12/09/2019 at 21:06 0 comments

    Changing the sundown time with the seasons is a nice feature. It's really easy to do thanks to the Astral library that I learned about in this thread:

    https://stackoverflow.com/questions/38986527/sunrise-and-sunset-time-in-python/38986561#38986561

    Just give it your location and you can look up the sunrise, sunset for any date. I use this method in a function that updates my scheduled "On" time each day at noon:

    def service_sundown(client):
        #Update any schedules with "sundown" in them to match daily changes
        #this should be run every day mid-day
        #print("sundown schedule running")
        sundown_events = [x for x in schedule.jobs if "sundown" in x.tags]
        for event in sundown_events:
            #print(event)
            n = event.next_run
            newsundown = get_sundown(n)
            event.next_run = datetime.datetime(n.year, n.month, n.day, newsundown.hour, newsundown.minute)
            event.at_time = datetime.time(newsundown.hour, newsundown.minute)
            client.publish(topic, payload="Next sundown set for: %s" % event.next_run.strftime("%H:%M"))

  • Scheduling and multi-thread in Python

    Mike Szczys12/09/2019 at 21:02 0 comments

    Since my original goal is to replace the automatic scheduling for turning the porchlight on and off I need to write that into the Python file.

    Why? Well, MQTT is just for transferring messages. So you can send "On" to my client script and it will turn the Wemo switch on. You can send "Status" and it'll report back with the status. But something needs to automatically watch for the schedule times and react when they come along.

    In Python, the "schedule" package does this for you. Set a time, a function to call, and any repeat paramaters (like do this every day) and it'll manage the schedule, needing only for a function to be called checking for pending operations.

    import schedule
    import time
    schedule.every().day.at("23:00").do(porchlight.off)
    while(True):
        schedule.run_pending()
        time.sleep(60)

    Threading

    The problem with running the MQTT and schedule in the same Python script is that both need to be services. Luckily the MQTT package has threading built in, so calling a loop start (instead of a loop forever) will spin it off into its own thread and it won't interfere with the while loop above.

    client.loop_start()

  • Running Python MQTT Client as a Linux Service

    Mike Szczys12/09/2019 at 20:54 0 comments

    Home Automation is only useful if it's automatic. So with a proof of concept Python script I needed to turn it into a service. This is pretty easy with systemd. All you need is a "yourservicename.service" file in the /etc/systemd/system folder that calls your script.

    Important parts on this are to name the correct user and file location in your service:

    [Service]
    Type=simple
    User=pi
    ExecStart=/usr/bin/python3 /home/pi/wemoswitch-to-mqtt/wemo-mqtt-control.py
    
    [Install]
    WantedBy=multi-user.target

    Start it with systemctl (protip, you'll want to use systemctl status yourservicename.service to see if it had errors or is running correctly):

    systemctl enable mqtt_porchlight.service
    systemctl start mqtt_porchlight.service

  • MQTT Broker and Client on Raspberry Pi

    Mike Szczys12/09/2019 at 20:50 0 comments

    Although I've know about MQTT for years, this is the first I've done beyond a "hello world" style commandline exploration of it. The lightweight protocol runs on a ton of devices and is just a simple text delivery protcol based on a publish/subscribe model.

    Follow Elliot's Tutorial:

    This process was super-easy for me because Elliot wrote a 4-part series on MQTT (I only needed 2 parts of it for this project) that everyone should check out:

    https://hackaday.com/2016/05/09/minimal-mqtt-building-a-broker/

    I have a Raspberry Pi on my network so installing a broker using the "mosquitto" package was a snap. One gotcha I ran into was the Raspbian had masked the broker service so I had to use the "systemctl unmask mosquitto.service" before enabling it and starting it with same.

    MQTT Python Client:

    Like I said, MQTT is just a simple text protocol so it's not going to do anything for you. The nice thing is that this makes it very flexible. I wanted three things to start: On,Off,Status -- so I just had to write functions that would listen for those incoming messages and react accordingly.

    I'm not using GPIO on the Pi but this guide is what I followed to get my MQTT up and running:

    https://www.abelectronics.co.uk/kb/article/1085/io-pi-tutorial---mqtt-control

    This uses the paho-mqtt package which can be installed with pip:

    pip3 install paho-mqtt

    The code I came up with is found on my repo: 

    https://github.com/szczys/wemoswitch-to-mqtt/blob/master/wemo-mqtt-control.py

  • Wemo control in Python

    Mike Szczys12/09/2019 at 20:17 0 comments

    First thing's first, I set out to see if there were any packages available to control a Wemo switch from inside the LAN. There are indeed as on the local network the system uses UPNP/Rest for control.

    There are tons of libraries for this across different languages. I ended up using the pywemo library:

    https://github.com/pavoni/pywemo

    It's easy to install with pip: 

    pip3 install pywemo

    And basic control is just a few lines:

    >>> import pywemo
    >>> devices = pywemo.discover_devices()
    >>> print(devices)
    [<WeMo LightSwitch "Crabapple">]
    >>> devices[0].get_state()
    0
    >>> devices[0].toggle()
    >>> devices[0].get_state()
    1
    >>> 

View all 5 project logs

Enjoy this project?

Share

Discussions

Tom Nardi wrote 12/12/2019 at 03:20 point

The term "wonky" is certainly one of the words I would use to describe my experience with the Wemo app/ecosystem. Probably the nicest one, in fact...

  Are you sure? yes | no

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates