12/09/2019 at 21:06 •
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:
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: 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"))
12/09/2019 at 21:02 •
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)
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.
12/09/2019 at 20:54 •
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
12/09/2019 at 20:50 •
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:
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:
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:
12/09/2019 at 20:17 •
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:
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.get_state() 0 >> devices.toggle() >> devices.get_state() 1 >>