Files
kaneda 85702880d5 0.6.0 blocco 2: Comandi impianto con interruttori, diagnostica in Impianto
- 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.
2026-10-10 09:48:41 +02:00

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()
}
}