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". Page { id: page allowedOrientations: Orientation.All 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 } Component.onCompleted: { page.syncFromPlant() if (api.configured) api.refresh() } Connections { target: api onSummaryChanged: page.syncFromPlant() } SilicaFlickable { anchors.fill: parent 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 { text: qsTr("Heating the house") } ValueRow { title: qsTr("Current target") subtitle: qsTr("What the plant is keeping now") value: page.fmt(page.houseTarget()) + " °C" } Slider { id: casaSlider 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 { 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 { 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 { text: qsTr("Domestic hot water") } ValueRow { 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 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 { 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 { 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 ------------------------------------------------------ // SectionHeader { text: qsTr("Hot water boost") } ActionButton { text: qsTr("Start DHW boost") confirmText: qsTr("Starting DHW boost") onTriggered: api.sendCommand("hot_water_boost_on") } ActionButton { 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 { } }