I have done most of my openHAB integration with icinga2 by adding MQTT bindings to the sensor/battery/state items I want to monitor and then implementing rules and checks via mqttwarn.
E.g. in my mqttwarn.ini
I have an icinga2
target configured;
[config:icinga2]
host = 'https://icinga2-host'
port = 5665
username = 'icinga2-api-username'
password = 'icinga2-api-password'
targets = {
# host service
'check-service' : [ 'host', 'service', 'mqttwarn' ],
}
Then I have a series of subscriptions (also in mqttwarn.ini
);
# various MQTT services/clients
[/clients/+]
targets = icinga2:check-service
format = icinga2_lwt_publish()
# zwave node alive/dead
[/network/+/+/zwave]
targets = icinga2:check-service
format = icinga2_network_zwave()
# battery reports for various sensors
[/sensor/+/+/battery]
targets = icinga2:check-service
format = icinga2_sensor_battery()
Then I have a series of functions which are being referenced in the targets above, e.g. icinga2_sensor_temp()
;
def icinga2_lwt_publish(data, srv):
# /clients/+
# /homie/+/$online
payload = data['payload']
parts = data['topic'].split('/')
host = parts[2]
if payload == '1' or payload == 'true':
status = 0
output = "OK: {0} is online".format(host)
else:
status = 2
output = "CRITICAL: {0} is offline".format(host)
icinga2_payload = {
'exit_status' : status,
'plugin_output' : output,
'service' : "{0}.home!mqtt-lwt".format(host),
}
return json.dumps(icinga2_payload)
def icinga2_network_zwave(data, srv):
payload = data['payload']
if payload == 'alive':
status = 0
code = 'OK'
elif payload == 'dead':
status = 2
code = 'CRITICAL'
else:
status = 3
code = 'UNKNOWN'
# /network/location/type/zwave
parts = data['topic'].split('/')
location = parts[2]
type = parts[3]
host = "{0}-{1}".format(location, type)
icinga2_payload = {
'exit_status' : status,
'plugin_output' : "{0}: zwave node is {1}".format(code, payload),
'service' : "{0}!zwave".format(host),
}
return json.dumps(icinga2_payload)
def icinga2_sensor_battery(data, srv):
batt_warn = 20
batt_crit = 10
battery = int(float(data['payload']))
status = 0
code = 'OK'
if battery <= batt_warn:
status = 1
code = 'WARNING'
if battery <= batt_crit:
status = 2
code = 'CRITICAL'
# /sensor/location/type/battery
parts = data['topic'].split('/')
location = parts[2]
type = parts[3]
host = "{0}-{1}".format(location, type)
icinga2_payload = {
'exit_status' : status,
'plugin_output' : "BATT {0}: {1}%".format(code, battery),
'service' : "{0}!battery".format(host),
'performance_data': [ "battery={0}%;{1};{2}".format(battery, batt_warn, batt_crit) ],
}
return json.dumps(icinga2_payload)
So once you establish the required payload for an icinga2 check it becomes pretty easy to add.
You then have to define the host/service/checkcommand in your icinga2 config and away you go. I won’t go into the icinga2 config as that is a whole new kettle of fish!
But the key bits from this are mqttwarn
. Using this tool it is very easy to take data from MQTT topics and transform it into something useful for another service. Without having to touch any openHAB config. I already had all my sensor data being published to MQTT topics in the hope I would one day be able to use it - and along came icinga2!
The real beauty of icinga2 is the ability to configure how and where you are notified. For example by default a service won’t send a notification until it has failed 5 checks (checks are typically executed every minute but this is of course configurable).
I have my system setup to publish alerts to Pushover (again via mqttwarn
) and also direct to a private Slack channel;

Here is a screenshot of my hallway pir sensor (a host) with 4 services being checked by icinga2;