Home Automation (part 3)

My current Home-Assistant setup

Currently my HA homepage looks like this:


Let's first go over the various parts of the UI, and how my setup is currently working befor diving into the configuration file details.

The web UI

  • At the top, we have the status of various sensors
    • Update notification
    • Sun status, useful sensor to automate things based on sunset/sunrise
    • Device tracker status: My wife's and my phone are both at home
    • Z-Wave embedded switch current power consumption
    • Current Weather
    • Speedtest: download, ping, upload
    • Z-Wave embedded switch power consumption sum: so we know since we started using HA the living room light consumed 5.62kWh
    • Transmisison torrent download and upload speed
  • Weblink section are custom links to whatever URL you want, here my transmission webui
  • Input Select shows a custom dropdown I created: Mode, I am using it to select the current working mode of my HA setup
    • Jour (day): when switching to it, switch off the living room light, no automation
    • Soir (evening): light set to a medium dimming level (90/255), media center playing will dim the light to 30/255 for better atmosphere
    • Soirée (party): As for soir setting, light 90/255, but no automation
    • Nuit (night): set living room light to very very low level (10/255)
  • Switch: as you may have guessed, that section list the switches that are not for light control
    • PC raton is a wake-on-lan switch to wake my computer up, unfortunately not working as the FreeBSD jail that runs HA won't let the WOL packet out...
  • Light: the switches to control lights, for dimming you can click on the name and get a slider to adjust level.
    • Lampadaire is my wall plug on which I plug a standing light
    • Salon is the living room wall switch controlled lights
  • Kodi: is my Openelec installation, my main media center
  • Ratoncast: is a chromecast, that we mainly use for netflix

By default there can be a lot of other things showing up, with pretty awful names, for example the Fibaro Z-Wave switch has various sensors and parameters, they all appear in there but you can rename them to friendly names and hide the unused ones in your configuration.

The Automation

I have only a few automation for now, but they are actually pretty handy, most of them are based on the custom Input Select.

  • At sunset - 2.5h set the mode to evening: That switch the living room on, and enable the media centers automation
  • At 1:30am switch the mode to night: light to minimum in living room and no automation based on media centers
  • At sunrise set the mode to day: switch off the living room if needed and no automation based on media centers

If the automation based on media centers is enable there is: when a media player starts playing dim the light when paused or stop, raise the light to its usual level

It may sound like I didn't setup much, but just that is actually really nice, we actually don't use the wall switch anymore, and only on a very few occasion change settings manually, it just works and we don't have to do anything, that's pretty awesome.

The configuration

Now for the ugly, if you just wanted to know what I did with HA quickly, that's about it, you can stop reading here :).

The configuration isn't very hard to understand, but it still does require a bit of fiddling and tweaking before getting things right.

Most of the components pages explains pretty well what to do and how to configure you devices. In addition there is the Examples or Cookbook page where you can find configuration from other people and snippets of automation for some commonly used cases, like dimming the lights when playing a movie.

The configuration is in YAML and can be splitted in multiple files using !include, I didn't do it myself yet, but will probably have to go this way if it gets any more complex than it currently is.


  # Name of the location where Home Assistant is running
  name: Home
  # Location required to calculate the time the sun rises and sets
  latitude: 48.80569
  longitude: 2.130699
  # C for Celsius, F for Fahrenheit
  temperature_unit: C
  # Pick yours from here: http://en.wikipedia.org/wiki/List_of_tz_database_time_zones
  time_zone: Europe/Paris

# Discover some devices automatically

# Allows you to issue voice commands from the frontend

# View all events in a logbook

# Enables the frontend

# Track the sun

# Prediction of weather
   platform: yr

# Show links to resources in log and frontend

# Enables support for tracking state changes over time.

# Checks for available updates

You give your setup a name, a location (to fetch sunrise/sunset), unit for temperature and your timezone.

Then in my case: enable discovery (that's how the chromecast is found), disable conversation: you can give voice command to HA from the webui, but I'm not a native english speaker, so I don't like talking to my phone in english, plus I do hope to do a better voice control system (always on) at some point. enable logbook, frontend, history and update checker enable sun tracking, based on location, that will create the sensor on top of the web UI and allow automation based on sunset and sunrise times * disable introduction: that is a nice to have at first when learning HA, but after that it mostly get annoying to me.

When using Z-Wave, you have to configure your dongle, as explained on the Z-Wave page:

  usb_path: /dev/cuaU0
  config_path: /usr/local/lib/python3.4/site-packages/libopenzwave-0.3.1-py3.4-freebsd-10.3-RELEASE-amd64.egg/config
  polling_interval: 60000


As explained earlier, by default, all sensors, switches, and their various settings will show up once HA detects them, the annoying part is that can create a lot of clutter and be pretty ugly as the default names of some devices are pretty awful.

To solve this HA provides the customize: section, where you can hide some devices, and change the friendly_name too. In the configuration you will still have to reference the original name, but at least for the UI you'll get a nice name.

Note that this is a subsection of the homeassistant: section, this one would be a good candidate for the first !include in my configuration file.

      friendly_name: Total Salon
      friendly_name: Instant. Salon
      friendly_name: Meteo
      hidden: true
      hidden: true
      hidden: true
      hidden: true
      hidden: true
      hidden: true
      hidden: true
      hidden: true
      hidden: true
      hidden: true

      friendly_name: Lampadaire
      friendly_name: Salon
      hidden: true
      hidden: true
      hidden: true

I don't think it is worth going over every part here, it is pretty clear, and definetily won't match anyone else setup, it is just here as a reference.


Here I use the sensor word in as a generic term, I'll include quite a list of various things within it, first the device tracker: I currently don't use it but it can be a great way to automate things based on weither you're home or not.

  platform: nmap_tracker
  home_interval: 10
  track_new_devices: no

There are other possibilities as you can see on the Presence Detection section of the components, one of the most popular being owntracks. But I went for a simple nmap on my local subnet, this will create a known_devices.yaml containing the list of the known hosts. As you can see I used the track_new_devices: no option, to avoid having any new device showing up, a friend who borrow your wifi for example etc, by default they will all show at the top of your homepage, that's why I used this option and the track: no option in known_devices.yaml file to limit to only tracking our two phones.

I also added speedtest to test our link speed periodically, and transimission to see if torrents are actually doing anything:

sensor 2:
  platform: speedtest
  minute: 30
    - 0
    - 6
    - 12
    - 18
    - ping
    - download
    - upload

sensor 3:
  platform: transmission
  port: 9091
    - 'download_speed'
    - 'upload_speed'

And that's it.

Media Players

The chromecast is automatically detected via the discover: module and there is no configuration entry related to it, except for the automation which is another part of this post.

So I only had to configure our Openelec media center, which is based on Kodi, which have its own component:

  platform: kodi
  host: http://192.168.0.X
  port: 80
  name: Kodi

Custom Switches

I have 2 switches added manually in the configuration, the wake-on-lan for my computer:

switch 1:
  platform: wake_on_lan
  mac_address: "XX:XX:XX:XX:XX:XX"
  name: PC raton
  host: "192.168.0.X"

The host ip is used to check if it is up for the switch in the web UI.

The second one is the input select to choose mode:

    name: "Mode"
      - Jour
      - Soir
      - Soiree
      - Nuit
    initial: Jour
    icon: mdi:power-settings

It creates a current_mode device you can refer to in the automation, you simply list the options and the initial setting to use when restarting HA, I added an icon, but that's optional.

You can also add sliders or boolean input, they are listed in the Automation components page.


If like me you use HA as your browser homepage, it can be useful to add links to some often used website or services, this is where you can use the weblink component, I simply added my transmission url:

    - name: Torrents
      url: http://192.168.0.X:9091
      icon: mdi:download


That's it about the devices and sensors we can now dive into the automation, I'm not sure it is really worth to detail everything, it can help getting a grasp of how it works, but every setup will be different, and most Examples will cover this better than I'll be able to. So what I'll do is simply explain what part of the automation I'm talking about, and paste the configuration part related to it.

All the automation rules will reside in the automation: section (who whould have guessed?)

Mode Switching Events

So, most of my automation is based on the mode the setup is running at, and when switching from one to another changing the light accordingly.

Switching to day mode, turn off all the lights. Currently we only have 2 lights both in the living room, so it make sense to simply use the service light witouth parameter so it act on all the light:

  - alias: Jour
      - platform: state
        entity_id: input_select.current_mode
        state: "Jour"
      service: light.turn_off

Switching to evening or party mode, turn the living room above and behing tv to 90/255 setting, only difference is that the media playing automation won't trigger if mode isn't evening:

  - alias: Soir
      - platform: state
        entity_id: input_select.current_mode
        state: "Soir"
      service: light.turn_on
        entity_id: light.fibaro_system_fgd212_dimmer_2_level_3
        brightness: 90

  - alias: Soiree
      - platform: state
        entity_id: input_select.current_mode
        state: "Soiree"
      service: light.turn_on
        entity_id: light.fibaro_system_fgd212_dimmer_2_level_3
        brightness: 90

Switching to night mode, set the light to the lowest level, we generally leave it running overnight, at this level, the consumption is about 2W, which really isn't much:

  - alias: Nuit
      - platform: state
        entity_id: input_select.current_mode
        state: "Nuit"
      service: light.turn_on
        entity_id: light.fibaro_system_fgd212_dimmer_2_level_3
        brightness: 10

Mode Switching Triggers

To automate switching from one mode to another, we have 3 time triggers, one for the evening, starting 2.5 hours before sunset

  - alias: "evening time"
      - platform: sun
        event: sunset
        offset: "-02:30:00"
      service: input_select.select_option
        entity_id: input_select.current_mode
        option: "Soir"

One for the night, with a hard limit set at 1:30am:

  - alias: "night time"
      - platform: time
        hours: 1
        minutes: 30
        seconds: 0
      service: input_select.select_option
        entity_id: input_select.current_mode
        option: "Nuit"

And one to go back to daytime mode, using the sunrise time:

  - alias: "day time"
      - platform: sun
        event: sunrise
      service: input_select.select_option
        entity_id: input_select.current_mode
        option: "Jour"

Now we have the mode switching automatically, let's handle the dimming of lights when watching movies!

Media Playing

Now based of if we are in the evening mode or not, we want the media players to trigger dimming the light. I tried to add a check on the content type for kodi, to avoid the dimming when listening to music, but it apparently dosen't work, and I didn't find out why yet.

For kodi:

  - alias: "Kodi paused/stopped"
      - platform: state
        entity_id: media_player.kodi
        from: 'playing'
      - condition: state
        entity_id: input_select.current_mode
        state: Soir
      - condition: template
        value_template: '{{ states.media_player.kodi.media_content_type != "video" }}'
      service: light.turn_on
      entity_id: light.fibaro_system_fgd212_dimmer_2_level_3
        brightness: 90

  - alias: "Kodi playing"
      - platform: state
        entity_id: media_player.kodi
        to: 'playing'
      - condition: state
        entity_id: input_select.current_mode
        state: Soir
      - condition: template
        value_template: '{{ states.media_player.kodi.media_content_type != "video" }}'
      service: light.turn_on
      entity_id: light.fibaro_system_fgd212_dimmer_2_level_3
        brightness: 30

For chromecast:

  - alias: "chromecast paused/stopped"
      - platform: state
        entity_id: media_player.ratoncast
        from: 'playing'
      - condition: state
        entity_id: input_select.current_mode
        state: Soir
      service: light.turn_on
      entity_id: light.fibaro_system_fgd212_dimmer_2_level_3
        brightness: 90

  - alias: "chromecast playing"
      - platform: state
        entity_id: media_player.ratoncast
        to: 'playing'
      - condition: state
        entity_id: input_select.current_mode
        state: Soir
      service: light.turn_on
      entity_id: light.fibaro_system_fgd212_dimmer_2_level_3
        brightness: 30


Currently one thing I would like to automate is running a script that would switch off the tv/amp when both media player have been idling for 30 minutes and if my wife computer isn't on.

For the light, I would like to replace the modes/timeslots in most cases except the night by a lux detection, and adjust brightness based on how much light there is in the living room.

I want to add other light in this room for other situation, I would love to have some sensors for temperature and humidity both inside and outside, automate the curtains too, and add some kind opened door/window detection too.

The possibilities are endless, only money, and ability in diy is the limits!

And that wraps it up for this serie of post on home automation, I'll try to keep posting the changes and hopefully my DIY sensors/controller based on ESP8266 in the near future.

31 juillet 2016 12:42:45 -- tags [ home-automation , home-assistant , light , dimming , configuration , yaml ]



As a reference, here is my current .vimrc file, stripped from a few things specific to my current job:

" ---------------
" Start Plug
" ---------------
call plug#begin('~/.vim/plugged')

" git
Plug 'tpope/vim-fugitive'

" utils
Plug 'rking/ag.vim'         " ag fro grepping in vim
Plug 'tpope/vim-commentary' " gcc gc etc for commenting
Plug 'tpope/vim-surround'   " change surrounding chars
Plug 'tpope/vim-unimpaired' " [<space> and more
Plug 'tpope/vim-sensible'   " default settings that makes sense
"Plug 'tpope/vim-rsi'        " shell/emacs binding in insert mode
Plug 'tpope/vim-tbone'      " tmux integration in vim
Plug 'junegunn/fzf', { 'dir': '~/.fzf', 'do': './install --all' }
Plug 'junegunn/fzf.vim'

" wiki + tw
Plug 'vimwiki/vimwiki'
Plug 'tbabej/taskwiki'

" appearance
Plug 'powerline/powerline'
Plug 'noah/fu'

" Add plugins to &runtimepath
call plug#end()

" ---------------
" Behavior
" ---------------
syntax on
set nobackup
set undodir=~/etc/vim/undo
set history=1000
set undolevels=1000
set wildignore=*.swp,*.bak,*.pyc,*.class
set hidden " allow changing buffer from unsaved

set ai
set cinoptions=(0
set cindent
set nocompatible
set ruler
set hlsearch
set wildmode=list:longest "bash like completion

set mouse=vn
set clipboard=unnamed

filetype plugin on
if has("autocmd")
  autocmd BufRead *.txt set tw=78 sw=2 ts=2 et
  autocmd BufRead *.py set tw=80 sw=4 ts=4 et
  autocmd BufRead *.sh set ts=4 sw=4 et noai nocin
  autocmd Bufread *.wiki set tw=80 ts=4 sw=4 et ai

" spellcheck in rst
autocmd FileType rst setlocal spell spelllang=en_us
autocmd Filetype rst set tw=80 sw=2 ts=2 et

" ---------------
" Appearance
" ---------------
set term=xterm-256color
set t_Co=256
set background=dark
set listchars=tab:▸\ ,eolcolorscheme fu

set laststatus=2
set cursorline
set nocursorcolumn
set colorcolumn=80
highlight ColorColumn ctermbg=16
highlight CursorLine ctermbg=23 term=bold cterm=bold

" Syntax error hilighting, this should be after colorscheme
syntax match Error "\(^\t.*\n\)\@<= \+"
syntax match Error "\(^ \+.*\n\)\@<=\t\+"
autocmd FileType c* syntax match Error '\%>80v.\+'

" enable powerline
set rtp+=/home/bleader/.vim/plugged/powerline/powerline/bindings/vim

" enable fzf
set rtp+=~/.fzf

" ---------------
" Binds
" ---------------

" use , for map leader, feel easier than \
let mapleader=","

set pastetoggle=<F9>

" edit/reload vimrc quickly
nmap <silent> <leader>ev :e $MYVIMRC<CR>
nmap <silent> <leader>sv :so $MYVIMRC<CR>

" allow use of ; in place of :
nnoremap ; :

" clear search hilight
nmap <silent> <leader>/ :nohl<CR>

" Error list binds
nnoremap <leader>n :cn<CR>zz
nnoremap <leader>p :cp<CR>zz

" compute line through rcpy https://github.com/bleader/rcpy
map <F4> yypV:!rcpy<CR>

" enable/disable list
imap <F1> <C-o>:set nolist!<CR>
map <F1> <ESC>:set nolist!<CR>

" moving around centering
nnoremap n nzz
nnoremap N Nzz
nnoremap * *zz
nnoremap # #zz
nnoremap g* g*zz
nnoremap g# g#zz
nnoremap [[ [[zz
nnoremap ]] ]]zz
nnoremap {{ {{zz
nnoremap }} }}zz

" debug printf in C
map <leader>dd oprintf("%s:%d\n", __func__, __LINE__);<Esc>==

" paste selection to haste
vnoremap Y <esc>:'<,'>:w !haste<CR>

" ---------------
" ---------------
nnoremap <leader>gd :Gvdiff<CR>
nnoremap <leader>gs :Gstatus<CR>
nnoremap <leader>gl :Glog --<CR>:copen<CR>
nnoremap <leader>gL :Git l<CR>
nnoremap <leader>gg :Ggrep <cword><CR>
nnoremap <leader>ag :Ag <cword><CR>
nnoremap <leader>gc :Gcommit -s -v<CR>
nnoremap <leader>gS :Git show<CR>
nnoremap <leader><leader>gS :Git show <cword><CR>
autocmd BufReadPost fugitive://* set bufhidden=delete

let g:git_branch_status_head_current=1 
let g:git_branch_status_text="branch "
let g:git_branch_status_nogit="no git"
let g:git_branch_status_around="{}"

fu! GitReview()
    Glog --reverse origin/master.. -- .
command Greview call GitReview()
nnoremap <leader>gr :Greview<CR>

" ---------------
" Cscope bindings and configuration (autoload of cscope.out)
" ---------------
nmap <leader>cs :cs find s <C-R>=expand("<cword>")<CR><CR>
nmap <leader><leader>cs :vert scs find s <C-R>=expand("<cword>")<CR><CR>
nmap <leader>cg :cs find g <C-R>=expand("<cword>")<CR><CR>
nmap <leader><leader>cg :vert scs find g <C-R>=expand("<cword>")<CR><CR>
nmap <leader>cc :cs find c <C-R>=expand("<cword>")<CR><CR>
nmap <leader><leader>cc :vert scs find c <C-R>=expand("<cword>")<CR><CR>
nmap <leader>ct :cs find t <C-R>=expand("<cword>")<CR><CR>
nmap <leader><leader>ct :vert scs find t <C-R>=expand("<cword>")<CR><CR>
nmap <leader>ce :cs find e <C-R>=expand("<cword>")<CR><CR>
nmap <leader><leader>ce :vert scs find e <C-R>=expand("<cword>")<CR><CR>
nmap <leader>cf :cs find f <C-R>=expand("<cfile>")<CR><CR>
nmap <leader><leader>cf :vert scs find f <C-R>=expand("<cfile>")<CR><CR>
nmap <leader>ci :cs find i ^<C-R>=expand("<cfile>")<CR>$<CR>
nmap <leader><leader>ci :vert scs find i ^<C-R>=expand("<cfile>")<CR>$<CR>
nmap <leader>cd :cs find d <C-R>=expand("<cword>")<CR><CR>
nmap <leader><leader>cd :vert scs find d <C-R>=expand("<cword>")<CR><CR>

if has("cscope") && filereadable("/usr/bin/cscope")
   set csprg=/usr/bin/cscope
   set csto=0
   set cst
   set nocsverb
   " add any database in current directory
   if filereadable("cscope.out")
      cs add cscope.out
   " else add database pointed to by environment
   elseif $CSCOPE_DB != ""
      cs add $CSCOPE_DB
   set csverb

fu! CscopeReload()
   cscope kill 0
   !cscope -R -b
   cscope add cscope.out

nmap <leader>cR :call CscopeReload()<CR>

" edit .configs
map <leader>uu ^i# <esc>$xxA is not set<esc>
map <leader>ss ^xxEld$a=y<esc>

let g:fzf_command_prefix="Fzf"
nnoremap <leader>f :FzfFiles<cr>
nnoremap <leader>b :FzfBuffers<cr>
inoremap <expr> <c-x><c-k> fzf#vim#complete#word({'left': '15%'})

30 décembre 2015 13:26:14 -- tags [ vim , configuration ]