Merge branch 'master' of ralfj.de:saartuer
authorRalf Jung <post@ralfj.de>
Mon, 14 Oct 2013 17:22:28 +0000 (19:22 +0200)
committerRalf Jung <post@ralfj.de>
Mon, 14 Oct 2013 17:22:28 +0000 (19:22 +0200)
1  2 
statemachine.py

diff --combined statemachine.py
index f2cac47d8df7d2462aaf8222b48816d4bd0a35e0,8f1c2fafc654d3a27977c5fe99d51e69129cef45..332f48de5e3f6f2b19566c5e39556a92c967fd85
@@@ -1,4 -1,4 +1,4 @@@
- from libtuer import ThreadFunction, logger, fire_and_forget
8from libtuer import ThreadFunction, logger, fire_and_forget
  from actor import Actor
  import os, random
  
@@@ -23,9 -23,9 +23,9 @@@ CLOSE_REPEAT_TIMEOUT = 
  CLOSE_REPEAT_NUMBER = 3
  
  # StateAboutToOpen constants
- ABOUTOPEN_NERVLIST = [(5, lambda : play_sound("flipswitch")), (10, lambda:play_sound("flipswitch")), (10, lambda:Logger.warning("Space open but switch not flipped for 10 seconds")),\
-       (20, lambda:play_sound("flipswitch")), (30, lambda:play_sound("flipswitch")), (30, lambda:Logger.error("Space open but switch not flipped for 30 seconds")),\
-       (40, lambda:play_sound("flipswitch")), (50, lambda:play_sound("flipswitch")), (56, lambda:play_sound("flipswitch")), (60, lambda:Logger.critical("Space open but switch not flipped for 60 seconds"))]
+ ABOUTOPEN_NERVLIST = [(5, lambda : play_sound("flipswitch")), (5, lambda:play_sound("flipswitch")), (0, lambda:Logger.warning("Space open but switch not flipped for 10 seconds")),\
+       (10, lambda:play_sound("flipswitch")), (10, lambda:play_sound("flipswitch")), (0, lambda:Logger.error("Space open but switch not flipped for 30 seconds")),\
+       (10, lambda:play_sound("flipswitch")), (10, lambda:play_sound("flipswitch")), (6, lambda:play_sound("flipswitch")), (4, lambda:Logger.critical("Space open but switch not flipped for 60 seconds"))]
  
  # StateAuf constants
  #  time that must pass between two bell_ringing events to buzz the door again (seconds)
@@@ -44,17 -44,13 +44,17 @@@ class Nerver()
        # If f returns something, that's also returned by nerv.
        def __init__(self, nervlist):
                self.nervlist = list(nervlist)
 +              self.last_event_time = time.time()
        
 -      def nerv(self, total_time):
 +      def nerv(self):
                if len(self.nervlist):
                        (time, f) = self.nervlist[0]
 +                      now = time.time()
 +                      time_gone = now-self.last_event_time
                        # check if the first element is to be triggered
 -                      if time >= total_time:
 +                      if time_gone >= time:
                                self.nervlist = self.nervlist[1:] # "pop" the first element, but do not modify original list
 +                              self.last_event_time = now
                                return f()
  
  
@@@ -69,6 -65,7 +69,6 @@@ class StateMachine()
        class State():
                def __init__(self, state_machine, nervlist = None):
                        self.state_machine = state_machine
 -                      self.time_entered = time.time()
                        self._nerver = None if nervlist is None else Nerver(nervlist)
                def handle_pins_event(self):
                        pass # one needn't implement this
@@@ -80,7 -77,7 +80,7 @@@
                                arg("412 Precondition Failed: The current state (%s) cannot handle the OPEN event" % self.__class__.__name__)
                def handle_wakeup_event(self):
                        if self._nerver is not None:
 -                              return self._nerver.nerv(time.time() - self.time_entered)
 +                              return self._nerver.nerv()
                def pins(self):
                        return self.state_machine.pins
                def actor(self):
        class StateUnlocking(State):
                def __init__(self,callback,sm):
                        # construct a nervlist
 -                      nervlist = [(t*OPEN_REPEAT_TIMEOUT, lambda: self.actor().act(Actor.CMD_UNLOCK)) for t in xrange(1, OPEN_REPEAT_NUMBER+1)]
 -                      nervlist += [((OPEN_REPEAT_NUMBER+1)*OPEN_REPEAT_TIMEOUT, self.could_not_open)]
 +                      nervlist = [(OPEN_REPEAT_TIMEOUT, lambda: self.actor().act(Actor.CMD_UNLOCK)) for t in xrange(OPEN_REPEAT_NUMBER)]
 +                      nervlist += [(OPEN_REPEAT_TIMEOUT, self.could_not_open)]
                        super().__init__(sm,nervlist)
                        self.callbacks=[callback]
                        # FIXME: can we send "202 processing: Trying to open the door" here? Are the callbacks multi-use?
                                logger.error("door manually locked, but space switch on - going to StateZu")
                                play_sound("manual_lock")
                                return StateZu(self.state_machine)
 -              # handle_wakeup_event intentionally not overwritten
        
        class StateLocking(State):
                # FIXME: Why does this even have callbacks?
                # TODO: share code with StateUnlocking
                def __init__(self,sm):
                        # construct a nervlist
 -                      nervlist = [(t*CLOSE_REPEAT_TIMEOUT, lambda: self.actor().act(Actor.CMD_LOCK)) for t in xrange(1, CLOSE_REPEAT_NUMBER+1)]
 +                      nervlist = [(t*CLOSE_REPEAT_TIMEOUT, lambda: self.actor().act(Actor.CMD_LOCK)) for t in range(1, CLOSE_REPEAT_NUMBER+1)]
                        nervlist += [((CLOSE_REPEAT_NUMBER+1)*CLOSE_REPEAT_TIMEOUT, self.could_not_close)]
                        super().__init__(sm, nervlist)
                        self.callbacks=[]
                        return StateAboutToOpen(self.state_machine)
        
        class StateAboutToLeave(State):
 +              def __init__(self, sm):
 +                      nervlist = [(LEAVE_TIMEOUT, lambda: StateLocking(self.state_machine))]
 +                      super().__init__(sm, nervlist)
                def handle_pins_event(self):
                        if not self.pins().door_closed:
                                return StateLeaving(self.state_machine)
                        if self.pins().door_locked:
                                return StateZu(self.state_machine)
 -              def handle_wakeup_event(self):
 -                      over = time.time() - self.time_entered
 -                      if over >= LEAVE_TIMEOUT:
 -                              return StateLocking(self.state_machine)
        
        class StateLeaving(State):
 +              def __init__(self, sm):
 +                      nervlist = [(LEAVE_TIMEOUT, lambda: StateAboutToOpen(self.state_machine))]
 +                      super().__init__(sm, nervlist)
                def handle_pins_event(self):
                        if self.pins().door_closed:
                                return StateLocking(self.state_machine)
                        if self.pins().door_locked:
                                return StateZu(self.state_machine)
 -              def handle_wakeup_event(self):
 -                      over = time.time() - self.time_entered
 -                      if over >= LEAVE_TIMEOUT:
 -                              return StateAboutToOpen(self.state_machine)
        
        def __init__(self, actor):
                self.actor = actor