diff --git a/.gitignore b/.gitignore index e69453e..91e01d3 100644 --- a/.gitignore +++ b/.gitignore @@ -17,8 +17,11 @@ __pycache__/ *.pyc # cataloghi compilati: si rigenerano in build da translations/*.ts -translations/*.qm +*.qm # temporanei *~ *.bak + +# binario compilato in locale: non fa parte del sorgente +harbour-aira diff --git a/docs/PIANO.md b/docs/PIANO.md index 04143ad..33496b2 100644 --- a/docs/PIANO.md +++ b/docs/PIANO.md @@ -352,6 +352,20 @@ Sono disegnate con Pillow (`scripts/make_glyphs.py`) in PNG bianche su trasparente, in `qml/icons/`: il PNG si vede di sicuro dentro il sandbox, l'SVG dipende dal supporto SVG. -**Stato attuale (0.6.7).** 85/85 verifiche del nucleo, 48/48 del bridge, +**0.6.8 — le icone dei tasti, misura vera.** Le icone della 0.6.7 erano grosse: +in un tasto largo un terzo di schermo il testo veniva tagliato. Dalla +documentazione Silica risulta che `icon` è un `Image`: senza dimensione prende +quella del file, e il pulsante la riporta all'icona di tema (misurata sullo +screenshot: 64 px, `Theme.iconSizeMedium`), lasciando 41 px di testo. Ora il +tasto dichiara `Theme.iconSizeExtraSmall` e i glifi riempiono il riquadro. Con +la geometria misurata sul telefono (161 px di tasto, rientri 16, distacco 24) +le etichette **Assenza**, **Torna**, **Altro** e le inglesi **Away**, **Home**, +**More** ci stanno con margine; "Comandi" (8 lettere) no, quindi il tasto dice +"Altro" e la pagina resta "Comandi impianto". Prova ripetibile: +`docs/icona/tasti-alla-misura-vera.png` (script in scratch, geometria nei +commenti); il pulsante Silica non espone il carattere, quindi non si può +rimpicciolire il testo: l'unica leva è l'icona. + +**Stato attuale (0.6.8).** 85/85 verifiche del nucleo, 48/48 del bridge, 191/191 stringhe tradotte, `qmllint` pulito, contratto UI↔bridge rispettato. Nessun comando è stato inviato all'impianto: tutto quanto sopra è a sola lettura. diff --git a/docs/anteprima/dashboard.png b/docs/anteprima/dashboard.png index 465b9b4..4e45409 100644 Binary files a/docs/anteprima/dashboard.png and b/docs/anteprima/dashboard.png differ diff --git a/docs/anteprima/it/dashboard.png b/docs/anteprima/it/dashboard.png index e37a7a1..72cc609 100644 Binary files a/docs/anteprima/it/dashboard.png and b/docs/anteprima/it/dashboard.png differ diff --git a/docs/icona/glifi-tasti.png b/docs/icona/glifi-tasti.png index f8831cf..b583958 100644 Binary files a/docs/icona/glifi-tasti.png and b/docs/icona/glifi-tasti.png differ diff --git a/docs/icona/tasti-alla-misura-vera.png b/docs/icona/tasti-alla-misura-vera.png new file mode 100644 index 0000000..cdaf58c Binary files /dev/null and b/docs/icona/tasti-alla-misura-vera.png differ diff --git a/documentation.list b/documentation.list new file mode 100644 index 0000000..e69de29 diff --git a/qml/icons/quick-away.png b/qml/icons/quick-away.png index 0b28594..4251dfd 100644 Binary files a/qml/icons/quick-away.png and b/qml/icons/quick-away.png differ diff --git a/qml/icons/quick-boost.png b/qml/icons/quick-boost.png index 47939aa..a9e1307 100644 Binary files a/qml/icons/quick-boost.png and b/qml/icons/quick-boost.png differ diff --git a/qml/icons/quick-commands.png b/qml/icons/quick-commands.png index 60dc559..50ec895 100644 Binary files a/qml/icons/quick-commands.png and b/qml/icons/quick-commands.png differ diff --git a/qml/pages/MainPage.qml b/qml/pages/MainPage.qml index 705c098..16f4740 100644 --- a/qml/pages/MainPage.qml +++ b/qml/pages/MainPage.qml @@ -248,7 +248,11 @@ Page { id: boostBtn width: (parent.width - 2 * parent.spacing) / 3 text: qsTr("Boost") + // La casella dell'icona la decide il tema: senza, l'Image + // prende la misura del file e si mangia il testo. icon.source: "../icons/quick-boost.png" + icon.width: Theme.iconSizeExtraSmall + icon.height: Theme.iconSizeExtraSmall onClicked: remorse.execute(boostBtn, qsTr("Starting DHW boost"), function() { api.sendCommand("hot_water_boost_on") }) } @@ -257,8 +261,12 @@ Page { id: assenzaBtn width: (parent.width - 2 * parent.spacing) / 3 // Il pulsante dice cosa succede premendolo, non lo stato. - text: page.raw("away_mode") ? qsTr("Back home") : qsTr("Away mode") + // Etichette corte: nel tasto, largo un terzo di schermo, + // icona e testo devono starci insieme. + text: page.raw("away_mode") ? qsTr("Home") : qsTr("Away") icon.source: "../icons/quick-away.png" + icon.width: Theme.iconSizeExtraSmall + icon.height: Theme.iconSizeExtraSmall onClicked: { if (page.raw("away_mode")) { remorse.execute(assenzaBtn, qsTr("Away mode off"), @@ -272,8 +280,12 @@ Page { Button { width: (parent.width - 2 * parent.spacing) / 3 - text: qsTr("Commands") + // "Comandi" (8 lettere) non ci sta accanto a un'icona in un + // terzo di schermo: la pagina resta "Comandi impianto". + text: qsTr("More") icon.source: "../icons/quick-commands.png" + icon.width: Theme.iconSizeExtraSmall + icon.height: Theme.iconSizeExtraSmall onClicked: page.openCommands() } } diff --git a/rpm/harbour-aira.spec b/rpm/harbour-aira.spec index 08756f7..f7303a3 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.6.7 +Version: 0.6.8 Release: 1 Group: Qt/Qt License: MIT @@ -37,6 +37,14 @@ Address and token of the bridge live in the app settings (AppConfigLocation); no personal data is stored in the binary. %changelog +* Sun Oct 11 2026 Carlo - 0.6.8-1 +- Home: le icone dei tasti rimpicciolite. Il pulsante Silica, se non si dice + altro, disegna l'icona a Theme.iconSizeMedium (64 px): in un tasto largo un + terzo di schermo restavano 41 px di testo e le etichette uscivano tagliate + ("Boos", "Asse", "Altro" no). Ora l'icona e' Theme.iconSizeExtraSmall e i + glifi riempiono il loro riquadro. Etichette piu' corte dove non ci stavano + (Assenza/Torna/Altro, Away/Home/More): con i numeri veri misurati sullo + screenshot ognuna ci sta con margine. La pagina resta "Comandi impianto" * Sun Oct 11 2026 Carlo - 0.6.7-1 - Home: i tre tasti delle azioni rapide hanno un'icona (fiamma = boost, casa = assenza, tre manopole = comandi). Il tema Sailfish non ha icone per questi diff --git a/scripts/make_glyphs.py b/scripts/make_glyphs.py index 13eb83d..8c49a59 100644 --- a/scripts/make_glyphs.py +++ b/scripts/make_glyphs.py @@ -18,7 +18,7 @@ import pathlib from PIL import Image, ImageDraw BASE = 688 # si disegna grande e si riduce: bordi puliti a ogni taglia -OUT = 172 # come l'icona piu' grande dell'app, abbondante per il tasto +OUT = 64 # il riquadro vero lo decide il tema (iconSizeExtraSmall) DEST = pathlib.Path(__file__).resolve().parent.parent / "qml" / "icons" BIANCO = (255, 255, 255, 255) VUOTO = (0, 0, 0, 0) @@ -75,11 +75,13 @@ def comandi(d, cx, cy, w, h): def main(): DEST.mkdir(parents=True, exist_ok=True) disegni = ( - ("quick-boost.png", fiamma, 0.58), - ("quick-away.png", casa, 0.74), - ("quick-commands.png", comandi, 0.82), + ("quick-boost.png", fiamma, 0.62), + ("quick-away.png", casa, 0.80), + ("quick-commands.png", comandi, 0.90), ) - lato = BASE * 0.72 # margine generoso: il tasto ha il suo + # il glifo riempie il suo riquadro (un filo di margine): la misura sul + # telefono la decide Theme.iconSizeExtraSmall nel pulsante, non il file + lato = BASE * 0.80 for nome, disegno, strettezza in disegni: img = nuova() d = ImageDraw.Draw(img) diff --git a/scripts/render_mockups.py b/scripts/render_mockups.py index c003c0d..39d4db3 100644 --- a/scripts/render_mockups.py +++ b/scripts/render_mockups.py @@ -343,9 +343,9 @@ TEXTS["en"].update({ "tap_adjust": "Tap a value to adjust it", "quick_actions": "Quick actions", "boost": "Boost", - "away_btn": "Away mode", - "back_home": "Back home", - "commands": "Commands", + "away_btn": "Away", + "back_home": "Home", + "commands": "More", "contorno": "Outside {a} · Thermostat {b} · Zones 1", "setpoints": "Setpoints", "current_target": "Current target", @@ -386,8 +386,8 @@ TEXTS["it"].update({ "quick_actions": "Azioni rapide", "boost": "Boost", "away_btn": "Assenza", - "back_home": "Torna a casa", - "commands": "Comandi", + "back_home": "Torna", + "commands": "Altro", "contorno": "Esterno {a} · Termostato {b} · Zone 1", "setpoints": "Regolazioni", "current_target": "Obiettivo attuale", @@ -510,13 +510,15 @@ def main_screen() -> Image.Image: d.rounded_rectangle([x, y, x + bw, y + 74], radius=18, fill=BTN_BG, outline=BTN_EDGE, width=2) icona = Image.open(OUT.parent.parent / "qml" / "icons" / glifi[i]).convert("RGBA") + # stessa proporzione del telefono: icona piccola del tema (32 su 540) + # riportata alla larghezza di questa anteprima lato = 42 icona = icona.resize((lato, lato), Image.LANCZOS) - tw = d.textlength(testo, font=font(24)) - blocco = lato + 12 + tw + tw = d.textlength(testo, font=font(26)) + blocco = lato + 20 + tw x0 = x + (bw - blocco) / 2 img.paste(icona, (int(x0), int(y + (74 - lato) / 2)), icona) - d.text((x0 + lato + 12, y + 23), testo, font=font(24), fill=PRIMARY) + d.text((x0 + lato + 20, y + 22), testo, font=font(26), fill=PRIMARY) y += 104 # ---- letture di contorno ----------------------------------------------- # diff --git a/src/main.cpp b/src/main.cpp index eabbbcd..c576d1f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -21,7 +21,7 @@ Q_DECL_EXPORT int main(int argc, char *argv[]) app->setOrganizationName(QStringLiteral("harbour")); app->setApplicationName(QStringLiteral("aira")); - app->setApplicationVersion(QStringLiteral("0.6.7")); + app->setApplicationVersion(QStringLiteral("0.6.8")); Settings settings; ApiClient api(&settings); @@ -36,7 +36,7 @@ Q_DECL_EXPORT int main(int argc, char *argv[]) // Prima riga del log: dice subito se il device sta girando la build nuova // o una stale (trappola nota del build engine). - qDebug() << "harbour-aira v0.6.7 build" << __DATE__ << __TIME__; + qDebug() << "harbour-aira v0.6.8 build" << __DATE__ << __TIME__; view->rootContext()->setContextProperty(QStringLiteral("appSettings"), &settings); view->rootContext()->setContextProperty(QStringLiteral("api"), &api); diff --git a/translations/harbour-aira-it.ts b/translations/harbour-aira-it.ts index 4b5a913..bdc9b89 100644 --- a/translations/harbour-aira-it.ts +++ b/translations/harbour-aira-it.ts @@ -520,52 +520,57 @@ - + target %1 °C obiettivo %1 °C - + Hot water Acqua calda - + Tap a value to adjust it Tocca un valore per regolarlo - + Quick actions Azioni rapide - + Boost Boost - - Back home - Torna a casa + + Home + Torna - + + Away + Assenza + + + Away mode off Assenza disattivata - + Away mode on Assenza attivata - - Commands - Comandi + + More + Altro - + Outside %1 °C · Thermostat %2 °C · Zones %3 Esterno %1 °C · Termostato %2 °C · Zone %3 @@ -580,7 +585,7 @@ Bridge non configurato. Apri le impostazioni e inserisci l'indirizzo del server e il token. - + Starting DHW boost Avvio del boost ACS @@ -589,11 +594,6 @@ Plant Impianto - - - Away mode - Assenza - PlantPage @@ -826,117 +826,117 @@ SetpointsPage - + Refresh Aggiorna - + Data Dati - + Plant Impianto - + Settings Impostazioni - + Setpoints Regolazioni - + Heating the house Riscaldamento della casa - + Current target Obiettivo attuale - + What the plant is keeping now Quello che l'impianto mantiene adesso - + New house target Nuovo obiettivo casa - + Set house to %1 °C Imposta casa a %1 °C - + House temperature to %1 °C Temperatura della casa a %1 °C - + Domestic hot water Acqua calda sanitaria - + DHW target Obiettivo acqua calda - + Water now %1 °C Acqua ora %1 °C - + New target Nuovo obiettivo - + Set target %1 °C Imposta obiettivo %1 °C - + DHW target to %1 °C Obiettivo ACS a %1 °C - + Hot water boost Boost acqua calda - + Start DHW boost Avvia boost ACS - + Starting DHW boost Avvio del boost ACS - + Stop DHW boost Ferma boost ACS - + Stopping DHW boost Arresto del boost ACS - + Commands go through the bridge and may take a few seconds. The status refreshes by itself afterwards. I comandi passano dal bridge e possono richiedere qualche secondo. Dopo l'invio lo stato si aggiorna da solo. diff --git a/translations/harbour-aira.ts b/translations/harbour-aira.ts new file mode 100644 index 0000000..c0e7ca7 --- /dev/null +++ b/translations/harbour-aira.ts @@ -0,0 +1,999 @@ + + + + + AiraJson + + + Automatic + + + + + + Heating + + + + + + Cooling + + + + + + Hot water + + + + + + Standby + + + + + + Off + + + + + Idle + + + + + Stopped + + + + + Running + + + + + server unreachable + + + + + HTTP error %1 + + + + + No data + + + + + Attention: one error + + + + + Attention: %1 errors + + + + + Away mode + + + + + Night mode + + + + + Heating at full power + + + + + Heating the hot water + + + + + Working + + + + + Everything is fine + + + + + Attention: one error on the plant + + + + + Attention: %1 errors on the plant + + + + + Away mode: the house is saving energy. + + + + + Night mode is on. + + + + + Boost: the house is heating at full power. + + + + + The heat pump is heating the hot water. + + + + + The heat pump is working. + + + + + Relax: the heat pump is running smoothly. + + + + + ApiClient + + + Bridge address not configured + + + + + + + Set the bridge address and token + + + + + Server unreachable (timeout) + + + + + + Unreadable response from the bridge + + + + + Enter the bridge address + + + + + Timeout: no response + + + + + Unreachable (HTTP %1) + + + + + Bridge reachable + + + + + + Bridge not configured + + + + + Timeout: no statistics + + + + + Timeout: command not sent + + + + + Command sent + + + + + CommandsPage + + + Refresh + + + + + Data + + + + + Plant + + + + + Settings + + + + + Plant commands + + + + + Modes + + + + + Away mode + + + + + Lowers the house and stops the hot water + + + + + Forced heating + + + + + Heats at full power until you stop it + + + + + Heating + + + + + The heating can turn on + + + + + Heating will be disabled + + + + + Domestic hot water + + + + + Hot water active + + + + + The heat pump keeps the water in temperature + + + + + Domestic hot water will stop being heated + + + + + Legionella cycle + + + + + Starting the legionella cycle: it takes a while + + + + + Noise + + + + + Night mode for one hour + + + + + The switches show the current state of the plant: the Status section is not needed any more. + + + + + Commands go through the bridge and may take a few seconds. The status refreshes by itself afterwards. + + + + + CoverPage + + + House + + + + + Hot water + + + + + Not updated · last %1 + + + + + outside %1 °C + + + + + DataPage + + + no data + + + + + Refresh + + + + + Plant + + + + + Settings + + + + + Data + + + + + Numbers calculated by Aira in the cloud: the app only reads them from your own bridge. + + + + + Reading the data... + + + + + Month of %1 + + + + + This month + + + + + Heat produced + + + + + What the heat pump gave the house + + + + + Electricity used + + + + + What the heat pump took from the grid + + + + + Efficiency, domestic hot water + + + + + Efficiency, heating + + + + + Efficiency (COP) is how much heat the pump delivers for each unit of electricity: higher is better. + + + + + Your savings, last %1 days + + + + + Saved on the bill + + + + + Compared with a gas boiler + + + + + CO₂ avoided + + + + + Not released into the air + + + + + Smart Tariff Control + + + + + Saving from heating when energy is cheaper + + + + + Efficiency month by month + + + + + Savings month by month + + + + + MainPage + + + No data yet + + + + + Not updated · last %1 + + + + + Updated at %1 + + + + + Refresh + + + + + Data + + + + + Plant + + + + + + Settings + + + + + Bridge not configured. Open the settings and enter the server address and the token. + + + + + House + + + + + + target %1 °C + + + + + Hot water + + + + + Tap a value to adjust it + + + + + Quick actions + + + + + Boost + + + + + Starting DHW boost + + + + + Back home + + + + + Away mode + + + + + Away mode off + + + + + Away mode on + + + + + Commands + + + + + Outside %1 °C · Thermostat %2 °C · Zones %3 + + + + + PlantPage + + + yes + + + + + no + + + + + Refresh + + + + + Data + + + + + Settings + + + + + Plant + + + + + Status + + + + + Connection + + + + + Mode + + + + + Away mode + + + + + Night mode + + + + + Forced heating + + + + + Inline heater + + + + + Manual mode + + + + + Defrost + + + + + Signature lights + + + + + Pump + + + + + Allowed modes + + + + + Outdoor temperature + + + + + Indoor temperature (pump) + + + + + Zones + + + + + Last reading + + + + + Accessories + + + + + No wall thermostat + + + + + Aira wall thermostat + + + + + Zone %1 · Connected + + + + + Measured temperature + + + + + Humidity + + + + + Signal + + + + + Battery + + + + + low + + + + + ok + + + + + Article + + + + + Versions + + + + + Device ID + + + + + Platform + + + + + Connectivity + + + + + Climate control + + + + + Outdoor unit + + + + + Outdoor unit EEPROM + + + + + Errors + + + + + No errors reported by the plant. + + + + + Errors reported + + + + + Diagnostics + + + + + Plant check + + + + + SetpointsPage + + + Refresh + + + + + Data + + + + + Plant + + + + + Settings + + + + + Setpoints + + + + + Heating the house + + + + + Current target + + + + + What the plant is keeping now + + + + + New house target + + + + + Set house to %1 °C + + + + + House temperature to %1 °C + + + + + Domestic hot water + + + + + DHW target + + + + + Water now %1 °C + + + + + New target + + + + + Set target %1 °C + + + + + DHW target to %1 °C + + + + + Hot water boost + + + + + Start DHW boost + + + + + Starting DHW boost + + + + + Stop DHW boost + + + + + Stopping DHW boost + + + + + Commands go through the bridge and may take a few seconds. The status refreshes by itself afterwards. + + + + + SettingsPage + + + checking… + + + + + Settings + + + + + + Language + + + + + + System + + + + + Changing the language reloads the app. + + + + + Bridge + + + + + Bridge address + + + + + Bridge token + + + + + Address and token live on the server: the token is in aira_bridge.json next to the bridge. Without a scheme, http:// is used. + + + + + Save and test + + + +