0.7.2: il tasto del boost diventa Stop mentre e' in corso

In Home e in copertina: un tocco ferma il boost invece di farne ripartire un
altro (dalla copertina era il caso peggiore). Il conto alla rovescia ora prende
il posto del suggerimento nella stessa riga e con lo stesso carattere: prima,
essendo piu' alto, spingeva giu' i tasti delle azioni rapide.
Glifo di stop disegnato con scripts/make_glyphs.py. Catalogo 199 voci.
This commit is contained in:
Carlo
2026-10-11 12:45:56 +02:00
parent f7447900f9
commit b4ac614723
11 changed files with 140 additions and 42 deletions
+2
View File
@@ -27,6 +27,8 @@ e ripiega sull'inglese; la si può scegliere anche nelle impostazioni dell'app.
in Home scorre da 30:00 a 00:00 e in copertina prende il posto dell'obiettivo
dell'acqua. I secondi vengono dalla fine del boost letta dall'impianto: il
conto è giusto anche se il boost l'ha avviato qualcun altro
- **Il tasto del boost diventa *Stop*** mentre il boost è in corso, in Home e in
copertina: un tocco lo ferma, invece di farne ripartire un altro
- **Assenza con le date**: toccando *Assenza* si apre una finestra dove si
scelgono il primo e l'ultimo giorno (calendario, un tocco ciascuno). In quel
periodo la casa resta a 15 °C e riprende il programma normale il giorno scelto
+3
View File
@@ -21,6 +21,9 @@ status, domestic hot water, and the house target temperature per zone.
it ticking down from 30:00 to 00:00, and the cover page shows it in place of
the hot water target. The seconds come from the plant's own boost end time, so
the count is right even if the boost was started from somewhere else
- **The boost button turns into *Stop*** while a boost is running, on the home
screen and on the cover: tapping it stops the boost instead of starting
another one
- **Away mode with dates**: tapping *Away* opens a dialog where you pick the
first and the last day (calendar, one tap each). The house is kept at 15 °C
for that period and resumes its normal programme on the day you chose as the
+30 -1
View File
@@ -435,7 +435,36 @@ la scatola, cioe' **sopra** l'etichetta che sporge. Da li' l'impressione che si
riga della Home**, cosi' se la disposizione non torna si legge dal registro
quale riga finisce dove invece di dedurlo da uno screenshot.
## 13. Conseguenze dell'uso reale (0.7.0)
## 13. Il tasto del boost diventa Stop, e la riga che spostava i tasti — v0.7.2
Carlo: *"Il boost funziona ma la scritta sposta in basso i pulsanti facendoli
coprire. Il pulsante di avvio boost dovrebbe diventare stop boost se il boost e'
attivo"*.
Due cose distinte, e la prima va detta perche' evita confusione: la riga che
**copriva** i tasti era il difetto di 0.7.1 (il tasto piu' basso del contenuto),
che al momento della segnalazione non era ancora installata sul telefono -- il
bridge si aggiorna da solo sul server, l'app no. La riga che invece li
**spostava** era nuova e vera: il conto alla rovescia prendeva il posto del
suggerimento ma con un carattere piu' grande (`fontSizeSmall` contro
`fontSizeExtraSmall`), quindi la Home cresceva di una decina di pixel e tutto
scendeva. Ora e' una riga sola, di altezza fissa, con il carattere del
suggerimento: sostituirsi non sposta piu' niente.
**Come è stato fatto (0.7.2).**
- tasto del boost condizionale (`Stop` con il glifo di stop quando `boostActive`)
**anche in copertina**: una copertina che riavvia il boost quando vuoi fermarlo
e' peggio di un tasto che non fa niente;
- `quick-boost-stop.png` disegnato in casa con `scripts/make_glyphs.py`, come gli
altri tre glifi;
- "Stop boost" per intero non ci sta accanto all'icona (92 px contro 73): resta
`Stop`, il senso lo porta il glifo. E' `tests/label_fit_check.py` a dirlo, che
adesso legge anche le etichette condizionali;
- `tests/cover_action_check.py` legge tutti i comandi dell'azione e tutte le
icone citate: prima si aspettava un solo letterale e su un invio condizionale
segnalava un problema inesistente.
## 14. Conseguenze dell'uso reale (0.7.0)
Deciso con l'uso, non in anticipo:
+6 -2
View File
@@ -176,8 +176,12 @@ CoverBackground {
// Il componente e' in Sailfish.Silica 1.0 (verificato nella guida dell'SDK).
CoverActionList {
CoverAction {
iconSource: "../icons/quick-boost.png"
onTriggered: api.sendCommand("hot_water_boost_on")
// Anche dalla copertina il tasto ferma quando il boost e' in corso:
// altrimenti un tocco per fermarlo ne farebbe ripartire un altro.
iconSource: api.boostActive ? "../icons/quick-boost-stop.png"
: "../icons/quick-boost.png"
onTriggered: api.sendCommand(api.boostActive ? "hot_water_boost_off"
: "hot_water_boost_on")
}
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

+34 -11
View File
@@ -223,28 +223,39 @@ Page {
}
}
// Conto alla rovescia del boost, da 30:00 a 00:00 (richiesta
// dell'utente): si vede solo mentre il boost e' in corso.
// Una sola riga, sempre della stessa altezza: mentre il boost corre
// il conto alla rovescia prende il posto del suggerimento senza
// spostare niente sotto. Il carattere e' quello del suggerimento
// (fontSizeExtraSmall): se fosse piu' grande, la riga piu' alta
// spingerebbe giu' i pulsanti e la riga di contorno finirebbe loro
// addosso (segnalato da Carlo).
Item {
visible: api.configured
width: parent.width
height: Math.max(contoRovescia.implicitHeight,
suggerimento.implicitHeight)
Label {
visible: api.configured && api.boostActive
id: contoRovescia
visible: api.boostActive
x: Theme.horizontalPageMargin
width: parent.width - 2 * Theme.horizontalPageMargin
text: qsTr("Boost · %1").arg(api.boostCountdown)
color: Theme.highlightColor
font.pixelSize: Theme.fontSizeSmall
font.pixelSize: Theme.fontSizeExtraSmall
font.bold: true
}
Label {
// Con il boost in corso questa riga sparisce: al suo posto c'e'
// il conto alla rovescia, cosi' la Home resta di una schermata.
visible: api.configured && !api.boostActive
id: suggerimento
visible: !api.boostActive
x: Theme.horizontalPageMargin
width: parent.width - 2 * Theme.horizontalPageMargin
text: qsTr("Tap a value to adjust it")
color: Theme.secondaryColor
font.pixelSize: Theme.fontSizeExtraSmall
}
}
// ---- azioni rapide --------------------------------------------- //
SectionHeader {
@@ -268,14 +279,26 @@ Page {
// sopra (segnalato da Carlo: "la riga sotto copre i
// pulsanti"). Vedi tests/label_fit_check.py.
height: Theme.itemSizeMedium
text: qsTr("Boost")
// Mentre il boost e' in corso il tasto ferma invece di
// avviare: dice cosa succede premendolo, come il tasto
// dell'assenza. "Stop boost" per intero non ci sta accanto
// all'icona (92 px contro 73 disponibili): resta "Stop",
// che il glifo di stop rende inequivocabile.
text: api.boostActive ? qsTr("Stop") : 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.source: api.boostActive ? "../icons/quick-boost-stop.png"
: "../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") })
onClicked: remorse.execute(
boostBtn,
api.boostActive ? qsTr("Stopping DHW boost")
: qsTr("Starting DHW boost"),
function() {
api.sendCommand(api.boostActive ? "hot_water_boost_off"
: "hot_water_boost_on")
})
}
Button {
+10 -1
View File
@@ -1,6 +1,6 @@
Name: harbour-aira
Summary: Control your Aira heat pump through a local bridge
Version: 0.7.1
Version: 0.7.2
Release: 1
Group: Qt/Qt
License: MIT
@@ -37,6 +37,15 @@ 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 <carlo@carlobaratto.it> - 0.7.2-1
- il tasto del boost diventa "Stop" (con glifo di stop) mentre il boost e' in
corso, in Home e in copertina: prima un tocco dalla copertina ne faceva
ripartire un altro invece di fermarlo.
- il conto alla rovescia prende il posto del suggerimento nella stessa riga e
con la stessa misura del carattere: essendo piu' alto spingeva giu' i tasti
delle azioni rapide.
- tests/cover_action_check.py controlla tutti i comandi dell'azione (anche
condizionali) e tutte le icone citate.
* Sun Oct 11 2026 Carlo <carlo@carlobaratto.it> - 0.7.1-1
- i tre tasti delle azioni rapide dichiarano la loro altezza: in Silica il tasto
la piglia dal tema (Theme.itemSizeExtraSmall, ~56 px) e non dal contenuto,
+10
View File
@@ -72,12 +72,22 @@ def comandi(d, cx, cy, w, h):
d.ellipse([kx - r, y - r, kx + r, y + r], fill=BIANCO)
def stop(d, cx, cy, w, h):
"""Ferma il boost: quadrato pieno dentro un anello (il segno universale)."""
r = min(w, h) / 2
d.ellipse([cx - r, cy - r, cx + r, cy + r], outline=BIANCO,
width=max(2, int(h * 0.12)))
q = r * 0.46
d.rectangle([cx - q, cy - q, cx + q, cy + q], fill=BIANCO)
def main():
DEST.mkdir(parents=True, exist_ok=True)
disegni = (
("quick-boost.png", fiamma, 0.62),
("quick-away.png", casa, 0.80),
("quick-commands.png", comandi, 0.90),
("quick-boost-stop.png", stop, 0.90),
)
# il glifo riempie il suo riquadro (un filo di margine): la misura sul
# telefono la decide Theme.iconSizeExtraSmall nel pulsante, non il file
+2 -2
View File
@@ -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.7.1"));
app->setApplicationVersion(QStringLiteral("0.7.2"));
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.7.1 build" << __DATE__ << __TIME__;
qDebug() << "harbour-aira v0.7.2 build" << __DATE__ << __TIME__;
view->rootContext()->setContextProperty(QStringLiteral("appSettings"), &settings);
view->rootContext()->setContextProperty(QStringLiteral("api"), &api);
+10 -2
View File
@@ -62,7 +62,7 @@ def main():
problemi.append("usa `iconSource`, non `icon.source`: `icon.source` e' del "
"pulsante Button e qui non darebbe errore, solo nessuna icona")
for m in re.finditer(r'iconSource\s*:\s*"([^"]+)"', testo):
for m in re.finditer(r'"(\.\./icons/[^"]+\.png)"', testo):
icona = (COPERTINA.parent / m.group(1)).resolve()
if not icona.exists():
problemi.append("l'icona %s non esiste (risolta da %s)"
@@ -70,9 +70,17 @@ def main():
else:
print("icona: %s -> %s" % (m.group(1), icona.relative_to(RADICE)))
comandi = re.findall(r'sendCommand\("([^"]+)"', testo)
# L'invio puo' essere condizionale (il tasto del boost avvia o ferma) e
# scritto su piu' righe: si prende tutto il testo fra sendCommand( e la
# parentesi di chiusura, poi tutti i letterali che sembrano un id.
comandi = []
for m in re.finditer(r"sendCommand\(([^)]*)\)", testo, re.S):
comandi += [s for s in re.findall(r'"([^"]+)"', m.group(1))
if re.match(r"^[a-z][a-z_]*$", s)]
if not comandi:
problemi.append("l'azione non invia nessun comando: a che serve?")
else:
print("comandi inviati: %s" % ", ".join(comandi))
for c in comandi:
if not BRIDGE.exists():
print("salto il controllo del comando %r: manca %s" % (c, BRIDGE))
+20 -10
View File
@@ -563,47 +563,57 @@
<translation>Acqua calda</translation>
</message>
<message>
<location filename="../qml/pages/MainPage.qml" line="232"/>
<location filename="../qml/pages/MainPage.qml" line="243"/>
<source>Boost · %1</source>
<translation>Boost · %1</translation>
</message>
<message>
<location filename="../qml/pages/MainPage.qml" line="244"/>
<location filename="../qml/pages/MainPage.qml" line="254"/>
<source>Tap a value to adjust it</source>
<translation>Tocca un valore per regolarlo</translation>
</message>
<message>
<location filename="../qml/pages/MainPage.qml" line="252"/>
<location filename="../qml/pages/MainPage.qml" line="263"/>
<source>Quick actions</source>
<translation>Azioni rapide</translation>
</message>
<message>
<location filename="../qml/pages/MainPage.qml" line="271"/>
<location filename="../qml/pages/MainPage.qml" line="287"/>
<source>Boost</source>
<translation>Boost</translation>
</message>
<message>
<location filename="../qml/pages/MainPage.qml" line="288"/>
<location filename="../qml/pages/MainPage.qml" line="287"/>
<source>Stop</source>
<translation>Stop</translation>
</message>
<message>
<location filename="../qml/pages/MainPage.qml" line="296"/>
<source>Stopping DHW boost</source>
<translation>Fermo il boost</translation>
</message>
<message>
<location filename="../qml/pages/MainPage.qml" line="311"/>
<source>Home</source>
<translation>Torna</translation>
</message>
<message>
<location filename="../qml/pages/MainPage.qml" line="288"/>
<location filename="../qml/pages/MainPage.qml" line="311"/>
<source>Away</source>
<translation>Assenza</translation>
</message>
<message>
<location filename="../qml/pages/MainPage.qml" line="294"/>
<location filename="../qml/pages/MainPage.qml" line="317"/>
<source>Away mode off</source>
<translation>Assenza disattivata</translation>
</message>
<message>
<location filename="../qml/pages/MainPage.qml" line="316"/>
<location filename="../qml/pages/MainPage.qml" line="339"/>
<source>More</source>
<translation>Altro</translation>
</message>
<message>
<location filename="../qml/pages/MainPage.qml" line="339"/>
<location filename="../qml/pages/MainPage.qml" line="362"/>
<source>Outside %1 °C · Thermostat %2 °C · Zones %3</source>
<translation>Esterno %1 °C · Termostato %2 °C · Zone %3</translation>
</message>
@@ -618,7 +628,7 @@
<translation>Bridge non configurato. Apri le impostazioni e inserisci l&apos;indirizzo del server e il token.</translation>
</message>
<message>
<location filename="../qml/pages/MainPage.qml" line="277"/>
<location filename="../qml/pages/MainPage.qml" line="297"/>
<source>Starting DHW boost</source>
<translation>Avvio del boost ACS</translation>
</message>