X-Git-Url: https://git.linta.de/?p=~helmut%2Fonoff.git;a=blobdiff_plain;f=onoff%2Fcommon.py;h=5d9565cd553c144a2815f171a811389c020bd343;hp=b491c6b95514ec23eee63b80dfe187cc1bba91a1;hb=873cb2015c559466d35bda40f0fba8abbb4c8cb5;hpb=87af7fc4fb334b2fa445ea3b1b278aceff51e12a diff --git a/onoff/common.py b/onoff/common.py index b491c6b..5d9565c 100644 --- a/onoff/common.py +++ b/onoff/common.py @@ -1,19 +1,18 @@ -""" -Defined states: - - 0: The device is inactive. - - ST_ACTIVE|ST_TRANSITION: The device is transitioning from inactive to active. - - ST_ACTIVE: The device is active. - - ST_TRANSITION: The device is transitioning from active to inactive. -""" - +import enum import logging -from gi.repository import GObject +from .gobject import ScheduledFunction logger = logging.getLogger("onoff.common") -ST_ACTIVE = 1 -ST_TRANSITION = 2 + +class OnoffState(enum.Flag): + inactive = 0 + active = 1 + deactivating = 2 + activating = 3 + transition = 2 + class OnoffDevice(object): """A device is a thing with two states, that can be asked to transition @@ -56,11 +55,11 @@ class InvertedDevice(OnoffDevice): self.device.notify.add(self.changestate) def changestate(self, state): - OnoffDevice.changestate(self, state ^ ST_ACTIVE) + OnoffDevice.changestate(self, state ^ OnoffState.active) @property def state(self): - return self.device.state ^ ST_ACTIVE + return self.device.state ^ OnoffState.active def activate(self): self.device.deactivate() @@ -80,7 +79,8 @@ class ThrottledDevice(OnoffDevice): """ @type device: OnoffDevice @type ondelay: int or float - @param ondelay: delay the report of ST_ACTIVE by this many seconds + @param ondelay: delay the report of OnoffState.active by this many + seconds @type offdelay: int or float @param offdelay: delay the actual deactivation by this many seconds """ @@ -88,7 +88,7 @@ class ThrottledDevice(OnoffDevice): self.device = device self.ondelay = ondelay self.offdelay = offdelay - self.desired_state = 0 + self.desired_state = OnoffState.inactive self.transition = None self.device.notify.add(self.changestate) @@ -96,25 +96,24 @@ class ThrottledDevice(OnoffDevice): def state(self): if self.transition is None: return self.device.state - return self.desired_state | ST_TRANSITION + return self.desired_state | OnoffState.transition def _schedule_transition(self, delay, func): assert self.transition is None - self.transition = GObject.timeout_add(int(1000 * delay), func) + self.transition = ScheduledFunction(delay, func) def _cancel_transition(self): assert self.transition is not None - ret = GObject.source_remove(self.transition) - assert ret + self.transition.cancel() self.transition = None def changestate(self, state): - if state != ST_ACTIVE: + if state != OnoffState.active: OnoffDevice.changestate(self, state) else: - if self.desired_state == 0: - logger.warn("device became active but we want inactive," + - "suppresing signal") + if self.desired_state == OnoffState.inactive: + logger.warning("device became active but we want inactive," + + "suppresing signal") elif self.transition is None: logger.debug("scheduling report of activation in %.1fs", self.ondelay) @@ -123,32 +122,41 @@ class ThrottledDevice(OnoffDevice): logger.debug("suppressing duplicate activation signal") def _report_active(self): - assert self.desired_state == ST_ACTIVE + assert self.desired_state == OnoffState.active assert self.transition is not None self.transition = None logger.debug("delivering activation signal") - OnoffDevice.changestate(self, ST_ACTIVE) + OnoffDevice.changestate(self, OnoffState.active) def activate(self): - if self.desired_state == 0 and self.transition is not None: + if self.desired_state == OnoffState.inactive and \ + self.transition is not None: logger.debug("cancelling pending deactivation") self._cancel_transition() - self.desired_state = ST_ACTIVE + curstate = self.device.state + if curstate == OnoffState.active: + self.desired_state = OnoffState.active + OnoffDevice.changestate(self, OnoffState.active) + return + logger.warning("device should be active during delayed " + + "deactivation, but is in state %s", curstate.name) + self.desired_state = OnoffState.active self.device.activate() self.changestate(self.device.state) def _do_stop(self): - assert self.desired_state == 0 + assert self.desired_state == OnoffState.inactive assert self.transition is not None self.transition = None logger.debug("actually deactivating") self.device.deactivate() def deactivate(self): - if self.desired_state == ST_ACTIVE and self.transition is not None: + if self.desired_state == OnoffState.active and \ + self.transition is not None: logger.debug("cancelling pending activation report") self._cancel_transition() - self.desired_state = 0 + self.desired_state = OnoffState.inactive if self.transition is None: logger.debug("scheduling actual deactivate in %.1fs", self.offdelay) @@ -161,7 +169,7 @@ class ThrottledDevice(OnoffDevice): if self.transition is not None: logger.info("cancelling pending transition") self._cancel_transition() - if self.desired_state == 0: + if self.desired_state == OnoffState.inactive: logger.info("invoking pending deactivate early during close") self.device.deactivate() self.device.notify.remove(self.changestate)