[Howto] Home automation with Home Assistant

Moderators: meveric, mdrjr, odroid

[Howto] Home automation with Home Assistant

Unread postby mad_ady » Mon Jun 12, 2017 7:04 pm

There comes a time in everyone's life when you want to put some things in order and have simple access to complex solutions. For example, maybe you have several scripts taking care of various problems (like turning a heater on/off, taking pictures with your security cameras, handling presence detection, etc), but you're the only one who can manage them because they require maintenance through ssh, or through some old-looking web page. I too have reached the same place in my life and have to look for an "umbrella" solution to manage all my personal automations and offer easy access for my family.
I was thinking of building a web dashboard to fit my needs, but I hate web development, I’m somewhat lazy and my sites are not good looking at all. Furthermore, it needed to be functional on all sorts of devices and screen sizes, and also future-proof. Fortunately I spent enough time looking around until I found the perfect solution - Home Assistant (https://home-assistant.io/) - HA for short.

Home Assistant is an open-source home automation platform built on Python 3 that supports over 650 components, which are modules that facilitate interaction with things like physical "smart" switches, relays, lights, sensors, network devices (TVs, routers, cameras, ...), software (like Kodi, MPD, Transmission, …), network services (like weather), but also allows you to add your own custom components. All the major home automation brands and technologies, like Hue, Nest, IKEA, Vera, ZigBee, MQTT, etc. are present and a complete list of components can be found here: https://home-assistant.io/components/.

Apart from the components, the platform has a dashboard-like web interface and an automation engine where you can combine data from different components and generate an event. For example, if it's Monday-Friday between 8:00 - 15:00 and the outside weather is sunny, and the outside temperature is above 30C and there is no chance of rain and the outside sprinklers have been off for at least 4 hours, then turn on the sprinklers for 20 minutes. The only complicated thing in the automation above is having a way to turn your sprinklers on and off - the rest is provided by existing components and Home Assistant's automation engine. Other use cases might include - locking and unlocking the front door when a specific person connects to the wifi (though I wouldn't do this), starting the air conditioning automatically when the system detects you’re coming home from work, etc. More use cases in this 1 hour video: https://www.youtube.com/watch?v=yWk7wn6FAGc. If you're familiar with Tasker for Android or IFTTT, then Home Assistant is the equivalent for your home.

Installation

You can install Home Assistant on any Odroid device. Depending on how many automations you plan to have you could use a C1 for a light set-up or even an XU4 for large homes and complex rules which might involve face recognition. I'm using it on a C2 which doubles as a Kodi player without issues.

We're going to do the "virtualenv" installation, which means that all the required python modules will be installed in a specific directory and will not interfere with system modules. We will also use a distinct user for Home Assistant. There are also Docker images available. The complete instructions with comments are here: https://home-assistant.io/docs/installation/virtualenv/

Code: Select all
$ sudo apt-get update
$ sudo apt-get dist-upgrade
$ sudo apt-get install python-pip python3-dev
$ sudo pip install --upgrade virtualenv
$ sudo adduser --system homeassistant
$ sudo addgroup homeassistant
$ sudo usermod -G dialout -a homeassistant
$ sudo mkdir /srv/homeassistant
$ sudo chown homeassistant:homeassistant /srv/homeassistant
$ sudo su -s /bin/bash homeassistant
$ virtualenv -p python3 /srv/homeassistant
$ source /srv/homeassistant/bin/activate
(homeassistant)$ pip3 install --upgrade homeassistant
$ exit


In order to start and manage the process, it's best to create a systemd service to handle it:
Code: Select all
$ sudo vi /etc/systemd/system/homeassistant.service
[Unit]
Description=Home Assistant
After=network.target time-sync.target
Requires=time-sync.target

[Service]
Type=simple
User=homeassistant
ExecStart=/srv/homeassistant/bin/hass -c "/home/homeassistant/.homeassistant"

[Install]
WantedBy=multi-user.target



In order to start Home Assistant, simply start its service:
Code: Select all
$ sudo service homeassistant start
$ sudo service homeassistant enable


Note that if you will be using components that need HTTPS, you will need to have time correctly set up at boot, so that the certificates are valid. The service startup depends on systemd-timesyncd, which in turn depends on ntp *not* being installed:

Code: Select all
$ sudo apt-get remove ntp
$ sudo service systemd-timesyncd restart
$ sudo systemctl enable systemd-timesyncd


In case of problems, you will be able to review the logs through journalctl:
Code: Select all
$ sudo journalctl -u homeassistant -f


Once the process starts, you will be able to connect to http://odroid-ip:8123/. Note that the first startup (or a startup following an update) might be slower, so leave it run for a few minutes until accessing the web interface. Home assistant also provides a native app for IOS (https://itunes.apple.com/us/app/home-as ... 68401?mt=8), while for Android clients you can pin the page as a homescreen launcher (Chrome -> navigate to http://odroid-ip:8123 -> Menu -> Add to homescreen).

Image
Figure 1 - Home Assistant startup page

The configuration file

In order to set up components and configure your installation, you'll have to work a lot with Home Assistant's configuration file(s). Hopefully, in a future version you might be able to handle the configuration directly from the web interface, but for now, you'll need a text editor. The main file is /home/homeassistant/.homeassistant/configuration.yaml. Its format is YAML - which stands for "Yet Another Markup Language". Like python, it uses white space (not tabs!) to delimit sections of code. By default it uses a two space indentation for nested sections. In case you get in trouble, you will receive error messages when starting the service. You can validate the syntax with a service like http://www.yamllint.com/ which will let you know where you went wrong. Here is a troubleshooting guide: https://home-assistant.io/docs/configur ... eshooting/.

Once you've made changes to the configuration file you will need to restart the homeassistant service to apply those changes. You can do this either from the shell with sudo service homeassistant restart, or from HA's web interface, by clicking the top left icon (menu), selecting the "Configuration" icon and calling the "Restart" option from the "Server Management" section. This video shows some tips you should consider when editing the configuration: https://www.youtube.com/watch?v=hFDVB2H6TNo.

Image
Figure 2 - The default configuration

If you plan on using HA from outside the LAN (e.g. from the Internet), you have several options. One of them is to enable HTTPS support and forward port 8123 on your router. This gives you encryption, but exposes your installation to the internet (and there might be vulnerabilities that could allow attackers take control of your system/LAN). A second option (which I prefer) is to set up a VPN on your router (or even on your Odroid) that allows you to connect and access HA (and other LAN resources) securely.

If you want to use HTTPS, in order for all features to work you will need to supply valid SSL certificates (not self-signed). In order to get valid certificates you will need to have a public DNS name (e.g. by using a dynamic DNS service like duckdns.org) and use letsencrypt.org to set up a valid SSL certificate for your installation. Step by step details can be found in this video: https://www.youtube.com/watch?v=BIvQ8x_iTNE. If you must use self-signed certificates, here's a guide: https://home-assistant.io/docs/ecosyste ... rtificate/.

Regardless of access mechanism - http or https, you will want to set up a password. HA doesn't support multiple user accounts, but you can set an API Password that you will need to log into the web interface. The best way to do this is to create a file that will keep all your sensitive data (like passwords and URLs), name it secrets.yaml and reference it in configuration.yaml.

Code: Select all
$ cat /home/homeassistant/.homeassistant/secrets.yaml
api_password: odroid
$ cat /home/homeassistant/.homeassistant/configuration.yaml

http:
  api_password: !secret api_password


Now, when you will restart HA, you will be asked for a password. More details about secrets here: https://home-assistant.io/docs/configuration/secrets/

Image
Figure 3 - Authentication

Setting up components

In order to get acquainted with how HA configuration works, we will set up some components. I want to set up weather, some IP cameras, Kodi and MPD, presence detection based on WiFi and also a 1-wire temperature sensor connected to the Odroid.

Weather from Darksky
There are several weather providers already integrated in HA (https://home-assistant.io/components/#weather), so you can pick your favourite. I'm going with DarkSky (https://home-assistant.io/components/sensor.darksky/) which provides quite accurate forecasts for my area. You should consult the component's help page for details about configuration and which variables you can use. You will need to register with Dark Sky and get an API Key which will let you make 1000 calls per day for free. It's best to save this API Key inside your secrets.yaml file (replace with your own key):

Code: Select all
darksky_api_key: 87f15cbb811204412cc75109777ea5cf


The configuration has several variables, most of which are optional, however, under configuration.yaml, under sensor you would have (feel free to delete the platform: yr entry):

Code: Select all
sensor:
  - platform: darksky
    api_key: !secret darksky_api_key
    name: Dark Sky
    monitored_conditions:
      - summary
      - precip_type
      - precip_probability
      - temperature
      - humidity
      - precip_intensity
      - wind_speed
      - pressure
      - wind_bearing
      - apparent_temperature
      - icon
      - minutely_summary
      - hourly_summary
      - temperature_max
      - temperature_min
    units: si
    update_interval: '00:15'


The code is mostly self-explanatory. It configures a new platform of the type darksky, with a specific name (optional) and api_key (required) and pulls a set of parameters (monitored_conditions) from the weather provider every 15 minutes. Your actual location is taken from the latitude/longitude parameters under homeassistant, so make sure that's correct. After you restart the homeassistant service, you should be able to see the monitored variables as badges on the top of your window. Clicking on a badge will show you how that particular value has changed over time.

Image
Figure 4 - Weather data

Viewing IP cameras
HA supports a lot of cameras (https://home-assistant.io/components/#camera) including reading data from a file, which could be used to display a graph, or visual data generated by other tools. We will be using the Generic MJPG Camera (https://home-assistant.io/components/camera.mjpeg/) component and the Local File (https://home-assistant.io/components/camera.local_file/) component.

The camera we want to monitor has the following URL (it's a public webcam): http://iris.not.iac.es/axis-cgi/mjpg/vi ... on=320x240 which we should add to the secrets.yaml file.

Code: Select all
camera1_stream_url: http://iris.not.iac.es/axis-cgi/mjpg/video.cgi?resolution=320x240
camera1_still_url: http://iris.not.iac.es/jpg/image.jpg


The configuration part inside configuration.yaml looks like this for both cameras:

Code: Select all
camera:
  - platform: mjpeg
    mjpeg_url: !secret camera1_stream_url
    still_image_url: !secret camera1_still_url
    name: Observatory in Spain
  - platform: local_file
    file_path: /tmp/tux.jpg



As usual, you will need to restart the HA service to reread the configuration (this might be a good time to comment out the introduction component as well). Note that when you click on a webcam you will see a live feed, otherwise the still image is updated every 10 seconds.

Image

Figure 5: Webcams!

So, what can you do with these configured webcams apart from looking at them? Well, you can use them with other components such as OpenCV (https://home-assistant.io/components/im ... ng.opencv/) to generate triggers when certain faces are seen, or Seven Segments Display (https://home-assistant.io/components/im ... _segments/) which can take readings of various digital displays.

Kodi and MPD
To configure media players, you can look under the Media Player component list https://home-assistant.io/components/#media-player. To configure Kodi (https://home-assistant.io/components/media_player.kodi/), you will need to enable the Allow remote control via HTTP option (http://kodi.wiki/view/Settings/Services/Control) and set an appropriate username and password first.
Add the user and password to the secrets.yaml file:
Code: Select all
kodi_user: kodi
kodi_pass: kodi

And next, edit configuration.yaml:
Code: Select all
media_player:
  - platform: kodi
    host: 192.168.1.140
    name: Kodi Livingroom
    username: !secret kodi_user
    password: !secret kodi_pass


To configure MPD, assuming that you already have a MPD server in your network, add the MPD component (https://home-assistant.io/components/media_player.mpd/), add the password to secrets.yaml:
Code: Select all
mpd_secret: mpd


And next, edit configuration.yaml:
Code: Select all
media_player:
...
  - platform: mpd
    host: 192.168.1.140
    name: MPD Living
    password: !secret mpd_secret


After you restart Home Assistant you will get the two new media players and you will be able to see their state (playing/stopped), control volume and even change the current playlist or use the text-to-speech component to have the media player "speak" what you want.

Image
Figure 6: Media players

Getting presence detection from an Asus router
The presence detection components (https://home-assistant.io/components/#p ... -detection) try to track people's locations so that you can apply geofencing rules (e.g. do something if a person enters or leaves a location). Usually tracking is done by detecting devices connected to a router (via wifi), or via bluetooth proximity (https://home-assistant.io/components/de ... h_tracker/), or by using location services such as Owntracks (https://home-assistant.io/components/de ... owntracks/).

We will use a router-based tracker - which, depending on your router periodically connects to the management interface of your router, lists the ARP table and discovers which devices are connected. A lot of router types are supported, from high-end vendors like Cisco, to consumer-grade routers like Asus, Netgear and TP-Link. Even open-source firmwares are supported, like OpenWRT, DD-WRT and Tomato.

We will be using an Asus router with ssh enabled, so we need the ASUSWRT component: https://home-assistant.io/components/de ... r.asuswrt/. You can chose to login with username/password or setup a ssh key and log in with a key instead. Note that certain firmware versions enable security measures which limit the number of ssh connections and can blacklist your IP if a lot of connections are initiated.

As usual, we will set private data (such as the path to the key or the ssh password) in the secrets.yaml file:

Code: Select all
router_user: admin
router_password: my_secret_password


Inside configuration.yaml add the following section:
Code: Select all
device_tracker:
  - platform: asuswrt
    host: 192.168.1.1
    username: !secret router_user
    password: !secret router_password
    interval_seconds: 120
    consider_home: 300
    track_new_devices: yes

The device tracker configuration page (https://home-assistant.io/components/device_tracker/) gives more details about what options you can use. The interval_seconds option is the time between scans (2 minutes) and the consider_home option keeps you "at home" even if your devices is not seen for 300 seconds.

Once you restart HA, after the initial discovery is done a new file will be created called known_devices.yaml. Here you will be able to assign a friendly name and even a picture to a specific device, or have other devices be ignored.

One entry in known_devices.yaml may look like this:
Code: Select all
aldebaran:
  hide_if_away: false
  mac: 00:1E:06:31:8C:5B
  name: aldebaran
  picture: /local/aldebaran.png
  track: true
  vendor: WIBRAIN

Notice that I added a path to local picture which is stored in /home/homeassistant/.homeassistant/www/aldebaran.png. You can create the www folder with:
Code: Select all
$ sudo mkdir /home/homeassistant/.homeassistant/www

If there are devices which you don't want to monitor, you can set track: false in known_devices.yaml

Image
Image

Figure 7 - Initial discovery/Customized entries


Measuring temperature from 1wire sensors
A very powerful feature of Home Assistant is the ability to track all sorts of sensors(https://home-assistant.io/components/#sensor). We want to monitor a temperature sensor based on the 1 wire protocol, connected locally to the Odroid (https://home-assistant.io/components/sensor.onewire/). Before adding the sensor in HA, make sure it’s readable from the command line. You can follow the setup guide on the wiki: http://odroid.com/dokuwiki/doku.php?id= ... ardware_1w

You will need to know the sensor’s ID to add it to HA:
Code: Select all
$ ls /sys/bus/w1/devices/
28-0516866e14ff  w1_bus_master1
$ cat /sys/bus/w1/devices/28-0516866e14ff/w1_slave
92 01 4b 46 7f ff 0c 10 b5 : crc=b5 YES
92 01 4b 46 7f ff 0c 10 b5 t=25125



Next, you can make these changes in configuration.yaml and poll the sensor every 5 minutes:
Code: Select all
sensor:
...
  - platform: onewire
    names:
      28-0516866e14ff: Living room
      scan_interval: '00:05'



Restart HA and the new reading will be visible in the web interface as a badge in the top part of the page.

Sorting out the views
You will notice that once you start adding a few components, the web interface starts to get messy with a lot of items scattered everywhere. You can use groups and views to clean up the interface and put related items in their own tab. To understand what needs to be done, let's clear the vocabulary.

Entities are variables which provide data - such as a sensor, or switch. Platforms (like dark_sky) usually provide access to multiple entities (min/max temperatures, forecast, etc). You can view a list of entities, their names and their value if you navigate in the web interface under Menu -> Developer tools -> States (<>) -> Entities.

A group is simply an object that holds a list of entities. Visually, a group is rendered as a panel, or a card. By default the group group.all_devices exists and holds the items discovered by a device tracker platform. Groups usually contain a list of entities.

A view is rendered as a separate tab inside Home Assistant. Views are actually groups of groups and differ from regular groups by having the property of view: yes. You can also add individual entities, as well as groups to a view.

We will group our existing sensors into the following categories:
  • The first tab is called Home and contains the following groups (it will be internally called default_view, so that it is displayed when you log in):
    [**]Weather data
    [**]Presence information
    [**]System information (to show you if there are updates available)
  • The second tab is called Media and contains the following groups:
    [**]Media players
  • The final tab is called Images and contains:
    [**]Webcams
The configuration looks similar to the list above:
Code: Select all
group:
  default_view:
    view: yes
    entities:
    - group.weather
    - group.presence
    - group.systeminfo
  media:
    view: yes
    entities:
    - group.mediaplayers
  images:
    view: yes
    entities:
    - camera.observatory_in_spain
    - camera.local_file
  weather:
    name: Weather
    entities:
    - sensor.dark_sky_apparent_temperature
    - sensor.dark_sky_daily_high_temperature
    - sensor.dark_sky_daily_low_temperature
    - sensor.dark_sky_hourly_summary
    - sensor.living_room
  presence:
    name: Presence
    entities:
    - device_tracker.aldebaran
    - device_tracker.nutty
  systeminfo:
    name: System Info
    entities:
    - updater.updater
  mediaplayers:
    name: Media Players
    entities:
    - media_player.mpd_livingroom
    - media_player.kodi_livingroom
 

Image

Figure 8 - A cleaner interface with views and groups
More details about groups and layout in this video: https://www.youtube.com/watch?v=fpiVMLNuxSs

Updating to a newer version

Since Home Assistant was not installed via apt-get, you will need to handle updates manually. Before updating it's best to read the release notes and verify that the update is not breaking any previous configurations (sometimes the configuration for new components gets redesigned so you need to redo it). You can get a notification for a new version by using the updater.updater entity which periodically checks for newer versions and can display them inside Home Assistant. Updates are pretty frequent - you can expect a "major" version every 2-3 weeks.

The update procedure is simple (and detailed here: https://home-assistant.io/docs/installa ... -assistant).

Code: Select all
$ sudo service homeassistant stop
$ sudo su -s /bin/bash homeassistant
$ source /srv/homeassistant/bin/activate
(homeassistant)$ pip3 install --upgrade homeassistant
(homeassistant)$ exit
$ sudo service homeassistant start


In the next articles we will look at setting up more complex components (like a remote relay, an air conditioning unit), setting up automations and setting up a dashboard.
Last edited by mad_ady on Thu Jul 20, 2017 10:06 pm, edited 2 times in total.
User avatar
mad_ady
 
Posts: 2587
Joined: Wed Jul 15, 2015 5:00 pm
Location: Bucharest, Romania
languages_spoken: english
ODROIDs: XU4, C1+, C2

Re: [Howto] Home automation with Home Assistant

Unread postby mad_ady » Mon Jun 12, 2017 7:07 pm

In this article we will do more advanced configuration with Home Assistant, but the examples are based on what was built in the first article (https://magazine.odroid.com/wp-content/ ... pdf#page=6). We'll be jumping from problem to problem, but going through these steps can teach you how to do more advanced things with Home Assistant and can serve as a general guide even if you don't need to implement the exact same things.

Working with Home Assistant's developer tools

In the previous article we've mentioned the Developer Tools inside Home Assistant. You can access them by going to the left panel in the web interface and hovering over the buttons. We have the following tools:
  • Services: Lets you make calls to all sorts of services exposed by your components. You can do things like trigger an automation, hide or show groups, reload HA configuration, control a media player object (play/pause/load playlist), etc. The available services can change based on what components you have active in your configuration. It's a good place to test some action before adding it to an automation
  • States: Lets you override the state of any entity. It also lists all entities, with their current state and attributes. You can use this list to find out an entity name, either to know how to reference it in the configuration (e.g. the entities visible in a view), or to use it in a template.
  • Events: Lets you generate an event on the event bus. There are several events available, but in practice I never had to generate events.
  • Templates: The HA templating engine uses Jinja2 templating syntax (http://jinja.pocoo.org/docs/dev/templates/) with the addition of exposing some internal variables. The templating syntax is more like a programming language, so take your time to read the documentation: https://home-assistant.io/docs/configur ... emplating/. The point of templates is to process input or output data and to format it in a different way. The Templates view gives you a workspace where you can play around and test the syntax before writing it to the configuration file. When you first load the page it will have a sample syntax, which among other things iterates through all your sensors and shows you their values. This can teach you that you can access a sensor state by calling {{ states.sensor.sensor_name.state }}. We'll play with an example in a minute.
  • Info: Shows you the current version as well as any errors that have been logged.

Image
Figure 1. Working with Developer Tools and Templates

In order to better understand the relationship between an entity name and how to use it in a template, let's run an experiment. Let's assume we need to get the icon of Dark Sky's Weather forecast. First of all - we need to use the States tool to get the correct entity name. If you search there for the name shown in the web interface "Dark Sky Hourly Summary", then we will find an entity called "sensor.dark_sky_hourly_summary". Most HA entities have a state and may have one or more attributes and those should already be visible in the States view.
Now we can switch to the Templates tool and we can add our own template at the end of the template dialog. Let's try the following templates and let's see what the output is:

Code: Select all
The states object is "{{ states }}"

The states.sensor object is "{{ states.sensor }}"

The states.sensor.dark_sky_hourly_summary object is "{{ states.sensor.dark_sky_hourly_summary }}"

The states.sensor.dark_sky_hourly_summary.state value is "{{ states.sensor.dark_sky_hourly_summary.state }}"

The states.sensor.dark_sky_hourly_summary.attributes.entity_picture  value is "{{ states.sensor.dark_sky_hourly_summary.attributes.entity_picture }}"



The outputs you receive can be viewed in the following image. Some of the data points to python objects, others (like state and attributes) return string values which you can use. With this information you are prepared to start writing templates and automations.

Image
Figure 2. Templates in action

Notification interface and HA API

If you have scripts which run in the background usually started by cron you may want to be notified when things go wrong and the script fails for whatever reason. Most tutorials online will show you how to send a notification email or SMS, but for problems which are not too critical - maybe you don't like checking email or being woken up at 3 AM. For this you can push messages to Home Assistant using curl and its API so that you can get notifications from your scripts whenever you log into Home Assistant. This way you get to know what happened if you regularly log into the web interface. A similar approach can be taken to change the states of Home Assistant entities by using external triggers, or you can use the API to query entities from external scripts.

To set this up, you only need to run a shell command from your script when handling an error:

Code: Select all
/usr/bin/curl -X POST -H "x-ha-access: api_password" \
-H "Content-Type: application/json" --data \
"{\"message\": \"Something bad happened in your script\", \"title\": \"My background script\"}" \
http://odroid-ip:8123/api/services/persistent_notification/create


The command above uses the persistent notification action (https://home-assistant.io/components/pe ... ification/) called via Home Assistant's API. For this you will need to provide the api_password and send a json object containing the message and title. Note that JSON mandates that you use the quote mark ("), and not apostrophe (') for quoting! The nice thing is that the notification will be displayed on all views/tabs, so you shouldn't miss it. The result will look like Figure 3.

Image
Figure 3. Persistent notification

Running external scripts on state change

I'd like to get weather forecast from Dark Sky in Romanian so that it is useful for non-english speakers in the household as well. Since Dark Sky doesn't support Romanian yet, I need to do it myself. No problem, we can do it with Home Assistant - here's the plan:
1. Install a translation program on the Odroid that can use various online translation services and output the desired language. I used trans: https://github.com/soimort/translate-shell

Code: Select all
$ sudo wget -O /usr/local/bin/trans git.io/trans
$ sudo chmod a+x /usr/local/bin/trans

Test the program to make sure it works as desired

Code: Select all
$ trans -b :ro "My name is my password"

2. Set up a new shell command component in Home Assistant (https://home-assistant.io/components/shell_command/) to call the command-line script. The shell component can execute a command and take the output of a template as parameter for the command. When a template is used as a parameter, the command execution is more strict and you are not allowed to use pipes or redirection to file. Should you need to use more complex command-lines with pipes and templates, you should add them to a shell script and call the script instead. Fortunately the trans command supports writing output directly to a file. Make the following changes to configuration.yaml:

Code: Select all
shell_command:
  translate_weather: '/usr/local/bin/trans -b :ro "{{ states.sensor.dark_sky_hourly_summary.state }}" -o /tmp/ha-weather-forecast.txt'



The command takes the state of the Dark Sky Hourly Summary sensor and passes it to trans for translation. Practice getting the right state by playing in the Template tool, as we've done before. It outputs the translated text into /tmp/ha-weather-forecast.txt. To run this command manually, log into the Home Assistant web interface, navigate to Developer Tools in the left panel and click on the Services icon. You can call the shell_command domain with the translate_weather service and without other parameters. If you check the temporary file you should see your translated weather forecast.

3. Import the translation back into Home Assistant by configuring a file sensor (https://home-assistant.io/components/sensor.file/). The file sensor monitors a file for changes and imports the last line into Home Assistant. Make the following changes to your configuration.yaml:

Code: Select all
sensor:

 - platform: file
    file_path: /tmp/ha-weather-forecast.txt
    name: Dark Sky Forecast Ro



You should also import this new entity in any views where you wish to use it:

Code: Select all
group:

  weather:
    entities:
...
      - sensor.dark_sky_forecast_ro


If you restart Home Assistant, you should see the new item in the Weather group. However, there is still a problem. This entity will never update. We still need to add a trigger so that when the English forecast changes, the translated forecast should change as well. For this we need to use automations.

Image
Figure 4. The translated forecast next to the original one

4. Create an automation by going to the Automation link in the side panel. Note that you currently need to use the Chrome browser for this step, since other browsers are not supported. Use the "+" button to add an automation, and give it a suggestive name, like "Weather forecast translation". The trigger should be "state" and the entity id should match the desired "source" entity - in or case "sensor.dark_sky_hourly_summary". Note that we are using the sensor name as it can be found in the States tool. You can leave the "From" and "To" fields blank, since we want it to trigger on any value change.

Next we need to specify an action or a sequence of actions to be performed when triggered. We need "Call Service" as an action type. The Alias is just a descriptive name for our action and we can call it "Run translate_weather shell_command". The Service field is composed from the whole service call - meaning domain and service name as used in the Services tool, so in our case it will be "shell_command.translate_weather". The Service Data field can be left blank in our case, since the component doesn't need additional parameters. You can now click the save icon to save your automation.

Image
Figure 5. Create a new automation

That should be enough. Now when the weather forecast changes it will trigger the automation and cause the forecast to be translated and saved in a different entity, except there is still a problem.
When you restart Home Assistant, the weather state might not change for a long time and your translation might return "unknown" until the first transition. To fix this, we'll run a second automation on Home Assistant startup to update the translation. This time the trigger will be platform homeassistant with event start. The action will be the same as the previous automation. Unfortunately, the web UI doesn't support yet this platform, so we'll have to edit the file manually.
All automations are saved in ~homeassistant/.homeassistant/automations.yaml. In this case, you would need to add the following to it:

Code: Select all
- action:
  - alias: Run translate_weather shell_command
    service: shell_command.translate_weather
  alias: Update weather translation on startup
  id: '1502097058891'
  trigger:
    platform: homeassistant
    event: start

If you look at the automation you've already added through the user interface, you'll see a very similar syntax. The only thing new is the id. This is simply the current UNIX timestamp, and needs to be unique for your system (you can get a new one with date +%s). Once this is configured, after you restart Home Assistant you will get the translated state shortly.

Toggling a system service from Home Assistant

Let's explore a new use case. Let's say you have a system service running on your Odroid that you want to turn on/off from Home Assistant. For me this will be Mycroft, because it uses some resources when idle and can get confused by ambient sounds when I'm watching a movie. More details about Mycroft here: viewtopic.php?f=52&t=27661. The point is you can use commands such as service mycroft start to control the service. You're not limited to services - you could toggle anything on or off.

To control it from Home Assistant we can use the command line switch component (https://home-assistant.io/components/sw ... mand_line/), so add the following to your configuration.yaml:

Code: Select all
switch:
  - platform: command_line
    switches:
      mycroft:
        command_on: sudo /usr/sbin/service mycroft start
        command_off: sudo /usr/sbin/service mycroft stop
        command_state: /usr/sbin/service mycroft status >/dev/null 2>&1
        friendly_name: "Mycroft status"



You can also add it to a separate view:

Code: Select all
group:

 switches:
    name: Switches
    view: yes
    entities:
    - switch.mycroft



There's one more thing you need to add for this to work. The sudo command will ask for a password by default, so we need to tell sudo that the user homeassistant can run the service command as root without a password. We can do this by running sudo visudo and adding the following line at the end of the file:

Code: Select all
homeassistant ALL=NOPASSWD: /usr/sbin/service


Let's expand this example a little. Let's say you want to be able to toggle a service running on a different device. The most secure way to do this would be through ssh. In order to do this, we'll need to setup keys for ssh, so that homeassistant user can run commands through ssh without being prompted for a password (note that for security's sake you'll need to protect your keys!). You will need to run the following steps with the homeassistant user.

1. Create a new ssh key for homeassistant with no password
Code: Select all
$ sudo su -s /bin/bash homeassistant
$ cd ~homeassistant
$ ssh-keygen -t rsa


Accept the default values (key stored in /home/homeassistant/.ssh/id_rsa, and no passphrase). You can use this key to control many devices (including using it to login on routers for presence detection) - no need to create multiple keys.

2. Copy the key to the remote system
Code: Select all
$ ssh-copy-id root@other-device-ip

Make sure you input the correct password for the account you're connecting as (I'm using root on the remote device).

3. Test the connection manually
Code: Select all
$ ssh root@other-device-ip hostname

You should receive one line with the other device's hostname, without being prompted for a password. If you get this, it means it works. If you don't, here's an awesome troubleshooting guide: https://www.nsc.liu.se/systems/ssh-tutorial.pdf

4. Configure it in Home Assistant - add a new switch entry in configuration.yaml:

Code: Select all
switch:
  - platform: command_line
    switches:
...
      mycroft_kitchen:
        command_on: ssh root@kitchen /usr/sbin/service mycroft start
        command_off: ssh root@kitchen /usr/sbin/service mycroft stop
        friendly_name: "Mycroft Kitchen status"


If you don't want the constant polling from Home Assistant for the state, you can omit the command_state line and in this case Home Assistant will assume it is off and will keep track only of the changes you make in the user interface. Also, the interface will change from a slider to two icons to activate/deactivate.

Image
Figure 6. Switches for system processes

Toggling a switch based on media playback or presence information


Now that we can manually turn Mycroft on or off (or any switch for that matter), let's make things interesting. I'd like to have Mycroft running when I'm at home (my phone is connected to the router and detected by the presence detection we've implemented in the previous article) and Kodi is not playing. But that can be ambiguous, so let's define what we really want:

  • User transitions from not_home to home and Kodi is idle => turn on Mycroft
  • User transitions from home to not_home => turn off Mycroft
  • User is home and Kodi transitions from anything to playing => turn off Mycroft
  • User is home and Kodi transitions from anything to idle => turn on Mycroft

For this, we will make a few automations. What's different from the previous automations will be the use of conditions (https://home-assistant.io/docs/scripts/conditions/). Triggers say when an action should happen, conditions are used as filters and say if that action should happen.

So, let's do the first one. My user is tracked by the device called nutty. Since the web interface doesn't support conditions (yet), we'll have to do it manually, in the config file (automations.yaml):

Code: Select all
- action:
  - alias: Turn on Mycroft
    service: switch.turn_on
    entity_id:
      - switch.mycroft
  alias: Turn on Mycroft when Nutty arrives home and Kodi is idle
  id: '1502097058892'
  trigger:
    platform: state
    entity_id: device_tracker.nutty
    to: 'home'
  condition:
    condition: and
    conditions:
      - condition: state
        entity_id: 'media_player.kodi_livingroom'
        state: 'idle'



The automation is triggered and evaluated each time the entity device_tracker.nutty changes state. When it is triggered, the condition is evaluated as well and if media_player.kodi_livingroom is idle at that time, then the action is executed and the switch is turned on. I could have also tested that Mycroft is off, but turning on an on switch has no effect.

If that is difficult to follow, here's a pseudo-code:
Code: Select all
onStateChange(device_tracker.nutty):
  if states.device_tracker.nutty.state == 'home':
    if states.media_player.kodi_livingroom.state == 'idle':
      switch.turn_on(switch.mycroft)

The off automation looks similar, but is simpler since it doesn't have an extra condition:
Code: Select all
- action:
  - alias: Turn off Mycroft
    service: switch.turn_off
    entity_id:
      - switch.mycroft
  alias: Turn off Mycroft when Nutty leaves home
  id: '1502097058893'
  trigger:
    platform: state
    entity_id: device_tracker.nutty
    to: 'not_home'


The last two automations should be triggered by Kodi state changes and use conditions to test if the user is home or not.

Code: Select all
- action:
  - alias: Turn off Mycroft
    service: switch.turn_off
    entity_id:
      - switch.mycroft
  alias: Turn off Mycroft when Kodi is playing and Nutty is home
  id: '1502097058894'
  trigger:
    platform: state
    entity_id: media_player.kodi_livingroom
    to: 'playing'
  condition:
    condition: and
    conditions:
      - condition: state
        entity_id: 'device_tracker.nutty'
        state: 'home'


And the last one should be:
Code: Select all
- action:
  - alias: Turn on Mycroft
    service: switch.turn_on
    entity_id:
      - switch.mycroft
  alias: Turn on Mycroft when Kodi is idle and Nutty is home
  id: '1502097058895'
  trigger:
    platform: state
    entity_id: media_player.kodi_livingroom
    to: 'idle'
  condition:
    condition: and
    conditions:
      - condition: state
        entity_id: 'device_tracker.nutty'
        state: 'home'


Once you're done editing automations.yaml, you can reload the automations directly from Home Assistant by going to the Configuration view and selecting Reload Automation.

You should now test the automations by triggering them and checking the result in all the cases to rule out any bugs. You can use the Logbook view to see when automations have been triggered.

Image
Fig 7: Logbook viewer

Customize the names and icons

Let's address one more issue - by default all switches have the "lightning" icon, and maybe you want to use something more appropriate. Also, you may later want to change the friendly name of an entity, and that would change its id and break the automations it's in. There are also some built-in groups - like all the devices managed by a device_tracker or all the automations which allows you to enable/disable/manually trigger an automation, but they are hidden by default. In order to make all these changes, we'll need to add a customize section in the beginning of the configuration file, under homeassistant:, indented by two spaces: https://home-assistant.io/docs/configur ... g-devices/

Let's do the following - let's display the automations group and change the icons for the switches with something more appropriate. You can use icons from Material Design (https://materialdesignicons.com/cheatsheet) or your own images. We will make changes to configuration.yaml:

Code: Select all
homeassistant:

  customize:
    group.all_automations:
      hidden: false
      friendly_name: All automations
    switch.mycroft:
      friendly_name: Mycroft living room
      icon: mdi:assistant
    switch.mycroft_kitchen:
      icon: mdi:assistant
    sensor.living_room:
      icon: mdi:temperature-celsius

group:
  default_view:
    entities:

    - group.all_automations


Image
Fig 8. Customizations for automations and icons

More examples

The Home Assistant community has lots of examples in their cookbook: https://home-assistant.io/cookbook/. But there are also a lot of great examples in their forums: https://community.home-assistant.io/c/projects (for example here's an alarm clock https://community.home-assistant.io/t/c ... ated/15195).
Last edited by mad_ady on Wed Aug 09, 2017 8:44 pm, edited 1 time in total.
User avatar
mad_ady
 
Posts: 2587
Joined: Wed Jul 15, 2015 5:00 pm
Location: Bucharest, Romania
languages_spoken: english
ODROIDs: XU4, C1+, C2

Re: [Howto] Home automation with Home Assistant

Unread postby mad_ady » Mon Jun 12, 2017 7:08 pm

reserved for dashboard integration
User avatar
mad_ady
 
Posts: 2587
Joined: Wed Jul 15, 2015 5:00 pm
Location: Bucharest, Romania
languages_spoken: english
ODROIDs: XU4, C1+, C2

Re: [Howto] Home automation with Home Assistant

Unread postby joerg » Mon Jun 12, 2017 7:57 pm

Very nice howto.
Do you know if Home Assistent also can communicate to i2c PCF8574 i/o expander? The background is that I have a home automation self developed running on raspi since about 7 years. In this time there were no projects availlable like Home Assistent or Pimatic. My self done I/O expanders are of 6 PCF8574 as 24V inputs and 6 PCF8574P as relais outputs. And the automation I programmed with Qt5. I just tried to port my home automation to pimatic, but it seems a little complicated to program everything with rules and also the webpage is not looking so nice.
So It would be nice if you or someone else can confirm that Home Assistant can do this, inclusive some logic for shutters.
joerg
 
Posts: 683
Joined: Tue Apr 01, 2014 2:14 am
Location: Germany
languages_spoken: german, english, español
ODROIDs: C1, C1+, C2

Re: [Howto] Home automation with Home Assistant

Unread postby mad_ady » Mon Jun 12, 2017 8:16 pm

I can't find anything specifically to that component, and from the data sheet I can see that it acts like a bridge from i2c to an 8bit bus? You could use a command line component to read/write data to the i2c bus via a command-line or script (https://community.home-assistant.io/t/w ... y-pi/11631). Since you already have this set up you could reuse your code with regard to accessing the I2C device (reading/writing data), and use HA as a frontend to collect data and prepare rules, etc.
More details about automations in the next article (I'm still learning that).
User avatar
mad_ady
 
Posts: 2587
Joined: Wed Jul 15, 2015 5:00 pm
Location: Bucharest, Romania
languages_spoken: english
ODROIDs: XU4, C1+, C2

Re: [Howto] Home automation with Home Assistant

Unread postby mad_ady » Thu Jul 20, 2017 10:08 pm

I updated the first post and fixed a problem in the systemd startup script that caused homeassistant to run as root. Please update your startup script if you've used the one in the first post or the magazine.
User avatar
mad_ady
 
Posts: 2587
Joined: Wed Jul 15, 2015 5:00 pm
Location: Bucharest, Romania
languages_spoken: english
ODROIDs: XU4, C1+, C2

Re: [Howto] Home automation with Home Assistant

Unread postby mad_ady » Wed Aug 09, 2017 8:47 pm

I've updated the second post and posted examples on creating automations and customizations with Home Assistant. Check it out: viewtopic.php?f=52&t=27321&p=193003#p193003
User avatar
mad_ady
 
Posts: 2587
Joined: Wed Jul 15, 2015 5:00 pm
Location: Bucharest, Romania
languages_spoken: english
ODROIDs: XU4, C1+, C2


Return to Ubuntu (All Linux'es)

Who is online

Users browsing this forum: No registered users and 1 guest