Hi,
Don't know if someone did this before but I wanted to visualize my zigbee network map from within domoticz.
After some digging around I found :
https://community.openhab.org/t/zigbee2 ... p/57784/29
It looked realy nice, and i wanted to implement this in my domoticz environement.
So i wrote a little python script to make this possible.
Prerequisites:
Graphviz installed (sudo apt-get install graphviz)
Graphviz dev files installed (sudo apt-get install -y graphviz-dev)
Python module : Paho mqtt client (pip3 install paho-mqtt)
you need an web server to display the map.
I used the default from domoticz (/domoticz/www) because it is already available, but any other will do.
First place the following files into the web root folder :
https://github.com/ariutta/svg-pan-zoom ... oom.min.js
(you can download it with
Code: Select all
wget https://github.com/ariutta/svg-pan-zoom/blob/master/dist/svg-pan-zoom.min.js
and move it to the web root folder)
This is needed so the generated svg file can be zoomed in/out from the browser.
The create a html file in the web root folder (e.g. ZigBee.html) with the following content :
- Spoiler: show
Code: Select all
<html>
<head>
<script src="svg-pan-zoom.min.js"></script>
</head>
<body style="margin: 0; padding: 0">
<embed type="image/svg+xml" src="zigbee.svg" id="map" width="100%" height="100%"/>
<script language="JavaScript">
document.getElementById('map').addEventListener('load', function(){
// Will get called after embed element was loaded
svgPanZoom(document.getElementById('map'), {
controlIconsEnabled: true
});
})
var panZoomMap = svgPanZoom('#map');
</script>
</body>
</html>
Then create a python script with the following code :
- Spoiler: show
Code: Select all
#!/usr/bin/python3
import os
import sys
import paho.mqtt.client as mqtt
import fileinput
import shutil
# Prerequisites:
# Graphviz (sudo apt-get install graphviz)
# Graphviz dev files (sudo apt-get install -y graphviz-dev)
# Paho mqtt client (pip3 install paho-mqtt)
# Settings for MQTT server
mqttserver = "192.168.0.31"
mqttserver_port = 1883
# File references
dotfile = "/tmp/zigbee.dot"
svgfile = "/tmp/zigbee.svg"
target_svgfile = "/home/pi/domoticz/www/zigbee.svg"
def on_connect(client, userdata, flags, rc):
print("Connected With Result Code: {}".format(rc))
def on_disconnect(client, userdata, rc):
print("Client Got Disconnected")
def on_message(client, userdata, message):
print("Message Recieved: "+message.payload.decode())
if os.path.exists(dotfile):
os.remove(dotfile)
file_with_data = open(dotfile,"w+")
file_with_data.write(message.payload.decode())
file_with_data.close()
client.disconnect()
client = mqtt.Client()
client.on_connect = on_connect
client.on_disconnect = on_disconnect
client.on_message = on_message
client.connect(mqttserver,mqttserver_port,60)
client.subscribe("zigbee2mqtt/bridge/networkmap/graphviz")
client.publish("zigbee2mqtt/bridge/networkmap", "graphviz")
client.loop_forever() # Wait until data received, the on_message function wil handle the output and disconnect from MQTT broker
# Modify the dot file
# Firt lines a little thicker
with fileinput.FileInput(dotfile, inplace=True, backup='.bak') as file:
for line in file:
print(line.replace("penwidth=0.5", "penwidth=3.5"), end='')
#generate svg file from dot source
command = "/usr/bin/sfdp -Nfontname=Arial -Nfontsize=9 -Ncolor=#666666 -Nstyle=filled -Nfillcolor=#eeeeee -Efontname=Arial -Efontsize=8 -Efontcolor=#cc0000 -Ecolor=#cccccc -Tsvg -o" + svgfile + " " + dotfile
print(command)
os.system(command)
#copy the new svg file to the webroot folder
if os.path.exists(target_svgfile):
os.remove(target_svgfile)
shutil.copyfile(svgfile, target_svgfile)
Adjust the MQTT server settings !!!
Adjust if needed the File References settings.
Schedule the python script to run e.g. every day, (after running refresh your browser cache, as I noticed the page does not update automatically)
After running the script you can go to your domoticz url with the "ZigBee.html" in the address.
e.g. http://domoticz_server_ip:port_number/ZigBee.html
What it does :
The script connects to the mqtt server and issue's two commands
An subscribe to the "zigbee2mqtt/bridge/networkmap/graphviz" topic and a publish to the "zigbee2mqtt/bridge/networkmap", "graphviz"" topic
The "client.loop_forever() is needed to wait for the mqtt server to respond with a message, because the subscribe/publish command need a little while to complete. It is basically an command to the sniffer to poll it's network and report the connections back.
This should not be done very frequently because it could congest your ZigBee network for a little while (especially in large networks with a lot of polling requests to do)
When a message is received (the data for the dot file) it wil be send to the dotfile.
This is the structure needed for graphviz to create a SVG file.
The the svg file is created with the "sfdp" command and placed into the web root folder.
Any suggestions and/or improvements are welcome.
(The next step is to replace the blocks with nice graphic/images but first I have to read in to the graphviz dot language....)
Regards
Peer