Frustrated with YAML and HA configuration in general

I really like Home Assistant, but I’m completely frustrated with the syntax of the configuration. I can’t seem to find any good formula or logic for why certain items are indented, or itemized. For example, this works formatted the way it is:

garage_lights_timer_off:
  alias: "Turn off Garage lights after 10 minutes"
  sequence:
    - delay:
        minutes: 10
    - condition: state
      entity_id: garage_lights_manual_mode
      state: 'off'
    - service: switch.turn_off
      data:
        entity_id: switch.garage_lights

But, this doesn’t:

garage_lights_timer_off:
  alias: "Turn off Garage lights after 10 minutes"
  sequence:
    - delay:
        minutes: 10
    - condition: state
        entity_id: garage_lights_manual_mode
        state: 'off'
    - service: switch.turn_off
      data:
        entity_id: switch.garage_lights

And the only difference is the indentation of “entity_id” and “state”. Which seems appropriate.

And this works:

office_lights_timer_reset:
  alias: "Reset Office Lights Timer"
  sequence:
    - service: switch.turn_on
      data:
        entity_id: switch.office_fan_light
    - service: switch.turn_on
      data:
        entity_id: switch.office_desk_lights

But, this doesn’t:

   office_lights_timer_reset:
      alias: "Reset Office Lights Timer"
      sequence:
        - service: switch.turn_on
          data:
            - entity_id: switch.office_fan_light
            - entity_id: switch.office_desk_lights

It seems like “entity_id” would be an itemized component of “data”, so that the block of code above doesn’t need to be repeated.

And, then there’s this whole “condition: condition:” thing:

  trigger:
    platform: time
    after: '08:00:00'
  condition:
    condition: time
    weekday:
      - mon
      - tue
      - wed
      - thu
      - fri

Is there any resource that could teach me how, and why I should indent something, when I should use multiple condition tags, or just pretty much anything that will teach me to create rules logically in my head? The syntax is really holding me back from doing some incredible stuff that I know is possible. I know how to script in many different languages, if that matters any.

Edit: Do you folks not feel the same way? Is writing the automation just blatantly obvious to you and there’s just something I’m missing?

1 Like

I suggest first reading up on the YAML syntax. I just read the wikipedia entry and was happy with that, but I think there are other resources that might explain it better. Blogs perhaps.

For example:
A word with colon after, translates to a key in a python dictionary. Anything after the colon, on the same line or indented below, will be the value mapped to the key. If the value is indented the value will hold a new data structure, either a dictionary or a list. Multiple equally indented keys on different rows, below the same parent, will be part of the same dictionary. A hyphen, -, translates to a python list item. Multiple equally indented hyphens on different rows, below the same parent, will be list items in the same list. If you apply these rules iteratively, you should have most of the big picture of how the YAML config makes a python structure of dicts and lists.

The second piece of info needed, is what HA expects in the configuration. This should be documented in the documentation. :smiley: A problem here is the fast pace of development in HA. As things are changing very fast, sometimes the expected configuration of HA for the components/platforms also changes, and often the documentation has a hard time keeping up to date, as some old examples might be left behind.

I think HA has a very good documentation but it will never be finished and we need to keep working on it, to make it up to date and as pedagogic as possible. Fortunately it’s pretty easy for anyone to update the docs, as every page has an “edit this page on Github” link.

2 Likes

Yes I felt the same way about YAML when I first started but it is amazing how quickly I got used to it. I am sure you will too, the more that you use it. The formatting rules are really simpler than they seem once you spend some time with it. And if it makes a difference, I probably know a third of the languages that you do! :laughing:

The reference @martinhjelmare directed you to is a great place to start but honestly, I just allowed myself to make mistakes and followed up with the error messages. I rarely miss an indent or something now, but I am sure even @balloob makes formatting errors now and again and he’s the head dev - and I’m sure with all the other languages that you know, you’ve probably had many a syntax issue that you spotted and shook your head over missing.

Allow yourself the luxury of failing and learning from it, like you’ve done before. :wink:

1 Like

Thanks for the words of encouragement! With all the other languages, at least there’s seemingly consistent rules to follow. I guess I’d much prefer a script-based configuration than a YAML one.

So far, I’ve been able to fumble through everything, it’s just a slow process because syntax I would expect to work often times doesn’t.

FWIW, I’ve found that using yamllint to check the YAML structure of all the included .yaml files before starting HASS is a huge time saver. I also look for errors in the log file while waiting for it to start. Something like this:

start() {
  local CMD="$PRE_EXEC /usr/local/bin/hass $FLAGS"
  find /var/opt/hass -type f -name "*.yaml" | while read file; do
     /usr/local/bin/yamllint -d "{require-starting-space: no}" "${file}"
  done
  su - $RUN_AS -c "$CMD"
  echo -n $"Starting HASS: "
  end=$((SECONDS+60))
  while [ $SECONDS -lt $end ]; do
    sleep 1
    echo -n "."
    errors=$(egrep -i "(Error|Warning|Invalid)" /var/opt/hass/home-assistant.log | egrep -v '(homeassistant.components.sensor.template: UndefinedError:)')
    errors="${errors}$(egrep -B1 "(^  in )" /var/opt/hass/home-assistant.log)"
    started=$(grep "Network ready" /var/opt/hass/home-assistant.log)
    if [ "${started}" != "" ]; then break; fi
    if [ "${errors}" != "" ]; then break; fi
  done
  if [ "${errors}" != "" ]; then
     echo
     echo "${errors}"
  elif [ "$(pgrep hass)" != "" ]; then
     success $"Starting HASS: "
  else
     fail $"Starting HASS: "
  fi
  echo
}

i know the feeling to.
it is really hard to get used to, and lots of times hard to find out what you can and cannot use on what place.

it would be really great if in the future there would be a GUI to edit the config.

Having a GUI always seems like the go to answer, but I think it actually makes us dumber as we rely on the nice friendly interface instead of knowing how things work. For systems that are designed for the average grandmother, yeah, I would expect a GUI interface to hand hold them through it, but with the power of HA, it is not meant for grandma to set it up. Its designed to do more than the crapy GUI interface driven drivel put out by the likes of Wink, Hue, Logitech, etc.

Writing your own automation, scripts, etc by hand lets you know exactly what you are doing, why you are doing it and you know when there is a problem you can fix it. With a GUI, you are stuck hoping that the GUI was programmed correctly and when you tell it to set something to a certain value that it is going to do just that. Its one more layer between my command and the action I want to be taken… and not just one more layer, but one more layer that I have no control over should it break.

Personally, the day HA starts slapping GUI editors all over the place and starts putting up barriers between me and the code is the day I start looking for another platform.

As for the original topic of this post, I am actually surprised by the frustration with YAML. I can honestly say that when they switched to YAML, I was over joyed. Working with YAML is clean and readable, probably as close as I can get to actually typing out a sentence of describing what you want done. Compared to JSON and XML, this is a dream.

It is actually not that difficult, but if you over analyze it, it seems more complex than it really is. The rules are simple and never changing, just take your time, and eventually you will be writing YAML at break neck speed :slight_smile:

P.S. - be thankful you are not on the SmartThings platform and writing Groovy code… blech!

Which editor do you use to create your .yaml’s?
I noticed that a good editor with syntax marking can save you a lot of headaches.
For editing code i use Sublime Text 3. Be sure to set it to ‘YAML’ markup in the bottom right corner. You will see it will give everything nice colors, which makes spotting errors much easier.

Further, each level of indentation always goes by 2 spaces.
First line has no spaces, then 2 spaces, then 4 spaces, then 6 spaces etc.

The YAMLLint is also a good tool to get started quicker. Maybe it should even be mentioned in the ‘Getting Started’ part of the website, to help beginners. I have created a pull request for it. Done.

@jbardi there Always a possiblity for both options.
a gui for those who want one and still the possibility to do it without the gui.
i hope that HA at some point gets popular enough that also grandma want to have it :wink:

i guess my stress lies with the part off yet another language to master.
and another part comes from inconsistencies in HA itself.

@ThinkPad thx. i downloaded sublime and it makes it a little better then what i used till now. :wink:

1 Like

I’ve used ConText for years now. As an aside, if you use the built in editor for WinSCP, note that it often doesn’t save in proper UTF-8 format - especially for special characters.

You must have read this: Escape degree sign in PHP cURL to HASS virtual sensor? :smile:

Yep! I was hoping to cross reference the knowledge. :wink:

No argument here. Yaml can be a frustrating pain in the ass. I deal with it like this: run everything through an online Yaml parser to weed out the dumb, and usually hard to find mistakes. And second: keep multiple copies handy. Before making additions, I make a copy of the files and stick them in a “Last Working Config” folder. That way I can always revert back.

1 Like

I use gulp as a task runner. I have a task that can validate the YAML and also a task that pushes the files to my pi via ssh. Here is the snippet for validating:

const gulp    = require('gulp');
const yaml    = require('gulp-yaml-validate');

gulp.task('yaml', () => {
  return gulp.src("**/*.yaml")
    .pipe(yaml());
});
gulp.task('default', ['yaml']);

I also find a good git flow can alleviate a lot of headaches with rolling back to a working version.

1 Like

I have moved away from HASS for the automation side of my house. I now use Node-Red with MQTT topics arranged based on the switch/sensor name.

ie HASS/switch/pool_pump/ with values of “on” and “off”

Then i use the following automation:

- alias: 'pool pump on'
  trigger:
    platform: mqtt
    topic: HASS/switch/pool_pump1/
    payload: 'on'
  action:
    service: switch.turn_on
    entity_id: switch.pool_pump1

- alias: 'pool pump off' 
  trigger:
    platform: mqtt
    topic: HASS/switch/pool_pump1/
    payload: 'off'
  action:
    service: switch.turn_off
    entity_id: switch.pool_pump1

In the future i think i will make a component which automatically subscribes to all appropriate topics, based on sensors and switches, as well as posts to the appropriate MQTT topics whenever there is a state change.

I can show more details if you like, but that should set you up to start if you want to go down this route.

Honestly, I’m not even sure why YAML is used. I haven’t seen documentation to justify this choice or anything.

There are all kinds of scripting languages that are less picky and allow for things like formulas and other more complex logic. Like, adding two numbers in YAML is an ordeal too complex to be worth indulging. I mean C-Script or Javascript would have been great. Or even python. A scripting language, rather than a markup language, would be much more suited to the kind of complexity that home automation entails if you ask me. Maybe use yaml only for customizing the frontend.

1 Like