Some work on the energy view
This commit is contained in:
parent
47ea7087c4
commit
4a91dbd334
@ -36,7 +36,7 @@ import QtCharts 2.2
|
|||||||
import Nymea 1.0
|
import Nymea 1.0
|
||||||
|
|
||||||
ChartView {
|
ChartView {
|
||||||
id: chart
|
id: root
|
||||||
backgroundColor: Style.tileBackgroundColor
|
backgroundColor: Style.tileBackgroundColor
|
||||||
backgroundRoundness: Style.cornerRadius
|
backgroundRoundness: Style.cornerRadius
|
||||||
theme: ChartView.ChartThemeLight
|
theme: ChartView.ChartThemeLight
|
||||||
@ -45,16 +45,19 @@ ChartView {
|
|||||||
legend.alignment: Qt.AlignRight
|
legend.alignment: Qt.AlignRight
|
||||||
titleColor: Style.foregroundColor
|
titleColor: Style.foregroundColor
|
||||||
|
|
||||||
|
property Thing rootMeter: null
|
||||||
property ThingsProxy meters: null
|
property ThingsProxy meters: null
|
||||||
property int multiplier: 1
|
property int multiplier: 1
|
||||||
|
|
||||||
|
readonly property State rootMeterTotalConsumedEnergyState: rootMeter ? rootMeter.stateByName("totalEnergyConsumed") : null
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: meters
|
target: meters
|
||||||
onCountChanged: chart.refresh()
|
onCountChanged: root.refresh()
|
||||||
}
|
}
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
chart.refresh()
|
root.refresh()
|
||||||
}
|
}
|
||||||
|
|
||||||
QtObject {
|
QtObject {
|
||||||
@ -65,22 +68,28 @@ ChartView {
|
|||||||
function refresh() {
|
function refresh() {
|
||||||
pieSeries.clear();
|
pieSeries.clear();
|
||||||
d.sliceMap = {}
|
d.sliceMap = {}
|
||||||
|
|
||||||
|
var unknownConsumerEnergy = 0;
|
||||||
|
if (rootMeter) {
|
||||||
|
unknownConsumerEnergy = rootMeter.stateByName("totalEnergyConsumed").value
|
||||||
|
}
|
||||||
|
|
||||||
for (var i = 0; i < meters.count; i++) {
|
for (var i = 0; i < meters.count; i++) {
|
||||||
var thing = meters.get(i);
|
var thing = meters.get(i);
|
||||||
var value = 0;
|
var value = 0;
|
||||||
var totalConsumedStateType = thing.thingClass.stateTypes.findByName("totalEnergyConsumed")
|
var totalConsumedStateType = thing.thingClass.stateTypes.findByName("totalEnergyConsumed")
|
||||||
if (totalConsumedStateType) {
|
if (totalConsumedStateType) {
|
||||||
var totalConsumedState = thing.states.getState(totalConsumedStateType.id)
|
var totalConsumedState = thing.states.getState(totalConsumedStateType.id)
|
||||||
value = value + (totalConsumedState.value * chart.multiplier)
|
value = value + (totalConsumedState.value * root.multiplier)
|
||||||
}
|
}
|
||||||
var totalProducedStateType = thing.thingClass.stateTypes.findByName("totalEnergyProduced")
|
var totalProducedStateType = thing.thingClass.stateTypes.findByName("totalEnergyProduced")
|
||||||
if (totalProducedStateType) {
|
if (totalProducedStateType) {
|
||||||
var totalProducedState = thing.states.getState(totalProducedStateType.id)
|
var totalProducedState = thing.states.getState(totalProducedStateType.id)
|
||||||
value = value - (totalProducedState.value * chart.multiplier)
|
value = value - (totalProducedState.value * root.multiplier)
|
||||||
}
|
}
|
||||||
var slice = pieSeries.append(thing.name, Math.max(0, value))
|
var slice = pieSeries.append(thing.name, Math.max(0, value))
|
||||||
var color = Style.accentColor
|
var color = Style.accentColor
|
||||||
for (var j = 0; j < i; j+=2) {
|
for (var j = 0; j <= i; j+=2) {
|
||||||
if (i % 2 == 0) {
|
if (i % 2 == 0) {
|
||||||
color = Qt.lighter(color, 1.2);
|
color = Qt.lighter(color, 1.2);
|
||||||
} else {
|
} else {
|
||||||
@ -88,7 +97,13 @@ ChartView {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
slice.color = color
|
slice.color = color
|
||||||
d.sliceMap[slice] = i
|
d.sliceMap[slice] = thing
|
||||||
|
unknownConsumerEnergy -= value
|
||||||
|
}
|
||||||
|
if (rootMeter) {
|
||||||
|
var slice = pieSeries.append(qsTr("Unknown"), unknownConsumerEnergy)
|
||||||
|
slice.color = Style.accentColor
|
||||||
|
d.sliceMap[slice] = rootMeter
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -98,24 +113,29 @@ ChartView {
|
|||||||
size: 0.8
|
size: 0.8
|
||||||
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
print("clicked slice", slice, d.sliceMap[slice], meters.get(d.sliceMap[slice]))
|
print("clicked slice", slice, d.sliceMap[slice], d.sliceMap[slice].name)
|
||||||
pageStack.push("../devicepages/SmartMeterDevicePage.qml", {thing: meters.get(d.sliceMap[slice])})
|
pageStack.push("../devicepages/SmartMeterDevicePage.qml", {thing: d.sliceMap[slice]})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
x: chart.plotArea.x + (chart.plotArea.width * 0.5) - (width / 2)
|
x: root.plotArea.x + (root.plotArea.width * 0.5) - (width / 2)
|
||||||
y: chart.plotArea.y + (chart.plotArea.height * 0.5) - (height / 2)
|
y: root.plotArea.y + (root.plotArea.height * 0.5) - (height / 2)
|
||||||
|
width: root.width
|
||||||
|
|
||||||
Label {
|
Label {
|
||||||
font.pixelSize: app.largeFont
|
font.pixelSize: app.largeFont
|
||||||
Layout.alignment: Qt.AlignHCenter
|
Layout.fillWidth: true
|
||||||
text: Math.round(pieSeries.sum * 1000) / 1000
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
text: root.rootMeter
|
||||||
|
? root.rootMeterTotalConsumedEnergyState.value.toFixed(2)
|
||||||
|
: Math.round(pieSeries.sum * 1000) / 1000
|
||||||
}
|
}
|
||||||
|
|
||||||
Label {
|
Label {
|
||||||
text: "KWh"
|
text: "KWh"
|
||||||
Layout.alignment: Qt.AlignHCenter
|
Layout.fillWidth: true
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -104,7 +104,7 @@ ThingsListPageBase {
|
|||||||
Label {
|
Label {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
text: sensorValueDelegate.stateValue
|
text: sensorValueDelegate.stateValue
|
||||||
? "%1 %2".arg(1.0 * Math.round(Types.toUiValue(sensorValueDelegate.stateValue.value, sensorValueDelegate.stateType.unit) * 100000) / 100000).arg(Types.toUiUnit(sensorValueDelegate.stateType.unit))
|
? "%1 %2".arg((1.0 * Math.round(Types.toUiValue(sensorValueDelegate.stateValue.value, sensorValueDelegate.stateType.unit) * 100000) / 100000).toFixed(3)).arg(Types.toUiUnit(sensorValueDelegate.stateType.unit))
|
||||||
: ""
|
: ""
|
||||||
elide: Text.ElideRight
|
elide: Text.ElideRight
|
||||||
verticalAlignment: Text.AlignVCenter
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
|||||||
@ -40,11 +40,18 @@ import "../delegates"
|
|||||||
MainViewBase {
|
MainViewBase {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
|
ThingsProxy {
|
||||||
|
id: energyMeters
|
||||||
|
engine: _engine
|
||||||
|
shownInterfaces: ["energymeter"]
|
||||||
|
}
|
||||||
|
|
||||||
ThingsProxy {
|
ThingsProxy {
|
||||||
id: consumers
|
id: consumers
|
||||||
engine: _engine
|
engine: _engine
|
||||||
shownInterfaces: ["smartmeterconsumer"]
|
shownInterfaces: ["smartmeterconsumer"]
|
||||||
}
|
}
|
||||||
|
|
||||||
ThingsProxy {
|
ThingsProxy {
|
||||||
id: producers
|
id: producers
|
||||||
engine: _engine
|
engine: _engine
|
||||||
@ -55,11 +62,11 @@ MainViewBase {
|
|||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: app.margins / 2
|
anchors.margins: app.margins / 2
|
||||||
contentHeight: energyGrid.childrenRect.height
|
contentHeight: energyGrid.childrenRect.height
|
||||||
|
visible: energyMeters.count > 0
|
||||||
|
|
||||||
GridLayout {
|
GridLayout {
|
||||||
id: energyGrid
|
id: energyGrid
|
||||||
width: parent.width
|
width: parent.width
|
||||||
visible: consumers.count > 0
|
|
||||||
columns: root.width > 600 ? 2 : 1
|
columns: root.width > 600 ? 2 : 1
|
||||||
rowSpacing: 0
|
rowSpacing: 0
|
||||||
columnSpacing: 0
|
columnSpacing: 0
|
||||||
@ -68,6 +75,8 @@ MainViewBase {
|
|||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
// Layout.preferredWidth: energyGrid.width / energyGrid.columns
|
// Layout.preferredWidth: energyGrid.width / energyGrid.columns
|
||||||
Layout.preferredHeight: width * .7
|
Layout.preferredHeight: width * .7
|
||||||
|
// FIXME: multiple root meters... Not exactly a use case, still possible tho
|
||||||
|
rootMeter: energyMeters.count > 0 ? energyMeters.get(0) : null
|
||||||
meters: consumers
|
meters: consumers
|
||||||
title: qsTr("Total consumed energy")
|
title: qsTr("Total consumed energy")
|
||||||
visible: consumers.count > 0
|
visible: consumers.count > 0
|
||||||
@ -183,7 +192,7 @@ MainViewBase {
|
|||||||
ValueAxis {
|
ValueAxis {
|
||||||
id: yAxis
|
id: yAxis
|
||||||
readonly property XYSeriesAdapter adapter: consumersRepeater.count > 0 ? consumersRepeater.itemAt(consumersRepeater.count - 1).adapter : null
|
readonly property XYSeriesAdapter adapter: consumersRepeater.count > 0 ? consumersRepeater.itemAt(consumersRepeater.count - 1).adapter : null
|
||||||
max: adapter ? Math.ceil(Math.max(adapter.maxValue * 0.95, adapter.maxValue * 1.05)) : 1
|
max: 7// adapter ? Math.ceil(Math.max(adapter.maxValue * 0.95, adapter.maxValue * 1.05)) : 1
|
||||||
min: adapter ? Math.floor(Math.min(adapter.minValue * 0.95, adapter.minValue * 1.05)) : 0
|
min: adapter ? Math.floor(Math.min(adapter.minValue * 0.95, adapter.minValue * 1.05)) : 0
|
||||||
// This seems to crash occationally
|
// This seems to crash occationally
|
||||||
// onMinChanged: applyNiceNumbers();
|
// onMinChanged: applyNiceNumbers();
|
||||||
@ -360,6 +369,7 @@ MainViewBase {
|
|||||||
Layout.preferredHeight: width * .7
|
Layout.preferredHeight: width * .7
|
||||||
backgroundColor: Style.tileBackgroundColor
|
backgroundColor: Style.tileBackgroundColor
|
||||||
backgroundRoundness: Style.cornerRadius
|
backgroundRoundness: Style.cornerRadius
|
||||||
|
rootMeter: energyMeters.count > 0 ? energyMeters.get(0) : null
|
||||||
meters: producers
|
meters: producers
|
||||||
title: qsTr("Total produced energy")
|
title: qsTr("Total produced energy")
|
||||||
visible: producers.count > 0
|
visible: producers.count > 0
|
||||||
@ -371,9 +381,9 @@ MainViewBase {
|
|||||||
EmptyViewPlaceholder {
|
EmptyViewPlaceholder {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
width: parent.width - app.margins * 2
|
width: parent.width - app.margins * 2
|
||||||
visible: !engine.thingManager.fetchingData && consumers.count == 0
|
visible: !engine.thingManager.fetchingData && energyMeters.count == 0
|
||||||
title: qsTr("There are no energy meters installed.")
|
title: qsTr("There are no energy meters installed.")
|
||||||
text: qsTr("To get an overview of your current energy usage, install some energy meters.")
|
text: qsTr("To get an overview of your current energy usage, install an energy meter.")
|
||||||
imageSource: "../images/smartmeter.svg"
|
imageSource: "../images/smartmeter.svg"
|
||||||
buttonText: qsTr("Add things")
|
buttonText: qsTr("Add things")
|
||||||
onButtonClicked: pageStack.push(Qt.resolvedUrl("../thingconfiguration/NewThingPage.qml"))
|
onButtonClicked: pageStack.push(Qt.resolvedUrl("../thingconfiguration/NewThingPage.qml"))
|
||||||
|
|||||||
Reference in New Issue
Block a user