So, I've got a Zwave stick, and a raspberry pi, and I'd like to have OZWCP running on it to help with troubleshooting, etc.
But last time I tried, it was showing the zwave stick as being the Primary controller, and I couldn't figure out if Hubitat agreed or disagreed. Is anyone doing something like this reliably long term?
Really trying to just figure out slow repeaters, possibly bad repeaters, or just holes in the mesh.
I've been using that combo for slightly more than a year but NOT 24x7
I plug in the stick and start OZWCP on a rPi as needed. Pretty rarely these days... my migration days are over, I hope... unless I just have to have another HE to keep up with the Jones and Whites.
Because I have two Hubitat Hubs I have two ZWave networks. I 'clone' one onto the Aeon ZStick and then do a backup to disk. Then I reset the Aeon ZStick and 'clone' the other hub... ending with a backup to disk.
Yes, OZWCP GUI does show the stick as Primary, yet the logs clearly say it's not.
I have a script that I modified when I was using HomeAssistant to quantify the OZW_Log and the zwcfg xml file. The script shows neighbors and hops. I hadn't used this in a while but I ran it against the files I collected with OZWCP today and it generates the list.
<?php
if($argc !== 3) {
die("Usage: {$argv[0]} OZW.log zwcfg.xml \n");
}
$ozwLog = $argv[1];
$zwcfg = $argv[2];
#$imageFilename= $argv[3];
$controllerId = 1;
$nodes = array();
echo "Reading XML\n";
if(FALSE) { // For debug when not having the xml file, should normally be FALSE
$fixed = array(1,2,3,4,5,6,9,10,13,15,17,18,19,20,21);
foreach($fixed as $n) {
$nodes[$n]['name'] = $n;
}
} else {
$xml = file_get_contents($zwcfg);
$xml = new SimpleXMLElement($xml);
foreach($xml->Node as $v) {
$id = (int) $v['id'];
$name = $v['name'];
$name = reset($name); // No clue why I get an array back
if(empty($name)) {
$name = "{$v->Manufacturer['name']} {$v->Manufacturer->Product['name']}";
}
echo "{$id} => {$name}\n";
$nodes[$id]['name'] = $name;
}
}
/*
2017-10-14 12:02:31.336 Info, Node001, Neighbors of this node are:
2017-10-14 12:02:31.336 Info, Node001, Node 2
2017-10-14 12:02:31.336 Info, Node001, Node 3
*/
echo "Reading OZW log\n";
$buf = file_get_contents($ozwLog);
$buf = explode(PHP_EOL, $buf);
foreach($buf as $line) {
if(preg_match('/.*Info, Node([0-9]{3}), +Neighbors of this node are:$/', $line, $matches) === 1) {
$node = (int) $matches[1];
echo $line . PHP_EOL;
if(!isset($nodes[$node])) {
die("Node {$node} not found in xml\n");
}
$nodes[$node]['neighbors'] = array();
}
else if(preg_match('/.*Info, Node([0-9]{3}), +Node ([0-9]+)$/', $line, $matches) === 1) {
$node = (int) $matches[1];
$neighbor = (int) $matches[2];
echo $line . PHP_EOL;
if(!isset($nodes[$node])) {
die("Node {$node} not initialized\n");
}
if(!isset($nodes[$node]['neighbors'])) {
echo "WARNING: {$node} -> {$neighbor} listed before a list header, ignoring\n";
continue;
}
if(!in_array($neighbor, $nodes[$node]['neighbors'])) {
$nodes[$node]['neighbors'][] = $neighbor;
}
}
}
echo "Calculating hops\n";
$nodes[$controllerId]['hops'] = 0; // The controller obviously has 0 hops
// Z-wave supports max 4 hops
for($maxHops = 1 ; $maxHops <= 4 ; $maxHops++) {
foreach($nodes as $id => $n) {
if(isset($n['hops'])) {
continue;
}
if(!isset($n['neighbors'])) { // Should not happen, this is a workaround
echo " WARNING: Node {$id} has no neighbors\n";
$nodes[$id]['hops'] = 5;
continue;
}
$hops = FALSE;
foreach($n['neighbors'] as $neighbor) {
if(!isset($nodes[$neighbor]['hops'])) {
continue;
}
if($hops === FALSE || $nodes[$neighbor]['hops']+1 < $hops) {
$hops = $nodes[$neighbor]['hops']+1;
}
}
if($hops !== FALSE && $hops <= $maxHops) {
$nodes[$id]['hops'] = $hops;
echo " $id has {$hops} hops to the controller\n";
}
}
}
// Set hops to FALSE for nodes without neighbors
foreach($nodes as $id => $n) {
if(isset($nodes[$id]['hops']) && $nodes[$id]['hops'] !== 5) {
continue;
}
$nodes[$id]['hops'] = FALSE;
}
$inputArr = array_merge(array($id, $name, $hops));
$fp = fopen("zwave.txt", "a+");
fputcsv($fp, $inputArr);
fclose($fp);