Exemple #1
0
    def play(self, wait_stopped = False, duration = float("inf"), threaded = True):
        self.lock.acquire()
        for submachine in self.submachines.values() :
            submachine.play(False, duration, threaded)
        self.begin = time()
        self.duration = duration
        if self.status == self.Status.Stopped :
            if self.debug: print("Starting machine \'" + self.name+"\'")
            globals()[self.name] = self
            exec(self.preamble)
            for line in self.preamble.splitlines() :
                imports = line.split(' ')
                if len(imports) >= 2:
                    if imports[0]=='def':
                        globals()[imports[1][:-3]] = locals()[imports[1][:-3]]
                    elif imports[0]=='import':
                        import_module(imports[1])
                    elif imports[0]=='from' and imports[2]=='import' :
                        if len(imports) == 4:
                            globals()[imports[3]] = getattr(__import__(imports[1]), imports[3])
                        elif len(imports) == 6 and imports[4]=='as':
                            globals()[imports[5]] = getattr(__import__(imports[1]), imports[3]) 

            self.set_state("Initial")
            self.status = self.Status.Playing
            if threaded :
                RepeatedTask.start(self)
        elif self.status == self.Status.Suspended :
            if self.debug : print("Resuming machine \'"+ self.name+"\'")
            self.status = self.Status.Playing
        self.lock.release()
        if wait_stopped:
            self.wait_stopped()
Exemple #2
0
 def __init__(self, verbose=False):
     RepeatedTask.__init__(self,1,self.step)
     self.name = "TheDiceMachine"
     self.frequency = 50.0
     self.status = self.Status.Stopped 
     self.state = None
     self.debug = False
Exemple #3
0
 def start(self):
     self.connection = com.Connection()
     self.connection.setStore(self.store)
     self.connection_keeper =  RepeatedTask(10,self.connectIfNeeded)
     self.connection_keeper.start()
     self.move_monitor = RepeatedTask(0.2,self.askValues)
     self.move_monitor.start()
Exemple #4
0
 def stop(self, threaded = True):
     self.lock.acquire()
     if self.debug : print("Stopping machine \'"+ self.name+"\'")
     self.status = self.Status.Stopped
     for submachine in self.submachines.values():
         submachine.stop()
     RepeatedTask.cancel(self)
     self.lock.release()
Exemple #5
0
 def __init__(self, verbose=False):
     RepeatedTask.__init__(self,1,self.step)
     self.name = "PingMachine"
     self.frequency = 10.0
     self.status = self.Status.Stopped 
     self.state = None
     self.debug = False
     self.submachines = {}
Exemple #6
0
 def play(self, threaded = True):
     if self.status == self.Status.Stopped :
         print("Starting machine '" + self.name+"'")
         globals()[self.name] = self
         self.set_state("Initial")
         self.status = self.Status.Playing
         if threaded : RepeatedTask.start(self)
     elif self.status == self.Status.Suspended :
         if self.debug : print("Resuming machine '"+ self.name+"'")
         self.status = self.Status.Playing
Exemple #7
0
    def __init__(self, debug=False):
        RepeatedTask.__init__(self,1,self.step)

        '''The name of the machine'''
        self.name = ""
        
        '''A description of its behaviour'''
        self.description = ""
        
        '''The frequency of the machine'''
        self.frequency = 1.0
        
        '''The preamble'''
        self.preamble = ""

        '''The code executed on stop'''
        self.onstop = ""
        
        '''The dict of states (name-> state)'''
        self.states = {}
        self.states['Initial'] = StateMachine.State("Initial")
        self.states['Final'] = StateMachine.State("Final")
         
        '''The dict of submachines'''
        self.submachines = {}
        
        '''The current state'''
        self.state = None
        
        '''The playing status of the machine'''
        self.status = self.Status.Stopped

        '''The error status of the machine'''
        self.error = ""

        '''The date where playing begins'''
        self.begin = time()
        
        '''The total playing duration'''
        self.duration = float("inf")
        
        '''The map of monitored moves to the map from states to output values'''
        self.monitored_states = {}

        self.debug = debug
        
        '''True if the machine is animated by a thread, falseif anaimated by calls to step (by an stm loader for example)'''
        self.threaded = False
        
        self.globals = globals()
        self.locals = locals()
        
        '''Minimal time to spend in the current state'''
        self.min_ticks = 0
Exemple #8
0
 def play(self):
     for submachine in self.submachines.values():
         submachine.play() 
     if self.status == self.Status.Stopped :
         print("Starting machine '" + self.name+"'")
         self.set_state("Initial")
         self.status = self.Status.Playing
         RepeatedTask.start(self)
     elif self.status == self.Status.Suspended :
         if self.debug : print("Resuming machine '"+ self.name+"'")
         self.status = self.Status.Playing
Exemple #9
0
    def play(self, wait_stopped = False, duration = float("inf"), threaded = True):
        try :
            self.lock.acquire()
            for submachine in self.submachines.values() :
                submachine.play(False, duration, threaded)
            self.begin = time()
            self.duration = duration
            self.error = ""
            if self.status == self.Status.Stopped :
                if self.debug: print("Starting machine \'" + self.name+"\'")
                self.state = None
                globals()[self.name] = self
                if self.preamble:
                    try :
                        exec(self.preamble, self.globals, self.locals)
                    except Exception as e:
                        self.error = "[" + str(datetime.datetime.now().time()) + "] " + " Failed to exec preamble : " + str(e)
                        print("Failed to exec preamble of machine "+ self.name + ": "+ str(e))
                        raise Exception(self.error)
                        
                for line in self.preamble.splitlines() :
                    imports = line.split(' ')
                    if len(imports) >= 2:
#                        if imports[0]=='def':
#                            globals()[imports[1][:-3]] = locals()[imports[1][:-3]]
                        if imports[0]=='import':
                            import_module(imports[1])
                        elif imports[0]=='from' and imports[2]=='import' :
                            if len(imports) == 4:
                                globals()[imports[3]] = getattr(__import__(imports[1]), imports[3])
                            elif len(imports) == 6 and imports[4]=='as':
                                globals()[imports[5]] = getattr(__import__(imports[1]), imports[3]) 
    
                self.set_state("Initial")
                self.status = self.Status.Playing
                if threaded:
                    RepeatedTask.start(self)
                self.threaded = threaded
                    
            elif self.status == self.Status.Suspended :
                if self.debug : print("Resuming machine \'"+ self.name+"\'")
                self.status = self.Status.Playing
            self.lock.release()
            
        except Exception as e:
            self.error = "[" + str(datetime.datetime.now().time()) + "] " + " Failed to step machine : " + str(e)
            print("Failed to step machine "+ self.name + ": "+ str(e))
            self.lock.release()
            
        if wait_stopped:
            self.wait_stopped()
Exemple #10
0
 def __init__(self, verbose=False):
     global PongMachine
     global PingMachine
     RepeatedTask.__init__(self,1,self.step)
     self.name = "PingPongMachine"
     self.frequency = 1.0
     self.status = self.Status.Stopped 
     self.state = None
     self.debug = False
     self.submachines = {}
     PongMachine = PongMachineClass()
     self.submachines['PongMachine'] = PongMachine
     PingMachine = PingMachineClass()
     self.submachines['PingMachine'] = PingMachine
Exemple #11
0
 def stop(self):
     if self.status == self.Status.Playing or self.status == self.Status.Suspended :
        if self.debug : print("Stopping machine \'"+ self.name+"\'")
        if self.threaded:
            RepeatedTask.cancel(self)
        self.status = self.Status.Stopped
        for submachine in self.submachines.values():
            submachine.stop()
        if self.onstop:
            try :
               exec(self.onstop, self.globals, self.locals)
            except Exception as e:
               self.error = "[" + str(datetime.datetime.now().time()) + "] " + " Failed to exec onstop : " + str(e)
               print("Failed to exec onstop of machine "+ self.name + ": "+ str(e))
               raise Exception(self.error)
        self.state = self.states["Initial"]
Exemple #12
0
    def __init__(self, debug=False):
        RepeatedTask.__init__(self,1,self.step)

        '''The name of the machine'''
        self.name = ""
        
        '''A description of its behaviour'''
        self.description = ""
        
        '''The frequency of the machine'''
        self.frequency = 1.0
        
        '''The preamble'''
        self.preamble = ""
        
        '''The dict of states (name-> state)'''
        self.states = {}
        self.states['Initial'] = StateMachine.State("Initial")
        self.states['Final'] = StateMachine.State("Final")
         
        '''The dict of submachines'''
        self.submachines = {}
        
        '''The current state'''
        self.state = None
        
        '''The playing status of the machine'''
        self.status = self.Status.Stopped

        '''The date where playing begins'''
        self.begin = time()
        
        '''The total playing duration'''
        self.duration = float("inf")
        
        self.debug = debug
Exemple #13
0
 def stop(self, threaded = True):
     if self.debug : print("Stopping machine '"+ self.name+"'")
     self.status = self.Status.Stopped
     RepeatedTask.cancel(self)
Exemple #14
0
class StateMachineServer(StateMachineLoader):
    
    def __init__(self,  hostname = 'localhost', port = 12345, storeFileName = '../common/commands.xml'):

        print("Creating StmServer connected to " + hostname + ":" + str(port))
        
        self.hostname = hostname
        self.port = port

        self.callbacks = {'StmError' : self.error,
                           'StmLoadXMLMachine':self.processLoadXMLMachineMessage,
                           'StmStartMachine':self.processStartMachineMessage,
                           'StmStopMachine':self.processStopMachineMessage,
                           'StmKillMachine':self.processKillMachineMessage,
                           'StmGetState' : self.processGetStateMessage,
                           'StmGetStates' : self.processGetStatesMessage,
                           'StmGetMachinesInfo':self.processGetMachinesInfo,
                           'StmSetMachineAttributes':self.processSetMachineAttributes,
                           'StmGetMachineAttributes':self.processGetMachineAttributes,
                           'StmEvaluatePythonExpressions':self.processEvaluatePythonExpressions,
                           'StmPing':self.processPing,
                           'StmGetAndSetMachineAttributes':self.StmGetAndSetMachineAttributes
                           }
        
        self.store = com.CommandsStore()
        self.store.parseXml(storeFileName)
        self.pending_messages = []
        self.lock_messages = RLock()
        StateMachineLoader.__init__(self)


    def start(self):
        self.connection = com.Connection()
        self.connection.setStore(self.store)
        self.connection_keeper =  RepeatedTask(10,self.connectIfNeeded)
        self.connection_keeper.start()
        self.move_monitor = RepeatedTask(0.2,self.askValues)
        self.move_monitor.start()


    '''Asynchronous reception and processing of messages
       messages are stored in an array and processed when no machine is stepping
       this is necessary for machine to send and get messages without creating race conditions in the mailbox
    '''
        
    def incomingMessageProcessor(self, message):
        self.lock_messages.acquire()
        self.pending_messages.append(message)
        self.lock_messages.release()

    def processPendingMessages(self):
        self.lock_messages.acquire()
        for message in self.pending_messages:
            self.processMessage(message)
        self.pending_messages = []
        self.lock_messages.release()

    def step(self):
        StateMachineLoader.step(self)
        self.processPendingMessages()
        
    '''asks values of moves in the remote move scheduler'''
    def askValues(self):
        try :
            if (self.connection.connected):
                for machine in self.machines.values():
                    if machine.machine.monitored_states:
                        states = machine.machine.monitored_states
                        for move in states:
                            response = self.connection.SchedulerGetMoveValues_response(move,states[move].keys())
                            if response and len(response) >= 3 :
                                for i in range(0, len(response[1])) :
                                    machine.machine.monitored_states[move][response[1][i]] = response[2][i]
        except Exception as e :
            print("[" + str(datetime.datetime.now()) + "] Stm move monitor: exception: " + str(e))

    '''connect to server if needed'''
    def connectIfNeeded(self):
        try :
            if (not self.connection.connected):
                print("[" + str(datetime.datetime.now()) + "] Stm server trying to connect to server")
                self.connection.connectTo(self.hostname, self.port, self.incomingMessageProcessor)
                self.testConnection()
                self.registerAsComponent()
                print("[" + str(datetime.datetime.now()) + "] Stm server connected to server")       
#            else :
 #               self.testConnection()
  #              pass
        except Exception as e :
            print("[" + str(datetime.datetime.now()) + "] Stm server: connection dead: " + str(e))
            self.connection.stop()
        

    def registerAsComponent(self):
        print('Registering component...')
        answer = self.connection.ServerRegisterComponent_response(com.CommandsStore.destinationToIndex['stm'])
        if answer is not None :
            print('Answer from server:' + str(answer))
        else :
            raise Exception('No answer to register component command')

    def testConnection(self):
        response = self.connection.ServerEcho_response("Hello", "you")

        if response is not None and response[0] == "Hello" and response[1] == "you":
            print("[" + str(datetime.datetime.now()) + '] STM Server: Connection alive')
        else :
            raise Exception('Connection dead')

    def error(self, message):
        print('Received error ' + message[0] + "\n")
        
    def processPing(self, message):
        return [ message[0] ]
    
    def processGetStatesMessage(self, message):
        return [ self.machines.keys() , [machine.machine.state.name for machine in self.machines.values()] ]

    def processGetStateMessage(self, message):
        machine = self.getMachine(message[0])
        if machine :
            state = machine.machine.state
            if state :
                return [ message[0] , state.name]
        return [ message[0] , 'Initial']
        
    def processGetMachinesInfo(self,message):
        answer = [ self.machines.keys() , [machine.machine.statusString() for machine in self.machines.values()] , [machine.machine.error for machine in self.machines.values()] ]
        return answer

    def processLoadXMLMachineMessage(self, message):
        xml = message[0]
        print("Loading machine " + xml )
        machine = StateMachine.from_xml_stream(xml)
        self.load(machine, False, float("inf"), True)
        for key in self.store.commands:
            setattr( machine, key, getattr(self.connection, key) )
            setattr( machine, key+"_response", getattr(self.connection, key+"_response") )
        machine.GetMoveValues = lambda movename, blocknames : machine.SchedulerGetOutputValues_response(movename,blocknames)
        return ['Loaded machine ' + machine.name]

    def getMachine(self, name):
        if name in self.machines :
            return self.machines[name]
        else :
            return None;
            
    def processStartMachineMessage(self,message):
        print('Starting machine ' + message[0]) 
        self.startMachine(message[0]);
        return ['Started machine ' + message[0]]

    def processStopMachineMessage(self,message):
        machine = self.getMachine(message[0])
        if machine :
            machine.machine.stop()
            return ['Stopped machine ' + message[0]]
        else :
            return ['Unknown machine ' + message[0]]


    def processKillMachineMessage(self,message):
        self.kill(message[0])
        return ['Killed machine ' + message[0]]
      
      
    def processSetMachineAttributes(self, message):
        machine = self.getMachine(message[0])
        if machine :
            machine.machine.set_attributes(message[1],message[2])
        
    def processGetMachineAttributes(self, message):
        machine = self.getMachine(message[0])
        if machine :
            return [machine.machine.get_attributes(message[1])]
        else:
            return []

    def StmGetAndSetMachineAttributes(self, message):
        machine = self.getMachine(message[0])
        if machine :
            machine.machine.set_attributes(message[1],message[2])
            return [machine.machine.get_attributes(message[3])]
        else :
            return []
        
    def processEvaluatePythonExpressions(self, message):
        if message[0] :
            machine = self.getMachine(message[0])
            if machine :
                machine.x = message[2]
                return [ [ machine.machine.evaluate(expression) for expression in message[1] ] ]
            else :
                return []
        else :
            x = message[2]
            answer = []
            for expression in message[1] :
                answer.append( float( eval(expression) ) )
            return [ answer ]
             
        
    def processMessage(self, message):
        try :
            if message.specification.name in self.callbacks:
                callback = self.callbacks[message.specification.name];
                #print("Processing message " + message.specification.name + " " +  str( message.uid ) );
                if(callback != None) : 
                    self.lock.acquire()
                    try :
                        data = callback(message.data)
                        if data != None :
                            self.connection.sendAnswer(message, data)
                        #else :
                        #    print('No answer to ' + message.specification.name)
                        self.lock.release()

                    except Exception as e :
                        self.lock.release()
                        print("Error '" + str(e) + "', failed to process command '" + message.specification.name + "'")
                        self.connection.sendAnswer(message, [str(e)], 'StmError')

        except Exception as e:
            print("Got exception " + str(e) + " while receiving message: " + str(message.uid))
Exemple #15
0
 def __init__(self):
     RepeatedTask.__init__(self,0.1,self.step)
     self.machines = []
     RepeatedTask.start(self)
Exemple #16
0
 def stop(self, threaded = True):
     if self.debug : print("Stopping machine '"+ self.name+"'")
     self.status = self.Status.Stopped
     for submachine in self.submachines.values():
         submachine.stop() 
     RepeatedTask.cancel(self)