From b2bda71fc606c9a9efd969c62a9be0ee0033e19f Mon Sep 17 00:00:00 2001 From: Michael Zanetti Date: Sat, 10 Sep 2022 01:22:16 +0200 Subject: [PATCH] More fixes in the Zigbee Topology map --- .../ui/system/zigbee/ZigbeeNetworkPage.qml | 234 ++++++++++-------- .../ui/system/zigbee/ZigbeeTopologyPage.qml | 22 +- 2 files changed, 139 insertions(+), 117 deletions(-) diff --git a/nymea-app/ui/system/zigbee/ZigbeeNetworkPage.qml b/nymea-app/ui/system/zigbee/ZigbeeNetworkPage.qml index 645e0711..69337e2c 100644 --- a/nymea-app/ui/system/zigbee/ZigbeeNetworkPage.qml +++ b/nymea-app/ui/system/zigbee/ZigbeeNetworkPage.qml @@ -104,7 +104,7 @@ SettingsPageBase { } SettingsPageSectionHeader { - text: qsTr("Network") + text: qsTr("Network state") } ColumnLayout { @@ -112,136 +112,156 @@ SettingsPageBase { Layout.leftMargin: Style.margins Layout.rightMargin: Style.margins - RowLayout { + GridLayout { Layout.fillWidth: true + columns: 2 + rowSpacing: Style.margins + columnSpacing: Style.margins - Label { - Layout.fillWidth: true - text: qsTr("Network state:") - } - - Label { - text: { - switch (network.networkState) { - case ZigbeeNetwork.ZigbeeNetworkStateOnline: - return qsTr("Online") - case ZigbeeNetwork.ZigbeeNetworkStateOffline: - return qsTr("Offline") - case ZigbeeNetwork.ZigbeeNetworkStateStarting: - return qsTr("Starting") - case ZigbeeNetwork.ZigbeeNetworkStateUpdating: - return qsTr("Updating") - case ZigbeeNetwork.ZigbeeNetworkStateError: - return qsTr("Error") + RowLayout { + Layout.preferredWidth: (parent.width - parent.columnSpacing) / 2 + Led { + Layout.preferredHeight: Style.iconSize + Layout.preferredWidth: Style.iconSize + state: { + switch (network.networkState) { + case ZigbeeNetwork.ZigbeeNetworkStateOnline: + return "on" + case ZigbeeNetwork.ZigbeeNetworkStateOffline: + return "off" + case ZigbeeNetwork.ZigbeeNetworkStateStarting: + return "orange" + case ZigbeeNetwork.ZigbeeNetworkStateUpdating: + return "orange" + case ZigbeeNetwork.ZigbeeNetworkStateError: + return "red" + } } } - } - Led { - Layout.preferredHeight: Style.iconSize - Layout.preferredWidth: Style.iconSize - state: { - switch (network.networkState) { - case ZigbeeNetwork.ZigbeeNetworkStateOnline: - return "on" - case ZigbeeNetwork.ZigbeeNetworkStateOffline: - return "off" - case ZigbeeNetwork.ZigbeeNetworkStateStarting: - return "orange" - case ZigbeeNetwork.ZigbeeNetworkStateUpdating: - return "orange" - case ZigbeeNetwork.ZigbeeNetworkStateError: - return "red" + Label { + Layout.fillWidth: true + text: { + switch (network.networkState) { + case ZigbeeNetwork.ZigbeeNetworkStateOnline: + return qsTr("Online") + case ZigbeeNetwork.ZigbeeNetworkStateOffline: + return qsTr("Offline") + case ZigbeeNetwork.ZigbeeNetworkStateStarting: + return qsTr("Starting") + case ZigbeeNetwork.ZigbeeNetworkStateUpdating: + return qsTr("Updating") + case ZigbeeNetwork.ZigbeeNetworkStateError: + return qsTr("Error") + } } } + } - } - RowLayout { - Layout.fillWidth: true + RowLayout { + 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 - text: qsTr("Channel") - } - - 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" + Layout.columnSpan: 2 + text: qsTr("Open for new devices") + enabled: network.networkState === ZigbeeNetwork.ZigbeeNetworkStateOnline visible: !network.permitJoiningEnabled + onClicked: zigbeeManager.setPermitJoin(network.networkUuid) } - Canvas { - id: canvas - Layout.preferredHeight: Style.iconSize - Layout.preferredWidth: Style.iconSize - rotation: -90 + Button { + Layout.fillWidth: true + text: qsTr("Extend") + enabled: network.networkState === ZigbeeNetwork.ZigbeeNetworkStateOnline visible: network.permitJoiningEnabled + onClicked: zigbeeManager.setPermitJoin(network.networkUuid, 254) + } - 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.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 + enabled: network.networkState == ZigbeeNetwork.ZigbeeNetworkStateOnline + visible: network.permitJoiningEnabled + text: qsTr("Close") + onClicked: { + zigbeeManager.setPermitJoin(network.networkUuid, 0) } } + } - 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 { - 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 { diff --git a/nymea-app/ui/system/zigbee/ZigbeeTopologyPage.qml b/nymea-app/ui/system/zigbee/ZigbeeTopologyPage.qml index ba10bb2b..a3d84758 100644 --- a/nymea-app/ui/system/zigbee/ZigbeeTopologyPage.qml +++ b/nymea-app/ui/system/zigbee/ZigbeeTopologyPage.qml @@ -278,21 +278,21 @@ Page { paintEdges(ctx, d.nodeItems[i], true) } if (d.selectedNodeItem) { - paintRoute(ctx, d.selectedNodeItem) + paintRoutes(ctx, d.selectedNodeItem) } for (var i = 0; i < d.nodeItems.length; i++) { paintNode(ctx, d.nodeItems[i]) } } - function paintRoute(ctx, nodeItem) { + function paintRoutes(ctx, nodeItem) { var node = nodeItem.node var nextHop = -1 if (node.type === ZigbeeNode.ZigbeeNodeTypeRouter) { for (var i = 0; i < node.routes.length; i++) { if (node.routes[i].destinationAddress === 0) { nextHop = node.routes[i].nextHopAddress - break; + paintRoute(ctx, nodeItem, nextHop); } } } else if (node.type === ZigbeeNode.ZigbeeNodeTypeEndDevice) { @@ -300,19 +300,21 @@ Page { for (var j = 0; j < network.nodes.get(i).neighbors.length; j++) { if (network.nodes.get(i).neighbors[j].networkAddress === node.networkAddress) { nextHop = network.nodes.get(i).networkAddress - break; + paintRoute(ctx, nodeItem, nextHop); } } } } + } - print("next hop", nextHop) - if (nextHop == -1) { + function paintRoute(ctx, nodeItem, nextHopAddress) { + print("next hop", nextHopAddress) + if (nextHopAddress == -1) { return; } var toNodeItem = null 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] break; } @@ -336,7 +338,7 @@ Page { ctx.setLineDash([1,0]) ctx.restore(); - paintRoute(ctx, toNodeItem) + paintRoutes(ctx, toNodeItem) } @@ -393,7 +395,7 @@ Page { function paintEdge(ctx, fromNodeItem, toNodeItem, lqi, selected) { ctx.save() - var percent = lqi / 255; + var percent = 1 - (lqi / 255); var goodColor = Style.green var badColor = Style.red var resultRed = goodColor.r + percent * (badColor.r - goodColor.r); @@ -588,7 +590,7 @@ Page { } ColorIcon { size: Style.smallIconSize - name: "zigbee/zigbee-router" + name: "zigbee/zigbee-coordinator" } Item { Layout.preferredWidth: Style.smallIconSize + Style.smallMargins