From 8b293f356501c269ec1534be419f7fdd304fbb8e Mon Sep 17 00:00:00 2001 From: Carlo Date: Sat, 10 Oct 2026 07:26:47 +0200 Subject: [PATCH] 0.3.0: pagina Altri comandi (assenza, night mode, forzato, legionella, ACS) --- README.md | 4 +- docs/PIANO.md | 8 ++ docs/PROTOCOL.md | 8 +- docs/anteprima/comandi.png | Bin 0 -> 67144 bytes qml/components/ActionButton.qml | 37 +++++++ qml/pages/CommandsPage.qml | 166 ++++++++++++++++++++++++++++++++ qml/pages/MainPage.qml | 20 ++++ rpm/harbour-aira.spec | 2 +- scripts/render_mockups.py | 30 +++++- src/airajson.cpp | 7 ++ tests/core_test.cpp | 4 + 11 files changed, 281 insertions(+), 5 deletions(-) create mode 100644 docs/anteprima/comandi.png create mode 100644 qml/components/ActionButton.qml create mode 100644 qml/pages/CommandsPage.qml diff --git a/README.md b/README.md index db3d900..9ea0e04 100644 --- a/README.md +++ b/README.md @@ -76,9 +76,11 @@ src/apiclient.{h,cpp} QNetworkAccessManager + watchdog di timeout src/settings.{h,cpp} QSettings su AppConfigLocation (sandbox SailJail) src/main.cpp context properties: appSettings, api qml/harbour-aira.qml ApplicationWindow + copertina -qml/pages/MainPage.qml dashboard e comandi +qml/pages/MainPage.qml dashboard e comandi acqua/riscaldamento +qml/pages/CommandsPage.qml gli altri comandi, con lo stato attuale in cima qml/pages/SettingsPage.qml qml/components/InfoRow.qml +qml/components/ActionButton.qml pulsante di comando, con conferma opzionale tests/core_test.cpp verifiche del nucleo (headless) docs/PIANO.md piano di progetto e scelte docs/PROTOCOL.md API del bridge diff --git a/docs/PIANO.md b/docs/PIANO.md index ce77ca1..34ea1bf 100644 --- a/docs/PIANO.md +++ b/docs/PIANO.md @@ -100,6 +100,14 @@ Non verificabile qui (serve il suo PC + il telefono): build RPM, istallazione, U - **App 0.2.0**: sezione "Riscaldamento" nella dashboard (temperatura in casa, obiettivo, stato zona, slider 5–30 °C a passi di 0,5 con conferma) e copertina con la temperatura di casa. Aggiunte le etichette per gli stati `PUMP_MODE_STATE_*`. Nucleo: **29/29**. +- **Bridge 0.3.0 + App 0.3.0**: pagina **"Altri comandi"** nell'app (dalla tendina in + alto o dal pulsante in fondo alla home) con assenza, night mode un'ora, riscaldamento + forzato on/off, funzione riscaldamento on/off, ciclo antilegionella, riscaldamento ACS + on/off e verifica impianto; i comandi che durano (forzato, legionella, disabilitazioni) + chiedono conferma. In cima alla pagina lo **stato attuale**, così non si preme alla + cieca. **Bug corretto nello stesso giro**: `force_heating` nello stato è un oggetto + `{enabled, remaining_time}`, e il bridge lo leggeva con `bool()` — sempre vero. Ora si + legge il campo `enabled`; il test lo copre (27/27). Nucleo app: **31/31**. - **App 0.2.1** (richiesta dell'utente): la temperatura della casa diventa il dato principale **in cima** alla home (valore grande, barra, obiettivo, slider e pulsante), l'acqua calda sanitaria scende in una propria sezione sotto, lo stato impianto va in diff --git a/docs/PROTOCOL.md b/docs/PROTOCOL.md index 3996fb2..44c9017 100644 --- a/docs/PROTOCOL.md +++ b/docs/PROTOCOL.md @@ -35,8 +35,14 @@ Valori pronti per la dashboard. "away_mode": false, "night_mode": false, "manual_mode": false, - "force_heating": true, + "force_heating": false, + "force_heating_remaining": "0s", "inline_heater": false, + "hot_water_heating": true, + "configured_modes": "PUMP_MODE_STATE_HEATING", + "pump_active_state": "PUMP_ACTIVE_STATE_IDLE", + "outdoor_defrost": false, + "signature_lights": true, "led_pattern": "LED_PATTERN_NORMAL", "zones": 1, "zone1_setpoint": 19.0, diff --git a/docs/anteprima/comandi.png b/docs/anteprima/comandi.png new file mode 100644 index 0000000000000000000000000000000000000000..81774495447839078e98fbd86ea601798c3fa170 GIT binary patch literal 67144 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 literal 0 HcmV?d00001 diff --git a/qml/components/ActionButton.qml b/qml/components/ActionButton.qml new file mode 100644 index 0000000..368e065 --- /dev/null +++ b/qml/components/ActionButton.qml @@ -0,0 +1,37 @@ +import QtQuick 2.0 +import Sailfish.Silica 1.0 + +// Pulsante a tutta larghezza per un comando del bridge. +// Se `confirmText` e' valorizzato, l'azione parte solo dopo la conferma +// (RemorseItem): la usano i comandi che cambiano lo stato in modo duraturo. +Item { + id: root + + width: parent ? parent.width : 0 + height: btn.height + + property string text: "" + property string confirmText: "" + signal triggered() + + Button { + id: btn + anchors { + left: parent.left + right: parent.right + leftMargin: Theme.horizontalPageMargin + rightMargin: Theme.horizontalPageMargin + } + text: root.text + onClicked: { + if (root.confirmText.length > 0) { + remorse.execute(btn, root.confirmText, function() { root.triggered() }) + } else { + root.triggered() + } + } + } + + // Fuori dal Button: dentro il pulsante i figli finiscono nel contentItem. + RemorseItem { id: remorse } +} diff --git a/qml/pages/CommandsPage.qml b/qml/pages/CommandsPage.qml new file mode 100644 index 0000000..5440eb6 --- /dev/null +++ b/qml/pages/CommandsPage.qml @@ -0,0 +1,166 @@ +import QtQuick 2.2 +import Sailfish.Silica 1.0 +import "../components" + +// Comandi secondari: quelli che non stanno nella home. In cima lo stato +// attuale, cosi' non si preme alla cieca. +Page { + id: page + + allowedOrientations: Orientation.All + + property string notice: "" + property bool noticeIsError: false + + function raw(key) { + return api.summary[key] + } + + function flag(key) { + return page.raw(key) ? qsTr("sì") : qsTr("no") + } + + function stato(key) { + return api.modeLabel(page.raw(key)) + } + + function showNotice(msg, isError) { + page.notice = msg + page.noticeIsError = isError === true + noticeTimer.restart() + } + + Timer { + id: noticeTimer + interval: 4000 + onTriggered: page.notice = "" + } + + Connections { + target: api + onErrorOccurred: page.showNotice(message, true) + onCommandFinished: page.showNotice(message, !ok) + } + + SilicaFlickable { + anchors.fill: parent + contentHeight: col.height + Theme.paddingLarge + + Column { + id: col + width: parent.width + spacing: Theme.paddingSmall + + PageHeader { title: qsTr("Altri comandi") } + + Label { + visible: page.notice.length > 0 + x: Theme.horizontalPageMargin + width: parent.width - 2 * Theme.horizontalPageMargin + text: page.notice + color: page.noticeIsError ? Theme.errorColor : Theme.highlightColor + font.pixelSize: Theme.fontSizeSmall + wrapMode: Text.Wrap + } + + // ---- stato attuale -------------------------------------------- // + SectionHeader { text: qsTr("Stato attuale") } + + InfoRow { label: qsTr("Assenza"); value: page.flag("away_mode") } + InfoRow { label: qsTr("Night mode"); value: page.flag("night_mode") } + InfoRow { label: qsTr("Riscaldamento forzato"); value: page.flag("force_heating") } + InfoRow { label: qsTr("Acqua calda attiva"); value: page.flag("hot_water_heating") } + InfoRow { label: qsTr("Pompa"); value: page.stato("pump_active_state") } + InfoRow { label: qsTr("Modalità consentite"); value: page.stato("configured_modes") } + + // ---- assenza --------------------------------------------------- // + SectionHeader { text: qsTr("Assenza") } + + ActionButton { + text: qsTr("Attiva assenza") + onTriggered: api.sendCommand("away_mode_on") + } + ActionButton { + text: qsTr("Disattiva assenza") + onTriggered: api.sendCommand("away_mode_off") + } + + // ---- rumore ---------------------------------------------------- // + SectionHeader { text: qsTr("Rumore") } + + ActionButton { + text: qsTr("Night mode per un'ora") + onTriggered: api.sendCommand("night_mode_1h") + } + + // ---- riscaldamento --------------------------------------------- // + SectionHeader { text: qsTr("Riscaldamento") } + + ActionButton { + text: qsTr("Forza riscaldamento") + confirmText: qsTr("Avvio del riscaldamento forzato") + onTriggered: api.sendCommand("force_heating_on") + } + ActionButton { + text: qsTr("Ferma riscaldamento forzato") + onTriggered: api.sendCommand("force_heating_off") + } + ActionButton { + text: qsTr("Abilita funzione riscaldamento") + onTriggered: api.sendCommand("heating_on") + } + ActionButton { + text: qsTr("Disabilita funzione riscaldamento") + confirmText: qsTr("Il riscaldamento verrà disabilitato") + onTriggered: api.sendCommand("heating_off") + } + + // ---- acqua calda ----------------------------------------------- // + SectionHeader { text: qsTr("Acqua calda sanitaria") } + + ActionButton { + text: qsTr("Ciclo antilegionella") + confirmText: qsTr("Avvio del ciclo antilegionella: richiede tempo") + onTriggered: api.sendCommand("legionella_cycle") + } + ActionButton { + text: qsTr("Abilita riscaldamento ACS") + onTriggered: api.sendCommand("hot_water_heating_on") + } + ActionButton { + text: qsTr("Disabilita riscaldamento ACS") + confirmText: qsTr("L'acqua calda smetterà di essere riscaldata") + onTriggered: api.sendCommand("hot_water_heating_off") + } + + // ---- diagnostica ----------------------------------------------- // + SectionHeader { text: qsTr("Diagnostica") } + + ActionButton { + text: qsTr("Verifica impianto") + onTriggered: api.sendCommand("ping") + } + + BusyIndicator { + visible: api.busy + anchors.horizontalCenter: parent.horizontalCenter + size: BusyIndicatorSize.Small + running: true + } + + Label { + x: Theme.horizontalPageMargin + width: parent.width - 2 * Theme.horizontalPageMargin + text: qsTr("I comandi passano dal bridge e possono richiedere qualche secondo. Dopo l'invio lo stato si aggiorna da solo.") + color: Theme.secondaryColor + font.pixelSize: Theme.fontSizeExtraSmall + wrapMode: Text.Wrap + } + } + } + + Component.onCompleted: { + if (api.configured) + api.refresh() + } +} diff --git a/qml/pages/MainPage.qml b/qml/pages/MainPage.qml index 22dbb7f..042262d 100644 --- a/qml/pages/MainPage.qml +++ b/qml/pages/MainPage.qml @@ -24,6 +24,10 @@ Page { pageStack.push(Qt.resolvedUrl("SettingsPage.qml")) } + function openCommands() { + pageStack.push(Qt.resolvedUrl("CommandsPage.qml")) + } + function showNotice(msg, isError) { page.notice = msg page.noticeIsError = isError === true @@ -101,6 +105,10 @@ Page { text: qsTr("Impostazioni") onClicked: page.openSettings() } + MenuItem { + text: qsTr("Altri comandi") + onClicked: page.openCommands() + } } Column { @@ -308,6 +316,18 @@ Page { InfoRow { visible: api.configured; label: qsTr("Errori"); value: page.count("errors_count") } InfoRow { visible: api.configured; label: qsTr("Aggiornato alle"); value: page.shortTime(page.raw("pump_updated")) } + Button { + visible: api.configured + anchors { + left: parent.left + right: parent.right + leftMargin: Theme.horizontalPageMargin + rightMargin: Theme.horizontalPageMargin + } + text: qsTr("Altri comandi") + onClicked: page.openCommands() + } + BusyIndicator { visible: api.busy anchors.horizontalCenter: parent.horizontalCenter diff --git a/rpm/harbour-aira.spec b/rpm/harbour-aira.spec index c9b7f5c..cee42ff 100644 --- a/rpm/harbour-aira.spec +++ b/rpm/harbour-aira.spec @@ -1,6 +1,6 @@ Name: harbour-aira Summary: Control your Aira heat pump through a local bridge -Version: 0.2.1 +Version: 0.3.0 Release: 1 Group: Qt/Qt License: MIT diff --git a/scripts/render_mockups.py b/scripts/render_mockups.py index 76171b8..9a14d62 100644 --- a/scripts/render_mockups.py +++ b/scripts/render_mockups.py @@ -216,10 +216,36 @@ def cover_screen() -> Image.Image: return img +def commands_screen() -> Image.Image: + img = background() + d = ImageDraw.Draw(img) + status_bar(d) + page_header(d, "Altri comandi") + + y = section_header(d, 156, "Stato attuale") + for lab, val in (("Assenza", "no"), ("Night mode", "no"), + ("Riscaldamento forzato", "no"), ("Acqua calda attiva", "sì"), + ("Pompa", "Ferma"), ("Modalità consentite", "Riscaldamento")): + y = label_pair(d, y, lab, val) + + y = section_header(d, y + 24, "Assenza") + y = button(d, y, "Attiva assenza") + y = button(d, y, "Disattiva assenza") + + y = section_header(d, y + 24, "Rumore") + y = button(d, y, "Night mode per un'ora") + + y = section_header(d, y + 24, "Riscaldamento") + y = button(d, y, "Forza riscaldamento", primary=True) + d.text(((W - d.textlength("(chiede conferma prima di partire)", font=font(22))) / 2, y - 4), + "(chiede conferma prima di partire)", font=font(22), fill=SECONDARY) + return img + + if __name__ == "__main__": OUT.mkdir(parents=True, exist_ok=True) - for name, fn in (("dashboard", main_screen), ("impostazioni", settings_screen), - ("copertina", cover_screen)): + for name, fn in (("dashboard", main_screen), ("comandi", commands_screen), + ("impostazioni", settings_screen), ("copertina", cover_screen)): path = OUT / f"{name}.png" fn().save(path) print(f"scritto {path} ({path.stat().st_size} byte)") diff --git a/src/airajson.cpp b/src/airajson.cpp index 8a60b85..476da6c 100644 --- a/src/airajson.cpp +++ b/src/airajson.cpp @@ -73,12 +73,19 @@ QString modeLabel(const QString &operatingStatus) return QStringLiteral("Stand-by"); if (s == QLatin1String("PUMP_MODE_STATE_OFF")) return QStringLiteral("Spento"); + // Stato operativo della pompa (state.pump_active_state). + if (s == QLatin1String("PUMP_ACTIVE_STATE_IDLE")) + return QStringLiteral("Ferma"); + if (s == QLatin1String("PUMP_ACTIVE_STATE_RUNNING")) + return QStringLiteral("In funzione"); if (s.isEmpty()) return QStringLiteral("—"); // Sconosciuto: togliamo il prefisso e mostriamo il resto, minuscolo. QString rest = s; rest.remove(QLatin1String("OPERATING_STATUS_")); rest.remove(QLatin1String("PUMP_MODE_STATE_")); + rest.remove(QLatin1String("PUMP_ACTIVE_STATE_")); + rest.remove(QLatin1String("POWER_PREFERENCE_")); return rest.toLower(); } diff --git a/tests/core_test.cpp b/tests/core_test.cpp index 9fb3b32..146ddba 100644 --- a/tests/core_test.cpp +++ b/tests/core_test.cpp @@ -68,6 +68,10 @@ int main(int argc, char *argv[]) "stato zona: in attesa"); check(AiraJson::modeLabel("PUMP_MODE_STATE_IGNOTO") == "ignoto", "stato zona sconosciuto -> senza prefisso"); + check(AiraJson::modeLabel("PUMP_ACTIVE_STATE_IDLE") == "Ferma", + "pompa ferma"); + check(AiraJson::modeLabel("PUMP_ACTIVE_STATE_RUNNING") == "In funzione", + "pompa in funzione"); check(AiraJson::modeLabel("OPERATING_STATUS_DEFROST") == "defrost", "stato sconosciuto: prefisso tolto, minuscolo");