Merge PR #878: More fixes in the Zigbee Topology map

This commit is contained in:
jenkins 2022-09-10 10:52:15 +02:00
commit 62b26b37d2
2 changed files with 139 additions and 117 deletions

View File

@ -104,7 +104,7 @@ SettingsPageBase {
} }
SettingsPageSectionHeader { SettingsPageSectionHeader {
text: qsTr("Network") text: qsTr("Network state")
} }
ColumnLayout { ColumnLayout {
@ -112,136 +112,156 @@ SettingsPageBase {
Layout.leftMargin: Style.margins Layout.leftMargin: Style.margins
Layout.rightMargin: Style.margins Layout.rightMargin: Style.margins
RowLayout { GridLayout {
Layout.fillWidth: true Layout.fillWidth: true
columns: 2
rowSpacing: Style.margins
columnSpacing: Style.margins
Label { RowLayout {
Layout.fillWidth: true Layout.preferredWidth: (parent.width - parent.columnSpacing) / 2
text: qsTr("Network state:") Led {
} Layout.preferredHeight: Style.iconSize
Layout.preferredWidth: Style.iconSize
Label { state: {
text: { switch (network.networkState) {
switch (network.networkState) { case ZigbeeNetwork.ZigbeeNetworkStateOnline:
case ZigbeeNetwork.ZigbeeNetworkStateOnline: return "on"
return qsTr("Online") case ZigbeeNetwork.ZigbeeNetworkStateOffline:
case ZigbeeNetwork.ZigbeeNetworkStateOffline: return "off"
return qsTr("Offline") case ZigbeeNetwork.ZigbeeNetworkStateStarting:
case ZigbeeNetwork.ZigbeeNetworkStateStarting: return "orange"
return qsTr("Starting") case ZigbeeNetwork.ZigbeeNetworkStateUpdating:
case ZigbeeNetwork.ZigbeeNetworkStateUpdating: return "orange"
return qsTr("Updating") case ZigbeeNetwork.ZigbeeNetworkStateError:
case ZigbeeNetwork.ZigbeeNetworkStateError: return "red"
return qsTr("Error") }
} }
} }
}
Led { Label {
Layout.preferredHeight: Style.iconSize Layout.fillWidth: true
Layout.preferredWidth: Style.iconSize text: {
state: { switch (network.networkState) {
switch (network.networkState) { case ZigbeeNetwork.ZigbeeNetworkStateOnline:
case ZigbeeNetwork.ZigbeeNetworkStateOnline: return qsTr("Online")
return "on" case ZigbeeNetwork.ZigbeeNetworkStateOffline:
case ZigbeeNetwork.ZigbeeNetworkStateOffline: return qsTr("Offline")
return "off" case ZigbeeNetwork.ZigbeeNetworkStateStarting:
case ZigbeeNetwork.ZigbeeNetworkStateStarting: return qsTr("Starting")
return "orange" case ZigbeeNetwork.ZigbeeNetworkStateUpdating:
case ZigbeeNetwork.ZigbeeNetworkStateUpdating: return qsTr("Updating")
return "orange" case ZigbeeNetwork.ZigbeeNetworkStateError:
case ZigbeeNetwork.ZigbeeNetworkStateError: return qsTr("Error")
return "red" }
} }
} }
} }
}
RowLayout { RowLayout {
Layout.fillWidth: true Layout.preferredWidth: (parent.width - parent.columnSpacing) / 2
Label { Canvas {
id: canvas
Layout.preferredHeight: Style.iconSize
Layout.preferredWidth: Style.iconSize
rotation: -90
visible: network.permitJoiningEnabled
property real progress: network.permitJoiningRemaining / network.permitJoiningDuration
onProgressChanged: {
canvas.requestPaint()
}
onPaint: {
var ctx = canvas.getContext("2d");
ctx.save();
ctx.reset();
var data = [1 - progress, progress];
var myTotal = 0;
for(var e = 0; e < data.length; e++) {
myTotal += data[e];
}
ctx.fillStyle = Style.foregroundColor
ctx.strokeStyle = Style.foregroundColor
ctx.lineWidth = 1;
ctx.beginPath();
ctx.moveTo(canvas.width/2,canvas.height/2);
ctx.arc(canvas.width/2,canvas.height/2,canvas.height/2,0,(Math.PI*2*((1-progress)/myTotal)),false);
ctx.lineTo(canvas.width/2,canvas.height/2);
ctx.fill();
ctx.closePath();
ctx.beginPath();
ctx.arc(canvas.width/2,canvas.height/2,canvas.height/2 - 1,0,Math.PI*2,false);
ctx.closePath();
ctx.stroke();
ctx.restore();
}
}
ColorIcon {
Layout.preferredHeight: Style.iconSize
Layout.preferredWidth: Style.iconSize
name: network.permitJoiningEnabled ? "/ui/images/lock-open.svg" : "/ui/images/lock-closed.svg"
visible: !network.permitJoiningEnabled
}
Label {
Layout.fillWidth: true
text: network.permitJoiningEnabled ? qsTr("Open for %0 s").arg(network.permitJoiningRemaining) : qsTr("Closed")
}
}
Button {
Layout.fillWidth: true Layout.fillWidth: true
text: qsTr("Channel") Layout.columnSpan: 2
} text: qsTr("Open for new devices")
enabled: network.networkState === ZigbeeNetwork.ZigbeeNetworkStateOnline
Label {
text: network.channel
}
}
RowLayout {
Layout.fillWidth: true
Label {
Layout.fillWidth: true
text: qsTr("Permit new devices:")
}
Label {
text: network.permitJoiningEnabled ? qsTr("Open for %0 s").arg(network.permitJoiningRemaining) : qsTr("Closed")
}
ColorIcon {
Layout.preferredHeight: Style.iconSize
Layout.preferredWidth: Style.iconSize
name: network.permitJoiningEnabled ? "/ui/images/lock-open.svg" : "/ui/images/lock-closed.svg"
visible: !network.permitJoiningEnabled visible: !network.permitJoiningEnabled
onClicked: zigbeeManager.setPermitJoin(network.networkUuid)
} }
Canvas { Button {
id: canvas Layout.fillWidth: true
Layout.preferredHeight: Style.iconSize text: qsTr("Extend")
Layout.preferredWidth: Style.iconSize enabled: network.networkState === ZigbeeNetwork.ZigbeeNetworkStateOnline
rotation: -90
visible: network.permitJoiningEnabled visible: network.permitJoiningEnabled
onClicked: zigbeeManager.setPermitJoin(network.networkUuid, 254)
}
property real progress: network.permitJoiningRemaining / network.permitJoiningDuration
onProgressChanged: {
canvas.requestPaint()
}
onPaint: { Button {
var ctx = canvas.getContext("2d"); Layout.fillWidth: true
ctx.save(); enabled: network.networkState == ZigbeeNetwork.ZigbeeNetworkStateOnline
ctx.reset(); visible: network.permitJoiningEnabled
var data = [1 - progress, progress]; text: qsTr("Close")
var myTotal = 0; onClicked: {
zigbeeManager.setPermitJoin(network.networkUuid, 0)
for(var e = 0; e < data.length; e++) {
myTotal += data[e];
}
ctx.fillStyle = Style.accentColor
ctx.strokeStyle = Style.accentColor
ctx.lineWidth = 1;
ctx.beginPath();
ctx.moveTo(canvas.width/2,canvas.height/2);
ctx.arc(canvas.width/2,canvas.height/2,canvas.height/2,0,(Math.PI*2*((1-progress)/myTotal)),false);
ctx.lineTo(canvas.width/2,canvas.height/2);
ctx.fill();
ctx.closePath();
ctx.beginPath();
ctx.arc(canvas.width/2,canvas.height/2,canvas.height/2 - 1,0,Math.PI*2,false);
ctx.closePath();
ctx.stroke();
ctx.restore();
} }
} }
} }
Button {
Layout.fillWidth: true
text: network.permitJoiningEnabled ? qsTr("Extend open duration") : qsTr("Open for new devices")
enabled: network.networkState === ZigbeeNetwork.ZigbeeNetworkStateOnline
onClicked: zigbeeManager.setPermitJoin(network.networkUuid)
}
} }
SettingsPageSectionHeader { SettingsPageSectionHeader {
text: qsTr("Connected devices") text: offlineNodes.count == 0
? qsTr("%n device(s)", "", Math.max(0, root.network.nodes.count - 1)) // -1 for coordinator node
: qsTr("%n device(s) (%1 disconnected)", "", Math.max(root.network.nodes.count - 1)).arg(offlineNodes.count)
ZigbeeNodesProxy {
id: offlineNodes
zigbeeNodes: root.network.nodes
showCoordinator: false
showOnline: false
}
} }
Label { Label {

View File

@ -278,21 +278,21 @@ Page {
paintEdges(ctx, d.nodeItems[i], true) paintEdges(ctx, d.nodeItems[i], true)
} }
if (d.selectedNodeItem) { if (d.selectedNodeItem) {
paintRoute(ctx, d.selectedNodeItem) paintRoutes(ctx, d.selectedNodeItem)
} }
for (var i = 0; i < d.nodeItems.length; i++) { for (var i = 0; i < d.nodeItems.length; i++) {
paintNode(ctx, d.nodeItems[i]) paintNode(ctx, d.nodeItems[i])
} }
} }
function paintRoute(ctx, nodeItem) { function paintRoutes(ctx, nodeItem) {
var node = nodeItem.node var node = nodeItem.node
var nextHop = -1 var nextHop = -1
if (node.type === ZigbeeNode.ZigbeeNodeTypeRouter) { if (node.type === ZigbeeNode.ZigbeeNodeTypeRouter) {
for (var i = 0; i < node.routes.length; i++) { for (var i = 0; i < node.routes.length; i++) {
if (node.routes[i].destinationAddress === 0) { if (node.routes[i].destinationAddress === 0) {
nextHop = node.routes[i].nextHopAddress nextHop = node.routes[i].nextHopAddress
break; paintRoute(ctx, nodeItem, nextHop);
} }
} }
} else if (node.type === ZigbeeNode.ZigbeeNodeTypeEndDevice) { } else if (node.type === ZigbeeNode.ZigbeeNodeTypeEndDevice) {
@ -300,19 +300,21 @@ Page {
for (var j = 0; j < network.nodes.get(i).neighbors.length; j++) { for (var j = 0; j < network.nodes.get(i).neighbors.length; j++) {
if (network.nodes.get(i).neighbors[j].networkAddress === node.networkAddress) { if (network.nodes.get(i).neighbors[j].networkAddress === node.networkAddress) {
nextHop = network.nodes.get(i).networkAddress nextHop = network.nodes.get(i).networkAddress
break; paintRoute(ctx, nodeItem, nextHop);
} }
} }
} }
} }
}
print("next hop", nextHop) function paintRoute(ctx, nodeItem, nextHopAddress) {
if (nextHop == -1) { print("next hop", nextHopAddress)
if (nextHopAddress == -1) {
return; return;
} }
var toNodeItem = null var toNodeItem = null
for (var i = 0; i < d.nodeItems.length; i++) { for (var i = 0; i < d.nodeItems.length; i++) {
if (d.nodeItems[i].node.networkAddress == nextHop) { if (d.nodeItems[i].node.networkAddress == nextHopAddress) {
toNodeItem = d.nodeItems[i] toNodeItem = d.nodeItems[i]
break; break;
} }
@ -336,7 +338,7 @@ Page {
ctx.setLineDash([1,0]) ctx.setLineDash([1,0])
ctx.restore(); ctx.restore();
paintRoute(ctx, toNodeItem) paintRoutes(ctx, toNodeItem)
} }
@ -393,7 +395,7 @@ Page {
function paintEdge(ctx, fromNodeItem, toNodeItem, lqi, selected) { function paintEdge(ctx, fromNodeItem, toNodeItem, lqi, selected) {
ctx.save() ctx.save()
var percent = lqi / 255; var percent = 1 - (lqi / 255);
var goodColor = Style.green var goodColor = Style.green
var badColor = Style.red var badColor = Style.red
var resultRed = goodColor.r + percent * (badColor.r - goodColor.r); var resultRed = goodColor.r + percent * (badColor.r - goodColor.r);
@ -588,7 +590,7 @@ Page {
} }
ColorIcon { ColorIcon {
size: Style.smallIconSize size: Style.smallIconSize
name: "zigbee/zigbee-router" name: "zigbee/zigbee-coordinator"
} }
Item { Item {
Layout.preferredWidth: Style.smallIconSize + Style.smallMargins Layout.preferredWidth: Style.smallIconSize + Style.smallMargins