Skip to content

Commit

Permalink
Use ObjectAcConnection to fetch /Ac/PvOn* phase totals
Browse files Browse the repository at this point in the history
The /Ac/PvOnGrid, /Ac/PvOnGenset and /Ac/PvOnOutput values may change
frequently, so the PvMonitor implementation was sub-optimal as it
re-calculated the phase totals for these values whenever a single
phase value was changed.

Use ObjectAcConnection to monitor these values instead, as that only
calculates the totals once per second.

Fixes #1908
  • Loading branch information
blammit committed Feb 17, 2025
1 parent 782c4c1 commit 4721818
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 50 deletions.
2 changes: 2 additions & 0 deletions components/ObjectAcConnection.qml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ QtObject {
property string bindPrefix
property string powerKey: "Power"
property string currentKey: "Current"
readonly property alias phaseCount: _phases.phaseCount

readonly property VeQuickItem powerL1: VeQuickItem {
uid: bindPrefix ? bindPrefix + "/L1/" + root.powerKey : ""
Expand Down Expand Up @@ -53,6 +54,7 @@ QtObject {
readonly property real current: _phaseCount.value === 1 && _currentL1.isValid ? _currentL1.value : NaN

readonly property PhaseModel phases: PhaseModel {
id: _phases
l2AndL1OutSummed: root.l2AndL1OutSummed
phaseCount: _phaseCount.value || 0
}
Expand Down
59 changes: 9 additions & 50 deletions data/common/PvMonitor.qml
Original file line number Diff line number Diff line change
Expand Up @@ -15,21 +15,15 @@ Instantiator {

// AC power is the total power from Ac/PvOnGrid/L*/Power, Ac/PvOnGenset/L*/Power
// and Ac/PvOnOutput/L*/Power.
function updateAcTotals() {
function _updateAcTotals() {
let _totalPower = NaN
let _totalCurrent = NaN

for (let i = 0; i < count; ++i) {
const acPv = objectAt(i)
if (!!acPv) {
for (let j = 0; j < acPv.pvPhases.count; ++j) {
const phase = acPv.pvPhases.objectAt(j)
if (!phase) {
continue
}
_totalPower = Units.sumRealNumbers(_totalPower, phase.power)
_totalCurrent = Units.sumRealNumbers(_totalCurrent, phase.current)
}
_totalPower = Units.sumRealNumbers(_totalPower, acPv.power)
_totalCurrent = Units.sumRealNumbers(_totalCurrent, acPv.current)
}
}
root.totalPower = _totalPower
Expand All @@ -53,48 +47,13 @@ Instantiator {
Global.system.serviceUid + "/Ac/PvOnOutput"
]

delegate: QtObject {
id: acPvDelegate
delegate: ObjectAcConnection {
required property string modelData

readonly property string serviceUid: modelData
readonly property int phaseCount: vePhaseCount.value || 0
bindPrefix: modelData

readonly property VeQuickItem vePhaseCount: VeQuickItem {
uid: acPvDelegate.serviceUid + "/NumberOfPhases"
onValueChanged: {
const phaseCount = value === undefined ? 0 : value
if (pvPhases.count !== phaseCount) {
pvPhases.model = phaseCount
Qt.callLater(root._updateMaximumPhaseCount)
}
}
}

// Each Ac/PvOnX uid has 1-3 phases with power and current, e.g. Ac/PvOnGrid/L1/Power,
// Ac/PvOnGrid/L1/Current
property var pvPhases: Instantiator {
model: null
delegate: QtObject {
id: phase

property real power: NaN
property real current: NaN

readonly property VeQuickItem vePower: VeQuickItem {
uid: acPvDelegate.serviceUid + "/L" + (model.index + 1) + "/Power"
onValueChanged: {
phase.power = value === undefined ? NaN : value
Qt.callLater(root.updateAcTotals)
}
}
readonly property VeQuickItem veCurrent: VeQuickItem {
uid: acPvDelegate.serviceUid + "/L" + (model.index + 1) + "/Current"
onValueChanged: {
phase.current = value === undefined ? NaN : value
Qt.callLater(root.updateAcTotals)
}
}
}
}
onPhaseCountChanged: Qt.callLater(root._updateMaximumPhaseCount)
onPowerChanged: Qt.callLater(root._updateAcTotals)
onCurrentChanged: Qt.callLater(root._updateAcTotals)
}
}

0 comments on commit 4721818

Please sign in to comment.