rocon_masters.py
Go to the documentation of this file.
00001 #!/usr/bin/env python
00002 #
00003 # License: BSD
00004 #   https://raw.github.com/robotics-in-concert/rocon_qt_gui/license/LICENSE
00005 #
00006 ##############################################################################
00007 # Imports
00008 ##############################################################################
00009 
00010 import os
00011 import string
00012 import subprocess
00013 import time
00014 import uuid
00015 import threading
00016 
00017 import rocon_console.console as console
00018 
00019 from . import utils
00020 
00021 ##############################################################################
00022 # Methods
00023 ##############################################################################
00024 
00025 
00026 def rocon_masters_cache_path():
00027     return os.path.join(utils.get_settings_cache_home(), "rocon_master.cache")
00028 
00029 ##############################################################################
00030 # Classes
00031 ##############################################################################
00032 
00033 
00034 class RoconMaster(object):
00035     __slots__ = [
00036         'index',
00037         'name',
00038         'uri',
00039         'host_name',
00040         'description',
00041         'icon',
00042         'flag',
00043         'current_row',
00044     ]
00045 
00046     rocon_remocon_check_up_script = utils.find_rocon_remocon_script('rocon_remocon_check_up')
00047 
00048     def __str__(self):
00049         s = self.name
00050         return s
00051 
00052     def set_unknown(self):
00053         self.name = "Unknown"
00054         self.description = "Unknown."
00055         self.icon = "unknown.png"
00056         self.flag = '0'
00057 
00058     def check(self):
00059         '''
00060         Given the uri and hostname, this proceeds to try and ping the rocon master to detect if it is available and
00061         if available, find the information on the other fields that fully describe a rocon master.
00062         '''
00063         if not (self.uri and self.host_name):
00064             console.logerror("Rocon Master : both uri and host_name should be configured before calling RoconMaster.check()")
00065             return
00066         # should check that uri and host name have been set
00067         output = subprocess.Popen([RoconMaster.rocon_remocon_check_up_script, self.uri, self.host_name], stdout=subprocess.PIPE)
00068         time_out_cnt = 0
00069         while True:
00070             result = output.poll()
00071             if time_out_cnt > 30:
00072                 console.logdebug("timeout: %s" % self.uri)
00073                 try:
00074                     output.terminate()
00075                 except:
00076                     console.logdebug("Error: output.terminate()")
00077                 self.set_unknown()
00078                 break
00079             elif result == 0:
00080                 args = output.communicate()[0]
00081                 self.name = args.split('\n')[0]
00082                 self.description = args.split('\n')[1]
00083                 self.icon = args.split('\n')[2]
00084 
00085                 if self.name == "Unknown":
00086                     self.flag = '0'
00087                 elif self.name == "Uncommunicable":
00088                     self.flag = '1'
00089                 else:
00090                     self.flag = '2'
00091                 break
00092 
00093             time.sleep(0.1)
00094             time_out_cnt += 1
00095 
00096 
00097 class RoconMasters(object):
00098 
00099     __slots__ = [
00100         'rocon_masters',  # { uuid : RoconMaster }
00101     ]
00102 
00103     def __init__(self):
00104         self.rocon_masters = {}
00105         self.load()
00106 
00107     ######################################
00108     # Emulating a dict
00109     ######################################
00110 
00111     def __contains__(self, index):
00112         return index in self.rocon_masters.keys()
00113 
00114     def __getitem__(self, index):
00115         return self.rocon_masters[index]
00116 
00117     def __len__(self):
00118         return len(self.rocon_masters)
00119 
00120     def keys(self):
00121         return self.rocon_masters.keys()
00122 
00123     def values(self):
00124         return self.rocon_masters.values()
00125 
00126     def clear(self):
00127         self.rocon_masters.clear()
00128 
00129     ######################################
00130     # Introspection
00131     ######################################
00132 
00133     def __str__(self):
00134         s = console.cyan + 'Rocon Masters:' + console.reset
00135         for rocon_master in self.rocon_masters.values():
00136             s += '\n  ' + console.yellow + str(rocon_master) + console.reset
00137         return s
00138 
00139     ######################################
00140     # Utility Functions
00141     ######################################
00142 
00143     def delete(self, index):
00144         del self.rocon_masters[index]
00145 
00146     def add(self, uri, host_name):
00147         rocon_master = RoconMaster()
00148         rocon_master.index = str(uuid.uuid4())
00149         rocon_master.name = "Unknown"
00150         rocon_master.uri = uri
00151         rocon_master.host_name = host_name
00152         rocon_master.icon = "unknown.png"
00153         rocon_master.description = ""
00154         rocon_master.flag = "0"
00155         self.rocon_masters[rocon_master.index] = rocon_master
00156         return rocon_master
00157 
00158     ######################################
00159     # Caching
00160     ######################################
00161 
00162     def load(self):
00163         """
00164         Gets a list of rocon masters and their info from cached data stored upon
00165         last exit of this application.
00166         """
00167         #read cache and display the rocon master list
00168         self.rocon_masters = {}
00169         try:
00170             cache_rocon_master_info_list = open(rocon_masters_cache_path(), 'r')
00171         except:
00172             console.logdebug("Remocon : no cached settings found, moving on.")
00173             return
00174         lines = cache_rocon_master_info_list.readlines()
00175         for line in lines:
00176             if line.count("[index="):
00177                 rocon_master = RoconMaster()
00178                 rocon_master.index = line[string.find(line, "[index=") + len("[index="):string.find(line, ",name=")]
00179                 rocon_master.name = line[string.find(line, "name=") + len("name="):string.find(line, ",master_uri=")]
00180                 rocon_master.uri = line[string.find(line, ",master_uri=") + len(",master_uri="):string.find(line, ",host_name=")]
00181                 rocon_master.host_name = line[string.find(line, ",host_name=") + len(",host_name="):string.find(line, ",description=")]
00182                 rocon_master.description = line[string.find(line, ",description=") + len(",description="):string.find(line, ",icon=")]
00183                 rocon_master.icon = line[string.find(line, ",icon=") + len(",icon="):string.find(line, ",flag=")]
00184                 rocon_master.flag = line[string.find(line, ",flag=") + len(",flag="):string.find(line, "]")]
00185                 self.rocon_masters[rocon_master.index] = rocon_master
00186         cache_rocon_master_info_list.close()
00187 
00188     def dump(self):
00189         """
00190         Dump the rocon masters to a cache file.
00191         """
00192         try:
00193             cache_rocon_master_info_list = open(rocon_masters_cache_path(), 'w')
00194         except:
00195             console.logerror("Remocon : no directory or file: %s" % rocon_masters_cache_path())
00196             return
00197         for rocon_master in self.rocon_masters.values():
00198             rocon_master_elem = '['
00199             rocon_master_elem += 'index=' + str(rocon_master.index) + ','
00200             rocon_master_elem += 'name=' + str(rocon_master.name) + ','
00201             rocon_master_elem += 'master_uri=' + str(rocon_master.uri) + ','
00202             rocon_master_elem += 'host_name=' + str(rocon_master.host_name) + ','
00203             rocon_master_elem += 'description=' + str(rocon_master.description) + ','
00204             rocon_master_elem += 'icon=' + rocon_master.icon + ','
00205             rocon_master_elem += 'flag=' + rocon_master.flag
00206             rocon_master_elem += ']\n'
00207 
00208             cache_rocon_master_info_list.write(rocon_master_elem)
00209         cache_rocon_master_info_list.close()
00210 
00211     def check(self):
00212         """
00213         Ping and update information for all registered rocon masters.
00214         """
00215         thread_pool = []
00216         for rocon_master in self.rocon_masters.values():
00217             t = threading.Thread(target=rocon_master.check)
00218             t.start()
00219             thread_pool.append(t)
00220 
00221         for t in thread_pool:
00222             t.join()


rocon_remocon
Author(s): Daniel Stonier, Donguk Lee
autogenerated on Fri Feb 12 2016 02:50:18