Make Automations More Readable By Breaking Out automations.yaml

A recent Feature Request got me thinking about cleaning up my automations to make them more readable.

The UI is a great way to create a simple new automation. You don’t need to know all the options and syntax, and you don’t need to know how to format proper YAML. The result is always a working autmation, which is stored in the automations.yaml file. But eventually you’ll want to do something more complex which the UI isn’t good at, or you’ll find sample YAML on this forum for an automation you want to try.

When you go to edit the automatically generated YAML file, it can be a confusing mix of different, though perfectly legal, YAML structures. The UI generates random, numeric id’s for each automation. It doesn’t put blank lines or comments in, and it will delete those if you add them. It doesn’t order the automations in any logical sequence.

Luckily, HA allows you to use the !include statement to break out your configuration into multiple files. By default, configuration.yaml already has one such statement for automations:

automation: !include automations.yaml

I created a new include, and gave each a label:

automation ui: !include automations.yaml
automation manual: !include my_automations.yaml

I renamed automations.yaml to my_automations.yaml and created a new, blank automations.yaml file. The UI will still add any new automations it creates to that new file, but it can never update my_automations.yaml.

Note that nothing in my_automations will be editable from within the UI, but frankly that seems more like a benefit than a limitation to me.

Now I have an automations file I can reformat to my own liking, without having the UI undo any of my changes. Right away I moved similar automations together, added a blank line between each automation, and added comments like this to break it up into sections:

#
# "Away" lighting automations
#

That made it easier to find and compare automations. I had some very confusing ones. YAML is pretty flexible, and all the different automations were created using different standards. Some came from the UI, while others were copied and pasted from samples I found on this forum.

Here’s an automation which I found confusing:

- id: '1568925959816'
  alias: Away - Study Lamp Off 945
  trigger:
  - at: '21:45'
    platform: time
  condition: []
  action:
  - data: {}
    service: switch.turn_off
    target:
      entity_id:
      - switch.study_lamp_switch
  initial_state: 'false'
  mode: single

The logic just didn’t jump out at me. Settings for the automation were both at the top and at the bottom. The sequence of lines in the trigger: and action: sections didn’t flow well. I switched things around to work the same, but make more sense to me:

- id: away_study_lamp_off
  alias: Away - Study Lamp Off 945
  initial_state: 'false'
  mode: single
  trigger:
  - platform: time
    at: 21:45
  action:
  - service: switch.turn_off
    target:
      entity_id: switch.study_lamp_switch

Obviously some of this is subjective. The point is, I was able to decide on a set of standard coding practices, and make all my automations follow that.

I’m thrilled with the result. My automations are easy to find, easy to understand, and easy to update.

At some point, if having them all in one file becomes unmanageable, I could break them up into multiple files using !include_dir_merge_list in place of just the !include.

I should note that there’s also a Feature Request to have automation grouping done within the UI. Feel free to vote for both FRs, and consider this a workaround until all of this can be done in the UI.

4 Likes

Why not just use Packages? It has the same “not UI editable” limitation with the additional advantage that a given file isn’t limited to just automations (unless you want it to be). You can “package” related sensors, scripts, and automations together in one place or you can have separate files for each category… it’s very flexible.

1 Like

Thanks, I never heard of packages. If I were starting out today (and I knew about them) I’d probably use packages. I like the idea of, well, packaging things together logically.

Unfortunately, I’m pretty heavily invested in the way HA natively “packages” the configuration.yaml file. I’ve figured out where to find everything, so making a big change now would be less beneficial. Probably the next time I start a project where I’m adding sensors, scripts and automations, I’ll look at packaging them!

I actually use both methods described above.

I use packages for things that should be logically placed together so I don’t need to open multiple files when working on a “system”.

And I use the !include method when building one-off things that don’t need to be used with other supporting entities created thru yaml.

And there is nothing stopping you from slowly migrating the things you already have over to packages as you understand them more and have the time.

they really do help with organizing more complex “systems” that have a lot of moving parts.

1 Like

Another method allowing both is:

default_config:
automation ui-automation: !include automations.yaml
automation: !include_dir_list include/automations

I have all my includes in the include directory and love that I can organize by directory structure under that. :thinking: I can even imagine working in a single file structure. I wish they had the same available for dashboards… Oh How I dislike the UI on that one!

I’m not sure exactly what you mean but you can configure dashboards in the same way.

Just use yaml mode and you can split your code up into different files using !includes as well.

Are you saing that I can have dashboards outside of the UI? OMG that would make my day!
Can you share what file and an example of the include line? Is it in the main configuration.yaml under

default_config:

?

prepare to have your day made! :laughing:

just add the following to configuration.yaml (note that I have my resources split using !include):

lovelace:
  mode: yaml
  resources: !include ui_lovelace_resources.yaml

then create a file called “ui-lovelace.yaml” and put your dashboards there (I have mine split using !includes):

title: Home Assistant (NUC)
views:
  - !include '/config/lovelace_views/lovelace_main_view.yaml'
  - !include '/config/lovelace_views/lovelace_smoker_view.yaml'
  - !include '/config/lovelace_views/lovelace_finance_view.yaml'
  - !include '/config/lovelace_views/lovelace_tank_view.yaml'
  - !include '/config/lovelace_views/lovelace_cam_view.yaml'
  - !include '/config/lovelace_views/lovelace_environment_view.yaml'
  - !include '/config/lovelace_views/lovelace_environment_alerts_view.yaml'
  - !include '/config/lovelace_views/lovelace_media_sonos_view.yaml'
  - !include '/config/lovelace_views/lovelace_media_view.yaml'
  - !include '/config/lovelace_views/lovelace_security_view.yaml'
.
.
.

then create the file structure to where you pointed the !includes above.

Screenshot 2022-04-24 074435

then add the dashboards via yaml to those files:

as an example:

lovelace_system_view.yaml (note the nested !include there too):

#####################################
title: System
#panel: true
type: custom:vertical-layout
layout:
  max_cols: 4
cards:
    
#####################  COLUMN 1  ################################
  - !include lovelace_system_view_dev_tools.yaml
  
##############################################

  - type: custom:stack-in-card
    cards:
      - type: 'custom:card-templater'
        entities:
          - input_boolean.zwave_ready
        card:
          type: markdown
          content_template: >
            {% if is_state('input_boolean.zwave_ready', 'on') %}
              <font size='+1' color='green'>The Z-Wave Network is Ready</font>
            {% else %}
              <font size='+1' color='red'>The Z-Wave Network is NOT Ready</font> 
            {% endif %}
      - type: entities
        show_header_toggle: false
        state_color: true
        entities:
          - binary_sensor.zwavejs_status
          - sensor.zwave_failed_nodes
          - type: custom:binary-control-button-row
            entity: input_boolean.show_test_view
            customTheme: true
            reverseButtons: true
            state_color: true
          - type: custom:binary-control-button-row
            entity: input_boolean.show_garage_power_view
            customTheme: true
            reverseButtons: true
            state_color: true
          - type: custom:binary-control-button-row
            entity: input_boolean.show_debug_view
            customTheme: true
            reverseButtons: true
            state_color: true
          - type: custom:binary-control-button-row
            entity: input_boolean.show_kids_views
            customTheme: true
            reverseButtons: true
            state_color: true
          - type: custom:binary-control-button-row
            entity: input_boolean.show_nws_test_alerts_view
            customTheme: true
            reverseButtons: true
            state_color: true

just to clarify…

you don’t have to use the vertical-layout card or any of the “show_x” stuff above. you can use whatever you want.

you can even easily convert your existing stuff over to yaml mode by just copying the existing dashboard yaml file to ui-lovelace.yaml (after making the changes above).

2 Likes

@007DJ

I made your day and I get nothing in return? Not even a response at all?

:laughing:

1 Like

Not true… I am just swamped in errors from the Alexa integration. I will be working it and I am truly excited. I hate the UI and only use it to help with small functions. YAML at least you can copy it and own it…
Example… Some integrations were acting up, I gave up and did the only tested and true repair Remove and Replace… Unfortunately, along with the Remove was all the entity configuration in the UI, Close to 50 entities that I had hidden and disabled, now back to haunt me… Thanks UI :frowning:
Wish me luck and I will SOON let you know what happens :slight_smile:

1 Like

no problem.

just joshin you.

Good Luck!!

Here is crack one… (I also configuration split using !include. My organization method is everything is located in /config/include I added the directory dashboard
My /config/configuration.yaml per your direction has the following added as:

homeassistant: !include include/homeassistant.yaml
default_config:
lovelace:
  mode: yaml
  resources: !include include/dashboard/dashboard.yaml

In the /config/include/dashboard/ directory is the dashboard.yaml:

title: Home Assistant
views:
  - !include '/config/include/dashboard/status.yaml'

In the same directory is the modified file status.yaml (Removing the first two lines placed in dashboard.yaml above. (Sense the file is 154 lines, I captured enough code for you to get the idea…

  - title: Status
    type: panel
    theme: Backend-selected
    badges: []
    cards:
      - type: vertical-stack
        cards:
          - title: Batteries
            type: horizontal-stack
            cards:
              - type: entities
                show_header_toggle: false
                state_color: true
                entities:
                  - entity: binary_sensor.ws_50_battery
                  - entity: binary_sensor.ws_50_battery_2
                  - entity: binary_sensor.ws_50_battery_3

But, unfortunately, configuration validation fails dramatically…


What are your thoughts? Meanwhile # is my best friend while I look for your reply :slight_smile:

First you need tro create a file in your base config directory (the same place your configuration.yaml is located) called ui-lovelace.yaml.

config dir
|
|–>configuation.yaml
|–>ui-lovelace.yaml

your first dashboard needs to go there.

so after you create that file cut the contents of your current “/config/include/dashboard/” and place that code into the ui-lovelace.yaml file.

then once you restart HA it should show up.

I think…unless I’ve missed something.

EDIT:

The “resources:” line is for adding custom front end cards/plugins/etc.

Crack two: I have definite changes, no errors, but still no control. Here is the changes that allowed me to progress…
/config/configuration.yaml

homeassistant: !include include/homeassistant.yaml
default_config:
automation ui-automation: !include automations.yaml
automation: !include_dir_list include/automations
script ui-script: !include scripts.yaml
script: !include_dir_named include/scripts

lovelace:
  mode: yaml
#  resources: !include ui_lovelace.yaml

begging of /config/ui_lovelace.yaml

title: Home
views:
  - title: Status
    type: panel
    theme: Backend-selected
    badges: []
    cards:
      - type: vertical-stack
        cards:
          - title: Batteries
            type: horizontal-stack
            cards:
              - type: entities
                show_header_toggle: false
                state_color: true
                entities:
                  - entity: binary_sensor.ws_50_battery
                  - entity: binary_sensor.ws_50_battery_2
                  - entity: binary_sensor.ws_50_battery_3
                  - entity: binary_sensor.ws_50_battery_4
                  - entity: binary_sensor.ws_50_battery_5

Results: Overview is the default dashboard. No matter what I place in the /config/ui_lovelace.yaml file, it remains unchanged.


In the control panel

I can add another dashboard, it defaults to UI mode. Clarification, I have tried a single dashboard yaml in the file, I have tried !includes and various combinations but the default is the only one displayed. Additionally, as you could see, I rem # the resources line, as it caused errors on start and I have no idea what they are or where they would go… Thoughts?

you have:

ui_lovelace.yaml

i said:

ui-lovelace.yaml

notice “_” vs “-”

all dashboards use dashes instead of underscores. ui-lovelace.yaml is just another dashboard. but it’s the default dashboard.

GREAT!!!
I must confess the syntax of HA catches me up every time :pleading_face:.
I am definitely having my day made. :nerd_face:.
Now I have to look back at your earlier posts to determine how you !include the different views within.
I think I have a pretty good idea, Wish me luck…
Meanwhile… Are you able to define/describe the resources function?

Works nicely; however, I can not figure how to add more tabs. I am pretty sure it again is just syntax.
Here are my files:
/config/ui-lovelace.yaml

title: dashboard
views:
  !include '/config/include/dashboard/status.yaml'
#  !include '/config/include/dashboard/s.yaml'

beginning of /config/include/dashboard/status.yaml (Single tab view)

  - title: Status
    type: panel
    theme: Backend-selected
    badges: []
    cards:
      - type: vertical-stack
        cards:
          - title: Batteries
            type: horizontal-stack
            cards:
              - type: entities
                show_header_toggle: false
                state_color: true
                entities:
                  - entity: binary_sensor.ws_50_battery
                  - entity: binary_sensor.ws_50_battery_2

s.yaml is an exact copy with the - title: S
both work independantly, but when both are enabled, I get the error

while parsing a block mapping in “/config/ui-lovelace.yaml”, line 1, column 1 expected , but found ‘’ in “/config/ui-lovelace.yaml”, line 4, column 3

So… my goal, would be each tab is an individual !include file. I am so close…
Thoughts?

Like any bit of .yaml, if you have more than one value, you need to write your things (here your views/tabs) as a list:

title: dashboard
views:
  - !include '/config/include/dashboard/status.yaml'
  - !include '/config/include/dashboard/s.yaml'

put the dash in the !include line and leave it out of the included file itself.

title: dashboard
views:
  - !include '/config/include/dashboard/status.yaml'
  - !include '/config/include/dashboard/s.yaml'
title: Status
type: panel
theme: Backend-selected
badges: []
cards:
  - type: vertical-stack
    cards:
      - title: Batteries
        type: horizontal-stack
        cards:
          - type: entities
            show_header_toggle: false
            state_color: true
            entities:
              - entity: binary_sensor.ws_50_battery
              - entity: binary_sensor.ws_50_battery_2
1 Like

Continuing to experiment I noticed that one dashboard tab errors…
t
Is that the “resources” thing we were talking about? Any idea how to add the custom card to the breakout to yaml code(s)