- 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.
216 lines
8.2 KiB
QML
216 lines
8.2 KiB
QML
import QtQuick 2.2
|
|
import Sailfish.Silica 1.0
|
|
import "../components"
|
|
|
|
// Impianto: la scheda "Impianto e accessori" dell'app ufficiale, con in piu'
|
|
// le versioni del software e gli errori. Tutto in sola lettura.
|
|
Page {
|
|
id: page
|
|
|
|
allowedOrientations: Orientation.All
|
|
|
|
function raw(key) {
|
|
return api.summary[key]
|
|
}
|
|
|
|
function temp(key) {
|
|
return api.formatValue(page.raw(key)) + " °C"
|
|
}
|
|
|
|
function flag(key) {
|
|
return page.raw(key) ? qsTr("yes") : qsTr("no")
|
|
}
|
|
|
|
function count(key) {
|
|
var v = page.raw(key)
|
|
if (v === undefined || v === null)
|
|
return "—"
|
|
return String(Math.round(Number(v)))
|
|
}
|
|
|
|
// Versioni e identificativo: possono mancare, quindi "—" invece di "null".
|
|
function testo(valore) {
|
|
if (valore === undefined || valore === null || valore === "")
|
|
return "—"
|
|
return String(valore)
|
|
}
|
|
|
|
// "2026-10-09 18:52:17.199340" -> "18:52"
|
|
function shortTime(s) {
|
|
if (!s)
|
|
return "—"
|
|
var parts = String(s).split(" ")
|
|
if (parts.length < 2)
|
|
return String(s)
|
|
return parts[1].substring(0, 5)
|
|
}
|
|
|
|
SilicaFlickable {
|
|
anchors.fill: parent
|
|
contentHeight: col.height + Theme.paddingLarge
|
|
|
|
PullDownMenu {
|
|
MenuItem {
|
|
text: qsTr("Refresh")
|
|
onClicked: api.refresh()
|
|
}
|
|
MenuItem {
|
|
text: qsTr("Data")
|
|
onClicked: pageStack.push(Qt.resolvedUrl("DataPage.qml"))
|
|
}
|
|
MenuItem {
|
|
text: qsTr("Settings")
|
|
onClicked: pageStack.push(Qt.resolvedUrl("SettingsPage.qml"))
|
|
}
|
|
}
|
|
|
|
Column {
|
|
id: col
|
|
width: parent.width
|
|
spacing: Theme.paddingSmall
|
|
|
|
PageHeader { title: qsTr("Plant") }
|
|
|
|
// La frase estesa dell'app ufficiale ("Relax: la pompa di calore
|
|
// funziona regolarmente"): sta qui e non in Home, dove serve
|
|
// spazio per le due letture. La calcola il C++ (AiraJson::stateLong).
|
|
Label {
|
|
x: Theme.horizontalPageMargin
|
|
width: parent.width - 2 * Theme.horizontalPageMargin
|
|
text: api.stateLong()
|
|
color: Theme.primaryColor
|
|
font.pixelSize: Theme.fontSizeMedium
|
|
horizontalAlignment: Text.AlignHCenter
|
|
wrapMode: Text.Wrap
|
|
}
|
|
|
|
// ---- stato ------------------------------------------------------ //
|
|
SectionHeader { text: qsTr("Status") }
|
|
|
|
InfoRow {
|
|
label: qsTr("Connection")
|
|
value: page.testo(page.raw("connected_via"))
|
|
}
|
|
InfoRow {
|
|
label: qsTr("Mode")
|
|
value: api.modeLabel(page.raw("operating_status"))
|
|
}
|
|
InfoRow { label: qsTr("Away mode"); value: page.flag("away_mode") }
|
|
InfoRow { label: qsTr("Night mode"); value: page.flag("night_mode") }
|
|
InfoRow { label: qsTr("Forced heating"); value: page.flag("force_heating") }
|
|
InfoRow { label: qsTr("Inline heater"); value: page.flag("inline_heater") }
|
|
InfoRow { label: qsTr("Manual mode"); value: page.flag("manual_mode") }
|
|
InfoRow { label: qsTr("Defrost"); value: page.flag("outdoor_defrost") }
|
|
InfoRow { label: qsTr("Signature lights"); value: page.flag("signature_lights") }
|
|
InfoRow { label: qsTr("Pump"); value: api.modeLabel(page.raw("pump_active_state")) }
|
|
InfoRow { label: qsTr("Allowed modes"); value: api.modeLabel(page.raw("configured_modes")) }
|
|
InfoRow { label: qsTr("Outdoor temperature"); value: page.temp("outdoor_temperature") }
|
|
InfoRow { label: qsTr("Indoor temperature (pump)"); value: page.temp("indoor_temperature") }
|
|
InfoRow { label: qsTr("Zones"); value: page.count("zones") }
|
|
InfoRow { label: qsTr("Last reading"); value: page.shortTime(page.raw("pump_updated")) }
|
|
|
|
// ---- accessori -------------------------------------------------- //
|
|
SectionHeader { text: qsTr("Accessories") }
|
|
|
|
Label {
|
|
x: Theme.horizontalPageMargin
|
|
width: parent.width - 2 * Theme.horizontalPageMargin
|
|
visible: Number(page.count("thermostats_count")) === 0
|
|
text: qsTr("No wall thermostat")
|
|
color: Theme.secondaryColor
|
|
font.pixelSize: Theme.fontSizeSmall
|
|
wrapMode: Text.Wrap
|
|
}
|
|
|
|
Column {
|
|
x: Theme.horizontalPageMargin
|
|
width: parent.width - 2 * Theme.horizontalPageMargin
|
|
spacing: 0
|
|
visible: Number(page.count("thermostats_count")) > 0
|
|
|
|
Label {
|
|
text: qsTr("Aira wall thermostat")
|
|
color: Theme.primaryColor
|
|
font.pixelSize: Theme.fontSizeSmall
|
|
}
|
|
Label {
|
|
text: qsTr("Zone %1 · Connected").arg(page.count("thermostat_zone"))
|
|
color: Theme.highlightColor
|
|
font.pixelSize: Theme.fontSizeExtraSmall
|
|
}
|
|
}
|
|
|
|
InfoRow {
|
|
visible: Number(page.count("thermostats_count")) > 0
|
|
label: qsTr("Measured temperature")
|
|
value: page.temp("thermostat_temperature")
|
|
}
|
|
InfoRow {
|
|
visible: Number(page.count("thermostats_count")) > 0
|
|
label: qsTr("Humidity")
|
|
value: api.formatNumber(page.raw("thermostat_humidity"), 1) + " %"
|
|
}
|
|
InfoRow {
|
|
visible: Number(page.count("thermostats_count")) > 0
|
|
label: qsTr("Signal")
|
|
value: page.count("thermostat_rssi") + " dBm"
|
|
}
|
|
InfoRow {
|
|
visible: Number(page.count("thermostats_count")) > 0
|
|
label: qsTr("Battery")
|
|
value: page.raw("thermostat_battery_low") ? qsTr("low") : qsTr("ok")
|
|
}
|
|
InfoRow {
|
|
visible: Number(page.count("thermostats_count")) > 0
|
|
label: qsTr("Article")
|
|
value: page.testo(page.raw("thermostat_article"))
|
|
}
|
|
|
|
// ---- versioni --------------------------------------------------- //
|
|
SectionHeader { text: qsTr("Versions") }
|
|
|
|
InfoRow { label: qsTr("Device ID"); value: page.testo(page.raw("device_id")) }
|
|
InfoRow { label: qsTr("Platform"); value: page.testo(page.raw("version_platform")) }
|
|
InfoRow { label: qsTr("Connectivity"); value: page.testo(page.raw("version_connectivity")) }
|
|
InfoRow { label: qsTr("Climate control"); value: page.testo(page.raw("version_climate_control")) }
|
|
InfoRow { label: qsTr("Outdoor unit"); value: page.testo(page.raw("version_outdoor_unit")) }
|
|
InfoRow { label: qsTr("Outdoor unit EEPROM"); value: page.testo(page.raw("version_outdoor_eeprom")) }
|
|
|
|
// ---- errori ----------------------------------------------------- //
|
|
SectionHeader { text: qsTr("Errors") }
|
|
|
|
Label {
|
|
x: Theme.horizontalPageMargin
|
|
width: parent.width - 2 * Theme.horizontalPageMargin
|
|
visible: page.count("errors_count") === "0"
|
|
text: qsTr("No errors reported by the plant.")
|
|
color: Theme.secondaryColor
|
|
font.pixelSize: Theme.fontSizeSmall
|
|
wrapMode: Text.Wrap
|
|
}
|
|
InfoRow {
|
|
visible: page.count("errors_count") !== "0"
|
|
label: qsTr("Errors reported")
|
|
value: page.count("errors_count")
|
|
}
|
|
|
|
// ---- diagnostica ------------------------------------------------ //
|
|
SectionHeader { text: qsTr("Diagnostics") }
|
|
|
|
ActionButton {
|
|
text: qsTr("Plant check")
|
|
onTriggered: api.sendCommand("ping")
|
|
}
|
|
|
|
Item { width: 1; height: Theme.paddingMedium }
|
|
}
|
|
}
|
|
|
|
NoticeBar { }
|
|
|
|
Component.onCompleted: {
|
|
if (api.configured)
|
|
api.refresh()
|
|
}
|
|
}
|