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 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + 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 @@ + +image/svg+xml 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) + } + } + } + } } }