Graph your Z-Wave mesh (Python, auto-update)

I’ll add a voice in favour of an implementation like this.

That should simple enough to implement. I can pretty easily adapt the code I had for subgraphs (which crashes the dot engine) and tweak the lines based on depth. Stay tuned. :slight_smile:

1 Like

[quote=“OmenWild, post:22, topic:40549”]
That should simple enough to implement. I can pretty easily adapt the code I had for subgraphs (which crashes the dot engine) and tweak the lines based on depth. [/quote]

Done and pushed. I’m thinking about creating a version that only shows a/the shortest path. That should reduce congestion and still give you an idea of what is connecting where.

My network looks like this:

1 Like

Two questions:

  1. What if there are multiple paths of the same length?
  2. What about an option to show them as grey lines instead, so that alternative routes are still shown?

Still sulks on my config though:

Traceback (most recent call last):
  File "./z-wave-graph.py.4", line 242, in <module>
    zwave = ZWave(config)
  File "./z-wave-graph.py.4", line 129, in __init__
    if 'base_url' in self.haconf['http']:
TypeError: argument of type 'NoneType' is not iterable

And a new one:

Traceback (most recent call last):
  File "./z-wave-graph.py.4", line 242, in <module>
    zwave = ZWave(config)
  File "./z-wave-graph.py.4", line 152, in __init__
    self._build_dot()
  File "./z-wave-graph.py.4", line 168, in _build_dot
    for node in self.nodes:
  File "./z-wave-graph.py.4", line 104, in __iter__
    self.create_ranks()
  File "./z-wave-graph.py.4", line 83, in create_ranks
    import networkx as nx
ModuleNotFoundError: No module named 'networkx'

I’m guessing you just added something else? Maybe networkx since if I run pip install networkx it no longer crashes out with that error, but I get a new one:

Traceback (most recent call last):
  File "./z-wave-graph.py.4", line 242, in <module>
    zwave = ZWave(config)
  File "./z-wave-graph.py.4", line 152, in __init__
    self._build_dot()
  File "./z-wave-graph.py.4", line 168, in _build_dot
    for node in self.nodes:
  File "./z-wave-graph.py.4", line 104, in __iter__
    self.create_ranks()
  File "./z-wave-graph.py.4", line 96, in create_ranks
    node.rank = len(nx.shortest_path(G, 1, key))
  File "/srv/homeassistant/homeassistant_venv_3.6/lib/python3.6/site-packages/networkx/algorithms/shortest_paths/generic.py", line 142, in shortest_path
    paths = nx.bidirectional_shortest_path(G, source, target)
  File "/srv/homeassistant/homeassistant_venv_3.6/lib/python3.6/site-packages/networkx/algorithms/shortest_paths/unweighted.py", line 226, in bidirectional_shortest_path
    results = _bidirectional_pred_succ(G, source, target)
  File "/srv/homeassistant/homeassistant_venv_3.6/lib/python3.6/site-packages/networkx/algorithms/shortest_paths/unweighted.py", line 294, in _bidirectional_pred_succ
    raise nx.NetworkXNoPath("No path between %s and %s." % (source, target))
networkx.exception.NetworkXNoPath: No path between 1 and 9.

I kinda expect that though, because neither remote has any neighbours (that’s normal for the Nodon remotes).

Makes sense to me and shouldn’t be too difficult.

Thanks for the continued testing. I think I have your first issue fixed and pushed. You were spot on for the second. I’ve added that module to the README. I put some code in place for the third, but can’t test until tonight when I can pair my minimote.

Nice layout. Helps make it understandable.

Even though I only have a few nodes, I thought this looks interesting enough for me to jump in.

I’ve got everything setup, including installing graphviz and network inside my venv, but am getting this error when I try to execute z-wave-graph.py manually (also from within my venv).

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/homeassistant/bin/z-wave-graph.py", line 243, in <module>
    zwave.render()
  File "/home/homeassistant/bin/z-wave-graph.py", line 211, in render
    self.dot.render(filename=self.filename, directory=self.directory)
  File "/srv/homeassistant/lib/python3.5/site-packages/graphviz/files.py", line 176, in render
    rendered = backend.render(self._engine, self._format, filepath)
  File "/srv/homeassistant/lib/python3.5/site-packages/graphviz/backend.py", line 127, in render
    raise ExecutableNotFound(args)
graphviz.backend.ExecutableNotFound: failed to execute ['dot', '-Tsvg', '-O', '/home/homeassistant/.homeassistant/www/z-wave-graph'], make sure the Graphviz executables are on your systems' PATH

I’ve set z-wave-graph.py to executable. And I noticed that I get a new file named ‘z-wave-graph’ inside the www directory whenever I run the script. Any ideas?

You also have to install the system packages that provide the binaries. The Python package just create the dot file and call the binaries to do the actual graphing. See GitHub - OmenWild/home-assistant-z-wave-graph: Graph your Z-Wave mesh automatically from within Home Assistant. .

I was able to get this working on hassio by doing some naughty/kludgey stuff. The naughty part is a shell script I created to install graphviz in the Home Assistant container every time Home Assistant starts. The only changes I did from your instructions are:

  1. Create /config/bin/install_graphviz.sh.
#! /bin/bash

apk add --no-cache graphviz graphviz-dev
pip3 install graphviz networkx
  1. Create /config/shell_command/install_graphviz.yaml.
install_graphviz: /config/bin/install_graphviz.sh
  1. Add an additional automation to execute shell_command.install_graphviz when Home Assistant starts.
automation:
- alias: Install graphviz on Home Assistant Startup
  id: Home_Assistant_Startup
  trigger:
    - platform: homeassistant
      event: start
  action:
    - service: shell_command.install_graphviz
  1. Modify /config/shell_command/z-wave-graph.yaml to point to the config location for hassio.
z_wave_graph: /config/bin/z-wave-graph.py -c /config/configuration.yaml
1 Like

The latest version on github gave me this:

Traceback (most recent call last):
  File "bin/z-wave-graph.py", line 11, in <module>
import networkx as nx
ImportError: No module named 'networkx'

I assume I need to pip install something, but heading for bed now.

Yup, you need the networkx module: pip3 install networkx from inside the venv (if you use one).

I’m working on updating the script to be a little more vocal about what to do.

Oh, you even updated README, I missed that. It’s working now again. I am still trying to go to bed though. It’s a challenge. :slight_smile:

1 Like

Bingo, that was it. I misread the Install section of the README as EITHER/OR. But I see it is really AND. I was able to run the script, but now getting a login error. Probably something to do with my url setup. I’ll take a look and see what I need to update.

Once you get into this stuff it’s hard to put it down. New version pushed that only graphs the shortest paths, so this is probably more like what Z-Wave is actually using when moving data around.

Based on where things are physically located, this graph of my 3 layer mesh makes a lot of sense to me. The interactions between layers 2 and 3 are are hard to track though. I’ll keep poking at it.

1 Like

Thanks for putting this together. Even though I only have a few nodes, it is very interesting, and I imagine will be vital when I expand my network. I was about to start tinkering with the graph from @magma1447 when I saw this pop up in the forums.

I finally got a chance to get back to this, and got it working. I use a NGINX reverse proxy setup, with only the api_password parameter set in my http config. At first, I was getting a failed login attempt notification in the frontend whenever I ran the script. After a few failed ideas, I finally got it working by adding the base_url parameter to my config, setting it to my internal IP address. Im not sure why this worked, as opposed to the default localhost value set in the script.

Ideally, I’d be able to use my external domain for the base_url instead of the internal IP. But when i tried that, I found that the script was still trying to connect on port 8123, and got a connection refused error. I also had to manually change use_ssl to True, since I don’t have a ssl_key parameter set in my config. But after changing to my internal IP, I reverted the script back to original.

Not sure if I think anything should be updated based on any of this, but figured I’d lay all that out here. I guess it would be nice to specify a port and use_ssl without a ssl_key. But that may make things too complicated for what its worth.

Maybe spoke too soon on having it working completely… I noticed that the automation is failing with an error on the shell command. Admittedly, this is the first time I’ve used a shell_command. But I was able to set up a test to create a temp file without any issue. Do I need to set this up any differently since I am using a venv?

Here is my shell_command config from configuration.yaml:

shell_command:
  z_wave_graph: ~/bin/z-wave-graph.py

Here is the error from the logs:

2018-01-25 21:50:00 ERROR (MainThread) [homeassistant.components.shell_command] Error running command: `~/bin/z-wave-graph.py`, return code: 1
NoneType: None

Am I missing something obvious?

Update coming for that. Those will be command line options.

Not to worry, that wasn’t just you having issues. On reviewing my logs I found out mine wasn’t working either. This should be fixed in the newest version. I had to switch to the hagraph method.

This is a fairly major update and gets me pretty close to what I wanted when I started. I switched from Graphviz to vis.js. I managed to get a layered graph that looks pretty good with my 3-layer network with 15 nodes. It’s still only graphing the shortest paths instead of all neighbors. I believe this view is more likely to match what the mesh may be doing.

As always, feedback welcome. If you scroll down the page with the graph you will see I left some of the vis.js debugging enabled so you can live-tweak the display. If you find a good set of values that works for large networks please send me the contents of the generate options area. I’ll need to make sure they stay compatible with smaller networks, but I may be able to auto-tune based on network size if I can get enough samples.

2 Likes

I keep finding you bugs :wink:

ssl.SSLError: [SSL: UNKNOWN_PROTOCOL] unknown protocol (_ssl.c:777)

I can work around that by setting --no-ssl, but while I get a JSON file, there’s no updated svg (and no errors). Do we need to install vis.js somehow?

(FYI, this is looking really nice!)

First of all thanks for the amazing work! This is a feature I always missed from Open Z-Wave Control Panel!

Here’s a screenshot of my interconnectivity, as you can see, it’s pretty bad, so I’m looking for suggestions, how to improve it. Most of my devices are 5-6 m apart but sometimes they do go through concrete slabs, and I have to admit my controller is right next to my Wi-Fi router, but even when I moved it a meter or so away, thinks didn’t change.

P.S. Since the last update none of my nodes are showing up (not in the JSON either). I presume this is because HASS doesn’t report the controller as having any neighbors.