123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244 |
- #
- # Moisture control - Global status/configuration widgets
- #
- # Copyright (c) 2013 Michael Buesch <m@bues.ch>
- #
- # This program is free software; you can redistribute it and/or modify
- # it under the terms of the GNU General Public License as published by
- # the Free Software Foundation; either version 2 of the License, or
- # (at your option) any later version.
- #
- # This program is distributed in the hope that it will be useful,
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- # GNU General Public License for more details.
- #
- # You should have received a copy of the GNU General Public License along
- # with this program; if not, write to the Free Software Foundation, Inc.,
- # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- #
- from pymoistcontrol.util import *
- from pymoistcontrol.potwidgets import *
- from pymoistcontrol.adcwidgets import *
- from pymoistcontrol.dayofweek import *
- from pymoistcontrol.bitindicator import *
- class GlobalConfigWidget(QWidget):
- """Global configuration widget."""
- # Signal: Emitted, if a configuration item changed.
- configChanged = Signal()
- # Signal: Emitted, if the RTC date or time was edited.
- rtcEdited = Signal()
- def __init__(self, parent):
- """Class constructor."""
- QWidget.__init__(self, parent)
- self.setLayout(QGridLayout(self))
- y = 0
- self.__shouldCheckRtc = True
- self.enableCheckBox = QCheckBox("Enable the regulator globally",
- self)
- self.layout().addWidget(self.enableCheckBox, y, 0, 1, 2)
- y += 1
- self.watchdogWarning = QLabel()
- palette = self.watchdogWarning.palette()
- palette.setColor(QPalette.WindowText, QColor(255, 0, 0))
- self.watchdogWarning.setPalette(palette)
- self.watchdogWarning.hide()
- self.watchdogWarningPotNumbers = []
- self.layout().addWidget(self.watchdogWarning, y, 0, 1, 2)
- y += 1
- label = QLabel("RTC time:", self)
- self.layout().addWidget(label, y, 0)
- hbox = QHBoxLayout()
- self.rtcEdit = QDateTimeEdit(self)
- self.rtcEdit.setDisplayFormat("yyyy.MM.dd hh:mm:ss")
- self.rtcEdit.setReadOnly(True)
- hbox.addWidget(self.rtcEdit)
- self.rtcEditCheckBox = QCheckBox("edit", self)
- hbox.addWidget(self.rtcEditCheckBox)
- self.layout().addLayout(hbox, y, 1)
- y += 1
- self.statWidgets = []
- for i in range(MAX_NR_FLOWERPOTS):
- label = QLabel("Pot %d:" % (i + 1), self)
- self.layout().addWidget(label, y, 0)
- potStatWidget = PotShortStatusWidget(i, self)
- self.statWidgets.append(potStatWidget)
- self.layout().addWidget(potStatWidget, y, 1)
- y += 1
- self.stateLabel = QLabel(self)
- self.layout().addWidget(self.stateLabel, y, 0, 1, 2)
- y += 1
- self.advancedCheckBox = QCheckBox("Advanced", self)
- self.layout().addWidget(self.advancedCheckBox, y, 0, 1, 2)
- y += 1
- self.advancedGroup = QGroupBox(self)
- self.advancedGroup.setLayout(QGridLayout())
- self.layout().addWidget(self.advancedGroup, y, 0, 1, 2)
- y += 1
- label = QLabel("Lowest possible ADC value:", self)
- self.advancedGroup.layout().addWidget(label, 0, 0)
- self.lowestSensorSpin = ADCSpinBox(self)
- self.advancedGroup.layout().addWidget(self.lowestSensorSpin, 0, 1)
- label = QLabel("Highest possible ADC value:", self)
- self.advancedGroup.layout().addWidget(label, 1, 0)
- self.highestSensorSpin = ADCSpinBox(self)
- self.advancedGroup.layout().addWidget(self.highestSensorSpin, 1, 1)
- self.ignoreChanges = 0
- self.enableCheckBox.stateChanged.connect(self.__enableChanged)
- self.rtcEditCheckBox.stateChanged.connect(self.__rtcEditChanged)
- self.advancedCheckBox.stateChanged.connect(self.__advancedChanged)
- self.lowestSensorSpin.valueChanged.connect(self.__lowestSensorChanged)
- self.highestSensorSpin.valueChanged.connect(self.__highestSensorChanged)
- self.__advancedChanged(self.advancedCheckBox.checkState())
- def globalEnableActive(self):
- return self.enableCheckBox.checkState() == Qt.Checked
- def getRtcDateTime(self):
- return self.rtcEdit.dateTime()
- def lowestRawSensorVal(self):
- return self.lowestSensorSpin.value()
- def highestRawSensorVal(self):
- return self.highestSensorSpin.value()
- def __lowestSensorChanged(self, newValue):
- if not self.ignoreChanges:
- self.configChanged.emit()
- def __highestSensorChanged(self, newValue):
- if not self.ignoreChanges:
- self.configChanged.emit()
- def __advancedChanged(self, newState):
- if newState == Qt.Checked:
- self.advancedGroup.show()
- else:
- self.advancedGroup.hide()
- def __enableChanged(self, newState):
- if self.ignoreChanges:
- return
- if newState != Qt.Checked:
- res = QMessageBox.question(self,
- "Disable globally?",
- "Do you really want to disable the "
- "controller globally?\n"
- "Watering of all pots will be stopped.",
- QMessageBox.Yes | QMessageBox.No)
- if res != QMessageBox.Yes:
- self.enableCheckBox.setCheckState(Qt.Checked)
- return
- self.configChanged.emit()
- def __rtcEditChanged(self, newState):
- if newState == Qt.Checked:
- self.rtcEdit.setReadOnly(False)
- else:
- self.rtcEdited.emit()
- self.rtcEdit.setReadOnly(True)
- def handleGlobalConfMessage(self, msg):
- self.ignoreChanges += 1
- if msg.flags & msg.CONTR_FLG_ENABLE:
- self.enableCheckBox.setCheckState(Qt.Checked)
- else:
- self.enableCheckBox.setCheckState(Qt.Unchecked)
- self.lowestSensorSpin.setValue(msg.sensor_lowest_value)
- self.highestSensorSpin.setValue(msg.sensor_highest_value)
- self.__shouldCheckRtc = True
- self.ignoreChanges -= 1
- def handleGlobalStateMessage(self, msg):
- text = []
- if msg.flags & msg.CONTRSTAT_ONOFFSWITCH:
- text.append("Hardware switch is on")
- else:
- text.append("Hardware switch is OFF")
- if msg.flags & msg.CONTRSTAT_NOTIFLED:
- text.append("Notification LED is ON")
- self.stateLabel.setText("; ".join(text))
- def handlePotStateMessage(self, msg):
- self.ignoreChanges += 1
- self.statWidgets[msg.pot_number].handlePotStateMessage(msg)
- self.ignoreChanges -= 1
- def __updateWatchdogWarning(self):
- if self.watchdogWarningPotNumbers:
- self.watchdogWarning.setText(
- "WARNING: The watering watchdog was triggered.\n"\
- "Watering is disabled on: %s" %\
- ", ".join("pot %d" % (n + 1) for n in self.watchdogWarningPotNumbers))
- self.watchdogWarning.show()
- else:
- self.watchdogWarning.setText("")
- self.watchdogWarning.hide()
- def handlePotRemStateMessage(self, msg):
- self.ignoreChanges += 1
- if msg.flags & msg.POT_REMFLG_WDTRIGGER:
- if msg.pot_number not in self.watchdogWarningPotNumbers:
- self.watchdogWarningPotNumbers.append(msg.pot_number)
- self.__updateWatchdogWarning()
- else:
- if msg.pot_number in self.watchdogWarningPotNumbers:
- self.watchdogWarningPotNumbers.remove(msg.pot_number)
- self.__updateWatchdogWarning()
- self.ignoreChanges -= 1
- def handlePotConfMessage(self, msg):
- self.ignoreChanges += 1
- self.statWidgets[msg.pot_number].enableMessageHandling(msg.flags & msg.POT_FLG_ENABLED)
- self.ignoreChanges -= 1
- def handlePotEnableChange(self, potNumber, enabled):
- self.statWidgets[potNumber].enableMessageHandling(enabled)
- def __syncRtc(self):
- # Sync RTC with PC clock.
- self.rtcEditCheckBox.setCheckState(Qt.Unchecked)
- self.rtcEdit.setDateTime(QDateTime.currentDateTime())
- self.rtcEdited.emit()
- def handleRtcMessage(self, msg):
- self.ignoreChanges += 1
- date = QDate(2000 + msg.year, msg.month + 1, msg.day + 1)
- time = QTime(msg.hour, msg.minute, msg.second)
- dateTime = QDateTime(date, time)
- if self.rtcEdit.isReadOnly():
- self.rtcEdit.setDateTime(dateTime)
- if self.__shouldCheckRtc:
- error = QDateTime.currentDateTime().secsTo(dateTime)
- if abs(error) > 30:
- res = QMessageBox.question(self,
- "Fix RTC time drift?",
- "The RTC is off by %d seconds.\n"
- "Do you want to synchronize the RTC "
- "with the PC's clock?" % error,
- QMessageBox.Yes | QMessageBox.No,
- QMessageBox.Yes)
- if res == QMessageBox.Yes:
- self.__syncRtc()
- self.__shouldCheckRtc = False
- self.ignoreChanges -= 1
|