Implement the last two states
authorRalf Jung <post@ralfj.de>
Thu, 10 Oct 2013 16:41:40 +0000 (18:41 +0200)
committerRalf Jung <post@ralfj.de>
Thu, 10 Oct 2013 16:41:40 +0000 (18:41 +0200)
statemachine.py

index 70f9fe3e3cd942d16a992087bb8e76705a895138..333285869f514af727d4a38d8cda9478f0462e45 100644 (file)
@@ -31,6 +31,9 @@ ABOUTOPEN_NERVLIST = [(5, lambda : play_sound("flipswitch")), (10, lambda:play_s
 #  time that must pass between two bell_ringing events to buzz the door again (seconds)
 AUF_BELLBUZZ_REPEAT_TIME = 2
 
+# Timeout we wait after the switch was switched to "Closed", until we assume nobody will open the door and we just lock it
+LEAVE_TIMEOUT = 30
+
 # play_sound constants
 SOUNDS_DIRECTORY = "/opt/tuer/sounds/"
 SOUNDS_PLAYER = "/usr/bin/mplayer"
@@ -181,12 +184,14 @@ class StateMachine():
                # handle_wakeup_event intentionally not overwritten
        
        class StateClosing(State):
+               # FIXME: Why does this even have callbacks?
                # TODO: share code with StateOpening, and possibly also with the nerv-mechanism from StateAboutToOpen
-               def __init__(self,callback,sm):
+               def __init__(self,sm):
                        super().__init__(sm)
-                       self.callbacks=[callback]
+                       self.callbacks=[]
                        # FIXME: can we send "202 processing: Trying to close the door" here? Are the callbacks multi-use?
                        self.tries = 0
+                       assert self.pins().door_closed, "Door is open while we should close it, this must not happen"
                        self.actor().act(Actor.CMD_CLOSE)
                def notify(self, did_it_work):
                        s = "200 okay: door closed" if did_it_work else ("500 internal server error: Couldn't close door with %d tries à %f seconds" % (CLOSE_REPEAT_NUMBER,CLOSE_REPEAT_TIMEOUT))
@@ -213,12 +218,26 @@ class StateMachine():
                                        return StateAboutToOpen(self.state_machine)
        
        class StateAboutToLeave(State):
-               #TODO Ralf
-               pass
+               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 StateClosing(self.state_machine)
        
        class StateLeaving(State):
-               #TODO Ralf
-               pass
+               def handle_pins_event(self):
+                       if self.pins().door_closed:
+                               return StateClosing(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