Day 6 of the Anvil Advent Calendar

Build a web app every day until Christmas, with nothing but Python!

Control your Christmas Tree from the Web

Christmas trees are appearing all over. But this year we can’t gather in the same room to turn ours on! So we’re controlling it from the web, with nothing but Python. Here’s how it works:

At the core of our Python-powered tree is a Raspberry Pi with an Energenie Pi-mote attached. This is a delightfully easy-to-use board that lets you control mains-powered devices, like our set of multi-coloured tree lights. You can get the Pi-mote and two socket controllers as a kit from Pimoroni. (Christmas tree not included.)

The wonderful GPIO Zero Python library drives the board, and an Anvil Uplink script allows us to control the whole thing from the web. Easy!

The Setup

Firstly, let’s get the tree and the Pi set up. The Pi-mote works from quite a distance with an aerial attached, so you can even put it elsewhere in the house. Plug in the lights, connect the Pi-mote to the Raspberry Pi, and get the Pi up and running on your WiFi.

The Raspberry Pi

Next up, let’s write ourselves a Python script to control the Pi-mote (and hence the lights). You can either connect the Pi to a screen, keyboard and mouse, or SSH in remotely. Either way, start by installing GPIO Zero which will let us control the Energenie Pi-mote. If you have a recent Raspberry Pi, it might even be installed already!

Next, fire up your favourite text editor and let’s write the script. I like Nano, but I don’t judge those who prefer Vim or Emacs. Too much.

$ nano tree_control.py

The following is all you need to control the lights. No, I’m not kidding, it really is this easy:

from gpiozero import Energenie

lights = Energenie(1) # You may need to adjust the channel here
def lights_on():
    print("Turning lights on!")
    lights.on()

def lights_off():
    print("Turning lights off!")
    lights.off()

Now we can test our script from Python, directly on the Pi:

$ python
>>> import tree_control.py
>>> lights_on()
Turning lights on!

Hopefully your lights switched on! If not, you may need to tweak the channel numbers in the Pi-mote boilerplate.

The Web App

Next up, let’s make the script accessible from the web. Head over to Anvil and create a new app. For now we’ll just create a form with two buttons:

Then enable the Uplink for your app, and copy the sample code into the top of the script on the Pi:

Now our script will connect to Anvil and listen for [Server Function calls] when it starts. We just need to make our lights_on and lights_off functions callable by adding the anvil.server.callable decorator. Your whole script now looks like this:

from gpiozero import Energenie
import anvil.server

anvil.server.connect("<UPLINK-KEY-HERE>")

lights = Energenie(1) # You may need to adjust the channel here
@anvil.server.callable
def lights_on():
    print("Turning lights on!")
    lights.on()

@anvil.server.callable
def lights_off():
    print("Turning lights off!")
    lights.off()

We also need to make sure the script doesn’t exit, so it keeps listening for server calls. Add this to the bottom of your script:

anvil.server.wait_forever()

And we’re good to go. Run your script, and you’ll see it connect:

$ python tree_control.py
Connecting to wss://anvil.works/uplink
Anvil websocket open
Authenticated OK

Head back to Anvil, and double click your “Lights On!” button. Here we can call the function on the Pi directly:

  def button_1_click(self, **event_args):
    """This method is called when the button is clicked"""
    anvil.server.call("lights_on")

Add a similar call to "lights_off" for the other button, and that’s it! Run your app, and control your tree! Or send the URL to a loved one you can’t visit this year, so they can do it from there:



Loading video...

Give the Gift of Python

Share this post: