class IvyRequester(object): def __init__(self, interface=None): self._interface = interface if interface is None: self._interface = IvyMessagesInterface("ivy requester") self.ac_list = [] def __del__(self): self.shutdown() def shutdown(self): if self._interface is not None: print("Shutting down ivy interface...") self._interface.shutdown() self._interface = None def get_aircrafts(self): wait_step = 0.1 timeout = 30 / wait_step # 30 seconds new_answer = False def aircrafts_cb(ac_id, msg): global new_answer self.ac_list = [int(a) for a in msg['ac_list'].split(',') if a] print("aircrafts: {}".format(self.ac_list)) new_answer = True self._interface.send_request('ground', "AIRCRAFTS", aircrafts_cb) # hack: sleep briefly to wait for answer while not new_answer and timeout > 0: sleep(wait_step) timeout -= 1 if not new_answer: print( "WARNING: Getting the list of aircraft timed out. The results might be outdated." ) # Didn't raise an exception or return None in order to not break the API return self.ac_list
class PprzConnect(object): """ Main class to handle the initialization process with the server in order to retrieve the configuration of the known aircraft and update for the new ones """ def __init__(self, notify=None, ivy=None, verbose=False): """ Init function Create an ivy interface if not provided and request for all aircraft :param notify: callback function called on new aircraft, takes a PprzConfig as parameter :param ivy: ivy interface to contact the server, if None a new one will be created :param verbose: display debug information """ self.verbose = verbose self._notify = notify self._conf_list_by_name = {} self._conf_list_by_id = {} if ivy is None: self._ivy = IvyMessagesInterface("PprzConnect") else: self._ivy = ivy sleep(0.1) self.get_aircrafts() def __del__(self): self.shutdown() def shutdown(self): """ Shutdown function Should be called before leaving if the ivy interface is not closed elsewhere """ if self._ivy is not None: if self.verbose: print("Shutting down ivy interface...") self._ivy.shutdown() self._ivy = None def conf_by_name(self, ac_name=None): """ Get a conf by its name :param ac_name: aircraft name, if None the complete dict is returned :type ac_name: str """ if ac_name is not None: return self._conf_list_by_name[ac_name] else: return self._conf_list_by_name def conf_by_id(self, ac_id=None): """ Get a conf by its ID :param ac_id: aircraft id, if None the complete dict is returned :type ac_id: str """ if ac_id is not None: return self._conf_list_by_id[ac_id] else: return self._conf_list_by_id @property def ivy(self): """ Getter function for the ivy interface """ return self._ivy def get_aircrafts(self): """ request all aircrafts IDs from a runing server and new aircraft when they appear """ def aircrafts_cb(sender, msg): ac_list = msg['ac_list'] for ac_id in ac_list: self.get_config(ac_id) #ac_list = [int(a) for a in msg['ac_list'].split(',') if a] if self.verbose: print("aircrafts: {}".format(ac_list)) self._ivy.send_request('ground', "AIRCRAFTS", aircrafts_cb) def new_ac_cb(sender, msg): ac_id = msg['ac_id'] self.get_config(ac_id) if self.verbose: print("new aircraft: {}".format(ac_id)) self._ivy.subscribe(new_ac_cb,PprzMessage('ground','NEW_AIRCRAFT')) def get_config(self, ac_id): """ Requsest a config from the server for a given ID :param ac_id: aircraft ID :type ac_id: str """ def conf_cb(sender, msg): conf = PprzConfig(msg['ac_id'], msg['ac_name'], msg['airframe'], msg['flight_plan'], msg['settings'], msg['radio'], msg['default_gui_color']) self._conf_list_by_name[conf.name] = conf self._conf_list_by_id[int(conf.id)] = conf if self._notify is not None: self._notify(conf) # user defined general callback if self.verbose: print(conf) self._ivy.send_request('ground', "CONFIG", conf_cb, ac_id=ac_id)