(moderator)
OK, hello everyone, welcome back. Next up we're going to have
Paulus Schoutsen, and he's going to talk to us
about "Awaken your home: "Python and the Internet of Things."
Give him applause. [applause]. (Paulus Schoutsen)
Awesome, awesome, hello everyone. Before I get started,
just a quick show of hands: who has heard here
of Home Assistant? OK, OK, that's cool. Who here in the room has
a smart internet of things device in their house? Awesome, and of those people
who live in a house, apartment, or do you actually live
in a house, apartment, or room? In that case, pay attention
because this is going to be useful. Um, my name is Paulus Schoutsen.
I'm a software engineer for a company called AppFolio
in San Diego. But I’m here not to talk
about my work today. I’ll talk about my side project,
Home Assistant, and how it could help you
to automate your home. And so first I want to talk about,
like, why does Home Assistant exist? Because we already have
the internet of things, we already have apps. Why would we need Python
to, like, manage this? And so the main reason this is:
is that there is no standard yet that is widely adopted
for home automation. And so every vendor who wants
to go quick to market, doesn’t want to, like, support
some small standard, they are like, you know what?
We'll just run our own cloud. We'll run our own protocol. And by doing so, they create
an isolated environment where, you know, your lights
do not know about your thermostat, they do not know
about your media player. And this goes one step further,
is that you as a user end up with, like, an app
per device type in your home. So you have one app to open
to get your thermostat going, one for your lights. And it's also resulted
in when you want to do automation that crosses these boundaries,
it's impossible because they don't know
about each other. And so to solve this, there's
this thing called a hub, a home automation hub. And so that is what --
how Home Assistant is. And a hub bridges,
um, these devices by speaking
all the different protocols that all these
different devices speak. And so when we look at what
the essence of a hub is, it's actually very simple. The first thing is it communicates
with the internet of things, sending out commands.
Thermostat, set your temperature. Light, turn on. Um, media player,
start playing a movie. But the other piece that it --
home control part is is that it gets information
from the internet of things. And we can break up the information
we get from the internet of things into two parts:
The first part is state. And so there's devices;
they have a state. At any point in time you can look
at the device and you can see its state. So, for example, a light,
its state is on, and there might be some
extra attributes that explain the state of that device. So if the light is on,
its brightness might be 60% and the color might be red. If a media player is playing,
the volume might be 80% and it’s playing a TV show
called "Game of Thrones." The other piece of information that we get
from the internet of things is events. And events is not something
you can just look by -- you can observe by looking
at, like, a device. You have to actually pay attention
and then the event happens. So for example, a light
is being turned on or motion is detected. And so this is like
the foundation of a hub. This is how you as a user
can control your home. And so the user will see
the information from home control and can issue commands saying,
like, "Hey, why don't you turn "the light on?
"Why don't you set the thermostat?" But of course this is also
perfect to automate. If the user knows,
"Oh, when I’m arriving home "and the sun is down,
I want the lights to turn on," that's home automation.
And so home automation is rule-based. The triggers for home automation
are always an event. So it cannot be, when the light
is on, trigger something, because it is active
over a longer period of time. But instead you're going to have
to look at when the light turns on. And so this is, for example,
in the example I just gave, it is when a person arrives home. And so the next part
is conditions. And so you want not always --
you don't always want your home automation rules
to execute when the certain event happens.
And so, in the example I gave, only when the sun has set do you actually want
to turn the lights on. And the last piece
of home automation is to actually
send the commands. "Let's turn the lights on." And so this combination
of home control and home automation is what makes
a home automation hub, and that is
what Home Assistant is. And so Home Assistant is
a home automation platform that is running on Python 3. It is open-source,
released under the MIT license. And it runs from tiny computers
like your $35 Raspberry Pi. And the nice thing,
because it is so easy, accessible to get running,
you host it locally. You know, for example,
that your data will stay yours. There will be nobody
looking at your data. And this is very important because
when you're doing home automation, your home automation hub
knows everything about you. It knows like,
which room are you in? Which lights are on?
Which -- what are you playing? What's your favorite TV show? And the next thing
that Home Assistant offers is that we allow you to track people
and things on a map, using like iBeacons or OwnTracks, which is an open-source
mobile phone application that talks directly
to Home Assistant. This gives you a whole
extra dimension to home automation. Because all of a sudden
you can say, "Hey, if I am arriving home "and I’m within two kilometers
of my home, why don't we "make sure that the thermostat
is gonna heat up my house?" or, "Hey, maybe when I’m at 7 PM
and I’m still at work, "let me get a notification,
say, 'hey, go home.'" [laughter] Home Assistant comes
with a responsive web application that you can run everywhere,
so you can run it on your mobile phone, on your tablet,
or on your browser. Another piece that is very nice
is that because we know the state of your home at a current point in time,
we're also keeping track of it. So you can go back in time
as sort of like a time machine and say, "Well, how did my home
look yesterday at 5 PM?" Or, "When did my kids
arrive home last night?" And the last piece is
that right now, Home Assistant contains already
286 built-in components and platforms that integrate a lot of different
services and devices. So the Philips Hue bulbs,
the Nest thermostats, the Ecobee thermostats,
but also, If This, Then That, the Amazon Echo, they all work
with Home Assistant. And so to see how Home Assistant
actually maps to the internet of things, it's actually very simple and it's a very,
almost like a one-on-one mapping about how I just described
the essence of a hub. So the core of Home Assistant
is an event bus. Any component, which are
the piece of code that you plug into Home Assistant,
can fire any event, and they can listen to any event. The next piece is a state machine. And the state machine stores
the state of so-called entities. I don't use the word device here
because we also track people or, like, uptime
of your computer. But the state machine, again,
it's very, like, open-minded. It doesn't force you to, say,
register how a light should be represented;
it doesn't matter. It just holds the state
and it holds -- uh, it just holds the state
and the entity and some extra data. And whenever the state changes,
it will fire a state changed event. And so now, as your code wants
to, like, listen for changes to states, it just again has to listen
to the event bus. The next piece is
the service registry. And so the service registry
will allow components to register services that they want
to make available to all the code that's on the event bus to allow
calling to control devices, for example. So a light component will register
it turned on a light, a switch will toggle
the switch service. So again, to call a service,
you fire an event on the event bus and then the service registry,
once it has executed your event, will fire back, "Hey, we
actually executed your service." And so as the calling code,
you know, OK, the work is done. And the last piece is the timer. So Home Assistant is
an event-based system. And what an event-based system
means is the state of your application can only change
based on the event. And so internally this happens
with a timer, and the timer will fire a time changed event
every second. And this will allow,
for example, listeners to say, "Hey, notify me at 7 PM"
to know when to actually fire. Another way the internal state
can change is with external events. So there are, for example,
certain devices that allow to push their state directly
to Home Assistant. So we get notified. So now let's have a look
how this actually works, right? Like, how does it work to integrate
an internet of things device into Home Assistant?
And so let's say we have a light bulb. And so to integrate the light bulb,
we have a light component. The light component,
in this case the light bulb, does not tell us about its state
so we have to pull for it. The light bulb, OK,
what's your state? I mean right
into the state machine. The state machine will do its job,
fires a state changed event. And the light component will talk
to the service registry to register the turn on command. Now let's say we have
a motion detector in our house. And we want the motion detector
to also integrate with Home Assistant. So we have a motion detector component,
and if a motion gets detected, it gets routed through
the motion detector component it pushes an event, and that component
will translate that event to the event bus and fires a motion detected event. Now we want to have
some automation. And so to get automation going,
we would have a simple automation component that only what it does is
it listens to the event bus. It listens for motion detected events,
fires to the event bus, let's call the service,
turn the light on, which gets routed
to the service registry, gets routed to the light component,
gets routed to a light bulb, a light bulb turns on. And all of this happens
without the components knowing about each other's existence. Every component runs in isolation. Every component, it just
only knows about its own things. And it just exposes the interfaces
that it wants to be -- wants to have exposed. And so there's one specific type
of component that we have. It’s called entity components.
And entity components in Home Assistant allow you
to add support. And so the entity components
sort of describe how Home Assistant expects
a light to work, or, like, what we expect from a light
or we expect from a thermostat. And so on top of these
entity components are platforms. So every integration we do
with the device or cloud is always represented
as a platform. They just follow the specifications
of your entity component. And then they are --
entity component abstracts the Home Assistant core away
from the platform so the platform doesn't actually have to know
about the state machine, the service registry, anything. So it does this
with an abstract base class. And so this abstract base class
consists of two parts. The first part is information
that we want to know about this device, and some of this information is
optional if you don't support it, otherwise, some are mandatory. So for example, in the case of a light,
is_on is very important, it’s mandatory for a light
because you have to know if the light is on or off. But the rgb_color
and the brightness are optional. We don't -- if your light
doesn't support it, you don't implement it. And the next thing that you
have to implement when you extend our abstract base class
is the methods. So for light it’s:
we want to be able to turn on, we want to be able to turn off. By just implementing
these two commands, you already have your own light. And you see how this, like --
it's actually this simple. So I wanna show an example
and this is -- I’m going to show three examples:
one of a sensor, one of a switch
and one of automation. And then I’m actually going to show
how it looks in real life. So let's say we have
a sensor platform. This is going to be
a hardcoded sensor platform so it will always return
a static value. And all these code examples
I’m going to put here on the slides -- and I hope it's readable
but I think it is -- do actually work. They can be copied straight
into Home Assistant without having to adjust any code. On the left, this is if you're
just at home reading the slides again, you would actually --
how you would add it to your configuration,
to your setup. And so when we start writing
our sensor platform, the first thing we do is that we
import our abstract base class. And then we implement it
with our own -- we extend that abstract base class. Then we want to give it a name,
so we say temperature. We want to say the state
of the sensor, which is 23. But of course 23
doesn't mean anything. It could be Fahrenheit,
it could be Celsius, so the last piece we have to expose
is a unit of measurement. And so now we the only thing left
is, how do we get this sensor into Home Assistant? And that's through a method,
and this is like a method you define in your module. Home Assistant will
automatically load your file, load your module,
and call this method. And so there are four parameters:
first is the Home Assistant instance. The second is the configuration
specific to your platform. Add_devices is a function,
a callback that you can call at any point in time, even later,
if you detect new types of your device. And discovery_info is
if your platform was actually automatically discovered instead
of issued by user configuration. And because this is hardcoded,
the only thing we're going to do is we're going to instantiate
an instance of our example sensor. We put it in a list because that's
what the add_devices expects. And then we pass it
to add_devices. And then it looks like this
in Home Assistant. We have our sensor. So now let's go a bit deeper. Let's see how a switch looks. But I didn't want to do
a hardcoded switch just as an instance variable
to control the state. I wanted to, like, represent
a real life scenario because in real life, home automation
is not that easy, you know? You have your app to control
your thermostat but somebody might just walk
to your thermostat and actually just change the temperature
and you have to be able to pick that up, you have to be able
to control that. And so to sort of mimic this
in the demo, I do it based on
the existence of a file. So if the file exists,
the switch is on. The file doesn't exist,
the switch is off. If we turn on the switch,
the file will get created. And if we turn off the switch,
the file will be removed. And so we can actually now
also go in the file system and remove the file and Home Assistant
will have to pick it up. So the extra piece to make it
more useful and reusable, we allow it to be configured
by a file path that you put
in your configuration. Um, if you look at the bottom left,
you see that we actually -- just inside the switch block
in the configuration -- we add file_path and we add
a path to a file. And so again we first start
by importing and extending the abstract base class.
And so by -- this will allow us -- this time we actually focus
on ToggleEntity as our abstract base class
which is the basis for a switch. And so we define a constructor
because we want to actually focus on a specific file path
that the user chose. Then we want to be able to test,
is the switch on or not? So we implemented update method. And this update method will just
use the built-in OS module to see if the file exists
on the machine. And this method will also be
automatically called by Home Assistant periodically
to make sure that Home Assistant has the latest representation
of your switch. Now we're gonna add a name. The name is going to be
the file name, so again, we use the built-in OS module. We want to expose if you're on
or not and so we will just expose the internal instance method --
yeah sorry, instance variable that we stored
in the update method. For turning on we're doing
the Python equivalent of the touch tool in Linux
so we open and close the file right away, making sure it gets -- exists. And for turn off,
we remove the file. And so now again,
the last piece is, um . . . to add it to Home Assistant.
And so again, we have a setup_platform method. And this time because we want
to have -- want to add the file path that the user supplies,
we adjust the configuration, which is a dictionary, with the data
that the user put in its platform block. We get that data, so we can just
reference config file_path, and there we have
the file path of the user. We add it to Home Assistant, and it will look, for example, like this. Here we observe hello
and the file world. And hello is on and world is off. And so before I’m going
to show how this actually works, I want to show one more example,
and this is the automation component, because this is the actual
fun part, of course. And so this automation component
is going to be very simple. It's like an xor component
and it's going to keep two switches in opposite states. And so again, you create a file
in your configuration directory if you want to add this, but this time
in the configuration section, you have to point it
at the two names of your switches that you want to observe. And this, for example,
would be a very simple one. "Hey, if my air conditioning
goes on, make sure that the fan "to the outside is off
and vice versa." And so this is a component,
this is not a platform. This is actually something
that runs directly on the Home Assistant core
and has knowledge of this. And so it's a slightly
different structure. So first, every component
has to define its domain. In this case it's
xor_automation. The next piece is
the setup method. The setup method is, there's no
entity component abstraction around the platform --
around this component, so this is the real -- this is how Home Assistant
loads its components. And so you get the Home Assistant instance
and you get the whole configuration, so everything
that the user supplied. In our case, we're just going
to extract the two entities that we’re going to observe, we're going to import some helpers
that will allow us to test if an entity is on
and toggle it. And toggle it means if it’s on,
we turn it off and vice versa. And so what we're going to do now
is that the component wants to make sure when it gets started
we're already in a good place. So it's going to test, "Hey, is entity_1
equal to the state of entity_2? "In that case, let's toggle
entity_2 so it's in a reverse state." And then we're going to add a --
we want to listen to state changes. So whenever entity_1 changes,
we want to make sure that we can update entity_2, if necessary,
and the same with entity_2 updates. And so almost this allows
for state listeners. And so what you get passed in
is the entity that changed, the previous state
and the new state it became. And so in our state change list
now it's very simple. We're going to first see,
what is the entity that change, so we know, what is the other
entity that we have to look at? We're going to compare
the two entities again and if one is not the same --
if both are the same, we're going to again
toggle the other one. Then we'll import a helper
to register our state callback listener. And so you're passing
your Home Assistant instance, you pass in
the entities you want to observe and you pass in
your state callback listener. And by doing so, this will actually
listen for state changed events on the event bus and it will
actually already filter out all the state changed events
that are not about the two entities we care about. So it's already, like,
filtered down a lot. And the last piece is
that you're going to return true to show -- to tell Home Assistant,
"Hey, this component, "it loaded successfully." And so now that we have
an automation component and we have file switches,
I have this demo ready. And so this is Home Assistant. I have two browsers open
that are both pointing at the same version
of Home Assistant. I have two switches,
but one is pointed at hello, the other is pointed at world. And so now if I’m going to turn
the hello switch, the file hello will be deleted,
our automation will kick in, turn world on, and because world
is being turned on, our world file will get created. So let's hope it works. There you go. [applause] OK, thank you.
And so . . . [laughter] Um, as you guys might have seen,
the other interface actually updated too.
And so, however, I’m going to click
again on the left top interface and at the bottom right
is going to update as well. And this is all instantly
because every -- the front end is connected to Home Assistant.
It is connected to the same event bus
that, like the rest of the components
are connected to. And because the front end
can observe state changes as they come in, it can update
the representation of the whole -- of your home inside the browser
and can immediately update this uh, in the browser for you to see. But of course, like I said before,
we want a real case scenario. So now let's see if we can --
if we delete this file, Home Assistant which is, like,
trying to update the switches in the background periodically,
will catch this, will delete the file,
so hello will be turned off because the file doesn't exist. Our automation again will kick in
and will create world. There you go. And so now you can see we can
actually handle external state and we can handle
internal commands. And so that's everything I wanted
to show to you guys today. If you, like, want to try
the interface on your phone right now, you can go to home-assistant.io/demo.
It should load fine. On your computer with Python 3,
you can run pip3 install home assistant. It will install the core. And you can actually run
the command line hass --open-ui and it will start the server,
it will start your browser pointing at the server, and it
will figure things out right away. If you want more website --
if you want more information or tutorials, you can check out
our website at home-assistant.io. You can also stop by our community
at community.home-assistant.io or our very active chat room if you run into any troubles. And also today at 5 PM, we're having an open space at C122. So if you want to, like,
get some help to get -- oh, C120?
OK, C120. So if you want to, like,
get started with it or, like, wanna meet and greet some
of the developers, because there are, I think
four of us right now at PyCon, that will be your chance. Thank you very much. [applause] Are there any questions? (moderator)
So hello, we have about five minutes for questions; there are
two microphones over here. (Paulus Schoutsen)
In the meanwhile, this is actually how Home Assistant looks
if you have a full system. We can turn things off,
you can, like, observe your media players,
you can do a lot. (audience member 1)
What did you write the, uh, uh, Android component in, Paulus?
It’s really nice. (Paulus Schoutsen)
Um, so it's not an Android component. It’s actually a website
and it runs Polymer web components. (audience member 1)
Perfect, thanks, it's just a question. (audience member 2)
Check one, two, we good? OK, I think the mike
is working now. Right?
OK, three really quick questions. First one: I noticed that the event bus
kind of took a minute when you deleted hello
and waiting for world to come up. Is that because of watchdog
or something, or will that happen if you flick a switch,
that kind of thing? Um, because obviously
flicking a switch, that’d be kind of a long time
to wait for lighting. Uh, question number two:
you were passing around an H-A-S-S object in there
but it wasn't clear what type that object was, so could you tell
a little bit about that object? And also, would there ever be
an occasion practically where you'd have more than one
of those objects, or is it in effect a singleton? Question number three:
is the home -- the notion of the home sort of hardcoded as a location? Because I’m working on living
on a school bus, so is it possible that you could
accommodate in your data model a home that moves? (Paulus Schoutsen)
Well, I mean, OK, so the first one, the event bus, I forgot your question.
But I’ll go on to the second question. (audience member 2)
The delay -- it took a second from hello, deleting hello
to get world, remember? (Paulus Schoutsen)
Uh, yeah, so it's, um . . . well, so it's instant like this
but it's not instant when you remove the file because
it is not constantly watching the operating system because
it's using our update method that we defined -- oh -- that we
defined earlier in the example. (audience member 2)
But what if that were a light switch? (Paulus Schoutsen)
If it was a light switch, it all depends on how fast
your light can say, "Hey, I’m turned on or turned off."
And so this depends per implementation. So for a bad light switch,
we have to be optimistic, assuming our command succeeded. If it is a LIFX bulb, we actually
get the state pushed to us. And for you, we just have to say
after we send the command, "Hey, did the command succeed?" The second question was the hass object,
which is the Home Assistant instance. And this is where you can interact
with the service registry, the bus, and the state machine. And the third, a moving home
would also be possible because we can like --
we don't right now have for -- is home-like detection.
But you could set up a dynamic GPS
that you set somewhere in your state machine
so it should be possible. (audience member 2)
Thank you. (audience member 3)
I wasn't here the first talk, I was just wondering,
have you talked about -- what is -- what do you use
for device-device communication in the back end, and also
between the hub and the web app? (Paulus Schoutsen)
So we use for -- the web app currently uses event stream, which is
a HTML5 JavaScript implementation to get all the events
into the front end. And for device communication,
it really depends on what the device supports.
So for Philips Hue, we speak their protocol. But so, some -- if there’s an open,
like Z-Wave, for example, is a home automation standard,
so then you have to plug in a USB stick that speaks Z-Wave
into your computer. Home Assistant will connect
to that and then can speak to the Z-Wave network
in whatever language they use. (audience member 4)
I just had a question that you just kind of answered:
is there any -- is there any recommendation of protocol,
of kind of compliance that devices should have
that would work better for this? Or just can -- or each model
as I can see can just implement the protocol for whatever
device I get? (Paulus Schoutsen)
So you just -- we don't specify any protocol. You -- we implement whatever. The platforms implement any --
only the protocols that one device is speaking because, you know,
vendors are not making things to integrate with Home Assistant,
but we want Home Assistant to integrate with vendors. (audience member 4)
OK, thanks. (audience member 5)
I’m just wondering how you avoid some kind of recursion problem
in the xor automation example, like when you change hello
via the interface and your component changes world,
what’s to prevent you again responding to world changing and going? (Paulus Schoutsen)
There's nothing preventing you. So Home Assistant doesn't know
how you're going to handle the event or what you're going to call next.
It's all within your component. So if in my example,
I wouldn't have to check if they are not --
if they are the same, it would indeed lead into recursion
and the system crashes. (audience member 6)
Do you integrate with 1-Wire devices? (Paulus Schoutsen)
Sorry, which one? (audience member 6)
1-Wire. (Paulus Schoutsen)
1-Wire, um, yes, I think we have a 1-Wire sensor
but I’m not 100% sure. (audience member)
Yes, we do. (Paulus Schoutsen)
I do, OK, yeah we do. (audience member 6)
Is it just the temperature sensor? (Paulus Schoutsen)
Yes, I heard. The expert is over there. (audience member 7)
So what's the recommended approach with -- for example, I have Arduinos
and any moment in time I have an X number of sensors
throughout my apartment. One right now is detecting
when my downstairs neighbor starts smoking a cigarette
and it alerts me. (laughter) So I'd like to have a light
in my Hue turn red or a text or something. What's the recommended approach
with your own --? (Paulus Schoutsen)
So the easiest way, if like -- so Arduinos, I think we have an Arduino USB protocol,
so you can actually talk -- if you connect it
to a Raspberry Pi, it could talk to the Arduino. But a lot of people are switched
to the ESP8266 which is a microcontroller which includes Wi-Fi
and then you can just send either a REST call directly
to Home Assistant, but a lot of people actually use
MQTT as a broker intermediate. (Paulus Schoutsen)
So that other things can also plug in easy. (audience member 7)
Thank you. (audience member 8)
Hi, I wanted to know about the Nest integration because at some point I wanted
to just keep a log, a history of the temperature in the home
using the Nest as a, you know, a measuring device. and Nest makes it very hard
because you have to go through their API certification process
and so on, so I was wondering if -- (Paulus Schoutsen)
So that will -- we have a Nest component. It integrates Nest, and we
record all the temperatures. So this is something
you can get for free if you were to use --
you can also then -- you don't only have to keep it
in Home Assistant. We have certain components
that actually support it too, like Grafana and Splunk. So you can have like,
analytics engines. (audience member 8)
Cool, thanks. (moderator)
I'm sorry, this is all we have time for questions.
If you have further questions, you can talk to the speaker directly. Give him a hand again. (Paulus Schoutsen)
Yeah, or at 5 PM. [applause]