0.2.1: temperatura della casa in cima alla home, acqua calda in sezione dedicata
This commit is contained in:
@@ -53,7 +53,7 @@ sfdk build # RPM in RPMS/
|
||||
sfdk deploy # sul dispositivo collegato
|
||||
```
|
||||
|
||||
Sorgenti dal tarball: `tar xzf harbour-aira-0.2.0.tar.gz` e compilare in una
|
||||
Sorgenti dal tarball: `tar xzf harbour-aira-0.2.1.tar.gz` e compilare in una
|
||||
cartella nuova (mai sopra una estrazione precedente: i Makefile restano stale).
|
||||
|
||||
### Verifica locale, senza SDK
|
||||
|
||||
@@ -100,6 +100,10 @@ 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**.
|
||||
- **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
|
||||
fondo. Stessa gerarchia nella copertina: casa in grande, ACS in una riga secondaria.
|
||||
- **F3 fatto**: `harbour-aira-bridge.service` (systemd utente, `enable --now`, parte al boot
|
||||
grazie a `Linger=yes`, `Restart=on-failure` verificato con SIGKILL → riparte in ~10 s) e
|
||||
regola `52-aira-bridge-lan.conf` in `/etc/nftables.d/`. Il firewall YunoHost ha
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 30 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 78 KiB After Width: | Height: | Size: 73 KiB |
@@ -29,7 +29,7 @@ CoverBackground {
|
||||
Label {
|
||||
width: parent.width
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
text: cover.t("dhw_current") + " °C"
|
||||
text: cover.t("zone1_temperature") + " °C"
|
||||
color: Theme.primaryColor
|
||||
font.pixelSize: Theme.fontSizeHuge
|
||||
}
|
||||
@@ -37,7 +37,7 @@ CoverBackground {
|
||||
Label {
|
||||
width: parent.width
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
text: qsTr("ACS · obiettivo %1 °C").arg(cover.t("dhw_target"))
|
||||
text: qsTr("casa · obiettivo %1 °C").arg(cover.t("zone1_setpoint"))
|
||||
color: Theme.secondaryColor
|
||||
font.pixelSize: Theme.fontSizeExtraSmall
|
||||
truncationMode: TruncationMode.Fade
|
||||
@@ -46,7 +46,7 @@ CoverBackground {
|
||||
Label {
|
||||
width: parent.width
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
text: qsTr("casa %1 °C · obiettivo %2 °C").arg(cover.t("zone1_temperature")).arg(cover.t("zone1_setpoint"))
|
||||
text: qsTr("ACS %1 °C · obiettivo %2 °C").arg(cover.t("dhw_current")).arg(cover.t("dhw_target"))
|
||||
color: Theme.secondaryColor
|
||||
font.pixelSize: Theme.fontSizeExtraSmall
|
||||
truncationMode: TruncationMode.Fade
|
||||
|
||||
+59
-63
@@ -139,46 +139,7 @@ Page {
|
||||
onClicked: page.openSettings()
|
||||
}
|
||||
|
||||
// ---- acqua calda ---------------------------------------------- //
|
||||
Label {
|
||||
visible: api.configured
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
text: qsTr("Acqua calda sanitaria")
|
||||
color: Theme.secondaryColor
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
}
|
||||
|
||||
Label {
|
||||
visible: api.configured
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
text: page.temp("dhw_current") + " °C"
|
||||
color: Theme.primaryColor
|
||||
font.pixelSize: Theme.fontSizeHuge
|
||||
}
|
||||
|
||||
ProgressBar {
|
||||
visible: api.configured
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
width: parent.width - 4 * Theme.horizontalPageMargin
|
||||
minimumValue: 20
|
||||
maximumValue: 65
|
||||
value: {
|
||||
var v = page.raw("dhw_current")
|
||||
return (v === undefined || v === null) ? 0 : Number(v)
|
||||
}
|
||||
}
|
||||
|
||||
Label {
|
||||
visible: api.configured
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
text: qsTr("obiettivo %1 °C").arg(page.temp("dhw_target"))
|
||||
color: Theme.secondaryColor
|
||||
font.pixelSize: Theme.fontSizeExtraSmall
|
||||
}
|
||||
|
||||
// ---- riscaldamento: temperatura della casa --------------------- //
|
||||
SectionHeader { visible: api.configured; text: qsTr("Riscaldamento") }
|
||||
|
||||
// ---- casa: temperatura della casa (dato principale) ------------ //
|
||||
Label {
|
||||
visible: api.configured
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
@@ -192,25 +153,34 @@ Page {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
text: page.temp("zone1_temperature") + " °C"
|
||||
color: Theme.primaryColor
|
||||
font.pixelSize: Theme.fontSizeLarge
|
||||
font.pixelSize: Theme.fontSizeHuge
|
||||
}
|
||||
|
||||
InfoRow {
|
||||
ProgressBar {
|
||||
visible: api.configured
|
||||
label: qsTr("Obiettivo casa")
|
||||
value: page.temp("zone1_setpoint") + " °C"
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
width: parent.width - 4 * Theme.horizontalPageMargin
|
||||
minimumValue: 5
|
||||
maximumValue: 30
|
||||
value: {
|
||||
var v = page.raw("zone1_temperature")
|
||||
return (v === undefined || v === null) ? 0 : Number(v)
|
||||
}
|
||||
}
|
||||
InfoRow {
|
||||
|
||||
Label {
|
||||
visible: api.configured
|
||||
label: qsTr("Stato riscaldamento")
|
||||
value: api.modeLabel(page.raw("zone1_mode"))
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
text: qsTr("obiettivo %1 °C · %2").arg(page.temp("zone1_setpoint")).arg(api.modeLabel(page.raw("zone1_mode")))
|
||||
color: Theme.secondaryColor
|
||||
font.pixelSize: Theme.fontSizeExtraSmall
|
||||
}
|
||||
|
||||
Slider {
|
||||
id: casaSlider
|
||||
visible: api.configured
|
||||
width: parent.width
|
||||
label: qsTr("Nuovo obiettivo")
|
||||
label: qsTr("Nuovo obiettivo casa")
|
||||
minimumValue: 5
|
||||
maximumValue: 30
|
||||
stepSize: 0.5
|
||||
@@ -237,27 +207,39 @@ Page {
|
||||
function() { api.sendCommand("set_heating_setpoint", page.targetCasa) })
|
||||
}
|
||||
|
||||
// ---- stato impianto ------------------------------------------- //
|
||||
SectionHeader { visible: api.configured; text: qsTr("Impianto") }
|
||||
// ---- acqua calda sanitaria ------------------------------------- //
|
||||
SectionHeader { visible: api.configured; text: qsTr("Acqua calda sanitaria") }
|
||||
|
||||
InfoRow { visible: api.configured; label: qsTr("Temperatura esterna"); value: page.temp("outdoor_temperature") + " °C" }
|
||||
InfoRow { visible: api.configured; label: qsTr("Temperatura interna (pompa)"); value: page.temp("indoor_temperature") + " °C" }
|
||||
InfoRow { visible: api.configured; label: qsTr("Modalità"); value: api.modeLabel(page.raw("operating_status")) }
|
||||
InfoRow { visible: api.configured; label: qsTr("Assenza"); value: page.flag("away_mode") }
|
||||
InfoRow { visible: api.configured; label: qsTr("Night mode"); value: page.flag("night_mode") }
|
||||
InfoRow { visible: api.configured; label: qsTr("Riscaldamento forzato"); value: page.flag("force_heating") }
|
||||
InfoRow { visible: api.configured; label: qsTr("Resistenze integrative"); value: page.flag("inline_heater") }
|
||||
InfoRow { visible: api.configured; label: qsTr("Zone"); value: page.count("zones") }
|
||||
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")) }
|
||||
Label {
|
||||
visible: api.configured
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
text: page.temp("dhw_current") + " °C"
|
||||
color: Theme.primaryColor
|
||||
font.pixelSize: Theme.fontSizeLarge
|
||||
}
|
||||
|
||||
// ---- comandi --------------------------------------------------- //
|
||||
SectionHeader { visible: api.configured; text: qsTr("Comandi acqua calda") }
|
||||
ProgressBar {
|
||||
visible: api.configured
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
width: parent.width - 4 * Theme.horizontalPageMargin
|
||||
minimumValue: 20
|
||||
maximumValue: 65
|
||||
value: {
|
||||
var v = page.raw("dhw_current")
|
||||
return (v === undefined || v === null) ? 0 : Number(v)
|
||||
}
|
||||
}
|
||||
|
||||
InfoRow {
|
||||
visible: api.configured
|
||||
label: qsTr("Obiettivo acqua calda")
|
||||
value: page.temp("dhw_target") + " °C"
|
||||
}
|
||||
|
||||
Slider {
|
||||
visible: api.configured
|
||||
width: parent.width
|
||||
label: qsTr("Obiettivo acqua calda")
|
||||
label: qsTr("Nuovo obiettivo")
|
||||
minimumValue: 45
|
||||
maximumValue: 60
|
||||
stepSize: 1
|
||||
@@ -312,6 +294,20 @@ Page {
|
||||
function() { api.sendCommand("hot_water_boost_off") })
|
||||
}
|
||||
|
||||
// ---- stato impianto ------------------------------------------- //
|
||||
SectionHeader { visible: api.configured; text: qsTr("Impianto") }
|
||||
|
||||
InfoRow { visible: api.configured; label: qsTr("Temperatura esterna"); value: page.temp("outdoor_temperature") + " °C" }
|
||||
InfoRow { visible: api.configured; label: qsTr("Temperatura interna (pompa)"); value: page.temp("indoor_temperature") + " °C" }
|
||||
InfoRow { visible: api.configured; label: qsTr("Modalità"); value: api.modeLabel(page.raw("operating_status")) }
|
||||
InfoRow { visible: api.configured; label: qsTr("Assenza"); value: page.flag("away_mode") }
|
||||
InfoRow { visible: api.configured; label: qsTr("Night mode"); value: page.flag("night_mode") }
|
||||
InfoRow { visible: api.configured; label: qsTr("Riscaldamento forzato"); value: page.flag("force_heating") }
|
||||
InfoRow { visible: api.configured; label: qsTr("Resistenze integrative"); value: page.flag("inline_heater") }
|
||||
InfoRow { visible: api.configured; label: qsTr("Zone"); value: page.count("zones") }
|
||||
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")) }
|
||||
|
||||
BusyIndicator {
|
||||
visible: api.busy
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
Name: harbour-aira
|
||||
Summary: Control your Aira heat pump through a local bridge
|
||||
Version: 0.2.0
|
||||
Version: 0.2.1
|
||||
Release: 1
|
||||
Group: Qt/Qt
|
||||
License: MIT
|
||||
|
||||
+26
-32
@@ -118,44 +118,41 @@ def main_screen() -> Image.Image:
|
||||
page_header(d, "Aira")
|
||||
|
||||
y = 156
|
||||
c = "Acqua calda"
|
||||
d.text(((W - d.textlength(c, font=font(26))) / 2, y), c, font=font(26), fill=SECONDARY)
|
||||
# ---- casa: il dato principale, in cima ------------------------------- #
|
||||
c = "Temperatura in casa"
|
||||
d.text(((W - d.textlength(c, font=font(24))) / 2, y), c, font=font(24), fill=SECONDARY)
|
||||
y += 40
|
||||
big = "51,0 °C"
|
||||
big = "23,0 °C"
|
||||
d.text(((W - d.textlength(big, font=font(92, bold=True))) / 2, y),
|
||||
big, font=font(92, bold=True), fill=PRIMARY)
|
||||
y += 116
|
||||
progress(d, y, (51.0 - 20) / (65 - 20))
|
||||
progress(d, y, (23.0 - 5) / (30 - 5))
|
||||
y += 22
|
||||
t = "obiettivo 55,0 °C"
|
||||
t = "obiettivo 19,0 °C · Riscaldamento"
|
||||
d.text(((W - d.textlength(t, font=font(24))) / 2, y), t, font=font(24), fill=SECONDARY)
|
||||
|
||||
# ---- riscaldamento: temperatura della casa -------------------------- #
|
||||
y = section_header(d, y + 44, "Riscaldamento")
|
||||
c = "Temperatura in casa"
|
||||
d.text(((W - d.textlength(c, font=font(24))) / 2, y), c, font=font(24), fill=SECONDARY)
|
||||
y += 34
|
||||
big2 = "23,0 °C"
|
||||
d.text(((W - d.textlength(big2, font=font(64, bold=True))) / 2, y),
|
||||
big2, font=font(64, bold=True), fill=PRIMARY)
|
||||
y += 88
|
||||
y = label_pair(d, y, "Obiettivo casa", "19,0 °C")
|
||||
y = label_pair(d, y, "Stato riscaldamento", "Riscaldamento")
|
||||
y = slider(d, y + 14, (19.0 - 5) / (30 - 5), "19,0 °C", "Nuovo obiettivo")
|
||||
y += 46
|
||||
y = slider(d, y, (19.0 - 5) / (30 - 5), "19,0 °C", "Nuovo obiettivo casa")
|
||||
y = button(d, y, "Imposta casa a 19,0 °C", primary=True)
|
||||
|
||||
y = section_header(d, y + 24, "Impianto")
|
||||
y = label_pair(d, y, "Esterna", "18,0 °C")
|
||||
y = label_pair(d, y, "Interna (pompa)", "22,5 °C")
|
||||
y = label_pair(d, y, "Modalità", "Automatico")
|
||||
y = label_pair(d, y, "Errori", "0")
|
||||
|
||||
y = section_header(d, y + 24, "Comandi acqua calda")
|
||||
y = slider(d, y, (55.0 - 45) / (60 - 45), "55 °C")
|
||||
# ---- acqua calda sanitaria ------------------------------------------- #
|
||||
y = section_header(d, y + 24, "Acqua calda sanitaria")
|
||||
acs = "51,0 °C"
|
||||
d.text(((W - d.textlength(acs, font=font(56, bold=True))) / 2, y),
|
||||
acs, font=font(56, bold=True), fill=PRIMARY)
|
||||
y += 76
|
||||
progress(d, y, (51.0 - 20) / (65 - 20))
|
||||
y += 22
|
||||
y = label_pair(d, y, "Obiettivo acqua calda", "55,0 °C")
|
||||
y = slider(d, y + 10, (55.0 - 45) / (60 - 45), "55 °C")
|
||||
y = button(d, y, "Imposta obiettivo ACS", primary=True)
|
||||
y = button(d, y, "Avvia boost ACS")
|
||||
y = button(d, y, "Ferma boost ACS")
|
||||
|
||||
# ---- stato impianto (scorre sotto) ----------------------------------- #
|
||||
y = section_header(d, y + 24, "Impianto")
|
||||
y = label_pair(d, y, "Esterna", "18,0 °C")
|
||||
y = label_pair(d, y, "Interna (pompa)", "22,5 °C")
|
||||
|
||||
d.text(((W - d.textlength("Trascina verso il basso per aggiornare",
|
||||
font=font(22))) / 2, y + 8),
|
||||
"Trascina verso il basso per aggiornare", font=font(22), fill=SECONDARY)
|
||||
@@ -206,19 +203,16 @@ def cover_screen() -> Image.Image:
|
||||
d.line([(card[0] + 34, card[1] + 100), (card[2] - 34, card[1] + 100)],
|
||||
fill=BTN_EDGE, width=2)
|
||||
y = card[1] + 132
|
||||
big = "51,0 °C"
|
||||
big = "23,0 °C"
|
||||
d.text(((W - d.textlength(big, font=font(76, bold=True))) / 2, y),
|
||||
big, font=font(76, bold=True), fill=PRIMARY)
|
||||
y += 108
|
||||
for lab, val in (("obiettivo", "55,0 °C"), ("esterna", "18,0 °C")):
|
||||
for lab, val in (("obiettivo", "19,0 °C"), ("ACS", "51,0 °C"), ("esterna", "18,0 °C")):
|
||||
d.text((card[0] + 34, y), lab, font=font(24), fill=SECONDARY)
|
||||
vw = d.textlength(val, font=font(24))
|
||||
d.text((card[2] - 34 - vw, y), val, font=font(24), fill=PRIMARY)
|
||||
y += 52
|
||||
vw = d.textlength("23,0 °C", font=font(24))
|
||||
d.text((card[0] + 34, y), "casa", font=font(24), fill=SECONDARY)
|
||||
d.text((card[2] - 34 - vw, y), "23,0 °C", font=font(24), fill=PRIMARY)
|
||||
d.text((card[0] + 34, card[3] - 60), "acqua calda sanitaria", font=font(22), fill=SECONDARY)
|
||||
d.text((card[0] + 34, card[3] - 60), "temperatura in casa", font=font(22), fill=SECONDARY)
|
||||
return img
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user