Files
harbour-aira/qml/pages/SetpointsPage.qml
T
Carlo f4bee218bb 0.7.6: via il banner del remorse dai tasti rapidi
Alla pressione Silica ri-parenta il RemorseItem dentro la fila dei tre tasti e
ci disegna sopra il banner (messaggio + conto alla rovescia) a margini fissi:
il suo riquadro non ha la larghezza del tasto, quindi copre i tasti vicini.
Il messaggio lo mostra gia' la NoticeBar, che ora ha altezza fissa a una riga e
una banda riservata sotto il contenuto in tutte e cinque le pagine.
2026-10-11 17:26:13 +02:00

267 lines
9.3 KiB
QML

import QtQuick 2.2
import Sailfish.Silica 1.0
import "../components"
// Regolazioni: le grandezze che si cambiano (obiettivo casa, obiettivo acqua
// calda) e il boost, ognuna con il valore attuale sempre visibile, le
// preimpostazioni per le dita fredde e la conferma esplicita.
//
// Pagina a parte perche' la Home deve restare una schermata da guardare: due
// slider dentro la pagina che scorre si contendevano anche il trascinamento.
// Qui lo slider e' la PROPOSTA, il numero grande e' quello vero dell'impianto:
// i due coincidono solo dopo "Imposta".
//
// La Home passa l'oggetto toccato ("house" o "water") e si vedono solo le sue
// regolazioni: toccando "Acqua calda" non ha senso trovarsi davanti anche la
// casa. Senza parametro si vedono tutte, come in origine.
Page {
id: page
allowedOrientations: Orientation.All
property string section: ""
property bool mostraCasa: page.section !== "water"
property bool mostraAcqua: page.section !== "house"
property real pendingHouse: 0
property bool houseTouched: false
property real pendingWater: 0
property bool waterTouched: false
function raw(key) {
return api.summary[key]
}
function fmt(value) { return api.formatValue(value) }
// Obiettivo vero dell'impianto (zona 1), a passi di mezzo grado.
function houseTarget() {
var v = page.raw("zone1_setpoint")
if (v === undefined || v === null || Number(v) <= 0)
return 0
return Math.round(Number(v) * 2) / 2
}
function waterTarget() {
var v = page.raw("dhw_target")
if (v === undefined || v === null)
return 0
return Math.round(Number(v))
}
// Allinea le proposte ai valori dell'impianto, ma non sovrascrive quello
// che l'utente sta scegliendo.
function syncFromPlant() {
if (!page.houseTouched)
page.pendingHouse = page.houseTarget()
if (!page.waterTouched)
page.pendingWater = page.waterTarget()
}
function houseChanged() { return Math.abs(page.pendingHouse - page.houseTarget()) > 0.001 }
function waterChanged() { return Math.abs(page.pendingWater - page.waterTarget()) > 0.001 }
// UNA sola assegnazione: in Qt 5.6 assegnare Component.onCompleted due volte
// nello stesso oggetto e' un errore di compilazione del file.
Component.onCompleted: {
page.syncFromPlant()
if (api.configured)
api.refresh()
}
Connections {
target: api
onSummaryChanged: page.syncFromPlant()
}
SilicaFlickable {
anchors.fill: parent
// Banda riservata al messaggio in fondo: cosi' non copre il contenuto.
anchors.bottomMargin: notice.banda
contentHeight: col.height + Theme.paddingLarge
PullDownMenu {
MenuItem {
text: qsTr("Refresh")
onClicked: api.refresh()
}
MenuItem {
text: qsTr("Data")
onClicked: pageStack.push(Qt.resolvedUrl("DataPage.qml"))
}
MenuItem {
text: qsTr("Plant")
onClicked: pageStack.push(Qt.resolvedUrl("PlantPage.qml"))
}
MenuItem {
text: qsTr("Settings")
onClicked: pageStack.push(Qt.resolvedUrl("SettingsPage.qml"))
}
}
Column {
id: col
width: parent.width
spacing: Theme.paddingSmall
PageHeader { title: qsTr("Setpoints") }
// ---- riscaldamento casa ---------------------------------------- //
SectionHeader {
visible: page.mostraCasa
text: qsTr("Heating the house")
}
ValueRow {
visible: page.mostraCasa
title: qsTr("Current target")
subtitle: qsTr("What the plant is keeping now")
value: page.fmt(page.houseTarget()) + " °C"
}
Slider {
id: casaSlider
visible: page.mostraCasa
width: parent.width
label: qsTr("New house target")
minimumValue: 5
maximumValue: 30
stepSize: 0.5
value: page.pendingHouse
valueText: page.fmt(value) + " °C"
onValueChanged: {
// Solo un movimento vero dell'utente segna "toccato": il
// valore che arriva dall'impianto non deve bloccarlo.
if (Math.abs(page.pendingHouse - value) > 0.001) {
page.houseTouched = true
page.pendingHouse = Math.round(value * 2) / 2
}
}
}
Row {
visible: page.mostraCasa
x: Theme.horizontalPageMargin
width: col.width - 2 * Theme.horizontalPageMargin
spacing: Theme.paddingSmall
Repeater {
model: [16, 17, 18, 19, 20, 21]
Button {
width: (col.width - 2 * Theme.horizontalPageMargin
- 5 * Theme.paddingSmall) / 6
text: modelData + "°"
onClicked: {
page.houseTouched = true
page.pendingHouse = modelData
}
}
}
}
ActionButton {
visible: page.mostraCasa
text: qsTr("Set house to %1 °C").arg(page.fmt(page.pendingHouse))
confirmText: qsTr("House temperature to %1 °C").arg(page.fmt(page.pendingHouse))
enabled: page.houseChanged()
onTriggered: api.sendCommand("set_heating_setpoint", page.pendingHouse)
}
// ---- acqua calda sanitaria ------------------------------------- //
SectionHeader {
visible: page.mostraAcqua
text: qsTr("Domestic hot water")
}
ValueRow {
visible: page.mostraAcqua
title: qsTr("DHW target")
subtitle: qsTr("Water now %1 °C").arg(page.fmt(page.raw("dhw_current")))
value: page.fmt(page.waterTarget()) + " °C"
}
Slider {
id: acquaSlider
visible: page.mostraAcqua
width: parent.width
label: qsTr("New target")
minimumValue: 45
maximumValue: 60
stepSize: 1
value: page.pendingWater
valueText: page.fmt(value) + " °C"
onValueChanged: {
if (Math.abs(page.pendingWater - value) > 0.001) {
page.waterTouched = true
page.pendingWater = Math.round(value)
}
}
}
Row {
visible: page.mostraAcqua
x: Theme.horizontalPageMargin
width: col.width - 2 * Theme.horizontalPageMargin
spacing: Theme.paddingSmall
Repeater {
model: [45, 47, 50, 55, 60]
Button {
width: (col.width - 2 * Theme.horizontalPageMargin
- 4 * Theme.paddingSmall) / 5
text: modelData + "°"
onClicked: {
page.waterTouched = true
page.pendingWater = modelData
}
}
}
}
ActionButton {
visible: page.mostraAcqua
text: qsTr("Set target %1 °C").arg(page.fmt(page.pendingWater))
confirmText: qsTr("DHW target to %1 °C").arg(page.fmt(page.pendingWater))
enabled: page.waterChanged()
onTriggered: api.sendCommand("set_hot_water_target", page.pendingWater)
}
// ---- boost ------------------------------------------------------ //
// Il boost e' dell'acqua calda: si vede con lei.
SectionHeader {
visible: page.mostraAcqua
text: qsTr("Hot water boost")
}
ActionButton {
visible: page.mostraAcqua
text: qsTr("Start DHW boost")
confirmText: qsTr("Starting DHW boost")
onTriggered: api.sendCommand("hot_water_boost_on")
}
ActionButton {
visible: page.mostraAcqua
text: qsTr("Stop DHW boost")
confirmText: qsTr("Stopping DHW boost")
onTriggered: api.sendCommand("hot_water_boost_off")
}
Label {
x: Theme.horizontalPageMargin
width: parent.width - 2 * Theme.horizontalPageMargin
text: qsTr("Commands go through the bridge and may take a few seconds. The status refreshes by itself afterwards.")
color: Theme.secondaryColor
font.pixelSize: Theme.fontSizeExtraSmall
wrapMode: Text.Wrap
}
Item { width: 1; height: Theme.paddingMedium }
}
}
NoticeBar { id: notice }
}