Home Assistant Customization and Automation From a Beginner

Are you into smart home automation? Are you interested in Home Assistant? I doubt you’d be reading this if you weren’t. I’m still a beginner, but I installed and was able to control all my devices with Home Assistant in 2 hours. That allowed me to control my devices, but I wanted to customize that control and add automation. This article goes through the Home Assistant customization and automation I’ve implemented up to this point.

Background

Over the years I’ve accumulated a lot of smart home devices. Home Assistant is already aware and can control the following devices:

  • DirecTV receivers
  • Denon A/V receivers
  • Google Home/Google Mini/Insignia Voice Activated Smart Speaker
  • Google Chromecast
  • Panasonic Viera TV
  • Panasonic Connected blu-ray player
  • LIFX Lights
  • TP-Link HS105 Smart Plug
  • My Veralite Z-wave controller which includes:
    • Light switches
    • Home Power Meter
    • Outlet Switches
    • Smart Plugs
    • Door Locks
    • Relay (used to open and close my garage door)
    • Motion/light/temperature sensors

I have integrated Google Assistant and Alexa voice control of Home Assistant so I can control many things by giving voice commands. I have a good set of devices to play with!

Home Assistant Customization

With the basics set up, it is time for me to delve into some customizations. I am going to walk through the steps I took to add more control to Home Assistant. These may not be the best ways to implement what I have done, but they work for me. Contact me with suggestions or leave them in the comments if you see improvements I can make. I’m still new to this!

Structuring YAML Configuration

The main configuration file for Home Assistant is appropriately named configuration.yaml. I quickly learned this file was going to become large and unwieldy if I kept all my YAML code in this file. You can use an include directive to create separate files for different parts of the configuration. For example, adding in the code:

switch: !include switches.yaml

makes it so I can keep all of the configurations for my switches in the file switches.yaml.

I used this directive to create separate files for my customizations, groups, scenes, lights,  REST commands, remotes, and scripts.

Changing DirecTV Channels

Directv Receiver
DirecTV Receiver to be controlled by Home Assistant

Home Assistant can control some basic functions of my DirecTV receiver, such as play and pause, but I couldn’t find a way for it to change to a specific channel. However, I know the receiver has a RESTful interface which includes the ability to change channels. There is a published list of more commands. My end goal is to be able to tell the DirecTV receiver to change to a specific channel (one of our commonly watched channels) by issuing a voice command to Alexa or Google Assistant. This ended up being a 3 step process.

Step 1: Giving Home Assistant the ability to change the channels

In order to use these commands, I decided to take advantage of Home Assistant’s RESTful command component.  I placed the following REST calls in my rest.yaml:

family_espn:
  url: http://<ip of DirecTV Receiver>:8080/tv/tune?major=206&minor=65535
family_tennis:
  url: http://<ip of DirecTV Receiver>:8080/tv/tune?major=217&minor=65535
family_nbatv:
  url: http://<ip of DirecTV Receiver>:8080/tv/tune?major=216&minor=65535

These commands allow me to change to channel ESPN (206), The Tennis Channel (217), and NBATV (216). I ended up adding many more channels.

Step 2: Calling these commands in Home Assistant

Adding REST commands just makes them available in Home Assistant, but it doesn’t really allow you to use them in the user interface. For this, I created scripts to call these commands. I added the following to my scripts.yaml file:

turn_on_espn:
  alias: "ESPN"
  sequence:
    - service: rest_command.family_espn

turn_on_tennis:
  alias: "The Tennis Channel"
  sequence:
    - service: rest_command.family_tennis

turn_on_nbatv:
  alias: "NBA TV"
  sequence:
    - service: rest_command.family_nbatv

As you can see, these commands correspond to rest commands in my rest.yaml file. The alias field creates a friendlier name for the command in the user interface and for voice commands. Speaking of voice commands…

Step 3: Configure Google Assistant and Alexa to change DirecTV channels

This step is almost completely automatic. I have Home Assistant configured to automatically expose script commands to Google Assistant and Alexa. After restarting Home Assistant, I simply had to tell both to discover devices. For Google Assistant there is a “Sync Devices” button on the Home Assistant Cloud configuration page in Home Assistant or you can tell Google Assistant to “sync my devices.” You can tell Alexa to  “discover new devices.” After this step, I can tell either voice assistant to “Turn on ESPN” or “Turn on The Tennis Channel” and DirecTV responds accordingly!

See also  The Top 5 Reasons I Have A Smart Home

Locking Doors

Deadbolt
Wish I had this model of deadbolt!

Home Assistant recognized the Yale Z-wave deadbolt locks that I have paired with my Vera controller. However, I want to be able to give one command to lock both doors to my house. A simple script solves this problem:

lock_doors:
  alias: "Lock Doors"
  sequence:
    - service: lock.lock
      data:
        entity_id: lock.front_door_deadbolt
    - service: lock.lock
      data:
        entity_id: lock.garage_deadbolt

Turn on TV for Chromecast

Chromecast
Just say “Turn on Chromecast”

Although it is tempting, I actually don’t want to turn Home Assistant into a remote control for all of my A/V equipment. Universal remotes are much better at controlling my equipment, and not everyone in my family will interact with the Home Assistant UI. Most every command or automation I would create would still require me to go get a remote to continue control (e.g. changing the volume, navigating menus, changing to channels I didn’t program into Home Assistant).  However, there are a couple of A/V devices that I often operate without my universal remote. One of them is the Chromecast. You use a smartphone to send content to a Chromecast, so voice command to turn the A/V equipment to the right settings for Chromecast makes sense.

Turning on my Chromecast involves turning on my Panasonic Viera TV, turning on my Denon Receiver, and then switching my Denon receiver to the Chromecast input. Scripts to the rescue again!

turn_on_chromecast:
  alias: "Chromecast"
  sequence:
    - service: media_player.turn_on
      data:
        entity_id: media_player.panasonic_viera
    - service: media_player.turn_on
      data:
        entity_id: media_player.family_room_denon
    - service: media_player.select_source
      data:
        entity_id: media_player.family_room_denon
        source: CHROMECAST

This is great, but it only turns on the Chromecast. If I didn’t use a remote, I also want to be able to turn off the Chromecast (turn the TV off, turn off the receiver). I created a generic script for this:

turn_off_famroomtv:
  alias: "Turn Off Family Room TV"
  sequence:
    - service: media_player.turn_off
      data:
        entity_id: media_player.panasonic_viera     
   - service: media_player.turn_off
      data:
        entity_id: media_player.family_room_denon

The problem is, for voice control, I want to be able to say “Turn on Chromecast” and “Turn off Chromecast.” Scripts only have “turn on” voice controls, because you don’t turn off scripts. I need to take these two scripts and combine them into a switch. So in switches.yaml I have:

- platform: template
  switches:
    family_room_tv_chromecast:
      value_template: "{{ is_state('media_player.panasonic_viera', 'on') }}"
      turn_on:
        service: script.turn_on
        data:
          entity_id: script.turn_on_chromecast
      turn_off:
        service: script.turn_on
        data:
          entity_id: script.turn_off_famroomtv

The value_template portion above determines whether this “switch” is on or off. In this case, if the Panasonic TV is on, the switch is considered to be on). Now, I can tell Google Assistant or Alexa to turn the Chromecast off or on and the right things will happen. I also created the friendly name Chromecast for the switch in customize.yaml and excluded the Chromecast script from the assistants so they wouldn’t confuse commands.

Remote Control of Projector

I have one A/V device that does not have network control. I’ve been controlling it (an older Epson 3010 projector) using the network to IR device Global Cache iP2IR ITach.  I have a similar need with this device as I had with the Chromecast. I have a Nintendo Switch connected to another Denon A/V receiver which is connected to this projector. When we play the Switch, we don’t use the universal remote, we just use a Switch controller. This makes turning on and off the equipment by voice desireable. This took me a few steps.

Home Assistant happens to have an ITach component (what doesn’t it have?). Unfortunately to use this component I needed to track down the Epson 3010 on and off codes in Pronto hex format. After a little googling I added the following code to my remote.yaml file:

See also  5 Downsides Of Having A Smart Home

- platform: itach
  name: Theater Room
  host: <IP Address>
  devices:
  - name: Epson 3010 Projector
    modaddr: 1
    connaddr: 3
    commands:
      - name: "On"
        data: "0000 006C 0000 0022 015B 00AD 0016 0041 0016 0041 0016 0016 0016 0016 0016 0016 0016 00
16 0016 0016 0016 0041 0016 0041 0016 0016 0016 0041 0016 0016 0016 0041 0016 0016 0016 0041 0016 0016 001
6 0016 0016 0016 0016 0016 0016 0016 0016 0041 0016 0016 0016 0016 0016 0041 0016 0041 0016 0041 0016 0041
0016 0041 0016 0016 0016 0041 0016 0041 0016 0016 0016 0622"
      - name: "Off"
        data: "0000 006C 0000 0022 015B 00AD 0016 0041 0016 0041 0016 0016 0016 0016 0016 0016 0016 00
16 0016 0016 0016 0041 0016 0041 0016 0016 0016 0041 0016 0016 0016 0041 0016 0016 0016 0041 0016 0016 001
6 0041 0016 0016 0016 0016 0016 0016 0016 0041 0016 0016 0016 0016 0016 0041 0016 0016 0016 0041 0016 0041
0016 0041 0016 0016 0016 0041 0016 0041 0016 0016 0016 0622"

This added a remote device on/off toggle to my Home Assistant UI which actually turned my projector on and off via the ITach! I was thrilled! After this I created scripts and a switch named “Nintendo” just like I did for the Chromecast, allowing me to use voice command to turn it on and off. The code is basically the same with a different receiver (still a Denon) and using the projector so I won’t post it here as this article is getting long enough already! My Theater room is pretty dark (basement with no windows) so I added turning the lights on to a low level to the on script and turning the lights off to the off script.

Presence Detection

I have always wanted to use presence detection as a trigger for automation, but I have never setup presence detection. I looked at using nmap and ping via Home Assistant to track my phone presence. For no particular reason, other than it seemed more people were using it, I decided to go with nmap. First I added the following code to configuration.yaml:

device_tracker:
  - platform: nmap_tracker
    home_interval: 10
    consider_home: 600
    scan_options: " -sP "
    new_device_defaults:
      track_new_devices: yes
      hide_if_away: False
    hosts:
      - <ip address 1>
      - <ip address 2>

I set the home_interval and consider_home options to cut down on false indications that a phone is not present when it goes to sleep or for some other reason drops off the network for a short time. After adding this code and Home Assistant creates a known_devices.yaml file with your nmap scanned devices. You can customize this file to meet your needs.

Alarmdotcom Integration

The instructions for this couldn’t be simpler. I just added my username and password. This integration allows me to arm and disarm my alarm, as well as view a general status message that tells me the state of the alarm and related sensors.

SMS/Email notifications

A good automation system needs to be able to notify me of certain events. When some events occur, I like to be notified via text. Rather than go through any complicated process to be able to send SMS messages, I took advantage of my cellular plan’s (Cricket) email to text gateway. This allows me to send an email to receive a text. I have a local email relay to my email provider (using postfix) on my network that I used with Home Assistant’s SMTP notify component. In my configuration.yaml I have:

notify:
  - name: smsgateway
    platform: smtp
    server: myserver.mydomain.com
    port: 25
    encryption: none
    sender: [email protected]
    recipient:
      - [email protected] 
    sender_name: HA Notification

This allows me to use send text messages to myself as I need. I can add a notify component that replaces the Cricket Wireless SMS gateway address with my email address to send myself an email notification. You could easily do this using Google’s SMTP server if you have a Google account (there is an example in the SMTP notify documentation linked above), but you’ll probably have to allow low-security apps to connect to your Google account.

Home Assistant Automation

Now I have almost all the remote control of my system that I can want. Remote control is nice, but automation is the key to a smarter home.  The first automation area I had in mind was security, and then I thought I’d have a little fun.

See also  Dusun Home Assistant IoT Gateway Review

Security

Alarm Automation

Like most alarms, my alarm can be armed stay (Someone is still at home) or away (No one is home). In either case, I want the deadbolts to lock. When I arm the alarm away, why not make sure the lights are off too?

Code for locking the doors when the alarm is armed stay in my automations.yaml file:

- id: alarm_armed
  alias: Alarm armed
  trigger:
    - platform: state
      entity_id: alarm_control_panel.alarmcom
      from: 'disarmed'
      to: 'armed_away'
    - platform: state
      entity_id: alarm_control_panel.alarmcom
      from: 'disarmed'
      to: 'armed_home'
  action:
    - service: lock.lock
      data:
        entity_id: lock.front_door_deadbolt
    - service: lock.lock
      data:
        entity_id: lock.garage_deadbolt

I don’t want every single light to turn off when I arm the alarm away, as some of my lights are outdoor lights. Also, I may convert more lights to smart lights in the future. In order to keep the code clean, I created a group with all of the lights I want to turn off and I reference that group in the code to turn off lights when the alarm is armed away:

- id: alarm_armed_away_lights_off
 alias: Alarm armed away lights off
  trigger:
    - platform: state
      entity_id: alarm_control_panel.alarmcom
      from: 'disarmed'
      to: 'armed_away'
  action:
    - service: light.turn_off
      entity_id: group.indoor_lights

Vacation Automation

Home lights
The lights are on. Is someone there?

A common security tip for your house when you are on vacation is to make it seem like your house is still occupied. I do this by scheduling certain lights (using groups again) to come on and go off at specific times. The automation code for this isn’t much different from what is above, other than the fact I use time-based triggers. I have these automations keep running until I am back home. When Home Assistant detects my presence, it turns the security lights off and disables the automation that automatically turns the lights on and off:

- id: welcome_vacation
  alias: Welcome from vacation
 trigger:
    platform: state
    entity_id: device_tracker.name_presence
    from: 'not_home'
    to: 'home'
  condition:
    condition: state
    entity_id: automation.turn_on_security_lights
    state: 'on'
  action:
    - service: light.turn_off
      entity_id: group.away_security_lights
    - service: automation.turn_off
      data:
        entity_id:
          - automation.turn_on_security_lights
          - automation.turn_off_security_lights
          - automation.turn_on_late_security_lights
          - automation.turn_off_late_security_lights
    - service: notify.smsgateway
      data:
        message: Hello! Welcome back from Vacation. I hope you had a great time. I have disabled the security light automations for you.
    - delay: '00:07:00'
    - service: media_player.volume_set
      data:
        entity_id: media_player.family_room_speaker
        volume_level: "0.5"
    - service:tts.google_say
      data:
        entity_id: media_player.family_room_speaker
        language: en
        message: Hello! Welcome back from Vacation. I hope you had a great time. I have disabled the security light automations for you.

Announcing My Arrival

You may have noticed in the code directly above a couple of things I hadn’t mentioned:

  1. The script also sends me a text informing me that the security automations have been turned off.
  2. The script casts a message to my Google Home welcoming me back from vacation.

I thought I’d have a bit of fun with casting. I similarly, when I get home from work during the week I also have the Google Home welcome me home. At least this way I know someone is always looking forward to my arrival :).

Final Thoughts

These configurations and automations took a bit Googling and a fair amount of work and testing, but it was fun, and now they just work. The presence detection could be better (sometimes it marks a phone away when it isn’t) but it definitely works well enough. After I add Zigbee and Z-wave capabilities and add more automation I’m going to tackle customizing the Lovelace UI next. I also may integrate my Harmony Hub remote control. I don’t consider myself a total beginner anymore, but I’m far from an expert. Wish me luck!

If you enjoyed this article please share, follow me on Twitter and subscribe to my site using the signup form below. If you have questions or suggestions please don’t hesitate to get in contact with me.

Editor’s note: This page contains affiliate links. For more information read our disclosures.

Share this:

Home Assistant Customization and Automation From a Beginner

by HomeTechHacker time to read: 12 min