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()
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
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()
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()
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 = {}
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
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
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
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()
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
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"]
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
def stop(self, threaded = True): if self.debug : print("Stopping machine '"+ self.name+"'") self.status = self.Status.Stopped RepeatedTask.cancel(self)
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))
def __init__(self): RepeatedTask.__init__(self,0.1,self.step) self.machines = [] RepeatedTask.start(self)
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)