diff --git a/libnymea-app/zwave/zwavemanager.cpp b/libnymea-app/zwave/zwavemanager.cpp index cc5ed09a..82c6ff29 100644 --- a/libnymea-app/zwave/zwavemanager.cpp +++ b/libnymea-app/zwave/zwavemanager.cpp @@ -315,9 +315,12 @@ ZWaveNode *ZWaveManager::unpackNode(const QVariantMap &nodeMap, ZWaveNode *node) node->setReachable(nodeMap.value("reachable").toBool()); node->setFailed(nodeMap.value("failed").toBool()); node->setSleeping(nodeMap.value("sleeping").toBool()); + node->setLinkQuality(nodeMap.value("linkQuality").toUInt()); QMetaEnum nodeTypeEnum = QMetaEnum::fromType(); node->setNodeType(static_cast(nodeTypeEnum.keyToValue(nodeMap.value("nodeType").toByteArray()))); + QMetaEnum roleEnum = QMetaEnum::fromType(); + node->setRole(static_cast(roleEnum.keyToValue(nodeMap.value("role").toByteArray()))); QMetaEnum deviceTypeEnum = QMetaEnum::fromType(); node->setDeviceType(static_cast(deviceTypeEnum.keyToValue(nodeMap.value("deviceType").toByteArray()))); diff --git a/libnymea-app/zwave/zwavenode.cpp b/libnymea-app/zwave/zwavenode.cpp index fa5fb593..e2e43506 100644 --- a/libnymea-app/zwave/zwavenode.cpp +++ b/libnymea-app/zwave/zwavenode.cpp @@ -32,6 +32,31 @@ void ZWaveNode::setNodeType(ZWaveNodeType nodeType) } } +QString ZWaveNode::nodeTypeString() const +{ + QMetaEnum metaEnum = QMetaEnum::fromType(); + return QString(metaEnum.valueToKey(m_nodeType)).remove(QRegExp("^ZWaveNodeType")); +} + +ZWaveNode::ZWaveNodeRole ZWaveNode::role() const +{ + return m_role; +} + +void ZWaveNode::setRole(ZWaveNodeRole role) +{ + if (m_role != role) { + m_role = role; + emit roleChanged(); + } +} + +QString ZWaveNode::roleString() const +{ + QMetaEnum metaEnum = QMetaEnum::fromType(); + return QString(metaEnum.valueToKey(m_role)).remove(QRegExp("^ZWaveNodeRole")); +} + ZWaveNode::ZWaveDeviceType ZWaveNode::deviceType() const { return m_deviceType; @@ -45,7 +70,7 @@ void ZWaveNode::setDeviceType(ZWaveDeviceType deviceType) QString ZWaveNode::deviceTypeString() const { QMetaEnum metaEnum = QMetaEnum::fromType(); - return metaEnum.valueToKey(m_deviceType); + return QString(metaEnum.valueToKey(m_deviceType)).remove(QRegExp("^ZWaveDeviceType")); } quint16 ZWaveNode::manufacturerId() const @@ -191,6 +216,19 @@ void ZWaveNode::setSleeping(bool sleeping) } } +quint8 ZWaveNode::linkQuality() const +{ + return m_linkQuality; +} + +void ZWaveNode::setLinkQuality(quint8 linkQuality) +{ + if (m_linkQuality != linkQuality) { + m_linkQuality = linkQuality; + emit linkQualityChanged(); + } +} + bool ZWaveNode::initialized() const { return m_initialized; diff --git a/libnymea-app/zwave/zwavenode.h b/libnymea-app/zwave/zwavenode.h index 595255ae..7f8e14f4 100644 --- a/libnymea-app/zwave/zwavenode.h +++ b/libnymea-app/zwave/zwavenode.h @@ -15,7 +15,11 @@ class ZWaveNode : public QObject Q_PROPERTY(bool reachable READ reachable NOTIFY reachableChanged) Q_PROPERTY(bool failed READ failed NOTIFY failedChanged) Q_PROPERTY(bool sleeping READ sleeping NOTIFY sleepingChanged) + Q_PROPERTY(quint8 linkQuality READ linkQuality NOTIFY linkQualityChanged) Q_PROPERTY(ZWaveNodeType nodeType READ nodeType NOTIFY nodeTypeChanged) + Q_PROPERTY(QString nodeTypeString READ nodeTypeString NOTIFY nodeTypeChanged) + Q_PROPERTY(ZWaveNodeRole role READ role NOTIFY roleChanged) + Q_PROPERTY(QString roleString READ roleString NOTIFY roleChanged) Q_PROPERTY(ZWaveDeviceType deviceType READ deviceType NOTIFY deviceTypeChanged) Q_PROPERTY(QString deviceTypeString READ deviceTypeString NOTIFY deviceTypeChanged) Q_PROPERTY(quint16 manufacturerId READ manufacturerId NOTIFY manufacturerIdChanged) @@ -37,6 +41,19 @@ public: }; Q_ENUM(ZWaveNodeType) + enum ZWaveNodeRole { + ZWaveNodeRoleUnknown = -0x01, + ZWaveNodeRoleCentralController = 0x00, + ZWaveNodeRoleSubController = 0x01, + ZWaveNodeRolePortableController = 0x02, + ZWaveNodeRolePortableReportingController = 0x03, + ZWaveNodeRolePortableSlave = 0x04, + ZWaveNodeRoleAlwaysOnSlabe = 0x05, + ZWaveNodeRoleReportingSleepingSlave = 0x06, + ZWaveNodeRoleListeningSleepingSlave = 0x07 + }; + Q_ENUM(ZWaveNodeRole) + enum ZWaveDeviceType { ZWaveDeviceTypeUnknown = 0x0000, ZWaveDeviceTypeCentralController = 0x0100, @@ -133,12 +150,19 @@ public: bool sleeping() const; void setSleeping(bool sleeping); + quint8 linkQuality() const; + void setLinkQuality(quint8 linkQuality); + ZWaveNodeType nodeType() const; void setNodeType(ZWaveNodeType nodeType); + QString nodeTypeString() const; + + ZWaveNodeRole role() const; + void setRole(ZWaveNodeRole role); + QString roleString() const; ZWaveDeviceType deviceType() const; void setDeviceType(ZWaveDeviceType deviceType); - QString deviceTypeString() const; // PlusDeviceType plusDeviceType() const; @@ -172,8 +196,10 @@ signals: void reachableChanged(); void failedChanged(); void sleepingChanged(); + void linkQualityChanged(); void nodeTypeChanged(); void deviceTypeChanged(); + void roleChanged(); void plusDeviceTypeChanged(); void manufacturerIdChanged(); @@ -193,8 +219,10 @@ private: bool m_reachable = false; bool m_failed = false; bool m_sleeping = false; + quint8 m_linkQuality = 0; ZWaveNodeType m_nodeType = ZWaveNodeTypeUnknown; + ZWaveNodeRole m_role = ZWaveNodeRoleUnknown; ZWaveDeviceType m_deviceType = ZWaveDeviceTypeUnknown; quint16 m_manufacturerId = 0; QString m_manufacturerName; diff --git a/nymea-app/ui/Configuration.qml b/nymea-app/ui/Configuration.qml index 67000922..d034227d 100644 --- a/nymea-app/ui/Configuration.qml +++ b/nymea-app/ui/Configuration.qml @@ -14,6 +14,7 @@ ConfigurationBase { mqttSettingsEnabled: true webServerSettingsEnabled: true zigbeeSettingsEnabled: true + zwaveSettingsEnabled: true modbusSettingsEnabled: true pluginSettingsEnabled: true diff --git a/nymea-app/ui/ConfigurationBase.qml b/nymea-app/ui/ConfigurationBase.qml index f7c2d26f..5a11e12f 100644 --- a/nymea-app/ui/ConfigurationBase.qml +++ b/nymea-app/ui/ConfigurationBase.qml @@ -14,6 +14,7 @@ Item { property bool mqttSettingsEnabled: false property bool webServerSettingsEnabled: false property bool zigbeeSettingsEnabled: false + property bool zwaveSettingsEnabled: false property bool modbusSettingsEnabled: false property bool pluginSettingsEnabled: false diff --git a/nymea-app/ui/SettingsPage.qml b/nymea-app/ui/SettingsPage.qml index 9d3d600f..63919abe 100644 --- a/nymea-app/ui/SettingsPage.qml +++ b/nymea-app/ui/SettingsPage.qml @@ -126,7 +126,7 @@ Page { iconSource: "../images/z-wave.svg" text: qsTr("Z-Wave") subText: qsTr("Configure Z-Wave networks") - visible: engine.jsonRpcClient.ensureServerVersion("6.1") && NymeaUtils.hasPermissionScope(engine.jsonRpcClient.permissions, UserInfo.PermissionScopeAdmin) && Configuration.zigbeeSettingsEnabled + visible: engine.jsonRpcClient.ensureServerVersion("6.1") && NymeaUtils.hasPermissionScope(engine.jsonRpcClient.permissions, UserInfo.PermissionScopeAdmin) && Configuration.zwaveSettingsEnabled onClicked: pageStack.push(Qt.resolvedUrl("system/zwave/ZWaveSettingsPage.qml")) } diff --git a/nymea-app/ui/system/zwave/ZWaveNetworkPage.qml b/nymea-app/ui/system/zwave/ZWaveNetworkPage.qml index f15b6354..48d61f84 100644 --- a/nymea-app/ui/system/zwave/ZWaveNetworkPage.qml +++ b/nymea-app/ui/system/zwave/ZWaveNetworkPage.qml @@ -277,19 +277,25 @@ SettingsPageBase { paramsFilter: {"networkUuid": nodeDelegate.node.networkUuid, "nodeId": nodeDelegate.node.nodeId} } 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: node.productName + " - " + node.manufacturerName// nodeThing ? nodeThing.name : node.model subText: node.state == ZigbeeNode.ZigbeeNodeStateInitializing ? qsTr("Initializing...") : nodeThings.count == 1 ? nodeThing.name : - nodeThings.count > 1 ? qsTr("%1 things").arg(nodeThings.count) : qsTr("Unrecognized device") + nodeThings.count > 1 ? qsTr("%1 things").arg(nodeThings.count) + : node.nodeType == ZWaveNode.ZWaveNodeTypeStaticController || node.nodeType == ZWaveNode.ZWaveNodeTypeController + ? qsTr("Network controller") : qsTr("Unrecognized device") iconName: nodeThing ? app.interfacesToIcon(nodeThing.thingClass.interfaces) : "/ui/images/z-wave.svg" - iconColor: busy ? Style.tileOverlayColor - : node.failed ? Style.red - : nodeThing != null ? Style.accentColor - : Style.iconColor + iconColor: busy + ? Style.tileOverlayColor + : node.nodeType == ZWaveNode.ZWaveNodeTypeController || node.nodeType == ZWaveNode.ZWaveNodeTypeStaticController + ? Style.green + : node.failed + ? Style.red + : nodeThing != null + ? Style.accentColor + : Style.iconColor progressive: false busy: !node.initialized @@ -300,22 +306,22 @@ SettingsPageBase { dialog.open() } - secondaryIconName: node && !node.sleeping ? "/ui/images/system-suspend.svg" : "" + secondaryIconName: node && node.sleeping ? "/ui/images/system-suspend.svg" : "" tertiaryIconName: { if (!node || !node.reachable) return "/ui/images/connections/nm-signal-00.svg" - if (signalStrength <= 25) + if (node.linkQuality <= 25) return "/ui/images/connections/nm-signal-25.svg" - if (signalStrength <= 50) + if (node.linkQuality <= 50) return "/ui/images/connections/nm-signal-50.svg" - if (signalStrength <= 75) + if (node.linkQuality <= 75) return "/ui/images/connections/nm-signal-75.svg" - if (signalStrength <= 100) + if (node.linkQuality <= 100) return "/ui/images/connections/nm-signal-100.svg" } @@ -412,10 +418,31 @@ SettingsPageBase { } Label { Layout.fillWidth: true - text: nodeInfoDialog.node.deviceTypeString.replace(/ZWaveDeviceType/, "") + text: nodeInfoDialog.node.deviceTypeString font: Style.smallFont horizontalAlignment: Text.AlignRight } + Label { + text: qsTr("Node type:") + font: Style.smallFont + } + Label { + Layout.fillWidth: true + text: nodeInfoDialog.node.nodeTypeString + font: Style.smallFont + horizontalAlignment: Text.AlignRight + } + Label { + text: qsTr("Role:") + font: Style.smallFont + } + Label { + Layout.fillWidth: true + text: nodeInfoDialog.node.roleString + font: Style.smallFont + horizontalAlignment: Text.AlignRight + } + Label { text: qsTr("Z-Wave plus:") font: Style.smallFont @@ -432,7 +459,7 @@ SettingsPageBase { } Label { Layout.fillWidth: true - text: (nodeInfoDialog.node.lqi * 100 / 255).toFixed(0) + " %" + text: nodeInfoDialog.node.linkQuality + " %" font: Style.smallFont horizontalAlignment: Text.AlignRight } @@ -477,13 +504,11 @@ SettingsPageBase { Layout.fillWidth: true Button { - // size: Style.iconSize - visible: node && node.type !== ZigbeeNode.ZigbeeNodeTypeCoordinator - // imageSource: "/ui/images/delete.svg" + visible: node && node.nodeType !== ZWaveNode.ZWaveNodeTypeController && node.failed text: qsTr("Remove") Layout.alignment: Qt.AlignLeft onClicked: { - var dialog = removeZigbeeNodeDialogComponent.createObject(app, {zigbeeNode: node}) + var dialog = removeZWaveNodeDialogComponent.createObject(app, {zwaveNode: node}) dialog.open() nodeInfoDialog.close() }