Skip to content

Commit

Permalink
Reduce the effect of noise on power flow direction visualisation
Browse files Browse the repository at this point in the history
We visualise the direction of power flow with an icon and a colour
e.g. feed-in icon with green colour gauge, versus grid-draw icon
     with blue colour gauge.

This commit ensures that we don't flicker between feed-in and
grid-draw visualisation if the value is actually zero and the
readings are just noise, by requiring that the power value
exceeds a certain magnitude before we recognise it.

Contributes to #1328
  • Loading branch information
chriadam committed Jul 18, 2024
1 parent d56eea0 commit 9f60dd3
Show file tree
Hide file tree
Showing 5 changed files with 27 additions and 18 deletions.
10 changes: 6 additions & 4 deletions components/SideMultiGauge.qml
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,14 @@ Item {
delegate: Item {
id: gaugeDelegate

readonly property bool feedingToGrid: root.inputMode
&& (model.power || 0) < 0

width: Theme.geometry_briefPage_edgeGauge_width
height: root.height

// ignore noise values (close to zero)
readonly property real modelValue: Math.floor(Math.abs(model[root.phaseModelProperty] || 0)) < 1.0 ? 0.0
: model[root.phaseModelProperty]
readonly property bool feedingToGrid: root.inputMode && modelValue < 0.0

SideGauge {
id: gauge
animationEnabled: root.animationEnabled
Expand Down Expand Up @@ -93,7 +95,7 @@ Item {
// reverses the gauge direction so that negative and positive values have the same
// value on the gauge, though negative values will be drawn in green.
value: root.visible
? (gaugeDelegate.feedingToGrid ? Math.abs(model[root.phaseModelProperty]) : model[root.phaseModelProperty])
? (gaugeDelegate.feedingToGrid ? Math.abs(gaugeDelegate.modelValue) : gaugeDelegate.modelValue)
: root.minimumValue
minimumValue: 0
maximumValue: Math.max(Math.abs(root.minimumValue), Math.abs(root.maximumValue))
Expand Down
19 changes: 12 additions & 7 deletions components/ThreePhaseBarGauge.qml
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,16 @@ Flow {
id: phaseRepeater

delegate: Item {
id: phaseDelegate

width: root.orientation === Qt.Vertical ? root.width : root._delegateLength
height: root.orientation === Qt.Vertical ? root._delegateLength : root.height

// ignore noise values (close to zero)
readonly property real modelValue: Math.floor(Math.abs(model[root.phaseModelProperty] || 0)) < 1.0 ? 0.0
: model[root.phaseModelProperty]
readonly property bool feedingToGrid: root.inputMode && modelValue < 0.0

Label {
id: phaseLabel

Expand All @@ -53,7 +60,7 @@ Flow {
// reverses the gauge direction so that negative and positive values have the same
// value on the gauge, though negative values will be drawn in green.
value: root.visible
? gaugeLoader.feedingToGrid ? Math.abs(model[root.phaseModelProperty]) : model[root.phaseModelProperty]
? phaseDelegate.feedingToGrid ? Math.abs(phaseDelegate.modelValue) : phaseDelegate.modelValue
: root.minimumValue
minimumValue: 0
maximumValue: Math.max(Math.abs(root.minimumValue), Math.abs(root.maximumValue))
Expand All @@ -65,15 +72,13 @@ Flow {
width: parent.width - (phaseLabel.visible ? phaseLabel.width : 0)
height: parent.height
sourceComponent: Global.isGxDevice ? cheapGauge : prettyGauge
readonly property bool feedingToGrid: root.inputMode
&& (model.power || 0) < 0
}

Component {
id: cheapGauge
CheapBarGauge {
foregroundColor: Theme.color_darkOk,gaugeLoader.feedingToGrid ? Theme.color_green : Theme.statusColorValue(valueStatus)
backgroundColor: Theme.color_darkOk,gaugeLoader.feedingToGrid ? Theme.color_darkGreen
foregroundColor: Theme.color_darkOk,phaseDelegate.feedingToGrid ? Theme.color_green : Theme.statusColorValue(valueStatus)
backgroundColor: Theme.color_darkOk,phaseDelegate.feedingToGrid ? Theme.color_darkGreen
: root.inOverviewWidget && valueStatus === Theme.Ok ? Theme.color_darkishBlue
: Theme.statusColorValue(valueStatus, true)
valueType: root.valueType
Expand All @@ -86,8 +91,8 @@ Flow {
Component {
id: prettyGauge
BarGauge {
foregroundColor: Theme.color_darkOk,gaugeLoader.feedingToGrid ? Theme.color_green : Theme.statusColorValue(valueStatus)
backgroundColor: Theme.color_darkOk,gaugeLoader.feedingToGrid ? Theme.color_darkGreen
foregroundColor: Theme.color_darkOk,phaseDelegate.feedingToGrid ? Theme.color_green : Theme.statusColorValue(valueStatus)
backgroundColor: Theme.color_darkOk,phaseDelegate.feedingToGrid ? Theme.color_darkGreen
: root.inOverviewWidget && valueStatus === Theme.Ok ? Theme.color_darkishBlue
: Theme.statusColorValue(valueStatus, true)
valueType: root.valueType
Expand Down
7 changes: 5 additions & 2 deletions components/ThreePhaseDisplay.qml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,10 @@ Flow {
delegate: Item {
id: phaseDelegate

readonly property bool feedingToGrid: root.inputMode && (model.power || 0) < 0
// ignore noise values (close to zero)
readonly property real modelValue: Math.floor(Math.abs(model[root.phaseModelProperty] || 0)) < 1.0 ? 0.0
: model[root.phaseModelProperty]
readonly property bool feedingToGrid: root.inputMode && modelValue < 0.0
readonly property int valueStatus: feedingToGrid ? Theme.Ok
: root.phaseModelProperty ? Theme.getValueStatus(valueRange.valueAsRatio * 100, root.valueType)
: Theme.Ok
Expand Down Expand Up @@ -82,7 +85,7 @@ Flow {
ValueRange {
id: valueRange

value: root.phaseModelProperty ? model[root.phaseModelProperty] : 0
value: phaseDelegate.modelValue
minimumValue: root.minimumValue
maximumValue: root.maximumValue
}
Expand Down
2 changes: 1 addition & 1 deletion data/common/AcInputPhaseModel.qml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import Victron.VenusOS
ListModel {
id: root

property int totalPower
property real totalPower
property real firstPhaseCurrent: count === 1 ? get(0).current : NaN

readonly property Timer _timer: Timer { // timer needed so the display doesn't update too frequently
Expand Down
7 changes: 3 additions & 4 deletions data/common/ActiveAcInput.qml
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,14 @@ Device {
readonly property int source: !!inputInfo ? inputInfo.source : VenusOS.AcInputs_InputSource_NotAvailable
readonly property alias gensetStatusCode: _acInputService.gensetStatusCode

readonly property real power: _phases.totalPower
// clamp to zero any values with magnitude < 1 (assume it's noise) to avoid UI flicker.
readonly property real power: (Math.floor(Math.abs(_phases.totalPower)) < 1.0) ? 0.0 : _phases.totalPower
readonly property real current: phases.count === 1 ? _phases.firstPhaseCurrent : NaN // multi-phase systems don't have a total current
readonly property alias currentLimit: _acInputService.currentLimit
readonly property alias phases: _phases

// Phase measurements from com.victronenergy.system/Ac/ActiveIn/L<1|2|3>
readonly property AcInputPhaseModel _phases: AcInputPhaseModel {
id: _phases
}
readonly property AcInputPhaseModel _phases: AcInputPhaseModel { id: _phases }

// Data from the input-specific service, e.g. com.victronenergy.vebus for a VE.Bus input,
// or com.victronenergy.grid for grid parallel systems.
Expand Down

0 comments on commit 9f60dd3

Please sign in to comment.