ingo wrote: > Rather stuck with this one, I'd like to automatically (re)set the > propery "relaystate" when one of the others (Tm, Tset, Th) is set, > regardless of wether their value has changed.
The easiest way to achieve your goal seems to be a read-only property: # this creates a class that should be shared by all RelayState instances; # therefore it belongs on the module level RelayState = namedtuple('RelayState', ['heat', 'cool']) # the states are immutable and can safely be defined outside the method HEAT = rlstate(1, 0) COOL = rlstate(0, 1) OFF = rlstate(0, 0) class Thermostat(): ... @property def relaystate(self): logger.debug("GETTER relaystate") lower = self.Tset - self.Th upper = self.Tset + self.Th if self.Tm < lower: return HEAT elif self.Tm > upper: return COOL else: return OFF If that doesn't work (because you want to operate an actual relay, say) you probably have to trigger a change in the TXXX setters: class Thermostat(): def __init__(self, Tm=20, Tset=20, Th=0.3): self._relaystate = None self.Tm = Tm self.Tset = Tset self.Th = Th def update_relaystate(self): try: state = self.calculate_relaystate() except AttributeError: pass else: self.relaystate = state @property def Tm(self): logger.debug("GETTER Tm") return self._Tm @Tm.setter def Tm(self, value): logger.debug("SETTER Tm") self._Tm = value self.update_relaystate() ... @property def relaystate(self): logger.debug("GETTER relaystate") return self._relaystate @relaystate.setter def relaystate(self, value): if value != self.relaystate: logger.debug( "SWITCHING relaystate from %s to %s", self.relaystate, value) self._relaystate = value def calculate_relaystate(self): lower = self.Tset-self.Th upper = self.Tset+self.Th if self.Tm < lower: return HEAT elif self.Tm > upper: return COOL else: return OFF > > Ingo > > My code so far: > > from collections import namedtuple > import logging > > logger = logging.getLogger() > logger.setLevel(logging.DEBUG) > stream_handler = logging.StreamHandler() > stream_handler.setLevel(logging.DEBUG) > formatter = logging.Formatter( > '[%(levelname)-8s] %(asctime)s (%(name)-8s) - %(message)s', > '%Y-%m-%d %H:%M:%S', > ) > stream_handler.setFormatter(formatter) > logger.addHandler(stream_handler) > > > class Thermostat(): > def __init__(self, Tm=20, Tset=20, Th=0.3): > logger.debug("__INIT__") > self.Tm = Tm > self.Tset = Tset > self.Th = Th > self.relaystate = None > > @property > def Tm(self): > logger.debug("GETTER Tm") > return self._Tm > @Tm.setter > def Tm(self, value): > logger.debug("SETTER Tm") > self._Tm = value > > @property > def Tset(self): > logger.debug("GETTER Tset") > return self._Tset > @Tset.setter > def Tset(self, value): > logger.debug("SETTER Tset") > self._Tset = value > > @property > def Th(self): > logger.debug("GETTER Th") > return self._Th > @Th.setter > def Th(self, value): > logger.debug("SETTER Th") > self._Th = value > > @property > def relaystate(self): > logger.debug("GETTER relaystate") > return self._relaystate > @relaystate.setter > def relaystate(self, value): > logger.debug("SETTER relaystate") > #on init while setting Tm, Tset and Th are not known > #so relaystate can not be calculated > try: > lower = self.Tset-self.Th > upper = self.Tset+self.Th > except AttributeError as e: > logger.debug("SETTER relaystate : %s", e) > self._relaystate = None > rlstate = namedtuple('relaystate', ['heat', 'cool']) > if self.Tm < lower: > value = rlstate(1,0) > elif self.Tm > upper: > value = rlstate(0,1) > elif self.Tm > lower and self.Tm < upper: > value = rlstate(0,0) > self._relaystate = value > > > if __name__ == "__main__": > > TS1 = Thermostat() > TS1.Tset = 44 > print("heat : ",TS1.relaystate.heat,"cool : ",TS1.relaystate.cool) > > _______________________________________________ > Tutor maillist - Tutor@python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor _______________________________________________ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor