Improve energy pages
This commit is contained in:
parent
a4336ae1c0
commit
dc399f28ae
@ -330,7 +330,7 @@ void LogsModel::fetchMore(const QModelIndex &parent)
|
||||
Q_UNUSED(parent)
|
||||
|
||||
if (!m_engine) {
|
||||
qCWarning(dcLogEngine()) << objectName() << "Cannot update. Engine not set";
|
||||
qCDebug(dcLogEngine()) << objectName() << "Cannot update yet. Engine not set";
|
||||
return;
|
||||
}
|
||||
if (m_busyInternal) {
|
||||
|
||||
@ -257,5 +257,6 @@
|
||||
<file>ui/components/CircleBackground.qml</file>
|
||||
<file>ui/devicepages/CoolingThingPage.qml</file>
|
||||
<file>ui/devicepages/EvChargerThingPage.qml</file>
|
||||
<file>ui/components/BlurredLabel.qml</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
||||
@ -91,7 +91,8 @@ Item {
|
||||
"o2sensor": "lightblue",
|
||||
"orpsensor": "yellow",
|
||||
"powersocket": "aquamarine",
|
||||
"evcharger": "limegreen"
|
||||
"evcharger": "limegreen",
|
||||
"energystorage": "limegreen"
|
||||
}
|
||||
|
||||
property var stateColors: {
|
||||
@ -111,4 +112,5 @@ Item {
|
||||
readonly property int fastAnimationDuration: 100
|
||||
readonly property int animationDuration: 150
|
||||
readonly property int slowAnimationDuration: 300
|
||||
readonly property int sleepyAnimationDuration: 2000
|
||||
}
|
||||
|
||||
37
nymea-app/ui/components/BlurredLabel.qml
Normal file
37
nymea-app/ui/components/BlurredLabel.qml
Normal file
@ -0,0 +1,37 @@
|
||||
import QtQuick 2.5
|
||||
import QtQuick.Controls 2.1
|
||||
import QtGraphicalEffects 1.0
|
||||
import Nymea 1.0
|
||||
|
||||
Item {
|
||||
id: root
|
||||
implicitWidth: label.implicitWidth + Style.margins * 2
|
||||
implicitHeight: label.implicitHeight + Style.margins * 2
|
||||
|
||||
property alias text: label.text
|
||||
property alias wrapMode: label.wrapMode
|
||||
property alias horizontalAlignment: label.horizontalAlignment
|
||||
property alias textFormat: label.textFormat
|
||||
|
||||
property bool blurred: false
|
||||
|
||||
Label {
|
||||
id: label
|
||||
anchors.fill: parent
|
||||
}
|
||||
|
||||
ShaderEffectSource {
|
||||
id: effectSource
|
||||
anchors.fill: parent
|
||||
sourceItem: label
|
||||
hideSource: true
|
||||
visible: false
|
||||
}
|
||||
|
||||
FastBlur {
|
||||
anchors.fill: parent
|
||||
source: effectSource
|
||||
radius: root.blurred ? 32 : 0
|
||||
Behavior on radius { NumberAnimation { duration: Style.animationDuration } }
|
||||
}
|
||||
}
|
||||
@ -56,6 +56,13 @@ Item {
|
||||
radius: width / 2
|
||||
color: Style.tileBackgroundColor
|
||||
}
|
||||
Rectangle {
|
||||
id: mask
|
||||
anchors.fill: background
|
||||
radius: height / 2
|
||||
visible: false
|
||||
color: "red"
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: background
|
||||
@ -85,7 +92,7 @@ Item {
|
||||
opacity: root.on ? 1 : 0
|
||||
anchors.fill: gradient
|
||||
source: gradient
|
||||
maskSource: background
|
||||
maskSource: mask
|
||||
Behavior on opacity { NumberAnimation { duration: Style.animationDuration } }
|
||||
|
||||
}
|
||||
|
||||
@ -40,6 +40,7 @@ import QtCharts 2.2
|
||||
Item {
|
||||
id: root
|
||||
implicitHeight: width * .6
|
||||
implicitWidth: 400
|
||||
|
||||
property Thing thing: null
|
||||
property StateType stateType: null
|
||||
|
||||
@ -66,52 +66,71 @@ ThingsListPageBase {
|
||||
thing: root.thingsProxy.getThing(model.id)
|
||||
|
||||
onClicked: {
|
||||
enterPage(index)
|
||||
enterPage(index, ["energystorage", "smartmeter"])
|
||||
}
|
||||
contentItem: GridLayout {
|
||||
contentItem: RowLayout {
|
||||
id: dataGrid
|
||||
columns: Math.floor(contentItem.width / 120)
|
||||
|
||||
Repeater {
|
||||
model: ListModel {
|
||||
Component.onCompleted: {
|
||||
if (itemDelegate.thing.thingClass.stateTypes.findByName("totalEnergyConsumed") !== null) {
|
||||
append( {stateName: "totalEnergyConsumed" })
|
||||
property State currentPowerState: itemDelegate.thing.stateByName("currentPower")
|
||||
property bool isEnergyMeter: itemDelegate.thing.thingClass.interfaces.indexOf("energymeter") >= 0
|
||||
property bool isBattery: itemDelegate.thing.thingClass.interfaces.indexOf("energystorage") >= 0
|
||||
property bool isEvCharger: itemDelegate.thing.thingClass.interfaces.indexOf("evcharger") >= 0
|
||||
property bool isProducer: itemDelegate.thing.thingClass.interfaces.indexOf("smartmeterproducer") >= 0
|
||||
property bool isConsumer: itemDelegate.thing.thingClass.interfaces.indexOf("smartmeterconsumer") >= 0
|
||||
property bool isProduction: currentPowerState.value < 0
|
||||
property bool isConsumption: currentPowerState.value > 0
|
||||
property double absValue: Math.abs(currentPowerState.value)
|
||||
property double cleanVale: (absValue / (absValue > 1000 ? 1000 : 1)).toFixed(1)
|
||||
property string unit: absValue > 1000 ? "kW" : "W"
|
||||
|
||||
ColorIcon {
|
||||
name: app.stateIcon("currentPower")
|
||||
color: app.stateColor("currentPower")
|
||||
size: Style.iconSize
|
||||
}
|
||||
|
||||
Label {
|
||||
Layout.fillWidth: true
|
||||
text: {
|
||||
if (dataGrid.isEnergyMeter) {
|
||||
if (dataGrid.isProduction) {
|
||||
return qsTr("%1 %2 returning").arg(dataGrid.cleanVale).arg(dataGrid.unit)
|
||||
} else {
|
||||
return qsTr("%1 %2 obtaining").arg(dataGrid.cleanVale).arg(dataGrid.unit)
|
||||
}
|
||||
if (itemDelegate.thing.thingClass.stateTypes.findByName("totalEnergyProduced") !== null) {
|
||||
append( {stateName: "totalEnergyProduced" })
|
||||
|
||||
} else if (dataGrid.isBattery || dataGrid.isEvCharger) {
|
||||
if (dataGrid.isProduction) {
|
||||
return qsTr("%1 %2 discharging").arg(dataGrid.cleanVale).arg(dataGrid.unit)
|
||||
} else {
|
||||
return qsTr("%1 %2 charging").arg(dataGrid.cleanVale).arg(dataGrid.unit)
|
||||
}
|
||||
if (itemDelegate.thing.thingClass.stateTypes.findByName("currentPower") !== null) {
|
||||
append({stateName: "currentPower"});
|
||||
|
||||
} else if (dataGrid.isProducer && !dataGrid.isConsumer) {
|
||||
if (dataGrid.isProduction) {
|
||||
return qsTr("%1 %2 producing").arg(dataGrid.cleanVale).arg(dataGrid.unit)
|
||||
} else {
|
||||
return qsTr("%1 %2 idling").arg(Math.max(0, dataGrid.cleanVale)).arg(dataGrid.unit)
|
||||
}
|
||||
|
||||
} else if (dataGrid.isConsumer && !dataGrid.isProducer) {
|
||||
if (dataGrid.isProduction) {
|
||||
return qsTr("%1 %2 idling").arg(Math.max(0, dataGrid.cleanVale)).arg(dataGrid.unit)
|
||||
} else {
|
||||
return qsTr("%1 %2 consuming").arg(dataGrid.cleanVale).arg(dataGrid.unit)
|
||||
}
|
||||
|
||||
} else {
|
||||
if (dataGrid.isProduction) {
|
||||
return qsTr("%1 %2 producing").arg(dataGrid.cleanVale).arg(dataGrid.unit)
|
||||
} else {
|
||||
return qsTr("%1 %2 consuming").arg(dataGrid.cleanVale).arg(dataGrid.unit)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
delegate: RowLayout {
|
||||
id: sensorValueDelegate
|
||||
Layout.preferredWidth: contentItem.width / dataGrid.columns
|
||||
|
||||
property StateType stateType: itemDelegate.thing.thingClass.stateTypes.findByName(model.stateName)
|
||||
property State stateValue: stateType ? itemDelegate.thing.states.getState(stateType.id) : null
|
||||
|
||||
ColorIcon {
|
||||
Layout.preferredHeight: Style.iconSize
|
||||
Layout.preferredWidth: height
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
color: app.stateColor(model.stateName)
|
||||
name: app.stateIcon(model.stateName)
|
||||
}
|
||||
|
||||
Label {
|
||||
Layout.fillWidth: true
|
||||
text: sensorValueDelegate.stateValue
|
||||
? "%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
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
font.pixelSize: app.smallFont
|
||||
}
|
||||
}
|
||||
elide: Text.ElideRight
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
font.pixelSize: app.smallFont
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -44,9 +44,14 @@ Page {
|
||||
|
||||
property ThingsProxy thingsProxy: thingsProxyInternal
|
||||
|
||||
function enterPage(index) {
|
||||
function enterPage(index, interfaces) {
|
||||
if (interfaces === undefined) {
|
||||
interfaces = root.shownInterfaces
|
||||
}
|
||||
|
||||
var thing = thingsProxy.get(index);
|
||||
var page = NymeaUtils.interfaceListToDevicePage(root.shownInterfaces);
|
||||
print("matching interfaces", interfaces)
|
||||
var page = NymeaUtils.interfaceListToDevicePage(interfaces);
|
||||
pageStack.push(Qt.resolvedUrl("../devicepages/" + page), {thing: thingsProxy.get(index)})
|
||||
}
|
||||
|
||||
|
||||
@ -236,6 +236,8 @@ Page {
|
||||
return boolComponent;
|
||||
case "color":
|
||||
return colorComponent
|
||||
case "double":
|
||||
return floatLabelComponent;
|
||||
default:
|
||||
if (entryDelegate.stateType.unit == Types.UnitUnixTime) {
|
||||
return dateTimeComponent
|
||||
@ -278,6 +280,17 @@ Page {
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: floatLabelComponent
|
||||
Label {
|
||||
property double value
|
||||
property string unitString
|
||||
text: value.toFixed(value > 1000 ? 0 : 2) + " " + unitString
|
||||
font.pixelSize: app.smallFont
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: dateTimeComponent
|
||||
Label {
|
||||
|
||||
@ -31,6 +31,7 @@
|
||||
import QtQuick 2.5
|
||||
import QtQuick.Controls 2.1
|
||||
import QtQuick.Layouts 1.1
|
||||
import QtGraphicalEffects 1.0
|
||||
import Nymea 1.0
|
||||
import "../components"
|
||||
import "../customviews"
|
||||
@ -38,75 +39,232 @@ import "../customviews"
|
||||
ThingPageBase {
|
||||
id: root
|
||||
|
||||
readonly property State totalEnergyConsumedState: root.thing.stateByName("totalEnergyConsumed")
|
||||
readonly property StateType totalEnergyConsumedStateType: root.thing.thingClass.stateTypes.findByName("totalEnergyConsumed")
|
||||
readonly property State totalEnergyProducedState: root.thing.stateByName("totalEnergyProduced")
|
||||
readonly property StateType totalEnergyProducedStateType: root.thing.thingClass.stateTypes.findByName("totalEnergyProduced")
|
||||
readonly property bool isEnergyMeter: root.thing && root.thing.thingClass.interfaces.indexOf("energymeter") >= 0
|
||||
readonly property bool isConsumer: root.thing && root.thing.thingClass.interfaces.indexOf("smartmeterconsumer") >= 0
|
||||
readonly property bool isProducer: root.thing && root.thingClass.interfaces.indexOf("smartmeterproducer") >= 0
|
||||
readonly property bool isBattery: root.thing && root.thingClass.interfaces.indexOf("energystorage") >= 0
|
||||
|
||||
Flickable {
|
||||
|
||||
readonly property State currentPowerState: root.thing.stateByName("currentPower")
|
||||
|
||||
// meters, producers, consumers
|
||||
readonly property State totalEnergyConsumedState: isEnergyMeter || isConsumer ? root.thing.stateByName("totalEnergyConsumed") : null
|
||||
readonly property StateType totalEnergyConsumedStateType: isEnergyMeter || isConsumer ? root.thing.thingClass.stateTypes.findByName("totalEnergyConsumed") : null
|
||||
readonly property State totalEnergyProducedState: isEnergyMeter || isProducer ? root.thing.stateByName("totalEnergyProduced") : null
|
||||
readonly property StateType totalEnergyProducedStateType: isEnergyMeter || isProducer ? root.thing.thingClass.stateTypes.findByName("totalEnergyProduced") : null
|
||||
|
||||
// Battery related states
|
||||
readonly property State batteryLevelState: isBattery ? root.thing.stateByName("batteryLevel") : null
|
||||
readonly property State batteryCriticalState: isBattery ? root.thing.stateByName("batteryCritical") : null
|
||||
readonly property State chargingState: isBattery ? root.thing.stateByName("chargingState") : null
|
||||
readonly property State capacityState: isBattery ? root.thing.stateByName("capacity") : null
|
||||
|
||||
|
||||
|
||||
readonly property real currentPower: currentPowerState ? currentPowerState.value : 0
|
||||
|
||||
readonly property date now: d.now
|
||||
readonly property date startTime: new Date(now.getTime() - 24 * 60 * 60 * 1000)
|
||||
|
||||
QtObject {
|
||||
id: d
|
||||
property date now: new Date()
|
||||
}
|
||||
Timer {
|
||||
interval: 60000
|
||||
repeat: true
|
||||
running: true
|
||||
onTriggered: d.now = new Date()
|
||||
}
|
||||
|
||||
GridLayout {
|
||||
id: contentGrid
|
||||
anchors.fill: parent
|
||||
topMargin: app.margins / 2
|
||||
contentHeight: contentGrid.height
|
||||
interactive: contentHeight > height
|
||||
columns: app.landscape ? 2 : 1
|
||||
|
||||
GridLayout {
|
||||
id: contentGrid
|
||||
width: parent.width - app.margins
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
columns: 1
|
||||
CircleBackground {
|
||||
id: background
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: width
|
||||
Layout.leftMargin: app.landscape ? Style.margins : Style.hugeMargins
|
||||
Layout.rightMargin: Style.hugeMargins
|
||||
Layout.topMargin: Style.hugeMargins
|
||||
Layout.bottomMargin: app.landscape ? Style.hugeMargins : Style.margins
|
||||
iconSource: ""
|
||||
onColor: batteryLevelState
|
||||
? currentPower < 0 ? "crimson" : "limegreen"
|
||||
: currentPower < 0 ? "limegreen" : "crimson"
|
||||
|
||||
BigTile {
|
||||
Layout.preferredWidth: contentGrid.width / contentGrid.columns
|
||||
showHeader: true
|
||||
header: Label {
|
||||
text: qsTr("Total energy consumption")
|
||||
}
|
||||
|
||||
onPressAndHold: {
|
||||
var contextMenuComponent = Qt.createComponent("../components/ThingContextMenu.qml");
|
||||
var contextMenu = contextMenuComponent.createObject(root, { thing: root.thing })
|
||||
contextMenu.x = Qt.binding(function() { return (root.width - contextMenu.width) / 2 })
|
||||
contextMenu.open()
|
||||
}
|
||||
|
||||
contentItem: RowLayout {
|
||||
ColorIcon {
|
||||
Layout.preferredHeight: Style.iconSize
|
||||
Layout.preferredWidth: Style.iconSize
|
||||
name: app.stateIcon("totalEnergyConsumed")
|
||||
color: app.stateColor("totalEnergyConsumed")
|
||||
}
|
||||
|
||||
Label {
|
||||
Layout.fillWidth: true
|
||||
text: root.totalEnergyConsumedState.value.toFixed(2) + " " + root.totalEnergyConsumedStateType.unitString
|
||||
font.pixelSize: app.largeFont
|
||||
}
|
||||
ColorIcon {
|
||||
Layout.preferredHeight: Style.iconSize
|
||||
Layout.preferredWidth: Style.iconSize
|
||||
name: app.stateIcon("totalEnergyProduced")
|
||||
color: app.stateColor("totalEnergyProduced")
|
||||
visible: root.totalEnergyProducedState !== null
|
||||
}
|
||||
|
||||
Label {
|
||||
Layout.fillWidth: true
|
||||
text: root.totalEnergyProducedState.value.toFixed(2) + " " + root.totalEnergyProducedStateType.unitString
|
||||
font.pixelSize: app.largeFont
|
||||
visible: root.totalEnergyProducedState !== null
|
||||
}
|
||||
}
|
||||
Rectangle {
|
||||
id: mask
|
||||
anchors.centerIn: parent
|
||||
width: background.contentItem.width
|
||||
height: background.contentItem.height
|
||||
radius: width / 2
|
||||
visible: false
|
||||
}
|
||||
|
||||
GenericTypeGraph {
|
||||
Layout.preferredWidth: contentGrid.width / contentGrid.columns
|
||||
thing: root.thing
|
||||
stateType: root.thingClass.stateTypes.findByName("currentPower")
|
||||
color: app.stateColor("currentPower")
|
||||
iconSource: app.stateIcon("currentPower")
|
||||
roundTo: 5
|
||||
Item {
|
||||
id: juice
|
||||
anchors.fill: parent
|
||||
|
||||
Rectangle {
|
||||
anchors.centerIn: parent
|
||||
width: background.contentItem.width
|
||||
height: background.contentItem.height
|
||||
property real progress: root.batteryLevelState ? root.batteryLevelState.value / 100 : 0
|
||||
anchors.verticalCenterOffset: height * (1 - progress)
|
||||
color: batteryCriticalState && batteryCriticalState.value ? "crimson" : "limegreen"
|
||||
visible: root.batteryLevelState
|
||||
}
|
||||
|
||||
RadialGradient {
|
||||
id: gradient
|
||||
anchors.centerIn: parent
|
||||
width: background.contentItem.width
|
||||
height: background.contentItem.height
|
||||
property real progress: Math.abs(root.currentPower) / 10000
|
||||
visible: currentPower != 0
|
||||
|
||||
Behavior on gradientRatio { NumberAnimation { duration: Style.sleepyAnimationDuration; easing.type: Easing.InOutQuad } }
|
||||
property real gradientRatio: (1 - progress) * 0.1
|
||||
gradient: Gradient{
|
||||
GradientStop { position: .399 + gradient.gradientRatio; color: "transparent" }
|
||||
GradientStop { position: .5; color: background.onColor }
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
anchors.centerIn: parent
|
||||
|
||||
Label {
|
||||
Layout.fillWidth: true
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
font: Style.hugeFont
|
||||
property bool toKilos: currentPower >= 1000
|
||||
property double value: Math.abs(currentPower / (toKilos ? 1000 : 1))
|
||||
text: "%1 %2".arg(value.toFixed(toKilos ? 2 : 1)).arg(toKilos ? "kW" : "W")
|
||||
}
|
||||
Label {
|
||||
Layout.fillWidth: true
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
text: {
|
||||
if (root.chargingState) {
|
||||
switch (root.chargingState.value) {
|
||||
case "idle":
|
||||
return qsTr("Idle")
|
||||
case "charging":
|
||||
return qsTr("Charging")
|
||||
case "discharging":
|
||||
return qsTr("Discharging")
|
||||
}
|
||||
}
|
||||
if (root.isProducer) {
|
||||
return qsTr("Production")
|
||||
}
|
||||
return root.currentPower < 0 ? qsTr("Return") : qsTr("Consumption")
|
||||
}
|
||||
font: Style.smallFont
|
||||
}
|
||||
|
||||
Label {
|
||||
Layout.fillWidth: true
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
font: Style.hugeFont
|
||||
visible: batteryLevelState
|
||||
text: "%1 %".arg(batteryLevelState ? batteryLevelState.value : "")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
OpacityMask {
|
||||
anchors.fill: background
|
||||
source: ShaderEffectSource {
|
||||
sourceItem: juice
|
||||
hideSource: true
|
||||
}
|
||||
maskSource: mask
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.fillHeight: true
|
||||
Layout.fillWidth: true
|
||||
Layout.margins: Style.bigMargins
|
||||
|
||||
ColumnLayout {
|
||||
id: textLayout
|
||||
anchors.fill: parent
|
||||
spacing: Style.margins
|
||||
|
||||
Label {
|
||||
Layout.fillWidth: true
|
||||
visible: isBattery
|
||||
wrapMode: Text.WordWrap
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
textFormat: Text.RichText
|
||||
property bool isCharging: root.chargingState && root.chargingState.value === "charging"
|
||||
property bool isDischarging: root.chargingState && root.chargingState.value === "discharging"
|
||||
property double availableWh: isBattery ? root.capacityState.value * 1000 * root.batteryLevelState.value / 100 : 0
|
||||
property double remainingWh: isCharging ? root.capacityState.value - availableWh : availableWh
|
||||
property double remainingHours: isBattery ? remainingWh / Math.abs(root.currentPower) : 0
|
||||
property date endTime: isBattery ? new Date(new Date().getTime() + remainingHours * 60 * 60 * 1000) : new Date()
|
||||
property int n: Math.round(remainingHours)
|
||||
|
||||
text: isCharging ? qsTr("At the current rate, the battery will be fully charged at %1.").arg('<span style="font-size:' + Style.bigFont.pixelSize + 'px">' + endTime.toLocaleTimeString(Locale.ShortFormat) + "</span>")
|
||||
: isDischarging ? qsTr("At the current rate, the battery will last until %1.").arg('<span style="font-size:' + Style.bigFont.pixelSize + 'px">' + endTime.toLocaleTimeString(Locale.ShortFormat) + "</span>")
|
||||
: qsTr("The battery is fully charged")
|
||||
}
|
||||
|
||||
BlurredLabel {
|
||||
Layout.fillWidth: true
|
||||
wrapMode: Text.WordWrap
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
visible: isEnergyMeter || isConsumer
|
||||
blurred: periodConsumptionModel.busy
|
||||
text: isConsumer ?
|
||||
qsTr("A total of %1 kWh has been <b>consumed</b> in the last 24 hours.").arg('<span style="font-size:' + Style.bigFont.pixelSize + 'px">' + (totalPeriodConsumption).toFixed(1) + '</span>')
|
||||
: qsTr("A total of %1 kWh has been <b>obtained</b> in the last 24 hours.").arg('<span style="font-size:' + Style.bigFont.pixelSize + 'px">' + (totalPeriodConsumption).toFixed(1) + '</span>')
|
||||
textFormat: Text.RichText
|
||||
|
||||
LogsModel {
|
||||
id: periodConsumptionModel
|
||||
objectName: "Root meter model"
|
||||
engine: root.isEnergyMeter ? _engine : null
|
||||
thingId: root.thing.id
|
||||
typeIds: isEnergyMeter ? [root.totalEnergyConsumedStateType.id] : []
|
||||
viewStartTime: root.startTime
|
||||
live: true
|
||||
}
|
||||
property LogEntry logEntryAtStart: periodConsumptionModel.busy ? null : periodConsumptionModel.findClosest(periodConsumptionModel.viewStartTime)
|
||||
property double totalPeriodConsumption: logEntryAtStart && totalEnergyConsumedState ? totalEnergyConsumedState.value - logEntryAtStart.value : 0
|
||||
}
|
||||
|
||||
BlurredLabel {
|
||||
visible: isEnergyMeter || isProducer
|
||||
Layout.fillWidth: true
|
||||
wrapMode: Text.WordWrap
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
blurred: periodProductionModel.busy
|
||||
text: isProducer ?
|
||||
qsTr("A total of %1 kWh has been <b>produced</b> in the last 24 hours.").arg('<span style="font-size:' + Style.bigFont.pixelSize + 'px">' + (totalPeriodProduction).toFixed(1) + '</span>')
|
||||
: qsTr("A total of %1 kWh has been <b>returned</b> in the last 24 hours.").arg('<span style="font-size:' + Style.bigFont.pixelSize + 'px">' + (totalPeriodProduction).toFixed(1) + '</span>')
|
||||
textFormat: Text.RichText
|
||||
|
||||
LogsModel {
|
||||
id: periodProductionModel
|
||||
engine: root.isEnergyMeter ? _engine : null
|
||||
thingId: root.thing.id
|
||||
typeIds: isEnergyMeter ? [root.totalEnergyProducedStateType.id] : []
|
||||
viewStartTime: root.startTime
|
||||
live: true
|
||||
}
|
||||
property LogEntry logEntryAtStart: periodProductionModel.busy ? null : periodProductionModel.findClosest(periodProductionModel.viewStartTime)
|
||||
property double totalPeriodProduction: logEntryAtStart && totalEnergyProducedState ? totalEnergyProducedState.value - logEntryAtStart.value : 0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user