Sulla copertina compare l'icona del boost (CoverAction). Una sola azione: la documentazione Silica ammette piu' di una azione ma dice che lo stile delle app di sistema ne mostra una. CoverBackground eredita da Cover, quindi l'elenco dichiarato li' si attacca; l'icona e' iconSource (non icon.source del Button: sbagliarlo non da' errore, l'icona semplicemente non compare). La riga in fondo si ancora a Cover.coverActionArea, cosi' l'icona non la copre. Nuovo controllo statico tests/cover_action_check.py: elenco figlio diretto del Cover, una sola azione, icona che esiste, id del comando presente nella tabella del bridge. Il componente e' nominato nella guida Silica dell'SDK di Carlo.
13 KiB
harbour-aira — versione italiana
English version: README.md
harbour-aira
App nativa Sailfish OS per una pompa di calore Aira Home: mostra lo stato dell'impianto e invia i comandi dell'acqua calda sanitaria e del riscaldamento (temperatura obiettivo della casa, per zona).
L'interfaccia è in inglese e italiano: di serie segue la lingua del telefono e ripiega sull'inglese; la si può scegliere anche nelle impostazioni dell'app.
Cosa mostra
- Home, una schermata da guardare: pallino colorato con lo stato in una riga ("Tutto regolare", "Sta scaldando l'acqua"), l'ora dell'ultimo aggiornamento, le due letture che contano (casa e acqua calda, ognuna con il suo obiettivo) affiancate e toccabili, e tre azioni rapide — boost, assenza, comandi impianto — ognuna con la sua icona. Sta in una schermata, senza scorrere: i comandi hanno pagine loro
- Regolazioni: obiettivo casa e obiettivo acqua calda, ognuno con il valore che l'impianto sta tenendo adesso, lo slider (la proposta: il valore vero non si muove), una fila di valori rapidi per le dita fredde e il pulsante di conferma, che si accende solo se c'è davvero qualcosa da cambiare. Il boost sta qui
- Dati: calore prodotto, elettricità usata, efficienza (COP) di acqua calda e riscaldamento, risparmio in bolletta, CO₂ evitata e risparmio Smart Tariff Control, mese per mese. Sono i numeri che Aira calcola nel cloud, gli stessi della scheda Dati dell'app ufficiale
- Impianto: stato (connessione, modalità, assenza/notte/riscaldamento forzato, modalità manuale, sbrinamento, luci di firma, stato pompa, modi consentiti, temperature esterna e interna, zone, ultima lettura), accessori (il termostato a parete con temperatura, umidità, segnale, batteria), versioni del software, numero di errori e verifica impianto. Qui sta anche la frase di stato estesa ("Relax: la pompa di calore funziona regolarmente")
- Comandi impianto: quattro interruttori (assenza, riscaldamento forzato, riscaldamento, acqua calda attiva) che mostrano lo stato e lo cambiano in un tocco, più i pulsanti per quello che uno stato non ce l'ha: ciclo legionella e night mode per un'ora. Gli interruttori seguono l'impianto, non lo anticipano
- Copertina con casa e acqua calda, ognuna con il valore che l'impianto sta tenendo adesso e il suo obiettivo ("22,9/19,0 °C"), più il pallino di stato come nella Home
- Indirizzo e token del bridge stanno nelle impostazioni dell'app (QSettings), mai nel binario
Anteprime del layout (valori veri dell'impianto, non screenshot — vedi
Stato). Queste sono in italiano; quelle in inglese stanno in
docs/anteprima/:
| Home | Regolazioni | Dati |
|---|---|---|
![]() |
![]() |
![]() |
| Impianto | Comandi impianto | Impostazioni | Copertina |
|---|---|---|---|
![]() |
![]() |
![]() |
![]() |
La lingua dell'interfaccia
L'inglese è la lingua sorgente delle stringhe (sta direttamente nel codice);
l'italiano sta nel catalogo translations/harbour-aira-it.ts, che lupdate
aggiorna e lrelease compila in build.
La scelta fatta nelle impostazioni è salvata in QSettings con il codice della
lingua; vuoto (o lingua assente) significa lingua di sistema, con ripiego
sull'inglese quando non esiste il catalogo corrispondente.
Qt 5.6 non ha QQmlEngine::retranslate() (arriva con Qt 5.10): installare un
traduttore non basta a ritradurre quello che è già a schermo. L'app quindi, al
cambio di lingua, ricarica la radice QML — la scelta ha effetto subito, al
prezzo di tornare alla pagina iniziale.
Anche i numeri seguono la lingua: le temperature passano da QLocale, quindi in
italiano si scrive 23,0 °C e in inglese 23.0 °C.
Perché c'è un bridge (e non una chiamata diretta al cloud)
Il cloud Aira espone gRPC su HTTP/2. Qt 5.6 — il toolkit su cui gira ogni
app Sailfish — non ha HTTP/2, quindi un client nativo non può parlarci
direttamente. Le alternative (impacchettare grpcio per aarch64 con
PyOtherSide, oppure riscrivere Cognito + gRPC in C++) sono fragili e costose.
Quindi la logica resta sul server, dove Python e i token già funzionano, e l'app è un client sottile che parla HTTP/1.1 + JSON. Effetto collaterale gradito: credenziali e token non stanno mai sul telefono.
Jolla (QML/C++ Qt 5.6) --HTTP/1.1 + JSON--> bridge (Linux in LAN) --gRPC--> cloud Aira
bridge/aira_bridge.py
Il bridge
Il codice sta in bridge/: istruzioni complete in
bridge/README.md (in inglese, perché è la parte che serve a
chi prova l'app su un altro impianto).
cd bridge
python3 -m venv .venv && . .venv/bin/activate
pip install -r requirements.txt
export AIRA_CONFIG_DIR="$HOME/.config/aira"
python setup_creds.py # email e password Aira: salvate in un file 600
python aira_bridge.py --port 8790
Al primo avvio il bridge genera un token in $AIRA_CONFIG_DIR/aira_bridge.json
(permessi 600): è il valore da incollare nelle impostazioni dell'app.
API completa in docs/PROTOCOL.md.
Impostazioni nell'app
Indirizzo e token si configurano nella pagina Impostazioni (QSettings in
~/.config/harbour/aira/aira.conf): niente dati personali nel binario.
Build
Servono l'SDK Sailfish (sfdk) e un target aarch64 (Jolla Phone 2026):
sfdk target install SailfishOS-5.0.0.62-aarch64
sfdk target use SailfishOS-5.0.0.62-aarch64
sfdk build # RPM in RPMS/
sfdk deploy # sul dispositivo collegato
Sorgenti dal tarball (harbour-aira-<versione>.tar.gz, se ne hai ricevuto uno):
estrarre in una cartella nuova (mai sopra una estrazione precedente: i
Makefile restano stale), oppure clonare direttamente questo repository.
Il log dell'app inizia con harbour-aira v<versione> build <data>: serve a
distinguere una build nuova da una stale senza indovinare.
Verifica locale, senza SDK
cd tests && mkdir -p build && cd build
~/Qt/5.15.2/gcc_64/bin/qmake ../core_test.pro && make && ./core_test
Copre la logica pura (src/airajson.cpp): normalizzazione dell'indirizzo,
lettura del riassunto e delle statistiche, etichette di stato, corpo dei comandi,
messaggi d'errore e la formattazione di numeri, importi e mesi della pagina Dati.
La UI Silica si verifica solo sul dispositivo.
C'è poi un controllo di contratto fra bridge e interfaccia: confronta le
chiavi che i QML leggono con quelle che il bridge restituisce davvero (26 da
/summary, 15 da /stats). Serve il bridge in esecuzione, e nasce dal fatto che
la UI qui non si può eseguire: un refuso in una chiave si vedrebbe sul telefono
come un "—" perenne, senza niente nel log.
python3 tests/ui_contract_check.py # bridge su 127.0.0.1:8790
python3 tests/ui_contract_check.py http://192.168.3.21:8790
Altri due controlli guardano i QML stessi, visto che qui non se ne può eseguire nessuno. Impiegano millisecondi e dicono il file di cui non sono contenti:
python3 tests/qml_check_bindings.py qml # nessuna proprietà assegnata due volte
python3 tests/qml_focus_check.py # un tocco apre solo quello che ha toccato
python3 tests/label_fit_check.py # le etichette dei tasti ci stanno
python3 tests/cover_action_check.py # l'azione di copertina c'e' ed e' collegata
Stato
- 85/85 verifiche del nucleo, compilazione senza warning (comprese le frasi di stato, breve ed estesa, e la severita' degli allarmi: quello che la Home dice dell'impianto è verificato senza telefono)
- 48/48 verifiche offline del bridge (
bridge/test_bridge_commands.py), comprese le conversioni Wh→kWh e degli importi delle statistiche - 191/191 stringhe tradotte nel catalogo italiano: il test carica il
.qmcompilato come famain.cppe verifica che in inglese l'etichetta di stato sia la sorgente e in italiano quella tradotta, e che togliendo il catalogo si torni all'inglese - numeri, importi e nomi dei mesi formattati con
QLocale: separatore decimale e posizione del simbolo di valuta seguono la lingua (verificato per entrambe) - controlli statici dove la UI non è eseguibile:
qmllintpulito su tutti i QML (valida solo la sintassi: senza il modulo Silica una proprietà inesistente passa in silenzio), le chiavi che i QML leggono sono quelle che il bridge manda (tests/ui_contract_check.py), e toccare una lettura in Home apre solo le regolazioni di quell'oggetto (tests/qml_focus_check.py) - nessuna assegnazione duplicata nei QML (
tests/qml_check_bindings.py, 13 file): assegnare due volte la stessa proprietà nello stesso oggetto — dueComponent.onCompletedin una pagina, tipicamente — fa fallire la creazione dell'oggetto in Qt 5.6, e sul telefono si vede soloType MainPage unavailablesenza il nome del file. Il controllo impiega millisecondi e dice la riga - provata dal vivo in sola lettura su un impianto Aira Home, statistiche comprese: coincidono con quelle mostrate dall'app ufficiale per lo stesso periodo (calore prodotto 70,8 kWh, elettricità 29,3 kWh, COP acqua calda 4,42, risparmio Smart Tariff Control 2,71 €)
- compilata ed eseguita su un telefono (Jolla, Sailfish OS 5.2): è proprio la
prima build ad aver rivelato il difetto della Home, corretto nella 0.6.1. Resta
non verificato l'invio di un comando a un impianto vero: finora solo
letture. Le immagini in
docs/anteprima/sono anteprime di layout costruite con i valori veri dell'impianto, non screenshot
Non c'è ancora la UI per il raffrescamento (il bridge sa farlo), né orari e curve; le versioni del software si vedono in sola lettura. La pagina Dati dipende dal servizio statistiche di Aira: su un impianto appena installato qualche mese non ha ancora dati e l'app scrive nessun dato invece del numero. Non è nella Jolla Store: è un client non ufficiale che parla con le API Aira usando il proprio account.
Struttura
harbour-aira.pro progetto qmake (icona, qml, docs)
src/airajson.{h,cpp} logica pura, testabile senza SDK
src/apiclient.{h,cpp} QNetworkAccessManager + watchdog di timeout
src/settings.{h,cpp} QSettings su AppConfigLocation (sandbox SailJail)
src/translator.{h,cpp} lingua dell'interfaccia: locale di sistema, ripiego
sull'inglese, ricarica della UI al cambio
src/main.cpp context properties: appSettings, api, translator
qml/harbour-aira.qml ApplicationWindow + copertina
qml/pages/MainPage.qml home: stato in una riga, due letture, azioni rapide
qml/pages/SetpointsPage.qml obiettivi casa e acqua, valori rapidi, boost
qml/pages/DataPage.qml energia, efficienza e risparmi
qml/pages/PlantPage.qml stato, accessori, versioni, errori, diagnostica
qml/pages/CommandsPage.qml i comandi impianto, stato negli interruttori
qml/pages/SettingsPage.qml
qml/components/InfoRow.qml etichetta a sinistra, valore a destra
qml/components/ValueRow.qml titolo e sottotitolo a sinistra, valore grande a destra
qml/components/ReadingCell.qml lettura toccabile: titolo, valore grande, barra
qml/components/NoticeBar.qml messaggi dei comandi, ancorati in fondo
qml/components/ActionButton.qml pulsante di comando, con conferma opzionale
qml/icons/ i tre glifi delle azioni rapide (disegnati, non dal tema)
tests/core_test.cpp verifiche del nucleo (headless)
tests/ui_contract_check.py chiavi dei QML contro quelle del bridge (bridge attivo)
tests/qml_check_bindings.py assegnazioni duplicate di proprieta' nei QML
tests/qml_focus_check.py un tocco apre solo le regolazioni di quell'oggetto
tests/label_fit_check.py le etichette dei tasti ci stanno accanto all'icona
tests/cover_action_check.py azione di copertina: figlia diretta del Cover, icona e comando esistono
bridge/aira_bridge.py servizio HTTP/1.1 + JSON verso il cloud (gRPC)
bridge/setup_creds.py salva le credenziali Aira (file 600)
bridge/aira_probe.py sonda di sola lettura: login + stato impianto
bridge/aira_stats_probe.py sonda di sola lettura delle statistiche del cloud
bridge/test_bridge_commands.py verifiche offline dei comandi e delle statistiche (48 controlli)
bridge/harbour-aira-bridge.service unit systemd utente
bridge/README.md istruzioni di installazione del bridge (inglese)
docs/PIANO.md piano di progetto e scelte
docs/PROTOCOL.md API del bridge
docs/UX-STUDIO.md studio UX e cosa è cambiato nella 0.6.0
docs/ux/ schemi dello studio UX
docs/icona/ proposte di icona e confronto prima/dopo
translations/ harbour-aira-it.ts (l'inglese è la lingua sorgente)
docs/anteprima/ anteprime di layout in inglese (in italiano: it/)
Licenza
MIT.






