Support for Raspberry Pi and Orange Pi GPIOs in Home Assistant

So, I’ve been off in the GPIO library salt mines for a while, but am now ready to circle back and document how to get GPIO inputs and outputs working in Home Assistant. This now works on both Raspberry Pi and OrangePi, assuming that my patch gets merged.

First off, let’s talk about GPIO outputs. This is something which has been working for a while on both platforms (a while being a week or so, assuming you’ve patched Home Assistant with my pull request, but you’re all doing that right?).

To configure an output in Home Assistant, you would add the following to configuration.yaml:

rpi_gpio:
  board_family: orange_pi

switch:
 - platform: rpi_gpio
   ports:
     PA7: LED

Where board_family can be either “raspberry_pi” or “orange_pi”. Note that for Raspberry Pis, the pin numbers are always numbers whereas for OrangePi we are using “SUNXI” numbering, which is of the form “PA7”.

The circuit for this LED is really simple:

A simple LED circuit

Now we have a switch we can control in Home Assistant:

Raspberry Pi LED switch in Home Assistant

GPIO inputs are similar. The configuration looks like this:

rpi_gpio:
  board_family: orange_pi

binary_sensor:
 - platform: rpi_gpio
   invert_logic: true
   ports:
     PA7: PUSHYBUTTON

With a circuit like this:

A circuit with a button in it

invert_logic set to true is required because our circuit sends the value of PA7 to ground when the button is pressed.

A push button being pressed in Home AssistantNoting that sensors look different to switches in Home Assistant, you can see the binary sensor at the top right of the image, with its history being displayed in the dialog box in the foreground.

Updated examples for OrangePi GPIOs

As part of working through adding OrangePi support to Home Assistant, Alastair and I decided to change to a different GPIO library for OrangePi to avoid the requirement for Home Assistant to have access to /dev/mem.

I just realised that I hadn’t posted updated examples of how to do GPIO output with the new library. So here’s a quick post about that.

Assuming that we have an LED on GPIO PA7, which is pin 29, then the code to blink the LED would look like this with the new library:

import OPi.GPIO as GPIO
import time


# Note that we use SUNXI mappings here because its way less confusing than
# board mappsings. For example, these are all the same pin:
# sunxi: PA7 (the label on the board)
# board: 29
# gpio:  7

GPIO.setmode(GPIO.SUNXI)
GPIO.setwarnings(False)
GPIO.setup('PA7', GPIO.OUT)

while True:
    GPIO.output('PA7', GPIO.HIGH)
    time.sleep(1)
    GPIO.output('PA7', GPIO.LOW)
    time.sleep(1)

The most important thing there is the note about SUNXI pin mappings. I find the whole mapping scheme hugely confusing, unless you use SUNXI and then its all fine. So learn from my fail people!

What about input? Well, that’s not too bad either. Let’s assume that you have a button in a circuit like this:

A circuit with a button in it

The to read the button the polling way, you’d just do this:

import OPi.GPIO as GPIO
import time

GPIO.setmode(GPIO.SUNXI)
GPIO.setwarnings(False)
GPIO.setup('PA7', GPIO.IN, pull_up_down=GPIO.PUD_DOWN)

while True:
    print('Reading...')
    if GPIO.input('PA7') == GPIO.LOW:
        print('Pressed')
    else:
        print('Released')
    time.sleep(1)

Let’s pretend it didn’t take me ages to get that to work right because I had the circuit wrong, ok?

Now, we have self respect, so you wouldn’t actually poll like that. Instead you’d use edge detection, and end up with code like this:

import OPi.GPIO as GPIO
import time

GPIO.setmode(GPIO.SUNXI)
GPIO.setwarnings(False)
GPIO.setup('PA7', GPIO.IN, pull_up_down=GPIO.PUD_DOWN)

def event_callback(channel):
    print('Event detected: %s' % GPIO.input('PA7'))
    
GPIO.add_event_detect('PA7', GPIO.BOTH, callback=event_callback, bouncetime=50)

while True:
    time.sleep(1)

So there ya go.

GPIO inputs on Raspberry Pi

Now that I have GPIO outputs working nicely for Home Assistant using either a Raspberry Pi or an Orange Pi, I want to get GPIO inputs working as well. Naively, that’s pretty easy to do in python on the Raspberry Pi:

import RPi.GPIO as GPIO
import time

GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
GPIO.setup(17, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)

while True:
    print('Reading...')
    if GPIO.input(17) == GPIO.HIGH:
        print('Pressed')
    else:
        print('Released')
    time.sleep(1)

That code is of course horrid. Its horrid because its polling the state of the button, and its quite likely that I can sneak a button press in during one of those sleeps and it will never be noticed. Instead we can use edge detection callbacks to be informed of button presses as they happen:

import RPi.GPIO as GPIO
import time

GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
GPIO.setup(17, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)

def event_callback(channel):
    print('Event detected: %s' % GPIO.input(17))
    
GPIO.add_event_detect(17, GPIO.BOTH, callback=event_callback, bouncetime=50)

while True:
    time.sleep(1)

This second program provides helpful output like this:

pi@raspberrypi:~ $ python gpio_button_edge_detect.py 
Event detected: 1
Event detected: 0

Which is me pressing the button once (it go high when pressed, and then low again when released). This is of course with a button wired to GPIO17 with a current limiting resistor between the button and the 3.3v rail.

Pull Requests for the LCA2019 Home Automation tutorial

A quick list of things I did for the LCA2019 Home Automation tutorial. Of course Alistair did a lot more, but I still want to track these.

Further adventures in Home Assistant OrangePi GPIO

Its funny how a single sentence can change your course. In the last post about this work, I said:

We also need to run hass as root,  because OrangePi GPIO support requires access to /dev/mem for reasons I haven’t dug into just yet.

That’s turned out to be (reasonably) a pretty big sticking point upstream. Access to /dev/mem gives you a whole bunch of access to the machine that Home Assistant probably shouldn’t have.

Alastair went off spelunking because he’s more patient than me and found yet another OrangePi GPIO library. I think we’re up to three or four of these at the moment, but this is the first one we’ve found which supports the sysfs interface to GPIO pins. That’s exciting because it removes our run-as-root requirement. Its unexciting in that the sysfs interface has been deprecated by the kernel, but will remain supported for a while.

I think people would be within their rights to conclude that the state of GPIO libraries for OrangePi is a bit of a dumpster fire right now.

Anyways, the point of this post is mostly to write down how to use the sysfs interface to GPIO pins so that I can remember it later, I’ll take more about this new library and if it meets our needs in a later post.

The first step is to determine what pin number the GPIO pin is. On the OrangePi these are labelled with names like “PA7”, which is the 7th bit in the “A” GPIO register. To convert that into a pin number as used by sysfs you do this:

def pin_number(letter, digit):
    return (ord(letter) - ord('A')) * 32 + digit

So, pin_number(‘A’, 7) for PA7 is just … 7.

Note that I now recommend that people use SUNXI pin mapping, as its much less confusing. You can read more about alternative pin mappings in this post of worked OrangePi GPIO examples.

Now we can enable the pin, set it to output, and then blink the LED to prove it works:

# cd /sys/class/gpio
# echo 7 > export
# cd gpio7
# echo "out" > direction
# echo 1 > value
# sleep 1
# echo 0 > value

The next step? To make sure that the new GPIO library supports sysfs access to GPIOs on the OrangePi Prime.

Adventures in Home Assistant Raspberry Pi GPIO

Alastair D’Silva is running what looks to be a very well prepared home automation tutorial at LCA2019 based on Home Assistant. I offered to have a hack on the support for GPIO pins on OrangePi boards in Home Assistant because it sounded interesting for a vacation week. The only catch being that I’d never done anything with GPIO pins at all on either Raspberry Pi or Orange Pi.

A simple LED circuit for a Raspberry PiThe first step seemed to be to get GPIO working at all on a Raspberry Pi (which is currently supported out of the box with Home Assistant). This online tutorial has a simple example of a circuit and the associated python code to blink a LED on a Raspberry Pi, so off I went to build that circuit.

The circuit has a LED with a 330 ohm pull up resistor on GPIO pin 18 on the board. The sample python code on the page above just blinks that LED, which I used to make sure that the circuit as working as intended.

To configure the GPIO pin as a switch in Home Assistant, I added the following to configuration.yaml (noting that the empty rpi_gpio entry isn’t strictly required, but will be later):

rpi_gpio:

switch:
 - platform: rpi_gpio
   ports:
     18: LED

Which leaves me with something like this in the web UI:

Raspberry Pi LED switch in Home Assistant

It even works!

I’ve lied to you a little bit above, for which I apologise. I’ve also been working on helping Alastair with adding Orange Pi to the rpi_gpio component in Home Assistant, as the tutorial is based on Orange Pi Primes, with a custom home automation shield installed. Now that I have a sample configuration that works for Raspberry Pi and a test circuit, its time to make sure that Orange Pi works correctly too.

Home Assistant doesn’t currently have any support for Orange Pi GPIOs. The first approach I took was to forward port this ancient patch which adds Orange Pis as a new component beside Raspberry Pis. That port is available here, but in the end I decided it would be nicer to just have the existing Raspberry Pi component also support Orange Pis, instead of duplicating a whole bunch of code and adding some confusion.

(It should be noted that there are downsides to this new approach — the code is more complicated this way, and Raspberry Pi owners need to download the Orange Pi GPIO library even though they’ll never use it. That said, I see these downsides as relatively minor).

GPIO pin mapping for an Orange PiA small hitch however. Orange Pi names the GPIO ports in a quite different way from how Raspberry Pi does, and this took some time to get used to. The mapping of GPIO pins was a little hard to find, so I’ll include it here (the image to the left). A second hitch was that I needed a linux image for the board. I’ve used Armbian Stretch, as the hass.io image is quite locked down (no ssh to the base OS for example).

Based on the pin image instead of the Pin 18 from the previous example, I moved to what is labelled on the tutorial shield as “PA7”, and which is referred to in code as Pin 29.

The code for blinking is a bit different from the example linked above, so here is a tweaked version:

import OPi.GPIO as GPIO
import time


GPIO.setboard(GPIO.PRIME)
GPIO.setmode(GPIO.BOARD)
GPIO.setwarnings(False)
GPIO.setup(29, GPIO.OUT)

while True:
    GPIO.output(29, GPIO.HIGH)
    time.sleep(1)
    GPIO.output(29, GPIO.LOW)
    time.sleep(1)

Note here that we need to specify what board we’re on (in this case a Prime), and we set the mode differently than the linked example.

So now let’s be over achievers and get things working in Home Assistant too! We need a configuration.yaml which includes something like this:

rpi_gpio:
  board_family: orange_pi
  board: prime

switch:
 - platform: rpi_gpio
   ports:
     29: LED

Note the additional config in the rpi_gpio entry. We also need to run hass as root,  because OrangePi GPIO support requires access to /dev/mem for reasons I haven’t dug into just yet.

OrangePi GPIO support currently requires a patch to Home Assistant, which you can find at a github branch.

The Consuming Fire

Another fast run read from Mr Scalzi, this book is the sequel to The Collapsing Empire. I think this book is actually better than the first, which I guess is fair given the first had to set the universe up. I particularly like the twist about two thirds of the way through this one, and I think the universe has a lot of potential to be really interesting in future books. Mr Scalzi remains on my I-buy-everything-he-does list.

I wish he’d write another book in the Old Man’s War universe.






The Consuming Fire Book Cover




The Consuming Fire





John Scalzi





Tor




October 18, 2018




336

The Consuming Fire by John Scalzi is the dazzling follow-up to The Collapsing Empire - a space opera in a universe on the brink of destruction. The Interdependency, humanity's interstellar empire, is on the verge of collapse. The Flow, the extra-dimensional pathway between the stars, is disappearing, leaving planets stranded. Billions of lives will be lost - unless desperate measures can be taken. Emperox Grayland II, the leader of the Interdependency, is ready to take those measures. But it's not that easy. There are those who believe the collapse of the Flow is a myth - or an opportunity for them to ascend to power. While Grayland prepares for disaster, others prepare for civil war. A war that will take place in the halls of power, the markets of business and the altars of worship as much as between spaceships. Nothing about this power struggle will be simple or easy . . . and all of human civilization is at stake.

HomeAssistant configuration

I’ve recently been playing with HomeAssistant, which is quite cool. Its not perfect — for example it broke recently for me without any debug logs indicating problems because it didn’t want to terminate SSL any more, but its better than anything else I’ve seen so far.

Along the way its been super handy to be able to refer to other people’s HomeAssistant configurations to see how they got things working. So in that spirit, here’s my current configuration with all of the secrets pulled out. Its not the most complicated config, but it does do some things which took me a while to get working. Some examples:

  • The Roomba runs when no one is home, and let’s me know when its bin is full.
  • A custom component to track when events last occurred so that I can rate limit things like how often the Roomba runs when no one is home.
  • I detect when my wired doorbell goes off, and play a “ding dong” MP3 in the office yurt out the back so I know when someone is visiting.
  • …and probably other things.

I intend to write up interesting things as I think of them, but we’ll see how we go with that.

Chaos Monkeys

A very well written tale of a Wall Street quant who left during the GFC to adventure in startup land and ended up at Facebook attempting to solve their monetization problems for an indifferent employer. Martinez must have been stomping around Mountain View because his description of the environment and what its like to work inside a Silicon Valley company ring very true to me.

A good read.






Chaos Monkeys Book Cover




Chaos Monkeys





Antonio Garcia Martinez





Business & Economics




Harper Paperbacks




July 24, 2018




320



The instant New York Times bestseller, now available in paperback and featuring a new afterword from the author--the insider's guide to the Facebook/Cambridge Analytica scandal, the inner workings of the tech world, and who really runs Silicon Valley “Incisive.... The most fun business book I have read this year.... Clearly there will be people who hate this book — which is probably one of the things that makes it such a great read.” — Andrew Ross Sorkin, New York Times Imagine a chimpanzee rampaging through a datacenter powering everything from Google to Facebook. Infrastructure engineers use a software version of this “chaos monkey” to test online services’ robustness—their ability to survive random failure and correct mistakes before they actually occur. Tech entrepreneurs are society’s chaos monkeys. One of Silicon Valley’s most audacious chaos monkeys is Antonio García Martínez. After stints on Wall Street and as CEO of his own startup, García Martínez joined Facebook’s nascent advertising team. Forced out in the wake of an internal product war over the future of the company’s monetization strategy, García Martínez eventually landed at rival Twitter. In Chaos Monkeys, this gleeful contrarian unravels the chaotic evolution of social media and online marketing and reveals how it is invading our lives and shaping our future.

Artemis

Its been ages since I’ve read a book in a couple of days, let alone stayed up late when I really shouldn’t in order to finish a book. Artemis is the book which broke me out of that rut — this is a fun, clever, light read. Its quite different when compared to The Martian, but I think that’s good. Weir has attempted to do something new instead of just playing on his previous successes.

An excellent book, and Mr Weir is solidly landing on my buy-everything-he-writes list.






Artemis Book Cover




Artemis





Andy Weir





Fiction




Del Rey




November 13, 2017




384



She grew up on the moon, of course she has a dark side... Jazz Bashara is a criminal. Well, sort of. Life on Artemis, the first and only city on the moon, is tough if you're not a rich tourist or an eccentric billionaire. So smuggling in the occasional harmless bit of contraband barely counts, right? Not when you've got debts to pay and your job as a porter barely covers the rent. Everything changes when Jazz sees the chance to commit the perfect crime, with a reward too lucrative to turn down. But pulling off the impossible is just the start of Jazz's problems, as she learns that she's stepped square into a conspiracy for control of Artemis itself - and that now, her only chance at survival lies in a gambit even more unlikely than the first.