diff --git a/nymea-app/images.qrc b/nymea-app/images.qrc
index 792e16ed..0ccb1f66 100644
--- a/nymea-app/images.qrc
+++ b/nymea-app/images.qrc
@@ -254,5 +254,7 @@
ui/images/thermostat/cooling.svg
ui/images/thermostat/heating.svg
ui/images/sensors/water.svg
+ ui/images/zigbee/deCONZ.svg
+ ui/images/zigbee/NXP.svg
diff --git a/nymea-app/resources.qrc b/nymea-app/resources.qrc
index 88480023..57b89867 100644
--- a/nymea-app/resources.qrc
+++ b/nymea-app/resources.qrc
@@ -220,7 +220,6 @@
ui/system/ZigbeeSettingsPage.qml
ui/system/ZigbeeAddNetworkPage.qml
ui/system/ZigbeeNetworkPage.qml
- ui/system/ZigbeeNetworkInfoPage.qml
ui/MainMenu.qml
ui/components/NymeaItemDelegate.qml
ui/components/NymeaSwipeDelegate.qml
diff --git a/nymea-app/ui/components/BigTile.qml b/nymea-app/ui/components/BigTile.qml
index 05dd08b6..8a7346f5 100644
--- a/nymea-app/ui/components/BigTile.qml
+++ b/nymea-app/ui/components/BigTile.qml
@@ -18,6 +18,8 @@ Item {
property alias topPadding: content.topPadding
property alias bottomPadding: content.bottomPadding
+ property bool interactive: true
+
signal clicked();
signal pressAndHold();
@@ -98,7 +100,12 @@ Item {
Layout.fillWidth: true
height: contentItem.implicitHeight
onClicked: root.clicked()
- onPressAndHold: root.pressAndHold()
+ hoverEnabled: root.interactive
+ onPressAndHold: {
+ if (root.interactive) {
+ root.pressAndHold()
+ }
+ }
}
}
}
diff --git a/nymea-app/ui/images/zigbee/NXP.svg b/nymea-app/ui/images/zigbee/NXP.svg
new file mode 100644
index 00000000..574bac3b
--- /dev/null
+++ b/nymea-app/ui/images/zigbee/NXP.svg
@@ -0,0 +1,93 @@
+
+
diff --git a/nymea-app/ui/images/zigbee/deCONZ.svg b/nymea-app/ui/images/zigbee/deCONZ.svg
new file mode 100644
index 00000000..9ad21f2b
--- /dev/null
+++ b/nymea-app/ui/images/zigbee/deCONZ.svg
@@ -0,0 +1,56 @@
+
+
diff --git a/nymea-app/ui/system/ZigbeeNetworkInfoPage.qml b/nymea-app/ui/system/ZigbeeNetworkInfoPage.qml
deleted file mode 100644
index 2f986171..00000000
--- a/nymea-app/ui/system/ZigbeeNetworkInfoPage.qml
+++ /dev/null
@@ -1,126 +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 .
-*
-* 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("Network settings")
- backButtonVisible: true
- onBackPressed: pageStack.pop()
- }
-
- SettingsPageSectionHeader {
- text: qsTr("Hardware information")
- }
-
- NymeaSwipeDelegate {
- Layout.fillWidth: true
- text: qsTr("MAC address:")
- subText: root.network.macAddress
- progressive: false
- prominentSubText: false
- }
-
- NymeaSwipeDelegate {
- Layout.fillWidth: true
- text: qsTr("Serial port")
- subText: root.network.serialPort
- progressive: false
- prominentSubText: false
- }
-
- NymeaSwipeDelegate {
- Layout.fillWidth: true
- text: qsTr("Baud rate")
- subText: root.network.baudRate
- progressive: false
- prominentSubText: false
- }
-
- NymeaSwipeDelegate {
- Layout.fillWidth: true
- text: qsTr("Controller backend")
- subText: root.network.backend
- progressive: false
- prominentSubText: false
- }
-
- NymeaSwipeDelegate {
- Layout.fillWidth: true
- text: qsTr("Controller firmware version")
- subText: root.network.firmwareVersion
- progressive: false
- prominentSubText: false
- }
-
- SettingsPageSectionHeader {
- text: qsTr("Manage network")
- }
-
- ColumnLayout {
-
- Button {
- Layout.fillWidth: true
- Layout.leftMargin: app.margins
- Layout.rightMargin: app.margins
- text: qsTr("Remove network")
- onClicked: {
- root.zigbeeManager.removeNetwork(root.network.networkUuid)
- pageStack.pop()
- pageStack.pop()
- }
- }
-
- Button {
- Layout.fillWidth: true
- Layout.leftMargin: app.margins
- Layout.rightMargin: app.margins
- text: qsTr("Factory reset controller")
- onClicked: {
- root.zigbeeManager.factoryResetNetwork(root.network.networkUuid)
- pageStack.pop()
- }
- }
- }
-
-
-}
diff --git a/nymea-app/ui/system/ZigbeeNetworkPage.qml b/nymea-app/ui/system/ZigbeeNetworkPage.qml
index b451d0e5..cb967384 100644
--- a/nymea-app/ui/system/ZigbeeNetworkPage.qml
+++ b/nymea-app/ui/system/ZigbeeNetworkPage.qml
@@ -42,15 +42,10 @@ SettingsPageBase {
property ZigbeeNetwork network: null
header: NymeaHeader {
- text: qsTr("Network") + " " + root.network.macAddress
+ text: qsTr("ZigBee network settings")
backButtonVisible: true
onBackPressed: pageStack.pop()
- HeaderButton {
- text: qsTr("Settings")
- imageSource: "../images/settings.svg"
- onClicked: pageStack.push(Qt.resolvedUrl("ZigbeeNetworkInfoPage.qml"), { network: root.network, zigbeeManager: root.zigbeeManager })
- }
}
SettingsPageSectionHeader {
@@ -93,46 +88,74 @@ SettingsPageBase {
}
SettingsPageSectionHeader {
- text: qsTr("Network control")
+ text: qsTr("Hardware information")
}
NymeaSwipeDelegate {
Layout.fillWidth: true
- text: root.network.permitJoiningEnabled ? qsTr("The network is open") : qsTr("The network is closed")
- subText: root.network.permitJoiningEnabled ? qsTr("Devices can join this network") : qsTr("Devices are not allowed to join this network")
+ text: qsTr("MAC address:")
+ subText: root.network.macAddress
progressive: false
prominentSubText: false
}
- ColumnLayout {
-
- ProgressBar {
- Layout.fillWidth: true
- Layout.leftMargin: app.margins
- Layout.rightMargin: app.margins
- visible: root.network.permitJoiningEnabled
- from: root.network.permitJoiningDuration
- to: 0
- value: root.network.permitJoiningRemaining
- }
-
- Button {
- Layout.fillWidth: true
- Layout.leftMargin: app.margins
- Layout.rightMargin: app.margins
- enabled: network.networkState === ZigbeeNetwork.ZigbeeNetworkStateOnline
- text: root.network.permitJoiningEnabled ? qsTr("Extend network open duration") : qsTr("Open network for new ZigBee devices")
- onClicked: root.zigbeeManager.setPermitJoin(root.network.networkUuid)
- }
-
- Button {
- Layout.fillWidth: true
- Layout.leftMargin: app.margins
- Layout.rightMargin: app.margins
- visible: network.networkState === ZigbeeNetwork.ZigbeeNetworkStateOnline && root.network.permitJoiningEnabled
- text: qsTr("Close network")
- onClicked: root.zigbeeManager.setPermitJoin(root.network.networkUuid, 0)
- }
+ NymeaSwipeDelegate {
+ Layout.fillWidth: true
+ text: qsTr("Serial port")
+ subText: root.network.serialPort
+ progressive: false
+ prominentSubText: false
}
+ NymeaSwipeDelegate {
+ Layout.fillWidth: true
+ text: qsTr("Baud rate")
+ subText: root.network.baudRate
+ progressive: false
+ prominentSubText: false
+ }
+
+ NymeaSwipeDelegate {
+ Layout.fillWidth: true
+ text: qsTr("Controller backend")
+ subText: root.network.backend
+ progressive: false
+ prominentSubText: false
+ }
+
+ NymeaSwipeDelegate {
+ Layout.fillWidth: true
+ text: qsTr("Controller firmware version")
+ subText: root.network.firmwareVersion
+ progressive: false
+ prominentSubText: false
+ }
+
+ SettingsPageSectionHeader {
+ text: qsTr("Manage network")
+ }
+
+ ColumnLayout {
+
+ Button {
+ Layout.fillWidth: true
+ Layout.leftMargin: app.margins
+ Layout.rightMargin: app.margins
+ text: qsTr("Remove network")
+ onClicked: {
+ root.zigbeeManager.removeNetwork(root.network.networkUuid)
+ pageStack.pop()
+ }
+ }
+
+ Button {
+ Layout.fillWidth: true
+ Layout.leftMargin: app.margins
+ Layout.rightMargin: app.margins
+ text: qsTr("Factory reset controller")
+ onClicked: {
+ root.zigbeeManager.factoryResetNetwork(root.network.networkUuid)
+ }
+ }
+ }
}
diff --git a/nymea-app/ui/system/ZigbeeSettingsPage.qml b/nymea-app/ui/system/ZigbeeSettingsPage.qml
index c0003e9f..1289294a 100644
--- a/nymea-app/ui/system/ZigbeeSettingsPage.qml
+++ b/nymea-app/ui/system/ZigbeeSettingsPage.qml
@@ -54,51 +54,164 @@ SettingsPageBase {
engine: _engine
}
- // Disabled for now, the Resources API won't make it in time
-// SettingsPageSectionHeader {
-// text: qsTr("General")
-// }
-
-// NymeaSwipeDelegate {
-// Layout.fillWidth: true
-// text: qsTr("Zigbee enabled")
-// subText: qsTr("Enable or disable Zigbee altogether")
-// prominentSubText: false
-// progressive: false
-// additionalItem: Switch {
-// anchors.centerIn: parent
-// }
-// }
-
- SettingsPageSectionHeader {
- text: qsTr("ZigBee networks")
- }
-
- Label {
+ Item {
Layout.fillWidth: true
- Layout.leftMargin: app.margins; Layout.rightMargin: app.margins
- wrapMode: Text.WordWrap
- text: qsTr("There are no ZigBee networks set up yet. In order to use ZigBee, create a ZigBee network.")
+ Layout.preferredHeight: root.height
visible: zigbeeManager.networks.count == 0
- }
- Repeater {
- model: zigbeeManager.networks
- delegate: NymeaSwipeDelegate {
- Layout.fillWidth: true
- property var network: zigbeeManager.networks.get(index)
- iconName: "../images/zigbee.svg"
- text: model.backend + " - " + model.macAddress
- subText: model.serialPort + " - " + model.firmwareVersion
- onClicked: pageStack.push(Qt.resolvedUrl("ZigbeeNetworkPage.qml"), { zigbeeManager: zigbeeManager, network: network })
+ 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: {
+ pageStack.push(Qt.resolvedUrl("ZigbeeAddNetworkPage.qml"), {zigbeeManager: zigbeeManager})
+ }
}
}
- Button {
- Layout.fillWidth: true
- Layout.margins: app.margins
- text: qsTr("Add a ZigBee network")
- onClicked: pageStack.push(Qt.resolvedUrl("ZigbeeAddNetworkPage.qml"), {zigbeeManager: zigbeeManager})
+
+ ColumnLayout {
+ Layout.margins: app.margins / 2
+ Repeater {
+ model: zigbeeManager.networks
+ delegate: BigTile {
+ Layout.fillWidth: true
+ interactive: false
+
+ contentItem: ColumnLayout {
+ spacing: app.margins
+ RowLayout {
+ ColorIcon {
+ name: "/ui/images/zigbee/" + model.backend + ".svg"
+ Layout.preferredWidth: app.iconSize
+ Layout.preferredHeight: app.iconSize
+ }
+
+ Label {
+ Layout.fillWidth: true
+ text: model.backend
+ font.pixelSize: app.largeFont
+ }
+
+ ProgressButton {
+ Layout.preferredWidth: app.iconSize
+ Layout.preferredHeight: app.iconSize
+ imageSource: "/ui/images/configure.svg"
+ longpressEnabled: false
+ onClicked: pageStack.push(Qt.resolvedUrl("ZigbeeNetworkPage.qml"), { zigbeeManager: zigbeeManager, network: zigbeeManager.networks.get(index) })
+ }
+ }
+ 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: app.iconSize
+ Layout.preferredWidth: app.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("Network joining:")
+ }
+ Label {
+ text: model.permitJoiningEnabled ? qsTr("Open for %0 s").arg(model.permitJoiningRemaining) : qsTr("Closed")
+ }
+ ColorIcon {
+ Layout.preferredHeight: app.iconSize
+ Layout.preferredWidth: app.iconSize
+ name: model.permitJoiningEnabled ? "/ui/images/lock-open.svg" : "/ui/images/lock-closed.svg"
+ visible: !model.permitJoiningEnabled
+ }
+ Canvas {
+ id: canvas
+ Layout.preferredHeight: app.iconSize
+ Layout.preferredWidth: app.iconSize
+ rotation: -90
+ visible: model.permitJoiningEnabled
+
+ property real progress: model.permitJoiningRemaining / model.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: model.permitJoiningEnabled ? qsTr("Extend open duration") : qsTr("Open for new devices")
+ enabled: model.networkState === ZigbeeNetwork.ZigbeeNetworkStateOnline
+ onClicked: zigbeeManager.setPermitJoin(model.networkUuid)
+ }
+ }
+ }
+ }
}
}