# 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). ![architettura](docs/architettura.svg) ## 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/`](bridge/): istruzioni complete in [bridge/README.md](bridge/README.md) (in inglese, perché è la parte che serve a chi prova l'app su un altro impianto). ```sh 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](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): ```sh 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: `tar xzf harbour-aira-0.3.0.tar.gz` e compilare in una cartella nuova (mai sopra una estrazione precedente: i Makefile restano stale). Il log dell'app inizia con `harbour-aira v build `: serve a distinguere una build nuova da una stale senza indovinare. ### Verifica locale, senza SDK ```sh 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, etichette di stato, corpo dei comandi, messaggi d'errore. **La UI Silica si verifica solo sul dispositivo.** ## 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/main.cpp context properties: appSettings, api qml/harbour-aira.qml ApplicationWindow + copertina 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) 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/test_bridge_commands.py verifiche offline dei comandi (27 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 ``` ## Licenza MIT.