Monitor Running Services Using Systemd and Homeassistant

Systemd and HomeAssistant

I was having issues with my Raspberry Pi, specifically the Bluetooth service running through systemd. So naturally I wanted to be able to track when the service was reporting as failed or offline/disabled, and that manifested in another custom sensor setup for HomeAssistant. This is a python script that will iterate through system services given in a list and create sensors in your HomeAssistant instance and have their state mapped to the sensor state (running = on, failed/stopped = off). I have it set up to run every few minutes through a cron job, and its worked flawlessly so far.

import requests
import json
import subprocess
import time
import os

# systemd-service-sensor

# URL for homeassistant instance
hass_url = "http://HA_URL/api/states/sensor."

# Headers for homeassistant instance
hass_headers = {'Accept': 'application/json',
                'Content-Type': 'application/json',
                'x-ha-access': 'HA_PASSWORD'
               }

# Services I want to track
services = ["bluetooth.service","cron.service",
            "dasher.service","nginx.service",
            "ntp.service","ssh.service","supervisor.service"]

for service in services:

  # Get status information from systemctl
  service_info = subprocess.check_output("systemctl is-active " + service + "; exit 0",
                                         stderr=subprocess.STDOUT, 
                                         stdin=open(os.devnull), 
                                         shell=True).decode('utf-8').replace("\n","")

  # Generate payload for HASS
  hass_payload = {
        "state": service_info,
        "attributes": {
             "friendly_name": service.replace("."," ")
        }
  }

  # Formate sensor name to be *service*_service instead of *service*.service
  hass_sensor = service.replace(".","_")
  hass_sensor = hass_sensor.replace("-","_")

  # POST data to HASS
  hass_request = requests.post(hass_url + hass_sensor,
                               headers=hass_headers,
                               data=json.dumps(hass_payload))