Instructions how-to use Zabbix as your Controller with MQTT, part 2 (Auto-Discovery of Sensors)
-
Part 2. First have a look at part 1.
Here's an additional script created in Python to implement Auto-Discovery and automatic creation of sensors and nodes in Zabbix. It's using the Zabbix-API to check and create hostgroup, hosts and items automatically, if they're new and presented to the Controller (after power-on of the node sensors). The script runs on my RPI, where my Mosquitto and Zabbix is installed too.
Script description.
The script connects to the mosquitto broker and listens to the MQTT traffic from the MySensors network.- First it checks if the Zabbix-hostgroup exists, named "MySensors". If not it's created automatically.
- When a new sensor-node is presented via MQTT a Zabbix-host is created automatically, added to the hostgroup, and the host is named with the Topics prefix + Node-ID.
- When a new Child sensor is presented a Zabbix-Item is created, added to the host, and given the name of the Presentation Topic. The key of the Zabbix-Item is set to the value of Child-Id. The Item-name can later be modified to anything of your preference.
Run the script in the background together with the script described in part 1. The first script passes the data to Zabbix. And this script handles the automatic creation of the sensors.
Script:
import paho.mqtt.client as mqtt import time from pyzabbix import ZabbixMetric, ZabbixSender from zabbix.api import ZabbixAPI # Create ZabbixAPI class instance zapi = ZabbixAPI(url='http://localhost/zabbix/', user='Admin', password='zabbix') # Moquitto Topic Prefix topic_sub = "domoticz/in/MyMQTT/" # Name of Zabbix hostgroup hostGroup = 'MySensors' # Create hostgroup, if missing result = zapi.do_request('hostgroup.get', {'filter': {'name': [hostGroup]}}) if [name['name'] for name in result['result']] == []: zapi.hostgroup.create(name=hostGroup) result = zapi.do_request('hostgroup.get', {'filter': {'name': [hostGroup]}}) print(time.strftime("%c")+" Hostgroup created: "+hostGroup+" : "+str(result)) # log hostgroup creation # Get hostgroup-id groupId = [name['groupid'] for name in result['result']] # Mosquitto: the callback for when the client receives a CONNACK response from the server. def on_connect(client, userdata, flags, rc): print("Connected with result code "+str(rc)) # Mosquitto: subscribing in on_connect() means that if we lose the connection and # reconnect then subscriptions will be renewed. client.subscribe(topic_sub+"+/+/+/+/+") # Mosquitto: the callback for when a PUBLISH message is received from the server. def on_message(client, userdata, msg): msg.topic = msg.topic.replace("/", ".") myNode = msg.topic[:msg.topic.find(".", len(topic_sub)+1)] myItem = msg.topic[len(myNode)+1:] mySplit = myItem.split('.') # Check if host (node) exist, or create new host. # 255 = child, 0 = presentation, 17 = S_ARDUINO_NODE if myItem == '255.0.0.17': result = zapi.do_request('host.get', {'filter':{'host':[myNode]}}) if [host['host'] for host in result['result']] == []: # new node sensor, create host result = zapi.do_request('host.create', {'host': myNode, 'interfaces': [{'type': 1, 'main': 1, 'useip': 1, 'ip': '127.0.0 .1', 'dns': '', 'port': '10050'}], 'groups': [{'groupid': groupId[0]}]}) print(time.strftime("%c")+" Host created: "+myNode+" : "+str(result)) # log host creation # create item I_BATTERY_LEVEL result = zapi.do_request('host.get', {'filter':{'host':[myNode]}}) hostId = [item['hostid'] for item in result['result']] result = zapi.do_request('item.create', {'hostid': hostId[0], 'value_type': '0','type': '2', 'name': 'I_BATTERY_LEVEL', ' key_': '255.3.0.0'}) print(time.strftime("%c")+" Item created: I_BATTERY_LEVEL : "+str(result)) # log item creation if mySplit[1] == '0': # command = presentation if mySplit[0] != '255': # child = 255, don't create item result = zapi.do_request('item.get', {'host': myNode, 'filter': {'key_':[mySplit[0]]}}) if [host['key_'] for host in result['result']] == []: # new child, create item result = zapi.do_request('host.get', {'filter':{'host':[myNode]}}) hostId = [item['hostid'] for item in result['result']] result = zapi.do_request('item.create', {'hostid': hostId[0], 'value_type': '0','type': '2', 'name': myItem, 'key_': mySplit[0]}) print(time.strftime("%c")+" Item created: "+myItem+" : "+str(result)) # log item creation # Mosquitto: client start-up. client = mqtt.Client() client.on_connect = on_connect client.on_message = on_message client.connect("localhost", 1883, 60) # Mosquitto: blocking call that processes network traffic, dispatches callbacks and # handles reconnecting. client.loop_forever()
Run the script e.g. in the background as a daemon and printouts sent to a log file "zabbix_cnfg.log
python -u mqtt_zabbix_api.py > zabbix_cnfg.log 2>&1 &
I'm quite new with Python scripting, so it's possible the code isn't that elegant. But it works fine for me. :simple_smile:
And it's fun!