Home Assistant Sensors

I’m trying to use check_hassio (GitHub - check-plugins/check_hassio: Home Assistant sensor plugin for Nagios/Icinga) to monitor some temperature sensors, these are Zigbee sensors controlled by Home Assistant. I want to have a Home Assistant host in Icinga which has multiple sensor checks, there will be other Home Assistant hosts in the future, for now there’s just one.

Rather than create a service for each sensor, I’d like to just define all of the sensors along with thresholds in the host definition. I have this working for a single sensor:

object CheckCommand "check_hassio" {
  import "plugin-check-command"
  command = [ PluginDir + "/check_hassio" ]
  arguments += {
    "-H" = {
      description = "Host"
          required = true
          value = "$host.address$"
      }
    "-t" = {
      description = "Token"
      value = "$host.vars.hass_token$"
    }
    "-s" = {
      description = "Sensor"
      value = "$host.vars.sensors.name$"
    }
    "-F" = {
      description = "Float"
    }
    "-w" = {
      description = "Warning"
      value = "$host.vars.sensors.warn$"
    }
    "-c" = {
      description = "Critical"
      value = "30"
      value = "$host.vars.sensors.crit$"
    }
  }
}

object Host "HASS2" {
  import "generic-host"
  import "home-assistant"
  address = "xxx.xxx.xxx.xxx"
  vars.app = "HASS"
  vars.sensors = { name = "sensor.temp_aisle_1_temperature", warn = "23", crit = "26" }
}

apply Service "HASS" {
  check_command = "check_hassio"
  assign where host.vars.app == "HASS"
}

How can I make this work for multiple? I thought of maybe putting it inside an array like this:

vars.sensors = [
    { name = "sensor.temp_aisle_1_temperature", warn = "23", crit = "26" },
    { name = "sensor.temp_aisle_2_temperature", warn = "26", crit = "30" }
  ]

But then I’m unsure how to use it in the service/command. How would I get that to work?

Or is there a better way to do this? Should I just be creating a service for each sensor? Or create each as a host (they would all point to the Home Assistant server IP as that’s the API the command is querying)?

1 Like

Well, you can do something like this Apply Rule using Dictionaries on each host, maybe it gives you an idea on how you could make this work.

object Host "homeassistant" {
import "generic-host"
vars.dict["key1"] = "value1"
vars.dict["key2"] = "value2"
}
apply Service "HomeAssistant-" for (key => value in host.vars.dict) {
import "generic-service"
check_command = "dummy"
vars.dummy_text = value
}

Cheers!

1 Like

Alright, i have been a bit bored today, so i made this small PoC, based on the Icinga Docs and your Examples.

object CheckCommand "check_hassio" {
  import "plugin-check-command"
  command = [ PluginDir + "/check_hassio" ]
  arguments += {
    "-H" = {
      description = "Host"
          required = true
          value = "$host.address$"
      }
    "-t" = {
      description = "Token"
      value = "$host.vars.hass_token$"
    }
    "-s" = {
      description = "Sensor"
      value = "$host.vars.sensors.name$"
    }
    "-F" = {
      description = "Float"
    }
    "-w" = {
      description = "Warning"
      value = "$service.vars.warn$"
    }
    "-c" = {
      description = "Critical"
      value = "30"
      value = "$service.vars.crit$"
    }
  }
}

I only changed the values of -c and -w to service.vars.

Then, here is my Host object. Pretty similar to yours, we have different sensors as host variables with different values for the warning and critical Threshold:

object Host "homeassistant" {
  check_command = "dummy"
  address = "192.168.177.72"
  vars.app = "HASS"
  vars.sensors["temp1"] = {
    sensor_name = "Temperature 1"
    sensor_id = "7568"
    warn = 23
    crit = 26
  }
  vars.sensors["temp2"] = {
    sensor_name = "Temperature 2"
    sensor_id = "7569"
    warn = 26
    crit = 30
  }
}

And here is the Service Apply rule, just looping through all host.vars.sensors objects and creating a service for each of them.

apply Service for (sensor => config in host.vars.sensors) {
  check_command = "check_hassio"

  vars += config
  assign where host.vars.app == "HASS"
  display_name = "Sensor Check for " + vars.sensor_name + "-" + vars.sensor_id

  check_interval = 5s
  retry_interval = 15s
}

Now, lets check in IcingaDB-Web How many Services on our Host are:

Id say this looks pretty fine. One Host with two different Services, and the Thresholds are getting properly mapped to the right Service. Cheers @penguist

3 Likes

This is exactly what I needed! Thank you

I just changed value = “$host.vars.sensors.name$” to value = “$service.vars.sensor_name$” so it passes the name to the command and it works

2 Likes

I like this thread very much. On the above, could you please confirm that the needed change is in the CheckCommand definition?

Regarding the line below, could you please tell me what would be the name assigned to the Service, if nothing had been specified?

Thank you!

I changed the name a little to just include a display name in each sensor definition. The sensor_name variable is required as this is the name of the sensor entity within Home Assistant, check_hassio uses this to get the data from the Home Assistant API. I removed the sensor_id as I don’t need it for my setup.

This is my full working config:

object CheckCommand "check_hassio" {
  import "plugin-check-command"
  command = [ PluginDir + "/check_hassio" ]
  arguments += {
    "-H" = {
      description = "Host"
          required = true
          value = "$host.address$"
      }
    "-t" = {
      description = "Token"
      value = "$host.vars.hass_token$"
    }
    "-s" = {
      description = "Sensor"
      value = "$service.vars.sensor_name$"
    }
    "-F" = {
      description = "Float"
    }
    "-w" = {
      description = "Warning"
      value = "$service.vars.warn$"
    }
    "-c" = {
      description = "Critical"
      value = "$service.vars.crit$"
    }
  }
}

object Host "homeassistant" {
  check_command = "dummy"
  address = "xxx.xxx.xxx.xxx"
  vars.hass_token = "xxxxxxxxxx"
  vars.app = "HASS"
  vars.sensors["temp1"] = {
    sensor_name = "sensor.temp_aisle_1_temperature"
    sensor_dispname = "Temperature Aisle 1"
    warn = 23
    crit = 26
  }
  vars.sensors["temp2"] = {
    sensor_name = "sensor.temp_aisle_2_temperature"
    sensor_dispname = "Temperature Aisle 2"
    warn = 26
    crit = 30
  }
}

apply Service for (sensor => config in host.vars.sensors) {
  check_command = "check_hassio"

  vars += config
  assign where host.vars.app == "HASS"
  display_name = vars.sensor_dispname

  check_interval = 5s
  retry_interval = 15s
}

You just need to supply the IP of the Home Assistant host and the token and then customise with your sensors.

I quickly found that I have some binary sensor types so I adapted the config:

object CheckCommand "check_hassio" {
  import "plugin-check-command"
  command = [ PluginDir + "/check_hassio" ]
    arguments += {
      "-H" = {
        description = "Host"
        required = true
        value = "$host.address$"
      }
      "-t" = {
        description = "Token"
        value = "$host.vars.hass_token$"
      }
      "-s" = {
        description = "Sensor"
        value = "$service.vars.sensor_name$"
      }
      "-F" = {
        set_if = {{ macro("$service.vars.sensor_type$") == "float" }}
        description = "Float"
      }
      "-w" = {
        set_if = "$service.vars.warn$"
        description = "Warning"
        value = "$service.vars.warn$"
      }
      "-c" = {
        set_if = "$service.vars.crit$"
        description = "Critical"
        value = "$service.vars.crit$"
      }
      "-R" = {
        set_if = {{ macro("$service.vars.sensor_type$") == "binary" }}
        description = "Regex"
      }
      "-e" = {
        set_if = {{ macro("$service.vars.sensor_type$") == "binary" }}
        description = "Expect"
        value = "$service.vars.expect$"
      }
   }
}

object Host "homeassistant" {
  check_command = "dummy"
  address = "xxx.xxx.xxx.xxx"
  vars.hass_token = "xxxxxxxxxx"
  vars.app = "HASS"
  vars.sensors["temp1"] = {
    sensor_name = "sensor.temp_aisle_1_temperature"
    sensor_dispname = "Temperature Aisle 1"
    sensor_type = "float"
    warn = 23
    crit = 26
  }
  vars.sensors["temp2"] = {
    sensor_name = "sensor.temp_aisle_2_temperature"
    sensor_dispname = "Temperature Aisle 2"
    sensor_type = "float"
    warn = 30
    crit = 33
  }
  vars.sensors["ac1op"] = {
    sensor_name = "binary_sensor.ac1_operation"
    sensor_dispname = "Aircon 1 Operation"
    sensor_type = "binary"
    expect = "on"
  }
  vars.sensors["ac1fault"] = {
    sensor_name = "binary_sensor.ac1_fault"
    sensor_dispname = "Aircon 1 Fault"
    sensor_type = "binary"
    expect = "off"
  }
}

apply Service for (sensor => config in host.vars.sensors) {
  check_command = "check_hassio"

  vars += config
  assign where host.vars.app == "HASS"
  display_name = vars.sensor_dispname

  check_interval = 5s
  retry_interval = 15s
}