- CommandsPage: 4 interruttori (TextSwitch) al posto di 8 pulsanti in coppie accendi/spegni, piu' 3 pulsanti per le azioni senza stato. Gli interruttori seguono il dato vero (automaticCheck: false), non anticipano l'impianto, e la sezione 'Stato attuale' non serve piu'. - La pagina si chiama 'Comandi impianto'. - PlantPage: frase estesa dello stato, diagnostica (verifica impianto) e le letture che non avevano posto (pompa, modi consentiti, manuale, sbrinamento, luci di firma). - SettingsPage: 'Salva' e 'Prova connessione' diventano 'Salva e prova'. - ApiClient: dopo un comando riuscito lo stato si rilegge da solo (prima non si aggiornava nulla: l'aggiornamento automatico non esisteva). - NoticeBar anche su Dati, Impianto e Comandi; via i messaggi dentro il contenuto che scorre.
247 lines
7.9 KiB
QML
247 lines
7.9 KiB
QML
import QtQuick 2.2
|
|
import Sailfish.Silica 1.0
|
|
import "../components"
|
|
|
|
// Dati: calore prodotto, elettricita' usata, efficienza (COP) e risparmi, come
|
|
// la scheda "Dati" dell'app ufficiale. Sono numeri che Aira calcola nel cloud:
|
|
// il bridge li legge in sola lettura e li tiene in cache per 10 minuti.
|
|
Page {
|
|
id: page
|
|
|
|
allowedOrientations: Orientation.All
|
|
|
|
// La pagina non ha solo la lettura: mostra anche cosa sta facendo.
|
|
property bool loading: false
|
|
property string error: ""
|
|
|
|
function stats() {
|
|
return api.stats
|
|
}
|
|
|
|
function mese() {
|
|
return page.stats()["month"] || {}
|
|
}
|
|
|
|
function risparmi() {
|
|
return page.stats()["savings"] || {}
|
|
}
|
|
|
|
function tariffa() {
|
|
return page.stats()["smart_tariff"] || {}
|
|
}
|
|
|
|
function valuta() {
|
|
return page.stats()["currency"] || "EUR"
|
|
}
|
|
|
|
function kwh(valore) {
|
|
if (valore === undefined || valore === null)
|
|
return "—"
|
|
return api.formatValue(valore) + " kWh"
|
|
}
|
|
|
|
// Il COP ha due decimali, la temperatura uno: per questo non basta fmt().
|
|
function cop(valore) {
|
|
if (valore === undefined || valore === null)
|
|
return qsTr("no data")
|
|
return api.formatNumber(valore, 2)
|
|
}
|
|
|
|
function soldi(valore) {
|
|
if (valore === undefined || valore === null)
|
|
return "—"
|
|
return api.formatMoney(valore, page.valuta())
|
|
}
|
|
|
|
function meseNome(chiave) {
|
|
return api.monthLabel(chiave)
|
|
}
|
|
|
|
Connections {
|
|
target: api
|
|
onStatsChanged: {
|
|
page.error = ""
|
|
page.loading = false
|
|
}
|
|
onStatsRefreshed: {
|
|
page.loading = false
|
|
if (!ok)
|
|
page.error = message
|
|
}
|
|
onErrorOccurred: page.error = message
|
|
}
|
|
|
|
SilicaFlickable {
|
|
anchors.fill: parent
|
|
contentHeight: col.height + Theme.paddingLarge
|
|
|
|
PullDownMenu {
|
|
MenuItem {
|
|
text: qsTr("Refresh")
|
|
onClicked: {
|
|
page.loading = true
|
|
api.refreshStats()
|
|
}
|
|
}
|
|
MenuItem {
|
|
text: qsTr("Plant")
|
|
onClicked: pageStack.push(Qt.resolvedUrl("PlantPage.qml"))
|
|
}
|
|
MenuItem {
|
|
text: qsTr("Settings")
|
|
onClicked: pageStack.push(Qt.resolvedUrl("SettingsPage.qml"))
|
|
}
|
|
}
|
|
|
|
Column {
|
|
id: col
|
|
width: parent.width
|
|
spacing: Theme.paddingSmall
|
|
|
|
PageHeader { title: qsTr("Data") }
|
|
|
|
Label {
|
|
x: Theme.horizontalPageMargin
|
|
width: parent.width - 2 * Theme.horizontalPageMargin
|
|
text: qsTr("Numbers calculated by Aira in the cloud: the app only reads them from your own bridge.")
|
|
color: Theme.secondaryColor
|
|
font.pixelSize: Theme.fontSizeExtraSmall
|
|
wrapMode: Text.Wrap
|
|
}
|
|
|
|
// Gli errori non si mostrano piu' qui dentro: il messaggio arriva
|
|
// ancorato in fondo alla pagina (NoticeBar), dove si vede sempre.
|
|
|
|
Label {
|
|
visible: Object.keys(page.stats()).length === 0 && page.error.length === 0
|
|
x: Theme.horizontalPageMargin
|
|
width: parent.width - 2 * Theme.horizontalPageMargin
|
|
text: qsTr("Reading the data...")
|
|
color: Theme.secondaryColor
|
|
font.pixelSize: Theme.fontSizeSmall
|
|
wrapMode: Text.Wrap
|
|
}
|
|
|
|
// ---- energia e efficienza del mese ----------------------------- //
|
|
SectionHeader {
|
|
visible: Object.keys(page.stats()).length > 0
|
|
text: page.mese()["label"]
|
|
? qsTr("Month of %1").arg(page.meseNome(page.mese()["label"]))
|
|
: qsTr("This month")
|
|
}
|
|
|
|
ValueRow {
|
|
visible: Object.keys(page.stats()).length > 0
|
|
title: qsTr("Heat produced")
|
|
subtitle: qsTr("What the heat pump gave the house")
|
|
value: page.kwh(page.mese()["heat_kwh"])
|
|
}
|
|
|
|
ValueRow {
|
|
visible: Object.keys(page.stats()).length > 0
|
|
title: qsTr("Electricity used")
|
|
subtitle: qsTr("What the heat pump took from the grid")
|
|
value: page.kwh(page.mese()["energy_kwh"])
|
|
}
|
|
|
|
InfoRow {
|
|
visible: Object.keys(page.stats()).length > 0
|
|
label: qsTr("Efficiency, domestic hot water")
|
|
value: page.cop(page.mese()["cop_dhw"])
|
|
}
|
|
|
|
InfoRow {
|
|
visible: Object.keys(page.stats()).length > 0
|
|
label: qsTr("Efficiency, heating")
|
|
value: page.cop(page.mese()["cop_heating"])
|
|
}
|
|
|
|
Label {
|
|
visible: Object.keys(page.stats()).length > 0
|
|
x: Theme.horizontalPageMargin
|
|
width: parent.width - 2 * Theme.horizontalPageMargin
|
|
text: qsTr("Efficiency (COP) is how much heat the pump delivers for each unit of electricity: higher is better.")
|
|
color: Theme.secondaryColor
|
|
font.pixelSize: Theme.fontSizeExtraSmall
|
|
wrapMode: Text.Wrap
|
|
}
|
|
|
|
// ---- risparmi --------------------------------------------------- //
|
|
SectionHeader {
|
|
visible: Object.keys(page.risparmi()).length > 0
|
|
text: qsTr("Your savings, last %1 days").arg(page.stats()["period_days"] || 30)
|
|
}
|
|
|
|
ValueRow {
|
|
visible: Object.keys(page.risparmi()).length > 0
|
|
title: qsTr("Saved on the bill")
|
|
subtitle: qsTr("Compared with a gas boiler")
|
|
value: page.soldi(page.risparmi()["amount"])
|
|
valueColor: Theme.highlightColor
|
|
}
|
|
|
|
ValueRow {
|
|
visible: Object.keys(page.risparmi()).length > 0
|
|
title: qsTr("CO₂ avoided")
|
|
subtitle: qsTr("Not released into the air")
|
|
value: api.formatValue(page.risparmi()["co2_kg"]) + " kg"
|
|
}
|
|
|
|
ValueRow {
|
|
visible: Object.keys(page.tariffa()).length > 0
|
|
title: qsTr("Smart Tariff Control")
|
|
subtitle: qsTr("Saving from heating when energy is cheaper")
|
|
value: page.soldi(page.tariffa()["amount"])
|
|
valueColor: Theme.highlightColor
|
|
}
|
|
|
|
// ---- dettaglio mese per mese ------------------------------------ //
|
|
SectionHeader {
|
|
visible: page.stats()["cop_monthly"] && page.stats()["cop_monthly"].length > 0
|
|
text: qsTr("Efficiency month by month")
|
|
}
|
|
|
|
Repeater {
|
|
model: page.stats()["cop_monthly"] || []
|
|
|
|
InfoRow {
|
|
label: page.meseNome(modelData["month"])
|
|
value: page.cop(modelData["dhw_cop"])
|
|
}
|
|
}
|
|
|
|
SectionHeader {
|
|
visible: page.stats()["monthly_savings"] && page.stats()["monthly_savings"].length > 0
|
|
text: qsTr("Savings month by month")
|
|
}
|
|
|
|
Repeater {
|
|
model: page.stats()["monthly_savings"] || []
|
|
|
|
InfoRow {
|
|
label: page.meseNome(modelData["month"])
|
|
value: page.soldi(modelData["amount"])
|
|
}
|
|
}
|
|
|
|
BusyIndicator {
|
|
visible: page.loading
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
size: BusyIndicatorSize.Small
|
|
running: true
|
|
}
|
|
|
|
Item { width: 1; height: Theme.paddingMedium }
|
|
}
|
|
}
|
|
|
|
NoticeBar { }
|
|
|
|
Component.onCompleted: {
|
|
if (api.configured) {
|
|
page.loading = true
|
|
api.refreshStats()
|
|
}
|
|
}
|
|
}
|