Fixes for the energy dashboard for various corner cases

This commit is contained in:
Michael Zanetti 2022-09-15 17:43:43 +02:00
parent 0ba4b5b193
commit 32b2d42247
7 changed files with 92 additions and 75 deletions

View File

@ -190,7 +190,8 @@ EnergyLogEntry *EnergyLogs::find(const QDateTime &timestamp)
return nullptr;
}
QDateTime first = m_list.first()->timestamp();
int index = 1.0 * first.secsTo(timestamp) / (m_sampleRate * 60);
int index = qRound(1.0 * first.secsTo(timestamp) / (m_sampleRate * 60));
if (index < 0 || index >= m_list.count()) {
return nullptr;
}

View File

@ -113,20 +113,20 @@ MainViewBase {
columnSpacing: 0
CurrentConsumptionBalancePieChart {
Layout.fillWidth: true
Layout.preferredHeight: width
energyManager: energyManager
visible: producers.count > 0
animationsEnabled: Qt.application.active && root.isCurrentItem
}
CurrentProductionBalancePieChart {
Layout.fillWidth: true
Layout.preferredHeight: width
energyManager: energyManager
visible: producers.count > 0
animationsEnabled: Qt.application.active && root.isCurrentItem
}
// CurrentConsumptionBalancePieChart {
// Layout.fillWidth: true
// Layout.preferredHeight: width
// energyManager: energyManager
// visible: producers.count > 0
// animationsEnabled: Qt.application.active && root.isCurrentItem
// }
// CurrentProductionBalancePieChart {
// Layout.fillWidth: true
// Layout.preferredHeight: width
// energyManager: energyManager
// visible: producers.count > 0
// animationsEnabled: Qt.application.active && root.isCurrentItem
// }
PowerConsumptionBalanceHistory {
Layout.fillWidth: true
@ -134,46 +134,46 @@ MainViewBase {
visible: producers.count > 0
}
PowerProductionBalanceHistory {
Layout.fillWidth: true
Layout.preferredHeight: width
visible: producers.count > 0
}
// PowerProductionBalanceHistory {
// Layout.fillWidth: true
// Layout.preferredHeight: width
// visible: producers.count > 0
// }
ConsumersPieChart {
Layout.fillWidth: true
Layout.preferredHeight: width
energyManager: energyManager
visible: consumers.count > 0
colors: root.thingColors
consumers: consumers
animationsEnabled: Qt.application.active && root.isCurrentItem
}
// ConsumersPieChart {
// Layout.fillWidth: true
// Layout.preferredHeight: width
// energyManager: energyManager
// visible: consumers.count > 0
// colors: root.thingColors
// consumers: consumers
// animationsEnabled: Qt.application.active && root.isCurrentItem
// }
ConsumersHistory {
Layout.fillWidth: true
Layout.preferredHeight: width
visible: consumers.count > 0 || rootMeter != null
colors: root.thingColors
consumers: consumers
}
// ConsumersHistory {
// Layout.fillWidth: true
// Layout.preferredHeight: width
// visible: consumers.count > 0 || rootMeter != null
// colors: root.thingColors
// consumers: consumers
// }
PowerBalanceStats {
Layout.fillWidth: true
Layout.preferredHeight: width
energyManager: energyManager
visible: rootMeter != null || producers.count > 0
producers: producers
}
// PowerBalanceStats {
// Layout.fillWidth: true
// Layout.preferredHeight: width
// energyManager: energyManager
// visible: rootMeter != null || producers.count > 0
// producers: producers
// }
ConsumerStats {
Layout.fillWidth: true
Layout.preferredHeight: width
energyManager: energyManager
visible: consumers.count > 0
colors: root.thingColors
consumers: consumers
}
// ConsumerStats {
// Layout.fillWidth: true
// Layout.preferredHeight: width
// energyManager: energyManager
// visible: consumers.count > 0
// colors: root.thingColors
// consumers: consumers
// }
}
}
}

View File

@ -318,31 +318,37 @@ Item {
readonly property Thing thing: consumers.get(index)
property AreaSeries series: null
function getBaseValue(timestamp) {
var ret = 0
function calculateBaseValue(timestamp) {
if (index > 0) {
ret = consumersRepeater.itemAt(index - 1).getBaseValue(timestamp)
return consumersRepeater.itemAt(index - 1).calculateValue(timestamp)
}
return 0
}
function calculateValue(timestamp) {
var ret = calculateBaseValue(timestamp)
var entry = logs.find(timestamp)
if (entry) {
ret += entry.currentPower;
}
// print("calculating value for", thing.name, timestamp, ret)
return ret
}
function insertEntry(idx, entry) {
var baseValue = 0;
if (index > 0) {
baseValue = consumersRepeater.itemAt(index - 1).getBaseValue(entry.timestamp)
}
series.upperSeries.insert(idx, entry.timestamp.getTime(), entry.currentPower + baseValue)
// print("inserting entry for", thing.name, entry.timestamp)
var baseValue = calculateBaseValue(entry.timestamp);
series.lowerSeries.insert(idx, entry.timestamp.getTime(), baseValue)
series.upperSeries.insert(idx, entry.timestamp.getTime(), baseValue + entry.currentPower)
}
function addEntries(index, entries) {
print("adding entries for", thing.name)
// print("adding entries for", thing.name)
// Remove the leading 0-value entry
series.lowerSeries.removePoints(0, 1);
series.upperSeries.removePoints(0, 1);
for (var i = 0; i < entries.length; i++) {
@ -359,6 +365,7 @@ Item {
}
// Add the leading 0-value entry back
series.lowerSeries.insert(0, series.upperSeries.at(0).x, 0)
series.upperSeries.insert(0, series.upperSeries.at(0).x, 0)
}
@ -381,11 +388,14 @@ Item {
onEntriesRemoved: {
// Remove the leading 0-value entry
consumerDelegate.series.lowerSeries.removePoints(0, 1);
consumerDelegate.series.upperSeries.removePoints(0, 1);
consumerDelegate.series.lowerSeries.removePoints(index, count)
consumerDelegate.series.upperSeries.removePoints(index, count)
// Add the leading 0-value entry back
consumerDelegate.series.lowerSeries.insert(0, consumerDelegate.series.upperSeries.at(0).x, 0)
consumerDelegate.series.upperSeries.insert(0, consumerDelegate.series.upperSeries.at(0).x, 0)
zeroSeries.shrink()
@ -409,13 +419,14 @@ Item {
Component.onCompleted: {
series = chartView.createSeries(ChartView.SeriesTypeArea, thing.name, dateTimeAxis, valueAxis)
series.lowerSeries = index == 0 ? zeroSeries : consumersRepeater.itemAt(index - 1).series.upperSeries
series.lowerSeries = lineSeriesComponent.createObject(series)
series.upperSeries = lineSeriesComponent.createObject(series)
series.color = NymeaUtils.generateColor(Style.generationBaseColor, index)
series.borderWidth = 0;
series.borderColor = series.color
// Add a first point at 0 value
series.lowerSeries.insert(0, new Date().getTime(), 0)
series.upperSeries.insert(0, new Date().getTime(), 0)
}
@ -554,7 +565,7 @@ Item {
backgroundRect: Qt.rect(mouseArea.x + toolTip.x, mouseArea.y + toolTip.y, toolTip.width, toolTip.height)
property int idx: Math.min(d.visibleValues, Math.max(0, Math.ceil(mouseArea.mouseX * d.visibleValues / mouseArea.width)))
property date timestamp: new Date(d.startTime.getTime() + (idx * d.sampleRate * 60000))
property var timestamp: new Date(Math.min(d.endTime.getTime(), Math.max(d.startTime, d.startTime.getTime() + (idx * d.sampleRate * 60000))))
property PowerBalanceLogEntry entry: powerBalanceLogs.find(timestamp)
property int xOnRight: Math.max(0, mouseArea.mouseX) + Style.smallMargins
@ -574,7 +585,7 @@ Item {
margins: Style.smallMargins
}
Label {
text: toolTip.entry.timestamp.toLocaleString(Qt.locale(), Locale.ShortFormat)
text: toolTip.entry ? toolTip.entry.timestamp.toLocaleString(Qt.locale(), Locale.ShortFormat) : 0
font: Style.smallFont
}
RowLayout {

View File

@ -35,21 +35,26 @@ StatsBase {
onConfigChanged: valueAxis.max = 1
onStartOffsetChanged: {
print("start offset changed", startOffset)
// print("updating because of offset change. fetchingData", powerBalanceLogs.fetchingData, "fetchPending", d.fetchPending)
refresh()
}
onStartTimeChanged: {
print("start time changed", startTime)
}
function refresh() {
if (powerBalanceLogs.loadingInhibited) {
return;
}
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++) {
var timestamp = root.calculateTimestamp(d.config.startTime(), d.config.sampleRate, d.startOffset + i + 1)
var previousTimestamp = root.calculateTimestamp(timestamp, d.config.sampleRate, -1)
// print("timestamp:", timestamp)
var entry = powerBalanceLogs.find(timestamp)
print("timestamp:", timestamp, "found", (entry ? entry.timestamp : ""))
var previousEntry = powerBalanceLogs.find(previousTimestamp);
if (entry && (previousEntry || !d.loading)) {
// print("found entry:", entry.timestamp, previousEntry)
@ -246,10 +251,10 @@ StatsBase {
categories: {
var ret = []
print("Updating categories from", d.config.startTime())
// print("Updating categories from", d.config.startTime())
for (var i = 0; i < d.config.count; i++) {
var timestamp = root.calculateTimestamp(d.config.startTime(), d.config.sampleRate, d.startOffset + i);
print("*** adding", timestamp, d.startOffset, i)
// print("*** adding", timestamp, d.startOffset, i)
ret.push(d.config.toLabel(timestamp))
}
return ret;

View File

@ -162,7 +162,7 @@ Item {
ActivityIndicator {
x: chartView.plotArea.x + (chartView.plotArea.width - width) / 2
y: chartView.plotArea.y + (chartView.plotArea.height - height) / 2 + (chartView.plotArea.height / 8)
visible: powerBalanceLogs.fetchingData && powerBalanceLogs.get(0).timestamp > d.startTime
visible: powerBalanceLogs.fetchingData && (powerBalanceLogs.count == 0 || powerBalanceLogs.get(0).timestamp > d.startTime)
opacity: .5
}
Label {
@ -491,7 +491,7 @@ Item {
backgroundRect: Qt.rect(mouseArea.x + toolTip.x, mouseArea.y + toolTip.y, toolTip.width, toolTip.height)
property int idx: Math.min(d.visibleValues, Math.max(0, Math.ceil(mouseArea.mouseX * d.visibleValues / mouseArea.width)))
property var timestamp: new Date(d.startTime.getTime() + (idx * d.sampleRate * 60000))
property var timestamp: new Date(Math.min(d.endTime.getTime(), Math.max(d.startTime, d.startTime.getTime() + (idx * d.sampleRate * 60000))))
property PowerBalanceLogEntry entry: powerBalanceLogs.find(timestamp)
property int xOnRight: Math.max(0, mouseArea.mouseX) + Style.smallMargins
@ -511,7 +511,7 @@ Item {
margins: Style.smallMargins
}
Label {
text: toolTip.entry.timestamp.toLocaleString(Qt.locale(), Locale.ShortFormat)
text: toolTip.entry ? toolTip.entry.timestamp.toLocaleString(Qt.locale(), Locale.ShortFormat) : ""
font: Style.smallFont
}

View File

@ -160,7 +160,7 @@ Item {
ActivityIndicator {
x: chartView.plotArea.x + (chartView.plotArea.width - width) / 2
y: chartView.plotArea.y + (chartView.plotArea.height - height) / 2 + (chartView.plotArea.height / 8)
visible: powerBalanceLogs.fetchingData && powerBalanceLogs.get(0).timestamp > d.startTime
visible: powerBalanceLogs.fetchingData && (powerBalanceLogs.count == 0 || powerBalanceLogs.get(0).timestamp > d.startTime)
opacity: .5
}
Label {
@ -481,7 +481,7 @@ Item {
backgroundRect: Qt.rect(mouseArea.x + toolTip.x, mouseArea.y + toolTip.y, toolTip.width, toolTip.height)
property int idx: Math.min(d.visibleValues, Math.max(0, Math.ceil(mouseArea.mouseX * d.visibleValues / mouseArea.width)))
property var timestamp: new Date(d.startTime.getTime() + (idx * d.sampleRate * 60000))
property var timestamp: new Date(Math.min(d.endTime.getTime(), Math.max(d.startTime, d.startTime.getTime() + (idx * d.sampleRate * 60000))))
property PowerBalanceLogEntry entry: powerBalanceLogs.find(timestamp)
property int xOnRight: Math.max(0, mouseArea.mouseX) + Style.smallMargins

View File

@ -124,11 +124,11 @@ Item {
function weeksStart() {
var d = new Date();
d.setHours(0, 0, 0, 0);
print("now is:", d, "weeksCount:", weeksCount)
// print("now is:", d, "weeksCount:", weeksCount)
// We'll start the week on Monday for now, given that's international ISO standard. For US and Canada we may want to introduce a setting at some point.
// JS Date starts on Sunday though, so we'll have to adjust
var dayOfWeek = (d.getDay() + 6) % 7
print("getDay", d.getDay(), "dayOfWeek", dayOfWeek, "getDate", d.getDate())
// print("getDay", d.getDay(), "dayOfWeek", dayOfWeek, "getDate", d.getDate())
d.setDate(d.getDate() - dayOfWeek - (weeksCount - 1) * 7);
return d
}