Merge PR #695: Fixes in zigbee settings

pull/696/head
Jenkins nymea 2021-10-22 09:09:23 +02:00
commit 5f07eb6c6e
3 changed files with 7 additions and 670 deletions

View File

@ -322,12 +322,12 @@ SettingsPageBase {
}
additionalItem: ColorIcon {
size: Style.smallIconSize
visible: node && !node.rxOnWhenIdle
anchors.verticalCenter: parent.verticalCenter
name: node.type === ZigbeeNode.ZigbeeNodeTypeRouter
? "/ui/images/zigbee-router.svg"
: "/ui/images/zigbee-enddevice.svg"
color: communicationIndicatorLedTimer.running ? Style.accentColor : Style.iconColor
Component.onCompleted: print("************+ node type", node.type)
}
onClicked: {
@ -371,18 +371,18 @@ SettingsPageBase {
progressive: false
subText: nodeInfoDialog.node.networkAddress
}
NymeaItemDelegate {
text: qsTr("Version")
Layout.fillWidth: true
progressive: false
subText: nodeInfoDialog.node.version
}
NymeaItemDelegate {
text: qsTr("Signal strength")
Layout.fillWidth: true
progressive: false
subText: (nodeInfoDialog.node.lqi * 100.0 / 255.0) + " %"
}
NymeaItemDelegate {
text: qsTr("Version")
Layout.fillWidth: true
progressive: false
subText: nodeInfoDialog.node.version
}
RowLayout {
Layout.fillWidth: true

View File

@ -1,486 +0,0 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2021, nymea GmbH
* Contact: contact@nymea.io
*
* This file is part of nymea.
* This project including source code and documentation is protected by
* copyright law, and remains the property of nymea GmbH. All rights, including
* reproduction, publication, editing and translation, are reserved. The use of
* this project is subject to the terms of a license agreement to be concluded
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
* under https://nymea.io/license
*
* GNU General Public License Usage
* Alternatively, this project may be redistributed and/or modified under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, GNU version 3. This project is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* this project. If not, see <https://www.gnu.org/licenses/>.
*
* For any further details and any questions please contact us under
* contact@nymea.io or see our FAQ/Licensing Information on
* https://nymea.io/license/faq
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
import QtQuick 2.8
import QtQuick.Controls 2.2
import QtQuick.Controls.Material 2.1
import QtQuick.Layouts 1.3
import "../components"
import Nymea 1.0
SettingsPageBase {
id: root
property ZigbeeManager zigbeeManager: null
property ZigbeeNetwork network: null
header: NymeaHeader {
text: qsTr("ZigBee network")
backButtonVisible: true
onBackPressed: pageStack.pop()
HeaderButton {
imageSource: "/ui/images/help.svg"
text: qsTr("Help")
onClicked: {
var popup = zigbeeHelpDialog.createObject(app)
popup.open()
}
}
HeaderButton {
imageSource: "/ui/images/configure.svg"
text: qsTr("Network settings")
onClicked: {
var page = pageStack.push(Qt.resolvedUrl("ZigbeeNetworkSettingsPage.qml"), { zigbeeManager: zigbeeManager, network: network })
page.exit.connect(function() {
pageStack.pop(root, StackView.Immediate)
pageStack.pop()
})
}
}
}
busy: d.pendingCommandId != -1
QtObject {
id: d
property int pendingCommandId: -1
function removeNode(networkUuid, ieeeAddress) {
d.pendingCommandId = root.zigbeeManager.removeNode(networkUuid, ieeeAddress)
}
}
Connections {
target: root.zigbeeManager
onRemoveNodeReply: {
if (commandId == d.pendingCommandId) {
d.pendingCommandId = -1
var props = {};
switch (error) {
case "ZigbeeErrorNoError":
return;
case "ZigbeeErrorAdapterNotAvailable":
props.text = qsTr("The selected adapter is not available or the selected serial port configration is incorrect.");
break;
case "ZigbeeErrorAdapterAlreadyInUse":
props.text = qsTr("The selected adapter is already in use.");
break;
default:
props.errorCode = error;
}
var comp = Qt.createComponent("../components/ErrorDialog.qml")
var popup = comp.createObject(app, props)
popup.open();
}
}
}
SettingsPageSectionHeader {
text: qsTr("Network")
}
ColumnLayout {
spacing: Style.margins
Layout.leftMargin: Style.margins
Layout.rightMargin: Style.margins
RowLayout {
Layout.fillWidth: true
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")
}
}
}
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"
}
}
}
}
RowLayout {
Layout.fillWidth: true
Label {
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"
visible: !network.permitJoiningEnabled
}
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.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 {
text: qsTr("Connected devices")
}
Label {
Layout.fillWidth: true
Layout.margins: Style.margins
horizontalAlignment: Text.AlignHCenter
text: qsTr("There are no ZigBee devices connectd yet. Open the network for new devices to join and start the pairing procedure from the ZigBee device. Please refer to the devices manual for more information on how to start the pairing.")
wrapMode: Text.WordWrap
visible: nodesModel.count === 0
}
Repeater {
model: ZigbeeNodesProxy {
id: nodesModel
zigbeeNodes: root.network.nodes
showCoordinator: false
newOnTop: true
}
delegate: NymeaSwipeDelegate {
id: nodeDelegate
readonly property ZigbeeNode node: nodesModel.get(index)
ThingsProxy {
id: nodeThings
engine: _engine
paramsFilter: {"ieeeAddress": nodeDelegate.node.ieeeAddress}
}
readonly property Thing nodeThing: nodeThings.count === 1 ? nodeThings.get(0) : null
property int signalStrength: node ? Math.round(node.lqi * 100.0 / 255.0) : 0
Layout.fillWidth: true
text: nodeThing ? nodeThing.name : node.model
subText: node.manufacturer || node.ieeeAddress
iconName: nodeThing ? app.interfacesToIcon(nodeThing.thingClass.interfaces) : "/ui/images/zigbee.svg"
iconColor: busy
? Style.tileOverlayColor
: nodeThing != null ? Style.accentColor : Style.iconColor
progressive: false
busy: node.state !== ZigbeeNode.ZigbeeNodeStateInitialized
canDelete: true
onDeleteClicked: {
var dialog = removeZigbeeNodeDialogComponent.createObject(app, {zigbeeNode: node})
dialog.open()
}
secondaryIconName: node && !node.rxOnWhenIdle ? "/ui/images/system-suspend.svg" : ""
tertiaryIconName: {
if (!node || !node.reachable)
return "/ui/images/connections/nm-signal-00.svg"
if (signalStrength <= 25)
return "/ui/images/connections/nm-signal-25.svg"
if (signalStrength <= 50)
return "/ui/images/connections/nm-signal-50.svg"
if (signalStrength <= 75)
return "/ui/images/connections/nm-signal-75.svg"
if (signalStrength <= 100)
return "/ui/images/connections/nm-signal-100.svg"
}
tertiaryIconColor: node.reachable ? Style.iconColor : "red"
Connections {
target: node
onLastSeenChanged: communicationIndicatorLedTimer.start()
}
Timer {
id: communicationIndicatorLedTimer
interval: 200
}
additionalItem: ColorIcon {
size: Style.smallIconSize
visible: node && !node.rxOnWhenIdle
anchors.verticalCenter: parent.verticalCenter
name: node.type === ZigbeeNode.ZigbeeNodeTypeRouter
? "/ui/images/zigbee-router.svg"
: "/ui/images/zigbee-enddevice.svg"
color: communicationIndicatorLedTimer.running ? Style.accentColor : Style.iconColor
}
onClicked: {
var popup = nodeInfoComponent.createObject(app, {node: node, nodeThing: nodeThing})
popup.open()
}
}
}
Component {
id: nodeInfoComponent
MeaDialog {
id: nodeInfoDialog
property ZigbeeNode node: null
property Thing nodeThing: null
headerIcon: nodeThing ? app.interfacesToIcon(nodeThing.thingClass.interfaces) : "/ui/images/zigbee.svg"
title: nodeThing ? nodeThing.name : node.model
standardButtons: Dialog.NoButton
NymeaItemDelegate {
text: qsTr("Model")
Layout.fillWidth: true
progressive: false
subText: nodeInfoDialog.node.model
}
NymeaItemDelegate {
text: qsTr("Manufacturer")
Layout.fillWidth: true
progressive: false
subText: nodeInfoDialog.node.manufacturer
}
NymeaItemDelegate {
text: qsTr("IEEE address")
Layout.fillWidth: true
progressive: false
subText: nodeInfoDialog.node.ieeeAddress
}
NymeaItemDelegate {
text: qsTr("Network address")
Layout.fillWidth: true
progressive: false
subText: nodeInfoDialog.node.networkAddress
}
NymeaItemDelegate {
text: qsTr("Signal strength")
Layout.fillWidth: true
progressive: false
subText: (nodeInfoDialog.node.lqi * 100.0 / 255.0) + " %"
}
NymeaItemDelegate {
text: qsTr("Version")
Layout.fillWidth: true
progressive: false
subText: nodeInfoDialog.node.version
}
RowLayout {
Layout.fillWidth: true
Button {
// size: Style.iconSize
visible: node && node.type !== ZigbeeNode.ZigbeeNodeTypeCoordinator
// imageSource: "/ui/images/delete.svg"
text: qsTr("Remove")
Layout.alignment: Qt.AlignLeft
onClicked: {
var dialog = removeZigbeeNodeDialogComponent.createObject(app, {zigbeeNode: node})
dialog.open()
nodeInfoDialog.close()
}
}
Item {
Layout.fillWidth: true
}
Button {
text: qsTr("OK")
onClicked: nodeInfoDialog.close()
Layout.alignment: Qt.AlignRight
}
}
}
}
Component {
id: removeZigbeeNodeDialogComponent
MeaDialog {
id: removeZigbeeNodeDialog
property ZigbeeNode zigbeeNode
headerIcon: "/ui/images/zigbee.svg"
title: qsTr("Remove ZigBee node") + " " + (zigbeeNode ? zigbeeNode.model : "")
text: qsTr("Are you sure you want to remove this node from the network?")
standardButtons: Dialog.Ok | Dialog.Cancel
Label {
text: qsTr("Please note that if this node has been assigned to a thing, it will also be removed from the system.")
Layout.fillWidth: true
wrapMode: Text.WordWrap
}
onAccepted: {
d.removeNode(zigbeeNode.networkUuid, zigbeeNode.ieeeAddress)
}
}
}
Component {
id: zigbeeHelpDialog
MeaDialog {
id: dialog
title: qsTr("ZigBee network help")
RowLayout {
spacing: Style.margins
ColorIcon {
Layout.preferredHeight: Style.iconSize
Layout.preferredWidth: Style.iconSize
name: "/ui/images/zigbee-router.svg"
}
Label {
text: qsTr("ZigBee router")
}
}
RowLayout {
spacing: Style.margins
ColorIcon {
Layout.preferredHeight: Style.iconSize
Layout.preferredWidth: Style.iconSize
name: "/ui/images/zigbee-enddevice.svg"
}
Label {
text: qsTr("ZigBee end device")
}
}
RowLayout {
spacing: Style.margins
ColorIcon {
Layout.preferredHeight: Style.iconSize
Layout.preferredWidth: Style.iconSize
name: "/ui/images/system-suspend.svg"
}
Label {
text: qsTr("Sleepy device")
}
}
}
}
}

View File

@ -1,177 +0,0 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2020, nymea GmbH
* Contact: contact@nymea.io
*
* This file is part of nymea.
* This project including source code and documentation is protected by
* copyright law, and remains the property of nymea GmbH. All rights, including
* reproduction, publication, editing and translation, are reserved. The use of
* this project is subject to the terms of a license agreement to be concluded
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
* under https://nymea.io/license
*
* GNU General Public License Usage
* Alternatively, this project may be redistributed and/or modified under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, GNU version 3. This project is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* this project. If not, see <https://www.gnu.org/licenses/>.
*
* For any further details and any questions please contact us under
* contact@nymea.io or see our FAQ/Licensing Information on
* https://nymea.io/license/faq
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
import QtQuick 2.8
import QtQuick.Controls 2.2
import QtQuick.Controls.Material 2.1
import QtQuick.Layouts 1.3
import "../components"
import Nymea 1.0
SettingsPageBase {
id: root
header: NymeaHeader {
text: qsTr("ZigBee")
backButtonVisible: true
onBackPressed: pageStack.pop()
HeaderButton {
imageSource: "../images/add.svg"
text: qsTr("Add ZigBee network")
onClicked: {
addNetwork()
}
}
}
function addNetwork() {
var addPage = pageStack.push(Qt.resolvedUrl("ZigbeeAddNetworkPage.qml"), {zigbeeManager: zigbeeManager})
addPage.done.connect(function() {pageStack.pop(root)})
}
ZigbeeManager {
id: zigbeeManager
engine: _engine
}
Item {
Layout.fillWidth: true
Layout.preferredHeight: root.height
visible: zigbeeManager.networks.count == 0
EmptyViewPlaceholder {
width: parent.width - app.margins * 2
anchors.centerIn: parent
title: qsTr("ZigBee")
text: qsTr("There are no ZigBee networks set up yet. In order to use ZigBee, create a ZigBee network.")
imageSource: "/ui/images/zigbee.svg"
buttonText: qsTr("Add network")
onButtonClicked: {
addNetwork()
}
}
}
ColumnLayout {
Layout.margins: app.margins / 2
Repeater {
model: zigbeeManager.networks
delegate: BigTile {
Layout.fillWidth: true
interactive: false
onClicked: pageStack.push(Qt.resolvedUrl("ZigbeeNetworkPage.qml"), { zigbeeManager: zigbeeManager, network: zigbeeManager.networks.get(index) })
header: RowLayout {
ColorIcon {
name: "/ui/images/zigbee/" + model.backend + ".svg"
Layout.preferredWidth: Style.iconSize
Layout.preferredHeight: Style.iconSize
}
Label {
Layout.fillWidth: true
text: model.backend
font.pixelSize: app.largeFont
}
}
contentItem: ColumnLayout {
spacing: app.margins
RowLayout {
Label {
Layout.fillWidth: true
text: qsTr("Network state:")
}
Label {
text: {
switch (model.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")
}
}
}
Led {
Layout.preferredHeight: Style.iconSize
Layout.preferredWidth: Style.iconSize
state: {
switch (model.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"
}
}
}
}
RowLayout {
Label {
Layout.fillWidth: true
text: qsTr("MAC address:")
}
Label {
text: model.macAddress
}
}
RowLayout {
Label {
Layout.fillWidth: true
text: qsTr("Firmware version:")
}
Label {
text: model.firmwareVersion
}
}
}
}
}
}
}