I made a script that automatically updates homeassistant when I change my yaml-files

When developing new code, I think the feedback cycle is very important to keep your flow. I set up a simple script that monitors a couple of your files and automatically sends updates commands to homeassistant when they are updated. It’s a few steps to setup, but let me know if you have any questions or suggestions of improvements

This instruction is for haspbian, but this should work on most unix-based systems.

create a file named update.sh with this code in it. Make sure to update the path, url and add your homeassistant password. Save the file somewhere on your server.

install inotifywait:
sudo apt-get install inotify-tools

#!/bin/bash
inotifywait -m /home/homeassistant/.homeassistant/ -e close_write |
while read path action file; do
    if [[ "$file" == "automations.yaml" ]]; then
    	echo "$file"
       	curl -X POST -H "x-ha-access: yourpass" -H "Content-Type: application/json" http://hassbian.local:8123/api/services/automation/reload
    fi
    if [[ "$file" == "groups.yaml" ]]; then
    	echo "$file"
		curl -X POST -H "x-ha-access: yourpass" -H "Content-Type: application/json" http://hassbian.local:8123/api/services/group/reload
    fi
    if [[ "$file" == "core.yaml" ]]; then
    	echo "$file"
       	curl -X POST -H "x-ha-access: yourpass" -H "Content-Type: application/json" http://hassbian.local:8123/api/services/homeassistant/reload_core_config
    fi
done

setup the following parts of your config with external files, make sure that the files have theese exact names.

configuration.yaml

homeassistant:
  customize: !include core.yaml
automation: !include automations.yaml
group: !include groups.yaml

run the file file by going to the folder where you put update.sh and write cd ./update.sh

Now whenever you update the files core.yaml automation.yaml or groups.yaml, the homeassistant will update the webinterface instantly

caveat:
core is a littlebit wonky, it won’t update the interface until the state is changed for the updated elements

bonuses:
1:
I use a plugin called sftp for sublime text, it allows you to sync a folder to a server via ssh. This means all I have to do to update my server is to save a file on my local computer. The change happens within a second.

2:
always want this script to run, therefore I added this to /etc/rc.local

cd /home/homeassistant/.homeassistant/external
 ./restart.sh > /tmp/log_restart &

exit 0

This runs the script as a daemon on startup and sends the output to log_restar. exit 0 closes the script, so you probably only want that once in rc.local

5 Likes

Hello, I want to try your script, but maybe you can help me with some info?
How to change one file like file group.yaml to folder group.yaml with multiple files.

if [[ "$file" == "groups.yaml" ]]; then
    	echo "$file"
		curl -X POST -H "x-ha-access: yourpass" -H "Content-Type: application/json" http://hassbian.local:8123/api/services/group/reload
    fi

In my configuration.yaml I have :

................
group: !include_dir_merge_named group
automation: !include_dir_merge_list automation
...............

Uou can use inoitfywait to monitor changes to folders aswell. I don’t have time right now, but I think you could use $path instead of $file to get the folder name(s), try echo $path. you also need to add option -r to look for subdirectories.

try pasting this in your terminal and then change some files and see what you get. Let me know if you need more help :slight_smile:

#!/bin/bash
inotifywait -m /home/homeassistant/.homeassistant/ -e close_write -4 |
while read path action file; do
   echo "file changed"
   echo $file
   echo $action
   echo $path
done

Thanks. I’ll try.

I think something like this should work (not verified):

#!/bin/bash
inotifywait -m /home/homeassistant/.homeassistant/ -e close_write -r |
while read path action file; do
    if [[ "$path" == "/home/homeassistant/.homeassistant/automation/" ]]; then
    	echo "$file"
       	curl -X POST -H "x-ha-access: yourpass" -H "Content-Type: application/json" http://hassbian.local:8123/api/services/automation/reload
    fi
    if [[ "$path" == "/home/homeassistant/.homeassistant/automation/" ]]; then
    	echo "$file"
		curl -X POST -H "x-ha-access: yourpass" -H "Content-Type: application/json" http://hassbian.local:8123/api/services/group/reload
    fi
done

Today I’ve had a long day and I’ve learned a bit from the mirage of IT programming. I tried your previous suggestion and almost gave up. With the last suggestion I advanced and I managed to get rid of many errors.
As a summary, others can learn:
When you copy-paste script from website to your file update.sh ( you composed this script in a Windows-based editor, and then copied it in your Raspberry’s folder) more surely you will receive a message like this:

.......: end of file unexpected (expecting "then")

The problem is the format of the file is “dos”, but in linux shell requires “unix”, so I install the “dos2unix”

$ sudo apt-get install dos2unix

Then :

root@hassbian:/home/homeassistant/.homeassistant/shell_command# dos2unix update.sh

Then you maybe you have problem with setting permission:

root@hassbian:/home/homeassistant/.homeassistant/shell_command# chmod +x update.sh


Help links:

  1. syntax-error
  2. stop script running
  3. dos2unix
  4. Short Shell Scripts
  5. raspbian scripts
1 Like

Well done, that’s how you learn, does it work now?

I used your code with little correction at path group/automation. I run sh update.sh from

root@hassbian:/home/homeassistant/.homeassistant/shell_command# sh update.sh

But when it’s running, nothing happens. (I’m already making changes to an group):

update.sh: 4: update.sh: [[: not found
update.sh: 8: update.sh: [[: not found
update.sh: 4: update.sh: [[: not found
update.sh: 8: update.sh: [[: not found

not sure what that is, can you try just pasting the code into your command window?

Some code from you but line 10 you have automated instead group.

1.     #!/bin/bash
2.     inotifywait -m /home/homeassistant/.homeassistant/ -e close_write -r |
3.     while read path action file; do
4.         if [[ "$path" == "all/home/homeassistant/.homeassistant/automation/" ]]; then
5.         	echo "$file"
6.            	curl -X POST -H "pass_ha" -H "Content-Type: application/json" http://hassbian.local:8123/api/services/automation/reload
7.         fi
8.         if [[ "$path" == "all/home/homeassistant/.homeassistant/group/" ]]; then
9.         	echo "$file"
10.            	curl -X POST -H "pass_ha" -H "Content-Type: application/json" http://hassbian.local:8123/api/services/group/reload
11.         fi
12.     done

Then I’ll try to change an view an group and nothing happened . (homeassistant don’t update the webinterface instantly).
Then I’ll try run script from line command and appear :
continuous and alternative

update.sh: 4: update.sh: [[: not found
update.sh: 8: update.sh: [[: not found

I tried a little bit of googling, is this line still in there:

#!/bin/bash

you could also try running

bash update.sh

or just copy paste the code into your command line.

So for my URL, if I am using a ddns service i change >

http://hassbian.local:8123/api/services/automation/reload
to
https://myservername.myddns.com/api/services/automation/reload”?

Or is there another way to do this locally so it is not going out and coming back? If it matters, I am running HASS on Ubuntu 16.04.

Thanks for the assist.

it should work if you use a path that you can use to visit your config from in your local network. You can try pasting the url into your web browser aswell.

The paths on lines 4 and 8, all/home/ is that a real path?

It works only up to ‘https://myservername.myddns.com’ once i add /api and anything further i get anything from 404 not found to 405 method not allowed when using the full path: ‘https://myservername.myddns.com/api/services/automation/reload’ Do you know if this is this to be expected or is something wrong?

405 is good, you are not suppose to use it as a website, but the http-endpoint exist. (you should be posting to it, but the browser performs a GET-request, that is why you get the error.)

ok. good to know, thanks.