Add systemd-logind to the Home Assistant OS to handle power button shutdown

I’m building my custom Raspberry Pi 4 based Home Assistant setup with custom 3D-printed case where I would like to have a button for graceful shutdown and startup of the system (I’ve described my work with it in depth in this thread) in a way that’s independent from all the HA Docker containers - i.e. not handle the power button in the Home Assistant but leave it to the system instead. Turns out Raspberry has a dedicated power off button capability - using the gpio-shutdown device tree overlay turns the GPIO3 pin into a power key - connecting it with GND brings the system to the halt state and connecting them again turns it on. One could even configure additional GPIO pin to act as an ACT LED, set its trigger to default-on and attach the pin to the backlit button to get a button, doubling as a power indicator - in such configuration the ACT LED is always on and turns off once the system is shut down! :grinning: All that’s required is adding the following snippet to the config.txt file on the boot partition:

dtparam=act_led_trigger=default-on
dtoverlay=act-led,gpio=4
dtoverlay=gpio-shutdown,gpio_pin=3

Although the power on functionality is hardware specific and works even when gpio-shutdown overlay is not loaded, for the shutdown to bring the system down gracefully it’s necessary to handle the KEY_POWER event somehow - this works out-of-box if the init process is systemd with systemd-logind service installed. HassOS uses systemd, but doesn’t have the systemd-logind service. According to the manpages, systemd-logind is responsible for:

  • Keeping track of users and sessions, their processes and their idle state.
  • Generating and managing session IDs.
  • Providing polkit-based access for users for operations such as system shutdown or sleep
  • Implementing a shutdown/sleep inhibition logic for applications
  • Handling of power/sleep hardware keys
  • Multi-seat management
  • Session switch management
  • Device access management for users
  • Automatic spawning of text logins (gettys) on virtual console activation and user runtime directory management

It’s a very small change in Buildroot to enable systemd-logind, merely requiring enabling the BR2_PACKAGE_SYSTEMD_LOGIND option. In fact, when writing this post I’m building the HassOS locally with the systemd-logind enabled to check it out on my RPI setup if it won’t break any core functionalities of the system. The “providing polkit-based access” got me worried, but HassOS doesn’t include polkit.

I thought about making a pull request to the HassOS repository on Github, but it might be more appropriate to discuss that matter first - after all, the vast majority of stuff introduced by systemd-logind seems unnecessary from the embedded systems point of view. However, I think it would be good to have some standardized hardware-agnostic way of handling the power button. :slightly_smiling_face:

Okay, so here is the summary of my test. I’ve built the latest version of HassOS (branch dev, commit 06e7ee7efbb613017b02c396c92c93a91a1bb744) with rpi4 target and BR2_PACKAGE_SYSTEMD_LOGIND enabled. I’ve flashed the built image to the SD card and added the following line to the config.txt on the boot partition:

dtoverlay=gpio-shutdown

I’ve attached the CONFIG USB stick with the public key in order to ssh to the host later, inserted the SD card into my Raspberry Pi 4, plugged the Ethernet cable and powered it on. Home Assistant starts normally - I’ve managed to go through onboarding, added Zigbee integration and few devices to the Zigbee network, with no differences when compared to the build without systemd-logind bundled with the system.

As you can see in the screenshot below, systemd-logind has found the power button successfully - pressing the button (connecting GPIO3 and GND) performs a graceful shutdown now:

3 Likes

I’m trying to do the same thing to have a power button on my pi running Home Assistant directly.

Did you find a more graceful way or is it still needful to manually compile things?