Fix destination node selection for Zigbee bindings
This commit is contained in:
parent
d6fe4d9249
commit
e95724b375
@ -49,12 +49,12 @@ StatsBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var upcomingTimestamp = root.calculateTimestamp(d.config.startTime(), d.config.sampleRate, d.config.count)
|
var upcomingTimestamp = root.calculateTimestamp(d.config.startTime(), d.config.sampleRate, d.config.count)
|
||||||
print("refreshing config start", d.config.startTime(), "upcoming:", upcomingTimestamp, "fetchPending", d.fetchPending)
|
// print("refreshing config start", d.config.startTime(), "upcoming:", upcomingTimestamp, "fetchPending", d.fetchPending)
|
||||||
for (var i = 0; i < d.config.count; i++) {
|
for (var i = 0; i < d.config.count; i++) {
|
||||||
var timestamp = root.calculateTimestamp(d.config.startTime(), d.config.sampleRate, d.startOffset + i + 1)
|
var timestamp = root.calculateTimestamp(d.config.startTime(), d.config.sampleRate, d.startOffset + i + 1)
|
||||||
var previousTimestamp = root.calculateTimestamp(timestamp, d.config.sampleRate, -1)
|
var previousTimestamp = root.calculateTimestamp(timestamp, d.config.sampleRate, -1)
|
||||||
var entry = powerBalanceLogs.find(timestamp)
|
var entry = powerBalanceLogs.find(timestamp)
|
||||||
print("timestamp:", timestamp, "found", (entry ? entry.timestamp : ""))
|
// print("timestamp:", timestamp, "found", (entry ? entry.timestamp : ""))
|
||||||
var previousEntry = powerBalanceLogs.find(previousTimestamp);
|
var previousEntry = powerBalanceLogs.find(previousTimestamp);
|
||||||
if (entry && (previousEntry || !d.loading)) {
|
if (entry && (previousEntry || !d.loading)) {
|
||||||
// print("found entry:", entry.timestamp, previousEntry)
|
// print("found entry:", entry.timestamp, previousEntry)
|
||||||
|
|||||||
@ -91,7 +91,8 @@ SettingsPageBase {
|
|||||||
|
|
||||||
NymeaItemDelegate {
|
NymeaItemDelegate {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
text: qsTr("Network topology")
|
text: qsTr("Network map")
|
||||||
|
visible: engine.jsonRpcClient.ensureServerVersion("6.2")
|
||||||
onClicked: {
|
onClicked: {
|
||||||
pageStack.push(Qt.resolvedUrl("ZigbeeNetworkTopologyPage.qml"), {zigbeeManager: root.zigbeeManager, network: root.network})
|
pageStack.push(Qt.resolvedUrl("ZigbeeNetworkTopologyPage.qml"), {zigbeeManager: root.zigbeeManager, network: root.network})
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,7 +8,7 @@ Page {
|
|||||||
id: root
|
id: root
|
||||||
|
|
||||||
header: NymeaHeader {
|
header: NymeaHeader {
|
||||||
text: qsTr("ZigBee network topology")
|
text: qsTr("ZigBee network map")
|
||||||
backButtonVisible: true
|
backButtonVisible: true
|
||||||
onBackPressed: pageStack.pop()
|
onBackPressed: pageStack.pop()
|
||||||
HeaderButton {
|
HeaderButton {
|
||||||
|
|||||||
@ -41,6 +41,7 @@ SettingsPageBase {
|
|||||||
property ZigbeeManager zigbeeManager: null
|
property ZigbeeManager zigbeeManager: null
|
||||||
property ZigbeeNetwork network: null
|
property ZigbeeNetwork network: null
|
||||||
property ZigbeeNode node: null
|
property ZigbeeNode node: null
|
||||||
|
readonly property ZigbeeNode coordinatorNode: root.network.nodes.getNodeByNetworkAddress(0)
|
||||||
|
|
||||||
header: NymeaHeader {
|
header: NymeaHeader {
|
||||||
text: qsTr("ZigBee node info")
|
text: qsTr("ZigBee node info")
|
||||||
@ -220,69 +221,92 @@ SettingsPageBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SettingsPageSectionHeader {
|
ColumnLayout {
|
||||||
text: qsTr("Bindings")
|
visible: engine.jsonRpcClient.ensureServerVersion("6.2")
|
||||||
}
|
|
||||||
|
|
||||||
property ZigbeeNode coordinatorNode: root.network.nodes.getNodeByNetworkAddress(0)
|
SettingsPageSectionHeader {
|
||||||
Repeater {
|
text: qsTr("Bindings")
|
||||||
model: root.node.bindings
|
}
|
||||||
delegate: NymeaSwipeDelegate {
|
|
||||||
id: bindingDelegate
|
|
||||||
Layout.fillWidth: true
|
|
||||||
property ZigbeeNodeBinding binding: root.node.bindings[index]
|
|
||||||
ThingsProxy {
|
|
||||||
id: destinationThings
|
|
||||||
engine: _engine
|
|
||||||
paramsFilter: {"ieeeAddress": bindingDelegate.binding.destinationAddress}
|
|
||||||
}
|
|
||||||
|
|
||||||
canDelete: true
|
Repeater {
|
||||||
progressive: false
|
model: root.node.bindings
|
||||||
text: {
|
delegate: NymeaSwipeDelegate {
|
||||||
if (destinationThings.count > 0) {
|
id: bindingDelegate
|
||||||
return destinationThings.get(0).name
|
Layout.fillWidth: true
|
||||||
|
property ZigbeeNodeBinding binding: root.node.bindings[index]
|
||||||
|
property ZigbeeNode destinationNode: root.network.nodes.getNode(binding.destinationAddress)
|
||||||
|
property ZigbeeNodeEndpoint endpoint: root.node.getEndpoint(binding.sourceEndpointId);
|
||||||
|
property ZigbeeCluster inputCluster: endpoint ? endpoint.getInputCluster(binding.clusterId) : null
|
||||||
|
property ZigbeeCluster outputCluster: endpoint ? endpoint.getOutputCluster(binding.clusterId) : null
|
||||||
|
property ZigbeeCluster usedCluster: inputCluster ? inputCluster : outputCluster
|
||||||
|
property Thing destinationThing: destinationThings.count > 0 ? destinationThings.get(0) : null
|
||||||
|
ThingsProxy {
|
||||||
|
id: destinationThings
|
||||||
|
engine: _engine
|
||||||
|
paramsFilter: {"ieeeAddress": bindingDelegate.binding.destinationAddress}
|
||||||
}
|
}
|
||||||
if (binding.destinationAddress != "") {
|
|
||||||
if (binding.destinationAddress == coordinatorNode.ieeeAddress) {
|
iconName: destinationNode && destinationNode == root.coordinatorNode
|
||||||
return Configuration.systemName
|
? "qrc:/styles/%1/logo.svg".arg(styleController.currentStyle)
|
||||||
|
: destinationThing
|
||||||
|
? app.interfacesToIcon(destinationThing.thingClass.interfaces)
|
||||||
|
: "/ui/images/zigbee.svg"
|
||||||
|
canDelete: true
|
||||||
|
progressive: false
|
||||||
|
text: {
|
||||||
|
if (binding.destinationAddress == "") {
|
||||||
|
return qsTr("Group: 0x%1").arg(NymeaUtils.pad(binding.groupAddress.toString(16), 4))
|
||||||
}
|
}
|
||||||
return binding.destinationAddress
|
var ret = ""
|
||||||
|
if (destinationNode) {
|
||||||
|
if (destinationNode == root.coordinatorNode) {
|
||||||
|
ret += Configuration.systemName
|
||||||
|
} else {
|
||||||
|
ret += destinationNode.model
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ret += binding.destinationAddress
|
||||||
|
}
|
||||||
|
|
||||||
|
if (destinationThings.count == 1) {
|
||||||
|
ret += " (" + destinationThings.get(0).name + ")"
|
||||||
|
} else if (destinationThings.count > 1) {
|
||||||
|
ret += " (" + destinationThing.count + " things)"
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
subText: {
|
||||||
|
var ret = usedCluster.clusterName();
|
||||||
|
if (binding.destinationAddress != "") {
|
||||||
|
ret += " (" + binding.sourceEndpointId + " -> " + binding.destinationEndpointId + ")"
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
onDeleteClicked: {
|
||||||
|
if (!node.rxOnWhenIdle) {
|
||||||
|
d.wakeupDialog = wakeupDialogComponent.createObject(root)
|
||||||
|
d.wakeupDialog.open()
|
||||||
|
}
|
||||||
|
d.pendingCommandId = zigbeeManager.removeBinding(network.networkUuid, binding)
|
||||||
}
|
}
|
||||||
return qsTr("Group: 0x%1").arg(NymeaUtils.pad(binding.groupAddress.toString(16), 4))
|
|
||||||
}
|
}
|
||||||
property ZigbeeNodeEndpoint endpoint: root.node.getEndpoint(binding.sourceEndpointId);
|
}
|
||||||
property ZigbeeCluster inputCluster: endpoint ? endpoint.getInputCluster(binding.clusterId) : null
|
|
||||||
property ZigbeeCluster outputCluster: endpoint ? endpoint.getOutputCluster(binding.clusterId) : null
|
Button {
|
||||||
property ZigbeeCluster usedCluster: inputCluster ? inputCluster : outputCluster
|
Layout.fillWidth: true
|
||||||
subText: {
|
Layout.leftMargin: Style.margins
|
||||||
var ret = usedCluster.clusterName();
|
Layout.rightMargin: Style.margins
|
||||||
if (binding.destinationAddress != "") {
|
text: qsTr("Add binding")
|
||||||
ret += " (" + binding.sourceEndpointId + " -> " + binding.destinationEndpointId + ")"
|
onClicked: {
|
||||||
}
|
var dialog = addBindingComponent.createObject(root)
|
||||||
return ret;
|
dialog.open()
|
||||||
}
|
|
||||||
onDeleteClicked: {
|
|
||||||
if (!node.rxOnWhenIdle) {
|
|
||||||
d.wakeupDialog = wakeupDialogComponent.createObject(root)
|
|
||||||
d.wakeupDialog.open()
|
|
||||||
}
|
|
||||||
d.pendingCommandId = zigbeeManager.removeBinding(network.networkUuid, binding)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Button {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.leftMargin: Style.margins
|
|
||||||
Layout.rightMargin: Style.margins
|
|
||||||
text: qsTr("Add binding")
|
|
||||||
onClicked: {
|
|
||||||
var dialog = addBindingComponent.createObject(root)
|
|
||||||
dialog.open()
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -382,27 +406,85 @@ SettingsPageBase {
|
|||||||
ComboBox {
|
ComboBox {
|
||||||
id: destinationNodeComboBox
|
id: destinationNodeComboBox
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
Layout.preferredHeight: Style.delegateHeight
|
||||||
model: network.nodes
|
model: network.nodes
|
||||||
displayText: currentDestinationNodeThings.count > 0
|
|
||||||
? currentDestinationNodeThings.get(0).name
|
|
||||||
: currentNode == root.coordinatorNode
|
|
||||||
? Configuration.systemName
|
|
||||||
: currentNode.model
|
|
||||||
property ZigbeeNode currentNode: network.nodes.get(currentIndex)
|
property ZigbeeNode currentNode: network.nodes.get(currentIndex)
|
||||||
|
property Thing currentNodeThing: currentNode && currentDestinationNodeThings.count > 0 ? currentDestinationNodeThings.get(0) : null
|
||||||
ThingsProxy {
|
ThingsProxy {
|
||||||
id: currentDestinationNodeThings
|
id: currentDestinationNodeThings
|
||||||
engine: _engine
|
engine: _engine
|
||||||
paramsFilter: {"ieeeAddress": destinationNodeDelegate.node.ieeeAddress}
|
paramsFilter: destinationNodeComboBox.currentNode ? {"ieeeAddress": destinationNodeComboBox.currentNode.ieeeAddress} : {}
|
||||||
}
|
}
|
||||||
delegate: ItemDelegate {
|
|
||||||
|
contentItem: RowLayout {
|
||||||
|
id: destinationNodeContentItem
|
||||||
|
width: parent.width - destinationNodeComboBox.indicator.width - Style.smallMargins
|
||||||
|
height: Style.delegateHeight
|
||||||
|
spacing: Style.smallMargins
|
||||||
|
|
||||||
|
ColorIcon {
|
||||||
|
Layout.leftMargin: Style.smallMargins
|
||||||
|
size: Style.iconSize
|
||||||
|
name: destinationNodeComboBox.currentNode == root.coordinatorNode
|
||||||
|
? "qrc:/styles/%1/logo.svg".arg(styleController.currentStyle)
|
||||||
|
: destinationNodeComboBox.currentNodeThing
|
||||||
|
? app.interfacesToIcon(destinationNodeComboBox.currentNodeThing.thingClass.interfaces)
|
||||||
|
: "/ui/images/zigbee.svg"
|
||||||
|
color: Style.accentColor
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
Label {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
text: destinationNodeComboBox.currentNode == root.coordinatorNode
|
||||||
|
? Configuration.systemName
|
||||||
|
: destinationNodeComboBox.currentNode.model + " - " + destinationNodeComboBox.currentNode.manufacturer
|
||||||
|
elide: Text.ElideRight
|
||||||
|
}
|
||||||
|
Label {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
text: destinationNodeComboBox.currentNode == root.coordinatorNode
|
||||||
|
? qsTr("Coordinator")
|
||||||
|
: currentDestinationNodeThings.count == 1
|
||||||
|
? destinationNodeComboBox.currentNodeThing.name
|
||||||
|
: currentDestinationNodeThings.count > 1
|
||||||
|
? qsTr("%1 things").arg(currentDestinationNodeThings.count)
|
||||||
|
: qsTr("Unrecognized device")
|
||||||
|
font: Style.smallFont
|
||||||
|
elide: Text.ElideRight
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// displayText: currentDestinationNodeThings.count > 0
|
||||||
|
// ? currentDestinationNodeThings.get(0).name
|
||||||
|
// : currentNode == root.coordinatorNode
|
||||||
|
// ? Configuration.systemName
|
||||||
|
// : currentNode.model
|
||||||
|
// ThingsProxy {
|
||||||
|
// id: currentDestinationNodeThings
|
||||||
|
// engine: _engine
|
||||||
|
// paramsFilter: {"ieeeAddress": destinationNodeComboBox.currentNode.ieeeAddress}
|
||||||
|
// }
|
||||||
|
delegate: NymeaItemDelegate {
|
||||||
id: destinationNodeDelegate
|
id: destinationNodeDelegate
|
||||||
property ZigbeeNode node: network.nodes.get(index)
|
property ZigbeeNode node: network.nodes.get(index)
|
||||||
|
property Thing nodeThing: destinationNodeThings.count > 0 ? destinationNodeThings.get(0) : null
|
||||||
|
iconName: node == coordinatorNode
|
||||||
|
? "qrc:/styles/%1/logo.svg".arg(styleController.currentStyle)
|
||||||
|
: nodeThing ? app.interfacesToIcon(nodeThing.thingClass.interfaces) : "/ui/images/zigbee.svg"
|
||||||
width: parent.width
|
width: parent.width
|
||||||
text: destinationNodeThings.count > 0
|
text: node == root.coordinatorNode
|
||||||
? destinationNodeThings.get(0).name
|
? Configuration.systemName
|
||||||
: node == root.coordinatorNode
|
: node.model + " - " + node.manufacturer
|
||||||
? Configuration.systemName
|
subText: node == root.coordinatorNode
|
||||||
: node.model
|
? qsTr("Coordinator")
|
||||||
|
: destinationNodeThings.count == 1
|
||||||
|
? nodeThing.name
|
||||||
|
: nodeThings.count > 1
|
||||||
|
? qsTr("%1 things").arg(nodeThings.count)
|
||||||
|
: qsTr("Unrecognized device")
|
||||||
|
progressive: false
|
||||||
|
|
||||||
ThingsProxy {
|
ThingsProxy {
|
||||||
id: destinationNodeThings
|
id: destinationNodeThings
|
||||||
engine: _engine
|
engine: _engine
|
||||||
|
|||||||
Reference in New Issue
Block a user