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


#1

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


Restart of HA
Restart / stop Home Assistant? Systemd
What can be reloaded without restarting?
#2

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
...............

#3

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

#4

Thanks. I’ll try.


#5

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

#6

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 :

[email protected]:/home/homeassistant/.homeassistant/shell_command# dos2unix update.sh

Then you maybe you have problem with setting permission:

[email protected]:/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

#7

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


#8

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

[email protected]:/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


#9

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


#10

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


#11

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.


#12

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.


#13

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.


#14

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


#15

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?


#16

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.)


#17

ok. good to know, thanks.