Zigbee2MQTT network map

One feature I absolutely love in Zigbee2MQTT is the network map. You can request zigbee2mqtt to put out a Graphviz representation of how your ZigBee network is set up. That way you can easily tell which of your devices are connected / paired to which and how big your ZigBee network grew over time.

It also will help you understand that with each non-battery powered ZigBee device your network will be more stable and allow for even more endpoints. It’s important to know that there are 3 types of ZigBee devices:

  • Coordinators
  • Routers
  • End Devices

Routers are ZigBee devices that End Devices can be paired to and that will route communications to other ZigBee devices. In order to do this they will have to be always on and can’t be in Standby. Therefore battery-driven sensors can not be routers! All mains powered devices though should be routers (e.g. bulbs, power plugs etc). Coordinators are routers that have one additional feature: they span the network and define all the network parameters. There can only be ONE coordinator per ZigBee network. This will be your XBee, CC2531, Qivicon etc stick. Routers/coordinators can be paired with a given number of ZigBee devices (for the CC2531 there is a limit of roughly 20). End Devices are all sensors that are low-energy and battery-driven (e.g. door sensors, temperature sensors). They will go to standby/sleep every now and then and will only sporadically send data. This is normal in order to save energy.

If you understand this concept it is clear that a ZigBee network can grow much bigger than what your coordinator is limited to. Each router will up the number of possible devices.

But back to topic…

Prerequisites

You will need to render GraphViz data so install graphviz via:

sudo apt-get install graphviz

You will also need to check your permissions for the 2 files zigbee.dot and zigbee.svg in the html folder. Those files need to be writeable for user openhab.

Last thing you will need is the great JavaScript library svg-pan.zoom by aruitta. It will allow you to zoom and pan the generated network map. Download it here:

/etc/openhab2/html/zigbee.map

This is a mapping file and will allow the rule below to replace network addresses with names. You can do this in zigbee2mqtt but you would have to do it again if you re-paired devices. I like to have this mapping in a separate file. You can use an empty file if you don’t want to replace anything. Otherwise define it like this:

0x000b14eacc194ff0=Dimmer Living Room
0x000b32add31850f=Dimmer Kitchen

If you’re paranoid don’t put this file into the html folder as it will be exposed by the web server. If you chose to place it in another place you will have to customize the rules file below.

Items

String  zigbee_NetworkMap { mqtt="<[broker:zigbee/bridge/networkmap/graphviz:state:default" }
Group zigbee_NetworkMap_Webview "ZigBee Topologie"

Sitemap

This webview item will display the HTML file below.

Group item=zigbee_NetworkMap_Webview {
    Webview url="/static/zigbee.html" height=16 icon="network"
}

Rules

This is were the heavy lifting is done. There are 2 rules. One is periodically requesting zigbee2mqtt for the network map. I do this once at night. The second rule will fire when the network map in Graphviz format has been sent by zigbee2mqtt. It will then replace all network addresses with nice display names from zigbee.map and also render the data into a SVG file. There are a lot of layout options that I chose fit my style. Feel free to modify this through the sfdp parameters.

import java.io.FileWriter
import java.io.FileReader
import java.io.BufferedReader

// parameters
val String dotFile = "/etc/openhab2/html/zigbee.dot"
val String mapFile = "/etc/openhab2/html/zigbee.map"
val String svgFile = "/etc/openhab2/html/zigbee.svg"

rule "Request ZigBee Network Map in Graphviz format"
when
    Time cron "0 0 4 * * ?"
then
    // ask zigbee2mqtt to generate graphviz network map (in DOT format)
    publish("broker", "zigbee2mqtt/bridge/networkmap", "graphviz")
end


rule "Fetch ZigBee tree in Graphviz format"
when
    Item zigbee_NetworkMap changed
then
    // once zigbee2mqtt sent graphviz network map => store it and convert it to PNG/SVG
    if (zigbee_NetworkMap.state !== NULL && zigbee_NetworkMap.state != "") {
        var String dotString = zigbee_NetworkMap.state.toString

        // load mapping file and regex-replace network addresses with friendly names
        var FileReader fr = new FileReader(mapFile);
        var BufferedReader br = new BufferedReader(fr);
        var String line
        var String[] split
        var String regex
        var String replace
        while ((line = br.readLine()) !== null) {
        	split  = line.split("=")
        	if(split.length == 2) {
        		regex = "(label=.*)(" + split.get(0) + ")(.*)"
        		replace = "$1" + split.get(1) + "$3"
        		dotString = dotString.replaceFirst(regex, replace)
        	}
        }
        fr.close();

        // store result to DOT file
        var fw = new FileWriter(dotFile, false);
        fw.write(dotString);
        fw.flush();
        fw.close();

        // render PNG/SVG
        executeCommandLine("/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, 5000)
    }
end

Attention: Customize the 2 parameters for publish command in the 1st rule to reflect the name of your defined MQTT broker and the MQTT topic zigbee2mqtt uses.

Static HTML page (/etc/openhab2/html/zigbee.html)

This is a simple wrapper HTML file that embeds the rendered SVG file and also loads a JavaScript library to pan and zoom into the graph (it can be quite big!).

<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>
8 Likes

Hi Andreas,

I’m trying to follow your tutorial but I’m struggling with the zigbee.dot and zigbee.svg files. They are not there. How do I get them?
Thanks for your help

Hi Stefan,
Could be several things:

  • This tutorial is for the MQTT 1.x binding, not the current MQTT 2.4. For the newest MQTT binding the publishing will need to be done differently.
  • While we’re talking about the publish. The first rule is publishing a MQTT message to zigbee2mqtt through your MQTT broker. The default topic for that is zigbee2mqtt/bridge/networkmap. In my installation I changed that to zigbee/… It’s not very obvious in my tutorial and I will correct that to make it run for a default installation of zigbee2mqtt. Please check the publish command in your rule and customize the first and second parameter to fit your setup. My MQTT broker is called broker and the topic is zigbee rather than the default zigbee2mqtt.
  • If it’s not that… we will need to check your logs to find out if both rules run and if not where they crash.

Regards
Andreas

Wow - that was quick.
I use the MQTT 1.x binding so that shouldn’t be an issue and I successfully managed to create a networkmap via mqtt-spy. So mqtt is working fine and i know how to handle.
In your tutorial you write:
You will also need to check your permissions for the 2 files zigbee.dot and zigbee.svg in the html folder. Those files need to be writeable for user openhab .

This is where a fail, because the two files simply do not exist in my installation.
I run openhab2 on a raspi and use the latest stable release

Ah I see. You will have to create them yourself and make them writeable. Once they’re created the rules will be able to modify them. Do it like this:

touch /etc/openhab2/html/zigbee.dot
touch /etc/openhab2/html/zigbee.svg
chown openhab:openhab /etc/openhab2/html/zigbee.*
chmod 755 /etc/openhab2/html/zigbee.*

Still not working: the zigbee.svg has size 0
Might be because I have no clue how to install the svg-pan.zoom.js library.
Anyway the rule ```
“Fetch ZigBee tree in Graphviz format”

After several iterations of this loop

       while ((line = br.readLine()) !== null) {
        logInfo("Fetch ZigBee tree in Graphviz format", "--> 2")
            split  = line.split("=")
            logInfo("Fetch ZigBee tree in Graphviz format", "--> 2.1")
            regex = "(label=.*)(" + split.get(0) + ")(.*)"
            logInfo("Fetch ZigBee tree in Graphviz format", "--> 2.2")
            replace = "$1" + split.get(1) + "$3"
            logInfo("Fetch ZigBee tree in Graphviz format", "--> 2.3")
            dotString = dotString.replaceFirst(regex, replace)
            logInfo("Fetch ZigBee tree in Graphviz format", "--> 2.4")
        }
        fr.close();

it happen to throw an error before 2.3
2019-02-28 11:18:26.674 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule 'Fetch ZigBee tree in Graphviz format': 1

The svg-pan.zoom.js library has nothing to do with this. It is only used in the visualization later when you want to see the resulting svg file.

Could you show some of your openHAB log? I need to see the state of the zigbee_NetworkMap item. Also your item configuration for zigbee would help debug this.

Which items are you refereing to. All my zigbee sensors?

Here are log the logs:

2019-02-28 12:14:29.346 [vent.ItemStateChangedEvent] - zigbee_NetworkMap changed from digraph G {
node[shape=record];

“0x00124b0002c5a15a” [style=“bold”, label="{0x00124b0002c5a15a|Coordinator|No model information available|online}"];

“0x7cb03eaa0a01933d” [style=“rounded”, label="{0x7cb03eaa0a01933d|Router|OSRAM Smart+ plug (AB3257001NJ)|offline}"];

“0x7cb03eaa0a01933d” -> “0x00124b0002c5a15a” [style=“dashed”, label=“0”]

“0x7cb03eaa00b2164c” [style=“rounded”, label="{0x7cb03eaa00b2164c|Router|OSRAM Smart+ plug (AB3257001NJ)|online}"];

“0x7cb03eaa00b2164c” -> “0x00124b0002c5a15a” [label=“67”]

“0x00158d00025f1b28” [style=“rounded, dashed”, label="{0x00158d00025f1b28|EndDevice|Xiaomi Aqara door & window contact sensor (MCCGQ11LM)|online}"];

“0x00158d00025f1b28” -> “0x00124b0002c5a15a” [label=“84”]

“0x00158d000256cd7d” [style=“rounded, dashed”, label="{0x00158d000256cd7d|EndDevice|Xiaomi Aqara water leak sensor (SJCGQ11LM)|online}"];

“0x00158d000256cd7d” -> “0x00124b0002c5a15a” [label=“98”]

“0x00158d0002e2220f” [style=“rounded, dashed”, label="{0x00158d0002e2220f|EndDevice|Xiaomi MiJia temperature & humidity sensor (WSDCGQ01LM)|online}"];

“0x00158d0002e2220f” -> “0x00124b0002c5a15a” [label=“60”]

“0x00158d000232c468” [style=“rounded, dashed”, label="{0x00158d000232c468|EndDevice|Xiaomi Aqara door & window contact sensor (MCCGQ11LM)|online}"];

“0x00158d000232c0b8” [style=“rounded, dashed”, label="{0x00158d000232c0b8|EndDevice|Xiaomi Aqara door & window contact sensor (MCCGQ11LM)|online}"];

“0x00158d000232c0b8” -> “0x00124b0002c5a15a” [label=“33”]

“0x00158d0002ca2d83” [style=“rounded, dashed”, label="{0x00158d0002ca2d83|EndDevice|Xiaomi Aqara door & window contact sensor (MCCGQ11LM)|online}"];

“0x00158d0002ca2d83” -> “0x00124b0002c5a15a” [label=“33”]

“0x00158d000236fe3c” [style=“rounded, dashed”, label="{0x00158d000236fe3c|EndDevice|Xiaomi Aqara door & window contact sensor (MCCGQ11LM)|online}"];

“0x00158d000236fe3c” -> “0x00124b0002c5a15a” [label=“47”]

“0x00158d0002ca2d45” [style=“rounded, dashed”, label="{0x00158d0002ca2d45|EndDevice|Xiaomi Aqara door & window contact sensor (MCCGQ11LM)|online}"];

“0x00158d0002ca2d45” -> “0x00124b0002c5a15a” [label=“1”]

“0x7cb03eaa0a013b10” [style=“rounded”, label="{0x7cb03eaa0a013b10|Router|OSRAM Smart+ plug (AB3257001NJ)|online}"];

“0x7cb03eaa0a013b10” -> “0x00124b0002c5a15a” [label=“1”]

“0x00158d000249c8c7” [style=“rounded, dashed”, label="{0x00158d000249c8c7|EndDevice|Xiaomi MiJia Honeywell smoke detector (JTYJ-GD-01LM/BW)|online}"];

“0x00158d000249c8c7” -> “0x00124b0002c5a15a” [label=“39”]

“0x00158d00028786c7” [style=“rounded, dashed”, label="{0x00158d00028786c7|EndDevice|Xiaomi MiJia Honeywell smoke detector (JTYJ-GD-01LM/BW)|online}"];

} to digraph G {

node[shape=record];

“0x00124b0002c5a15a” [style=“bold”, label="{0x00124b0002c5a15a|Coordinator|No model information available|online}"];

“0x7cb03eaa0a01933d” [style=“rounded”, label="{0x7cb03eaa0a01933d|Router|OSRAM Smart+ plug (AB3257001NJ)|offline}"];

“0x7cb03eaa0a01933d” -> “0x00124b0002c5a15a” [style=“dashed”, label=“0”]

“0x7cb03eaa00b2164c” [style=“rounded”, label="{0x7cb03eaa00b2164c|Router|OSRAM Smart+ plug (AB3257001NJ)|online}"];

“0x7cb03eaa00b2164c” -> “0x00124b0002c5a15a” [label=“67”]

“0x00158d00025f1b28” [style=“rounded, dashed”, label="{0x00158d00025f1b28|EndDevice|Xiaomi Aqara door & window contact sensor (MCCGQ11LM)|online}"];

“0x00158d00025f1b28” -> “0x00124b0002c5a15a” [label=“85”]

“0x00158d000256cd7d” [style=“rounded, dashed”, label="{0x00158d000256cd7d|EndDevice|Xiaomi Aqara water leak sensor (SJCGQ11LM)|online}"];

“0x00158d000256cd7d” -> “0x00124b0002c5a15a” [label=“98”]

“0x00158d0002e2220f” [style=“rounded, dashed”, label="{0x00158d0002e2220f|EndDevice|Xiaomi MiJia temperature & humidity sensor (WSDCGQ01LM)|online}"];

“0x00158d0002e2220f” -> “0x00124b0002c5a15a” [label=“61”]

“0x00158d000232c468” [style=“rounded, dashed”, label="{0x00158d000232c468|EndDevice|Xiaomi Aqara door & window contact sensor (MCCGQ11LM)|online}"];

“0x00158d000232c0b8” [style=“rounded, dashed”, label="{0x00158d000232c0b8|EndDevice|Xiaomi Aqara door & window contact sensor (MCCGQ11LM)|online}"];

“0x00158d000232c0b8” -> “0x00124b0002c5a15a” [label=“30”]

“0x00158d0002ca2d83” [style=“rounded, dashed”, label="{0x00158d0002ca2d83|EndDevice|Xiaomi Aqara door & window contact sensor (MCCGQ11LM)|online}"];

“0x00158d0002ca2d83” -> “0x00124b0002c5a15a” [label=“33”]

“0x00158d000236fe3c” [style=“rounded, dashed”, label="{0x00158d000236fe3c|EndDevice|Xiaomi Aqara door & window contact sensor (MCCGQ11LM)|online}"];

“0x00158d000236fe3c” -> “0x00124b0002c5a15a” [label=“45”]

“0x00158d0002ca2d45” [style=“rounded, dashed”, label="{0x00158d0002ca2d45|EndDevice|Xiaomi Aqara door & window contact sensor (MCCGQ11LM)|online}"];

“0x00158d0002ca2d45” -> “0x00124b0002c5a15a” [label=“1”]

“0x7cb03eaa0a013b10” [style=“rounded”, label="{0x7cb03eaa0a013b10|Router|OSRAM Smart+ plug (AB3257001NJ)|online}"];

“0x7cb03eaa0a013b10” -> “0x00124b0002c5a15a” [label=“1”]

“0x00158d000249c8c7” [style=“rounded, dashed”, label="{0x00158d000249c8c7|EndDevice|Xiaomi MiJia Honeywell smoke detector (JTYJ-GD-01LM/BW)|online}"];

“0x00158d000249c8c7” -> “0x00124b0002c5a15a” [label=“39”]

“0x00158d00028786c7” [style=“rounded, dashed”, label="{0x00158d00028786c7|EndDevice|Xiaomi MiJia Honeywell smoke detector (JTYJ-GD-01LM/BW)|online}"];

}

==> /var/log/openhab2/openhab.log <==

2019-02-28 12:14:29.362 [INFO ] [Fetch ZigBee tree in Graphviz format] - --> Start

2019-02-28 12:14:29.416 [INFO ] [Fetch ZigBee tree in Graphviz format] - --> 1

2019-02-28 12:14:29.447 [INFO ] [Fetch ZigBee tree in Graphviz format] - --> 2

2019-02-28 12:14:29.462 [INFO ] [Fetch ZigBee tree in Graphviz format] - --> 2.1

2019-02-28 12:14:29.477 [INFO ] [Fetch ZigBee tree in Graphviz format] - --> 2.2

2019-02-28 12:14:29.496 [INFO ] [Fetch ZigBee tree in Graphviz format] - --> 2.3

2019-02-28 12:14:29.506 [INFO ] [Fetch ZigBee tree in Graphviz format] - --> 2.4

2019-02-28 12:14:29.515 [INFO ] [Fetch ZigBee tree in Graphviz format] - --> 2

2019-02-28 12:14:29.524 [INFO ] [Fetch ZigBee tree in Graphviz format] - --> 2.1

2019-02-28 12:14:29.535 [INFO ] [Fetch ZigBee tree in Graphviz format] - --> 2.2

2019-02-28 12:14:29.548 [INFO ] [Fetch ZigBee tree in Graphviz format] - --> 2.3

2019-02-28 12:14:29.559 [INFO ] [Fetch ZigBee tree in Graphviz format] - --> 2.4

2019-02-28 12:14:29.569 [INFO ] [Fetch ZigBee tree in Graphviz format] - --> 2

2019-02-28 12:14:29.577 [INFO ] [Fetch ZigBee tree in Graphviz format] - --> 2.1

2019-02-28 12:14:29.589 [INFO ] [Fetch ZigBee tree in Graphviz format] - --> 2.2

2019-02-28 12:14:29.605 [INFO ] [Fetch ZigBee tree in Graphviz format] - --> 2.3

2019-02-28 12:14:29.615 [INFO ] [Fetch ZigBee tree in Graphviz format] - --> 2.4

2019-02-28 12:14:29.622 [INFO ] [Fetch ZigBee tree in Graphviz format] - --> 2

2019-02-28 12:14:29.629 [INFO ] [Fetch ZigBee tree in Graphviz format] - --> 2.1

2019-02-28 12:14:29.639 [INFO ] [Fetch ZigBee tree in Graphviz format] - --> 2.2

2019-02-28 12:14:29.653 [INFO ] [Fetch ZigBee tree in Graphviz format] - --> 2.3

2019-02-28 12:14:29.662 [INFO ] [Fetch ZigBee tree in Graphviz format] - --> 2.4

2019-02-28 12:14:29.670 [INFO ] [Fetch ZigBee tree in Graphviz format] - --> 2

2019-02-28 12:14:29.676 [INFO ] [Fetch ZigBee tree in Graphviz format] - --> 2.1

2019-02-28 12:14:29.687 [INFO ] [Fetch ZigBee tree in Graphviz format] - --> 2.2

2019-02-28 12:14:29.697 [INFO ] [Fetch ZigBee tree in Graphviz format] - --> 2.3

2019-02-28 12:14:29.707 [INFO ] [Fetch ZigBee tree in Graphviz format] - --> 2.4

2019-02-28 12:14:29.715 [INFO ] [Fetch ZigBee tree in Graphviz format] - --> 2

2019-02-28 12:14:29.722 [INFO ] [Fetch ZigBee tree in Graphviz format] - --> 2.1

2019-02-28 12:14:29.731 [INFO ] [Fetch ZigBee tree in Graphviz format] - --> 2.2

2019-02-28 12:14:29.741 [INFO ] [Fetch ZigBee tree in Graphviz format] - --> 2.3

2019-02-28 12:14:29.749 [INFO ] [Fetch ZigBee tree in Graphviz format] - --> 2.4

2019-02-28 12:14:29.757 [INFO ] [Fetch ZigBee tree in Graphviz format] - --> 2

2019-02-28 12:14:29.764 [INFO ] [Fetch ZigBee tree in Graphviz format] - --> 2.1

2019-02-28 12:14:29.774 [INFO ] [Fetch ZigBee tree in Graphviz format] - --> 2.2

2019-02-28 12:14:29.785 [INFO ] [Fetch ZigBee tree in Graphviz format] - --> 2.3

2019-02-28 12:14:29.793 [INFO ] [Fetch ZigBee tree in Graphviz format] - --> 2.4

2019-02-28 12:14:29.800 [INFO ] [Fetch ZigBee tree in Graphviz format] - --> 2

2019-02-28 12:14:29.807 [INFO ] [Fetch ZigBee tree in Graphviz format] - --> 2.1

2019-02-28 12:14:29.815 [INFO ] [Fetch ZigBee tree in Graphviz format] - --> 2.2

2019-02-28 12:14:29.828 [INFO ] [Fetch ZigBee tree in Graphviz format] - --> 2.3

2019-02-28 12:14:29.835 [INFO ] [Fetch ZigBee tree in Graphviz format] - --> 2.4

2019-02-28 12:14:29.843 [INFO ] [Fetch ZigBee tree in Graphviz format] - --> 2

2019-02-28 12:14:29.848 [INFO ] [Fetch ZigBee tree in Graphviz format] - --> 2.1

2019-02-28 12:14:29.858 [INFO ] [Fetch ZigBee tree in Graphviz format] - --> 2.2

2019-02-28 12:14:29.866 [INFO ] [Fetch ZigBee tree in Graphviz format] - --> 2.3

2019-02-28 12:14:29.877 [INFO ] [Fetch ZigBee tree in Graphviz format] - --> 2.4

2019-02-28 12:14:29.886 [INFO ] [Fetch ZigBee tree in Graphviz format] - --> 2

2019-02-28 12:14:29.892 [INFO ] [Fetch ZigBee tree in Graphviz format] - --> 2.1

2019-02-28 12:14:29.900 [INFO ] [Fetch ZigBee tree in Graphviz format] - --> 2.2

2019-02-28 12:14:29.908 [INFO ] [Fetch ZigBee tree in Graphviz format] - --> 2.3

2019-02-28 12:14:29.915 [INFO ] [Fetch ZigBee tree in Graphviz format] - --> 2.4

2019-02-28 12:14:29.922 [INFO ] [Fetch ZigBee tree in Graphviz format] - --> 2

2019-02-28 12:14:29.928 [INFO ] [Fetch ZigBee tree in Graphviz format] - --> 2.1

2019-02-28 12:14:29.938 [INFO ] [Fetch ZigBee tree in Graphviz format] - --> 2.2

2019-02-28 12:14:29.946 [INFO ] [Fetch ZigBee tree in Graphviz format] - --> 2.3

2019-02-28 12:14:29.953 [INFO ] [Fetch ZigBee tree in Graphviz format] - --> 2.4

2019-02-28 12:14:29.960 [INFO ] [Fetch ZigBee tree in Graphviz format] - --> 2

2019-02-28 12:14:29.965 [INFO ] [Fetch ZigBee tree in Graphviz format] - --> 2.1

2019-02-28 12:14:29.974 [INFO ] [Fetch ZigBee tree in Graphviz format] - --> 2.2

2019-02-28 12:14:29.983 [INFO ] [Fetch ZigBee tree in Graphviz format] - --> 2.3

2019-02-28 12:14:29.991 [INFO ] [Fetch ZigBee tree in Graphviz format] - --> 2.4

2019-02-28 12:14:29.998 [INFO ] [Fetch ZigBee tree in Graphviz format] - --> 2

2019-02-28 12:14:30.005 [INFO ] [Fetch ZigBee tree in Graphviz format] - --> 2.1

2019-02-28 12:14:30.014 [INFO ] [Fetch ZigBee tree in Graphviz format] - --> 2.2

2019-02-28 12:14:30.021 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule ‘Fetch ZigBee tree in Graphviz format’: 1

Okay, do you have any empty line in your zigbee.map file? Or any line that is not in the following format?

0x000b14eacc194ff0=somename

My rule is very strict and will crash when the zigbee.map file does not perfectly comply. Here’s an update to the while loop that will ignore lines that don’t match the necessary format.

while ((line = br.readLine()) !== null) {
split  = line.split("=")
if(split.length == 2) {
	regex = "(label=.*)(" + split.get(0) + ")(.*)"
	replace = "$1" + split.get(1) + "$3"
	dotString = dotString.replaceFirst(regex, replace)
}
}
1 Like

that did it - i had empty lines at the end
Thank you very much for your help!

1 Like

Great, I updated the initial post with the new loop code.

hi, great stuff. unfortunately I need some help as well. The svg is generated and displayed, but it seems the svg-pan-zoom library isn’t loaded correctly. my current setup looks like this:

/etc/openhab2/html

[13:49:26] openhab@smarthome:/etc/openhab2/html$ ll
total 44K
drwxrwxr-x+  3 openhab pi      4.0K Mar 14 13:49 ./
drwxrwxr-x+ 13 openhab pi      4.0K Feb 25 12:22 ../
-rw-rw-r--   1 openhab pi       451 Dec 18  2017 index.html
-rw-rw-r--   1 openhab pi       282 Dec 18  2017 readme.txt
drwxrwxr-x   3 openhab openhab 4.0K Mar 14 13:42 svg-pan-zoom/
-rw-rw-r--   1 openhab openhab 1.6K Mar 14 13:38 zigbee.dot
-rw-rw-r--   1 openhab openhab  625 Mar 14 13:43 zigbee.html
-rw-rw-r--   1 openhab openhab  13K Mar 14 13:38 zigbee.svg

/etc/openhab2/html/svg-pan-zoom

[13:49:27] openhab@smarthome:/etc/openhab2/html$ cd svg-pan-zoom/
[13:50:05] openhab@smarthome:/etc/openhab2/html/svg-pan-zoom$ ll
total 88K
drwxrwxr-x  3 openhab openhab 4.0K Mar 14 13:42 ./
drwxrwxr-x+ 3 openhab pi      4.0K Mar 14 13:49 ../
-rw-rw-r--  1 openhab openhab   77 Mar 14 13:42 browserify.js
-rw-rw-r--  1 openhab openhab 8.8K Mar 14 13:42 control-icons.js
drwxrwxr-x  2 openhab openhab 4.0K Mar 14 13:42 media/
-rw-rw-r--  1 openhab openhab 8.5K Mar 14 13:42 shadow-viewport.js
-rw-rw-r--  1 openhab openhab  504 Mar 14 13:42 stand-alone.js
-rw-rw-r--  1 openhab openhab  24K Mar 14 13:42 svg-pan-zoom.js
-rw-rw-r--  1 openhab openhab 7.1K Mar 14 13:42 svg-utilities.js
-rw-rw-r--  1 openhab openhab 3.9K Mar 14 13:42 uniwheel.js
-rw-rw-r--  1 openhab openhab 7.8K Mar 14 13:42 utilities.js

/etc/openhab2/html/zigbee.html

<html>
        <head>
                    <script src="svg-pan-zoom/svg-pan-zoom.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>

Result:

Hi Stefan,
looks to me as if the SVG itself has not been rendered well. The nodes should NOT overlap. The svg-pan-zoom library is merely for zooming and panning. I myself switched from using the sfdp tool for rendering and now use circo which gives me better looking results. This should come with the graphviz installation.

Could you try changing your rule to use the following executeCommandline?

executeCommandLine("/usr/bin/circo -Nfontname=Arial -Nfontsize=9 -Ncolor=#666666 -Nstyle=filled -Nfillcolor=#eeeeee -Efontname=Arial -Efontsize=8 -Efontcolor=#cc0000 -Ecolor=#cccccc -Tsvg -o" + svgFile + " " + dotFile, 6000)

Another thing regarding the svg-pan-zoom library: you put it in a subfolder. You merely need to put the svg-pan-zoom.js file in the html folder. You don’t need the other files. Not sure if that fixes your problem but it surely makes it less error prone with regards to relative paths.

Thanks for all your help. It still doesn’t work, but I was able to troubleshoot further.

  1. no change after switching from sfdp to circo
  2. the svg is rendered correctly. See output from nginx webserver below
  3. I’m not using the mapping file, but this shouldn’t be an issue, right?
  4. On the top left in the basic UI view, I see a “broken” icon. What’s this? (see screenshot)

nginx view:

basic ui view (see top left broken icon)

You see the broken icon because you did not define an icon for your webview. In your sitemap use something like

Webview url="/static/zigbee.html" height=16 icon="network"

instead of

Webview url="/static/zigbee.html" height=16

Concerning your zooming problem I could just guess. I could imagine this would be a rights issue. Try

chown -R openhab:openhab /etc/openhab2/html/svg-pan-zoom

I’m not sure if there is something cached by openHAB. So if reloading the browser doesn’t do the trick, it will maybe needed to restart openHAB. But this is just a guess. Other idea is that your problem is browser related. I’m using chrome and it works fine. Which browser are you using? Maybe try out an other one.

thanks, I’ll check this. Got a bit further. Using chrome browser developer tools I noticed the following error:

Uncaught ReferenceError: require is not defined at svg-pan-zoom.js:1

It points to svg-pan-zoom.js right here:

var Wheel = require(’./uniwheel’)

Do I need some require.js file?

Ah, I see. You copied from src/ folder. Copy the .js-files from dist/ folder and retry.

1 Like

Halleluja :wink: Thanks a lot

@AndreasBrett I highly recommend adding this piece of information to your tutorial :wink:

done

1 Like