Autostart using systemd

Newer Linux distributions are trending towards using systemd for managing daemons. Typically, systems based on Fedora, ArchLinux, or Debian (8 or later) use systemd. This includes Ubuntu releases including and after 15.04, CentOS, and Red Hat. If you are unsure if your system is using systemd, you may check with the following command:

ps -p 1 -o comm=

If the preceding command returns the string systemd, continue with the instructions below.


A service file is needed to control Home Assistant with systemd. The template below should be created using a text editor. Note, root permissions via sudo will likely be needed. The following should be noted to modify the template:

  • ExecStart contains the path to hass and this may vary. Check with whereis hass for the location.

  • For most systems, the file is /etc/systemd/system/home-assistant@YOUR_USER.service with YOUR_USER replaced by the user account that Home Assistant will run as (normally homeassistant).

  • If unfamiliar with command-line text editors, sudo nano -w [filename] can be used with [filename] replaced with the full path to the file. Ex. sudo nano -w /etc/systemd/system/home-assistant@YOUR_USER.service. After text entered, press CTRL-X then press Y to save and exit.

Python virtual environment

If you’ve setup Home Assistant in virtualenv following our manual installation guide for Raspberry Pi (or the Python installation guide), the following template should work for you. If Home Assistant install is not located at /srv/homeassistant, please modify the ExecStart= line appropriately. YOUR_USER should be replaced by the user account that Home Assistant will run as (e.g homeassistant).

The file will be called /etc/systemd/system/home-assistant@YOUR_USER.service

[Unit]
Description=Home Assistant
After=network-online.target

[Service]
Type=simple
User=%i
WorkingDirectory=/home/%i/.homeassistant
ExecStart=/srv/homeassistant/bin/hass -c "/home/%i/.homeassistant"
RestartForceExitStatus=100

[Install]
WantedBy=multi-user.target

Now head down to the Next Steps section

Docker

If you want to use Docker, the following template should work for you.

[Unit]
Description=Home Assistant
Requires=docker.service
After=docker.service

[Service]
Restart=always
RestartSec=3
ExecStart=/usr/bin/docker run --name=home-assistant-%i -v /home/%i/.homeassistant/:/config -v /etc/localtime:/etc/localtime:ro --net=host homeassistant/home-assistant
ExecStop=/usr/bin/docker stop -t 2 home-assistant-%i
ExecStopPost=/usr/bin/docker rm -f home-assistant-%i

[Install]
WantedBy=multi-user.target

Next Steps

You need to reload systemd to make the daemon aware of the new configuration.

sudo systemctl --system daemon-reload

To have Home Assistant start automatically at boot, enable the service.

sudo systemctl enable home-assistant@YOUR_USER

To disable the automatic start, use this command.

sudo systemctl disable home-assistant@YOUR_USER

To start Home Assistant now, use this command.

sudo systemctl start home-assistant@YOUR_USER

You can also substitute the start above with stop to stop Home Assistant, restart to restart Home Assistant, and ‘status’ to see a brief status report as seen below.

$ sudo systemctl status home-assistant@YOUR_USER
● [email protected] - Home Assistant for YOUR_USER
Loaded: loaded (/etc/systemd/system/home-assistant@YOUR_USER.service; enabled; vendor preset: disabled)
Active: active (running) since Sat 2016-03-26 12:26:06 CET; 13min ago
Main PID: 30422 (hass)
CGroup: /system.slice/system-home\x2dassistant.slice/home-assistant@YOUR_USER.service
├─30422 /usr/bin/python3 /usr/bin/hass
└─30426 /usr/bin/python3 /usr/bin/hass
[...]

To get Home Assistant’s logging output, simple use journalctl.

sudo journalctl -f -u home-assistant@YOUR_USER

Because the log can scroll quite quickly, you can select to view only the error lines:

sudo journalctl -f -u home-assistant@YOUR_USER | grep -i 'error'

When working on Home Assistant, you can easily restart the system and then watch the log output by combining the above commands using &&

sudo systemctl restart home-assistant@YOUR_USER && sudo journalctl -f -u home-assistant@YOUR_USER

Automatically restarting Home Assistant on failure

If you want to restart the Home Assistant service automatically after a crash, add the following lines to the [Service] section of your unit file:

Restart=on-failure
RestartSec=5s
21 Likes

Thanks good explanation got it working.

Advice to everyone new to Raspberry OS / linux.

Use “sudo nano” to sudo edit text files.
It’s harder to start but easier in the end because gksudo & other sudo methods to gui edit text files are hard to get working now in latest versions of Linux

Thank you for this! These steps should absolutely be included in the manual installation guide. Or at least include a link to this post.

2 Likes

Thanks for the guide. Home Assistant doesn’t start and I believe it has got to do with the folder structure. Here’s the output for sudo systemctl status home-assistant@homeassistant

   Loaded: loaded (/etc/systemd/system/[email protected]; enabled; vendor preset: disabled)
   Active: failed (Result: exit-code) since Fri 2020-09-04 19:18:58 EDT; 3min 15s ago
  Process: 5409 ExecStart=/opt/homeassistant/bin/hass -c /home/%i/.homeassistant (code=exited, status=200/CHDIR)
 Main PID: 5409 (code=exited, status=200/CHDIR)

Sep 04 19:18:58 vortexbox systemd[1]: Started Home Assistant.
Sep 04 19:18:58 vortexbox systemd[1]: [email protected]: Main process exited, code=exited, status=200/CHDIR
Sep 04 19:18:58 vortexbox systemd[1]: [email protected]: Unit entered failed state.
Sep 04 19:18:58 vortexbox systemd[1]: [email protected]: Failed with result 'exit-code'.

I have confirmed the Home Assistant install with whereis hass so I believe this is correct

what does your systemd service file look like?

As in /etc/systemd/system/home-assistant@YOUR_USER.service

I have created a user homeassistant so created /etc/systemd/system/[email protected] as per the above instructions for a virtual environment (setup done via Installing Home Assistant Core on Fedora) - only change is the location of home assistant which I checked via whereis hass

Description=Home Assistant
After=network-online.target
[Service]
Type=simple
User=%i
WorkingDirectory=/home/%i/.homeassistant
ExecStart=/opt/homeassistant/bin/hass -c "/home/%i/.homeassistant"

[Install]
WantedBy=multi-user.target 

File details as follows

-rwxr-xr-x 1 root root 238 Sep  4 18:53 /etc/systemd/system/[email protected] ```
1 Like

Thanks for this great guide! It works perfect except … for locally executed command lines.
My HA is installed in Python virt.environment on Debian. I have a pretty simple CPUtemp sensor ( platform: command_line) with
command: cat /sys/class/thermal/thermal_zone0/temp
This runs as expected when HA is manually invoked:

> sudo -u homeassistant -H -s
> cd /srv/homeassistant
> source bin/activate
> hass

The CPU temperature is read periodically and then displayed in my GUI.

But today I implemented the ‘systemd’ script to autostart the HA and … I started to receive this strange error message every minute:

hass[978]: /bin/sh: 1: cat: not found
hass[978]: ERROR (SyncWorker_1) [homeassistant.components.command_line] Command failed: cat /sys/class/thermal/thermal_zone0/temp

It looks like HA (run by systemd) is invoking the command line with sh shell and not bash. Why? What am I doing wrong?
I already checked the passwd file for homeassistant user and it is correctly set to /bin/bash. How can I troubleshoot this further?

Yeah, something strange, really…
I’ve added this extra line to home-assistant.service file to check what shell the Home Assistant is being started:

ExecStartPre=echo $SHELL >> /home/homeassistant/asa.txt

daemon.log showed an interesting result:

Oct 16 08:25:48 localhost systemd[1]: Stopped Home Assistant.
Oct 16 08:27:21 localhost systemd[1]: Reloading.
Oct 16 08:27:37 localhost systemd[1]: Starting Home Assistant...
Oct 16 08:27:37 localhost echo[24133]: /bin/bash >> /home/homeassistant/asa.txt
Oct 16 08:27:37 localhost systemd[1]: Started Home Assistant.
[...]
Oct 16 08:27:55 localhost hass[24134]: /bin/sh: 1: cat: not found
Oct 16 08:27:55 localhost hass[24134]: 2020-10-16 08:27:55 ERROR (SyncWorker_18) [homeassistant.components.command_line] Command failed: cat /sys/class/thermal/thermal_zone0/temp

Now I see that systemd works properly and starts Home Assistant from bash. But then, Home Assistant (for unknown reason) fires its own command line scripts from (much limited) sh shell. Gosh, why?
Or more precisely, why this happen only when HA is autostarted by this systemd script?

I am facing the same issue with the same setup (HA installed in virtual environment) : when starting Home Automation manually with hass, I can run shell_commands without issue.

But when starting with the autostart systemd script, the commands are not successfull. In my case I am trying to send an infrared signal to my amp with ir-ctl and tried to send the command directly or via a script

Dec 22 12:53:50 raspberrypi hass[13207]: 2020-12-22 12:53:50 ERROR (MainThread) [homeassistant.components.shell_command] Error running command: `/bin/bash -c "/usr/bin/ir-ctl -g 75000 -S rc5x_20:0x100c00 -S rc5x_20:0x100c00 -d /dev/lirc0"`, return code: 66
Dec 22 13:10:17 raspberrypi hass[13207]: 2020-12-22 13:10:17 ERROR (MainThread) [homeassistant.components.shell_command] Error running command: `~/pm53_ir_control.sh volumeup`, return code: 66
Dec 22 13:10:17 raspberrypi hass[13207]: NoneType: None

Have you found a correction for this issue?

I’m having problems enabling the service. I installed in a python virtual environment.

Here’s the output of the systemctl status:

[email protected] - Home Assistant
   Loaded: loaded (/etc/systemd/system/[email protected]; enabled; vendor preset: enabled)
   Active: inactive (dead)

Dec 26 13:49:18 raspberrypi systemd[1]: /etc/systemd/system/[email protected]:8: Neither a valid executable name nor an absolute path: ~/homeassistant/bin/hass

Hass won’t execute out of a command line in its directory. Which is consistent with my assumption that hass is a python script.

How is the ExecStart supposed to work with a python script?

Thanks.

Here’s my resolution:

[Unit]
Description=Home Assistant
After=network-online.target

[Service]
Type=simple
User=%i
WorkingDirectory=/home/%i/.homeassistant

ExecStart=/home/pi/homeassistant/bin/python3 /home/pi/homeassistant/bin/hass

[Install]
WantedBy=multi-user.target

1 Like

I am not an expert, but maybe I can help you:
Services started as daemons have a more limited environment than a normal console login.
There is no stdin and stdout available and the PATH variable is not the same.
So, whatever you do within a service, you should work with full pathnames or add the necessary pathes at the beginning.

Perfect guide !

was working on my PI3 with raspbian install.

I would suggest to add/integrate it on the Doc

Thanks

Thanks for the guide. It worked great after a few modifications for my environment.

If your configuration uses a serial port for ZWave make sure that the HomeAssistant account in the systemctl file has access, or the daemon will start but not be able to communicate with the ZWave devices. Here is a link that explains Automatic ACL assignment at boot time. The HomeAssistat install scripts create the file /etc/udev/rules.d/90-extraacl.rules. This file gives permission to the USB serial ports for the user that ran the install scripts. If you run under a different user, the file will have to be edited to grant permission to that user.

The instructions ought to include that if you already had a working installation and you’re just trying to get Docker to start HA automatically on boot (because, say, as in my case, it used to start automatically but no longer does and you can’t figure out why), you have to change the path to the config folder from /home/%i/.homeassistant/ to whatever your correct current config path is. Otherwise you start over with a fresh blank config.

I second @KupieTools
Broke my entire install… Got a fresh HA without supervisor (don’t know why, but that’s problematic to restore a snapshot…). I don’t know how I’m gonna get out if this one. I ought to be more careful doing stuff I don’t know enough about ^^
Edit: Nevermind, I was lucky enough to give the wrong folder so I did not overwrite anything so all is well.
Beware if you’re not sure what you’re doing^^

if you have a component that accesses network at startup, After=network-online.target may not be sufficient. In my case, dns resolution was failing for my component when it accessed network at startup, probably because systemd was starting hass too early.
The following helped me: https://unix.stackexchange.com/a/356189/62292
My systemd file is:

[Unit]
Description=Home Assistant
After=NetworkManager-wait-online.service
Requires=NetworkManager-wait-online.service

[Service]
Type=simple
User=%i
WorkingDirectory=/home/%i/.homeassistant
ExecStart=/srv/homeassistant/bin/hass -c "/home/%i/.homeassistant"

[Install]

More info about my machine (standard Manjaro KDE)

[xxxxx@computer ~]$ systemctl is-enabled NetworkManager-wait-online.service systemd-networkd-wait-online.service
enabled
disabled
1 Like

Help please. After some system changes I find that I cannot get the Supervisor container to start after a reboot.


It starts fine if I trigger it manually.

I’ve checked /etc/systemd/system/hassio-supervisor.service

[Unit]
Description=Hass.io supervisor
Requires=docker.service
After=docker.service dbus.socket

[Service]
Type=simple
Restart=always
RestartSec=5s

ExecStartPre=-/usr/bin/docker stop hassio_supervisor
ExecStart=/usr/sbin/hassio-supervisor
ExecStop=-/usr/bin/docker stop hassio_supervisor


[Install]
WantedBy=multi-user.target

and tried
sudo systemctl daemon-reload
sudo systemctl restart

and
curl -Lo installer.sh https://raw.githubusercontent.com/home-assistant/supervised-installer/master/installer.sh
bash installer.sh

But still end up having to start the supervisor container manually. I see other posts that indicate some portion of the install might need to be re issued but have not been able to pick that apart and apply it to the current HA. My enviro

core-2021.2.3
supervisor-2021.02.11
Docker 20.10.4
Raspbian GNU/Linux 10

TIA

1 Like

editing this file helped me with manual restarting HA

sudo nano /etc/systemd/system/hassio-supervisor.service

and editing this line to:
#ExecStartPre=-/usr/bin/docker stop hassio_supervisor

and

sudo systemctl --system daemon-reload

I have that in there already. Thanks though

Funny coincidence, Same time you sent that - I was just watching the system restart and for a bit Supervisor was running and then fell over. I can restart the container and all is well>?>? Maybe there is another sequence issue. I dunno. Very frustrate. This all started with trying out TailScaled in place of Wireguard