Index: /fact/tools/PyDimCtrl/factdimserver.py
===================================================================
--- /fact/tools/PyDimCtrl/factdimserver.py	(revision 13808)
+++ /fact/tools/PyDimCtrl/factdimserver.py	(revision 13808)
@@ -0,0 +1,385 @@
+#!/usr/bin/python -tti
+
+# for tab completion
+import rlcompleter
+import readline
+readline.parse_and_bind('tab: complete')
+
+import sys      # for sys.exit() during bebugging mostly :-)
+import types                    # for dynamic class construction
+import time                     # for time.sleep
+from pprint import pprint       # for nice printing 
+
+from keyword import iskeyword   # in case dynamic methods are equal to keywords
+
+import pydim                    # for the C-API Dim Call Wrappers
+
+# using this line makes 'export DIM_DNS_NODE=daq' obsolete
+pydim.dic_set_dns_node('daq')
+
+class FactDimServer( object ):
+    def __init__(self, name):
+        """ sets name of instance to name of server, all uppercase
+        """
+        self.list_of_states = []
+        self.name = name.upper()
+        self.print_state = False
+        self.print_msg = False
+        self.reg_state_cb()
+        self.reg_msg_cb()
+        self.user_func = None
+
+    def _cmd(self, cmdstr, *args):
+        """ used by all dynamicly created methods, which call a Dim CMD
+        """
+        cmdstr=self.name+'/'+cmdstr.upper()
+        desc = services[self.name][cmdstr.upper()][0]
+        
+        # there is a work around for a bug in pydim
+        # even if a command needs no argument, and desc is also empty string
+        # one has to give one ... need to tell Niko about it.
+        if not desc:
+            desc = 'I'
+            args=(1,)
+        pydim.dic_sync_cmnd_service(cmdstr, args, desc, timeout=None)
+
+
+    def _get(self, service):
+        """ used by all dynamicly created methods, which get a service 
+        """
+        full_srv_name = self.name+'/'+service.upper()
+        desc = services[self.name][full_srv_name][0]
+        return pydim.dic_sync_info_service(full_srv_name, desc)
+
+
+    def __call__(self):
+        """ Wrapper / For Convenience
+            self.state() returns a string (if it exists)
+            *returns* numeric state code, parsed from return of self.state()
+        """
+        if hasattr(self, 'state'):
+            s = self.state()[0]
+            return int(s[ s.find('[')+1 : s.find(']') ])
+        else:
+            raise TypeError(self.name+' has no CMD called STATE')
+    
+    def wait(self, state_num, timeout=None):
+        """ waits for a certain state
+            BLOCKING
+            returns True if state was reached
+            returns False if timeout occured
+            raises TypeError if Server has no method state
+        """
+
+        if not hasattr(self, 'state'):
+            raise TypeError(self.name+' has no CMD called STATE')
+        if timeout == None:
+            timeout = float('inf')
+        else:
+            timeout = float(timeout)
+        start = time.time()
+        while not self() == state_num:
+            time.sleep(0.1)
+            if time.time() >= start+timeout:
+                return False
+        return True
+
+    def state_callback(self, state):
+        self.sts = state
+        try:
+            self.stn = int(state[state.find('[')+1 : state.find(']')]) 
+        except ValueError:
+            self.stn = None
+            
+        self.last_st_change = time.time()
+        self.list_of_states.append( (self.last_st_change, self.stn) )
+        if len(self.list_of_states) > 10000:
+            print "list_of_states too long, truncating..."
+            self.list_of_states = self.list_of_states[1000:]
+            
+        if self.user_func:
+            self.user_func( self.stn )
+        
+        if self.print_state: 
+            print state
+
+    def msg_callback(self, msg):
+        if self.print_msg:
+            print msg
+
+    def reg_state_cb(self):
+        if not hasattr(self, 'state'):
+            raise TypeError(self.name+' has no CMD called STATE')
+        service_name = self.name.upper()+'/STATE'
+        self.state_sid = pydim.dic_info_service(service_name, "C", self.state_callback)
+        if not self.state_sid:
+            del self.state_sid
+            raise IOError('could not register STATE client')
+
+    def reg_msg_cb(self):
+        if not hasattr(self, 'state'):
+            raise TypeError(self.name+' has no CMD called STATE')
+        service_name = self.name.upper()+'/MESSAGE'
+        self.msg_sid = pydim.dic_info_service(service_name, "C", self.msg_callback)
+        if not self.msg_sid:
+            del self.msg_sid
+            raise IOError('could not register MESSAGE client')
+
+    def unreg_state_cb(self):
+        if hasattr(self, 'state_sid'):
+            pydim.dic_release_service(self.state_sid)
+            del self.state_sid
+
+    def unreg_msg_cb(self):
+        if hasattr(self, 'msg_sid'):
+            pydim.dic_release_service(self.msg_sid)
+            del self.msg_sid
+
+    def __del__(self):
+        self.unreg_state_cb()
+        self.unreg_msg_cb()
+
+# utility functions for dynamic addid of methods to classes
+def add_command(cls, name): 
+    meth_name = name.split('/')[1].lower()
+    if iskeyword(meth_name):
+        meth_name += '_cmd'
+        
+    # this is the new command, it simple calls the _cmd() method
+    def new_command(self, *args):
+        self._cmd(meth_name, *args)
+        
+    new_command.__name__ = meth_name
+    
+    # from this line on, the docstring of the method is created
+    if name in dd:
+        if not dd[name]:
+            new_command.__doc__ = "DESC in SERVICE_DESC is empty ?!"
+        else:
+            new_command.__doc__ = dd[name]
+    else:
+        new_command.__doc__ = "-- no DESC found in SERVICE_DESC --"
+    new_command.__doc__ += '\n'
+    new_command.__doc__ += services[name.split('/')[0]][name][0]
+    
+    # this line make the new_command() method, a method of the class cls
+    # giving it the name new_command.__name__
+    setattr( cls, new_command.__name__, new_command)
+
+# add_getter is very similar to add_command,
+# the only difference is, that it calls _get() instead of _cmd()
+# and since _get() has a return value, this return value is vorwarded to the user
+def add_getter(cls, name): 
+    meth_name = name.split('/')[1].lower()
+    if iskeyword(meth_name):
+        meth_name += '_cmd'
+    def new_command(self):
+        return self._get(meth_name)
+    new_command.__name__ = meth_name
+    if name in dd:
+        if not dd[name]:
+            new_command.__doc__ = "DESC in SERVICE_DESC is empty ?!"
+        else:
+            new_command.__doc__ = dd[name]
+    else:
+        new_command.__doc__ = "-- no DESC found in SERVICE_DESC --"
+    new_command.__doc__ += '\n'
+    new_command.__doc__ += services[name.split('/')[0]][name][0]
+    setattr( cls, new_command.__name__, new_command)
+
+
+
+
+
+# In order to create classes according to the Dim-Servers, currently connected
+# to the DIS_DNS I have to parse DIS_DNS/SERVER_LIST
+# This is done in two steps, first I get the list of Server Names from DIS_DNS
+# and the I get the list of each servers services and cmds, 
+# from each servers SERVICE_LIST and the service/command description 
+# from each servers SERVICE_DESC
+# I get quite a lot of information, which I store in python dicts, or
+# even nested dicts, if necessary.
+
+def ParseDnsServerList():
+    # making server list
+    rawlist = pydim.dic_sync_info_service('DIS_DNS/SERVER_LIST','C')
+    # the output needs to be treated a bit .. it is a tuple with only one long string in it
+    # the string contains | and the strange character \x00
+    # I use both to cut the list apart
+    rawlist = rawlist[0].split('\x00')
+    servers_n_hosts = rawlist[0].split('|')
+    server_ids = rawlist[1].split('|')
+
+    servers = {}
+    for i,snh in enumerate(servers_n_hosts):
+        snh = snh.split('@')
+        s = snh[0]
+        h = snh[1]
+        sid = server_ids[i]
+        servers[s] = (sid, h)
+
+    return servers
+
+
+
+# servers should be a dict containing uppercase server names as keys,
+# the values are not needed, so it might be any iteratable python listlike type 
+# to be precise
+def ParseServersServiceList( servers ):
+    
+    services = {}
+    dd = {}
+    for server in servers:
+        # sl_raw is a tuple, with an really long string, which needs to be parsed
+        sl_raw = pydim.dic_sync_info_service(server+'/SERVICE_LIST','C')[0]
+        
+        # even without parsing, I can find out, if this server also gives me a 
+        # service description list. In case it does not, this is fine as well
+        # the doc string of the dynamicly created methods, will then contain 
+        # a note, that therer was no SERVICE_DESC ... 
+        if server+'/SERVICE_DESC' in sl_raw:
+            sd_raw = pydim.dic_sync_info_service(server+'/SERVICE_DESC','C')[0]
+        else:
+            sd_raw = ''
+        
+        # now before parsing, I strip off all ASCII zeroes '\x00' and all 
+        # line breaks off the *end* of the long string of both
+        # the service list sl
+        # and service description sd
+        #
+        # I think in sl_raw were alse some '\x00' in the middle .. these 
+        # are replaced by nothing, in case they are there.
+        sl_raw = sl_raw.rstrip('\x00\n')
+        sl_raw = sl_raw.replace('\x00','')
+        sd_raw = sd_raw.rstrip('\x00\n')
+        
+        # The lists are seperated by line breaks, so I split them using this
+        sl = sl_raw.split('\n')
+        sd = sd_raw.split('\n')
+        
+        # First I parse the service descriptons, so I have them available, 
+        # when I create the dict full of services.
+        # All desciptions look like this
+        # 'SERVER/SERVICE=some descriptive text' or
+        # 'SERVER/SERVICE='
+        # this I use to create the dictionary.
+        # create descripton dict dd from service_desc list sd
+        for d_str in sd:
+            service,equalsign,desc = d_str.partition('=')
+            #if '=' != equalsign:
+                # print "Error: server:", server, "desc:", d_str
+            dd[service] = desc
+
+        # Now I fill ther services dict. Each server gets a nested dict
+        # inside services. 
+        # Each service is explained in a string with a '|' in between.
+        # I use this for spliting. 
+        # The string look like this 
+        # SERVER/SERVICE|format-desc-str(e.g. I:2;C)|-empty- or CMD or RPC|
+        services[server] = {}
+        for service in sl:
+            service = service.split('|')
+            if service[0] in dd:
+                services[server][service[0]] = (
+                        service[1], service[2], dd[service[0]])
+    return services, dd
+
+
+servers = ParseDnsServerList()
+services, dd = ParseServersServiceList( servers )
+
+# create one class for each Fact Dim Server
+FactDimServerClasses = []
+for server_name in servers:
+    FactDimServerClasses.append( 
+            types.ClassType( server_name, (FactDimServer,), {}) )
+    for cmd in services[server_name]:
+        if 'CMD' in services[server_name][cmd][1]:
+            cmdname = cmd.split('/')[1]
+            add_command(FactDimServerClasses[-1], cmd)
+        elif not services[server_name][cmd][1]:
+            cmdname = cmd.split('/')[1]
+            add_getter(FactDimServerClasses[-1], cmd)
+
+
+
+# create an instace of each of the classes
+# and make it globally known, i.e. known to the Python interpreter
+# all the ServerClass instances are collected in a list
+# so one can get a quick overview --> print dims
+dims = []
+for i,server_name in enumerate(servers):
+    if server_name == 'DIS_DNS':
+        continue
+    new_instance = FactDimServerClasses[i](server_name)
+    dims.append( new_instance )
+    globals()[server_name.lower()] = new_instance
+del new_instance
+
+##############################################################################
+# class for colored printing
+
+class bcolors:
+        HEADER = '\033[95m'
+        OKBLUE = '\033[94m'
+        OKGREEN = '\033[92m'
+        WARNING = '\033[93m'
+        FAIL = '\033[91m'
+        ENDC = '\033[0m'
+
+        def disable(self):
+            self.HEADER = ''
+            self.OKBLUE = ''
+            self.OKGREEN = ''
+            self.WARNING = ''
+            self.FAIL = ''
+            self.ENDC = ''
+
+##############################################################################
+# class which implements colored printing
+# method calls can be used instead of Python print calls 
+# for conveniently printing colored output.
+
+
+class MSG( bcolors):
+    def __init__(self, verbose = True):
+        """ create MSG instance, 
+            default is verbose,
+            sets self.output
+            
+            if:
+            self.*output* = True, object behaves as expeted
+            if False, no call return anything
+        """
+        self.output = verbose
+    
+    def fail(self, text ):
+        """ print in RED
+        """
+        text = str(text)
+        if self.output:
+            print bcolors.FAIL + "ERROR:" + bcolors.ENDC,
+            print bcolors.FAIL + text + bcolors.ENDC
+
+    def warn(self, text ):
+        """ print in YELLOW
+        """
+        text = str(text)
+        if self.output:
+            print bcolors.WARNING + text + bcolors.ENDC
+
+    def ok(self, text ):
+        """ print in GREEN
+        """
+        text = str(text)
+        if self.output:
+            print bcolors.OKGREEN + text + bcolors.ENDC
+
+    def __call__(self, *args):
+        """ print as Python print would do 
+        """
+        if self.output:
+            for arg in args:
+                print arg,
+            print
+
Index: ct/tools/PyDimCtrl/fpydim.py
===================================================================
--- /fact/tools/PyDimCtrl/fpydim.py	(revision 13807)
+++ 	(revision )
@@ -1,385 +1,0 @@
-#!/usr/bin/python -tti
-
-# for tab completion
-import rlcompleter
-import readline
-readline.parse_and_bind('tab: complete')
-
-import sys      # for sys.exit() during bebugging mostly :-)
-import types                    # for dynamic class construction
-import time                     # for time.sleep
-from pprint import pprint       # for nice printing 
-
-from keyword import iskeyword   # in case dynamic methods are equal to keywords
-
-import pydim                    # for the C-API Dim Call Wrappers
-
-# using this line makes 'export DIM_DNS_NODE=daq' obsolete
-pydim.dic_set_dns_node('daq')
-
-class FactDimServer( object ):
-    def __init__(self, name):
-        """ sets name of instance to name of server, all uppercase
-        """
-        self.list_of_states = []
-        self.name = name.upper()
-        self.print_state = False
-        self.print_msg = False
-        self.reg_state_cb()
-        self.reg_msg_cb()
-        self.user_func = None
-
-    def _cmd(self, cmdstr, *args):
-        """ used by all dynamicly created methods, which call a Dim CMD
-        """
-        cmdstr=self.name+'/'+cmdstr.upper()
-        desc = services[self.name][cmdstr.upper()][0]
-        
-        # there is a work around for a bug in pydim
-        # even if a command needs no argument, and desc is also empty string
-        # one has to give one ... need to tell Niko about it.
-        if not desc:
-            desc = 'I'
-            args=(1,)
-        pydim.dic_sync_cmnd_service(cmdstr, args, desc, timeout=None)
-
-
-    def _get(self, service):
-        """ used by all dynamicly created methods, which get a service 
-        """
-        full_srv_name = self.name+'/'+service.upper()
-        desc = services[self.name][full_srv_name][0]
-        return pydim.dic_sync_info_service(full_srv_name, desc)
-
-
-    def __call__(self):
-        """ Wrapper / For Convenience
-            self.state() returns a string (if it exists)
-            *returns* numeric state code, parsed from return of self.state()
-        """
-        if hasattr(self, 'state'):
-            s = self.state()[0]
-            return int(s[ s.find('[')+1 : s.find(']') ])
-        else:
-            raise TypeError(self.name+' has no CMD called STATE')
-    
-    def wait(self, state_num, timeout=None):
-        """ waits for a certain state
-            BLOCKING
-            returns True if state was reached
-            returns False if timeout occured
-            raises TypeError if Server has no method state
-        """
-
-        if not hasattr(self, 'state'):
-            raise TypeError(self.name+' has no CMD called STATE')
-        if timeout == None:
-            timeout = float('inf')
-        else:
-            timeout = float(timeout)
-        start = time.time()
-        while not self() == state_num:
-            time.sleep(0.1)
-            if time.time() >= start+timeout:
-                return False
-        return True
-
-    def state_callback(self, state):
-        self.sts = state
-        try:
-            self.stn = int(state[state.find('[')+1 : state.find(']')]) 
-        except ValueError:
-            self.stn = None
-            
-        self.last_st_change = time.time()
-        self.list_of_states.append( (self.last_st_change, self.stn) )
-        if len(self.list_of_states) > 10000:
-            print "list_of_states too long, truncating..."
-            self.list_of_states = self.list_of_states[1000:]
-            
-        if self.user_func:
-            self.user_func( self.stn )
-        
-        if self.print_state: 
-            print state
-
-    def msg_callback(self, msg):
-        if self.print_msg:
-            print msg
-
-    def reg_state_cb(self):
-        if not hasattr(self, 'state'):
-            raise TypeError(self.name+' has no CMD called STATE')
-        service_name = self.name.upper()+'/STATE'
-        self.state_sid = pydim.dic_info_service(service_name, "C", self.state_callback)
-        if not self.state_sid:
-            del self.state_sid
-            raise IOError('could not register STATE client')
-
-    def reg_msg_cb(self):
-        if not hasattr(self, 'state'):
-            raise TypeError(self.name+' has no CMD called STATE')
-        service_name = self.name.upper()+'/MESSAGE'
-        self.msg_sid = pydim.dic_info_service(service_name, "C", self.msg_callback)
-        if not self.msg_sid:
-            del self.msg_sid
-            raise IOError('could not register MESSAGE client')
-
-    def unreg_state_cb(self):
-        if hasattr(self, 'state_sid'):
-            pydim.dic_release_service(self.state_sid)
-            del self.state_sid
-
-    def unreg_msg_cb(self):
-        if hasattr(self, 'msg_sid'):
-            pydim.dic_release_service(self.msg_sid)
-            del self.msg_sid
-
-    def __del__(self):
-        self.unreg_state_cb()
-        self.unreg_msg_cb()
-
-# utility functions for dynamic addid of methods to classes
-def add_command(cls, name): 
-    meth_name = name.split('/')[1].lower()
-    if iskeyword(meth_name):
-        meth_name += '_cmd'
-        
-    # this is the new command, it simple calls the _cmd() method
-    def new_command(self, *args):
-        self._cmd(meth_name, *args)
-        
-    new_command.__name__ = meth_name
-    
-    # from this line on, the docstring of the method is created
-    if name in dd:
-        if not dd[name]:
-            new_command.__doc__ = "DESC in SERVICE_DESC is empty ?!"
-        else:
-            new_command.__doc__ = dd[name]
-    else:
-        new_command.__doc__ = "-- no DESC found in SERVICE_DESC --"
-    new_command.__doc__ += '\n'
-    new_command.__doc__ += services[name.split('/')[0]][name][0]
-    
-    # this line make the new_command() method, a method of the class cls
-    # giving it the name new_command.__name__
-    setattr( cls, new_command.__name__, new_command)
-
-# add_getter is very similar to add_command,
-# the only difference is, that it calls _get() instead of _cmd()
-# and since _get() has a return value, this return value is vorwarded to the user
-def add_getter(cls, name): 
-    meth_name = name.split('/')[1].lower()
-    if iskeyword(meth_name):
-        meth_name += '_cmd'
-    def new_command(self):
-        return self._get(meth_name)
-    new_command.__name__ = meth_name
-    if name in dd:
-        if not dd[name]:
-            new_command.__doc__ = "DESC in SERVICE_DESC is empty ?!"
-        else:
-            new_command.__doc__ = dd[name]
-    else:
-        new_command.__doc__ = "-- no DESC found in SERVICE_DESC --"
-    new_command.__doc__ += '\n'
-    new_command.__doc__ += services[name.split('/')[0]][name][0]
-    setattr( cls, new_command.__name__, new_command)
-
-
-
-
-
-# In order to create classes according to the Dim-Servers, currently connected
-# to the DIS_DNS I have to parse DIS_DNS/SERVER_LIST
-# This is done in two steps, first I get the list of Server Names from DIS_DNS
-# and the I get the list of each servers services and cmds, 
-# from each servers SERVICE_LIST and the service/command description 
-# from each servers SERVICE_DESC
-# I get quite a lot of information, which I store in python dicts, or
-# even nested dicts, if necessary.
-
-def ParseDnsServerList():
-    # making server list
-    rawlist = pydim.dic_sync_info_service('DIS_DNS/SERVER_LIST','C')
-    # the output needs to be treated a bit .. it is a tuple with only one long string in it
-    # the string contains | and the strange character \x00
-    # I use both to cut the list apart
-    rawlist = rawlist[0].split('\x00')
-    servers_n_hosts = rawlist[0].split('|')
-    server_ids = rawlist[1].split('|')
-
-    servers = {}
-    for i,snh in enumerate(servers_n_hosts):
-        snh = snh.split('@')
-        s = snh[0]
-        h = snh[1]
-        sid = server_ids[i]
-        servers[s] = (sid, h)
-
-    return servers
-
-
-
-# servers should be a dict containing uppercase server names as keys,
-# the values are not needed, so it might be any iteratable python listlike type 
-# to be precise
-def ParseServersServiceList( servers ):
-    
-    services = {}
-    dd = {}
-    for server in servers:
-        # sl_raw is a tuple, with an really long string, which needs to be parsed
-        sl_raw = pydim.dic_sync_info_service(server+'/SERVICE_LIST','C')[0]
-        
-        # even without parsing, I can find out, if this server also gives me a 
-        # service description list. In case it does not, this is fine as well
-        # the doc string of the dynamicly created methods, will then contain 
-        # a note, that therer was no SERVICE_DESC ... 
-        if server+'/SERVICE_DESC' in sl_raw:
-            sd_raw = pydim.dic_sync_info_service(server+'/SERVICE_DESC','C')[0]
-        else:
-            sd_raw = ''
-        
-        # now before parsing, I strip off all ASCII zeroes '\x00' and all 
-        # line breaks off the *end* of the long string of both
-        # the service list sl
-        # and service description sd
-        #
-        # I think in sl_raw were alse some '\x00' in the middle .. these 
-        # are replaced by nothing, in case they are there.
-        sl_raw = sl_raw.rstrip('\x00\n')
-        sl_raw = sl_raw.replace('\x00','')
-        sd_raw = sd_raw.rstrip('\x00\n')
-        
-        # The lists are seperated by line breaks, so I split them using this
-        sl = sl_raw.split('\n')
-        sd = sd_raw.split('\n')
-        
-        # First I parse the service descriptons, so I have them available, 
-        # when I create the dict full of services.
-        # All desciptions look like this
-        # 'SERVER/SERVICE=some descriptive text' or
-        # 'SERVER/SERVICE='
-        # this I use to create the dictionary.
-        # create descripton dict dd from service_desc list sd
-        for d_str in sd:
-            service,equalsign,desc = d_str.partition('=')
-            #if '=' != equalsign:
-                # print "Error: server:", server, "desc:", d_str
-            dd[service] = desc
-
-        # Now I fill ther services dict. Each server gets a nested dict
-        # inside services. 
-        # Each service is explained in a string with a '|' in between.
-        # I use this for spliting. 
-        # The string look like this 
-        # SERVER/SERVICE|format-desc-str(e.g. I:2;C)|-empty- or CMD or RPC|
-        services[server] = {}
-        for service in sl:
-            service = service.split('|')
-            if service[0] in dd:
-                services[server][service[0]] = (
-                        service[1], service[2], dd[service[0]])
-    return services, dd
-
-
-servers = ParseDnsServerList()
-services, dd = ParseServersServiceList( servers )
-
-# create one class for each Fact Dim Server
-FactDimServerClasses = []
-for server_name in servers:
-    FactDimServerClasses.append( 
-            types.ClassType( server_name, (FactDimServer,), {}) )
-    for cmd in services[server_name]:
-        if 'CMD' in services[server_name][cmd][1]:
-            cmdname = cmd.split('/')[1]
-            add_command(FactDimServerClasses[-1], cmd)
-        elif not services[server_name][cmd][1]:
-            cmdname = cmd.split('/')[1]
-            add_getter(FactDimServerClasses[-1], cmd)
-
-
-
-# create an instace of each of the classes
-# and make it globally known, i.e. known to the Python interpreter
-# all the ServerClass instances are collected in a list
-# so one can get a quick overview --> print dims
-dims = []
-for i,server_name in enumerate(servers):
-    if server_name == 'DIS_DNS':
-        continue
-    new_instance = FactDimServerClasses[i](server_name)
-    dims.append( new_instance )
-    globals()[server_name.lower()] = new_instance
-del new_instance
-
-##############################################################################
-# class for colored printing
-
-class bcolors:
-        HEADER = '\033[95m'
-        OKBLUE = '\033[94m'
-        OKGREEN = '\033[92m'
-        WARNING = '\033[93m'
-        FAIL = '\033[91m'
-        ENDC = '\033[0m'
-
-        def disable(self):
-            self.HEADER = ''
-            self.OKBLUE = ''
-            self.OKGREEN = ''
-            self.WARNING = ''
-            self.FAIL = ''
-            self.ENDC = ''
-
-##############################################################################
-# class which implements colored printing
-# method calls can be used instead of Python print calls 
-# for conveniently printing colored output.
-
-
-class MSG( bcolors):
-    def __init__(self, verbose = True):
-        """ create MSG instance, 
-            default is verbose,
-            sets self.output
-            
-            if:
-            self.*output* = True, object behaves as expeted
-            if False, no call return anything
-        """
-        self.output = verbose
-    
-    def fail(self, text ):
-        """ print in RED
-        """
-        text = str(text)
-        if self.output:
-            print bcolors.FAIL + "ERROR:" + bcolors.ENDC,
-            print bcolors.FAIL + text + bcolors.ENDC
-
-    def warn(self, text ):
-        """ print in YELLOW
-        """
-        text = str(text)
-        if self.output:
-            print bcolors.WARNING + text + bcolors.ENDC
-
-    def ok(self, text ):
-        """ print in GREEN
-        """
-        text = str(text)
-        if self.output:
-            print bcolors.OKGREEN + text + bcolors.ENDC
-
-    def __call__(self, *args):
-        """ print as Python print would do 
-        """
-        if self.output:
-            for arg in args:
-                print arg,
-            print
-
Index: /fact/tools/PyDimCtrl/pyfactctrl.py
===================================================================
--- /fact/tools/PyDimCtrl/pyfactctrl.py	(revision 13808)
+++ /fact/tools/PyDimCtrl/pyfactctrl.py	(revision 13808)
@@ -0,0 +1,597 @@
+#!/usr/bin/python -tti
+from fpydim import *
+
+
+
+def IsReadyForDataTaking( verbose = True ):
+    drive = drive_control
+    bias = bias_control
+    fad = fad_control
+    
+    msg = MSG()
+    msg.output = verbose
+    msg("Checking if System isready for data taking... ")
+
+    ok = True
+    if not drive() == 7:
+        msg.warn( drive.state()[0] + "  NOT ok")
+        ok = False
+    if not feedback() == 12:
+        msg.warn( feedback.state()[0] + "  NOT ok")
+        ok = False
+    if not bias() == 9:
+        msg.warn( bias.state()[0] + "  NOT ok")
+        ok = False
+    if not fad() == 4:
+        msg.warn( fad.state()[0] + "  NOT ok")
+        ok = False
+    
+    if ok:
+        msg.ok( " all ok " )
+
+    return ok
+
+def StopTracking( verbose = True ):
+    msg = MSG()
+    msg.output = verbose
+
+    # defining a shortcut 
+    drive = drive_control
+
+    drive.stop()
+    if not drive.wait(5, 10):
+        msg.warn("drive did not reach state 5 after 10 seconds")
+        msg.warn( drive.state()[0].rstrip('\x00') )
+        return False
+
+    return True
+
+def TakeDataRun( verbose = True ):
+    fad = fad_control    
+    msg = MSG()
+    msg.output = verbose
+    if not IsReadyForDataTaking( verbose=False ):
+        msg.fail("System not Ready for DataTaking")
+        IsReadyForDataTaking( verbose=True )
+        return False
+    mcp.start(300,-1,'data\0')
+    if not fad.wait(8, 10):
+        msg.warn("FAD not in Writing Data after 10seconds")
+        return False
+    msg("... taking data: 300 seconds - normal data run")
+    if not fad.wait(4, 330):
+        msg.warn("FAD did not return to Connected, after 330 seconds")
+        return False
+    return True
+
+def TrackSource( Shift=0.6, Angle=50, SrcName='Crab', verbose=True):
+    drive = drive_control
+    
+    msg = MSG()
+    msg.output = verbose
+
+    if not drive.wait(5, 10):
+        msg.warn("drive not ready after 10sec")
+        msg.warn( drive.state()[0].rstrip('\x00') )
+        return False
+
+    SrcName += '\0'
+    drive.track_source( Shift, Angle, SrcName)
+    
+    return True
+
+def WaitForTracking( CalmDownTime = 30, verbose = True):
+    drive = drive_control
+
+    msg = MSG()
+    msg.output = verbose
+
+    if not drive.wait(6, 10):
+        msg.warn("drive not in state moving after 10sec")
+        return False
+
+    if not drive.wait(7, 10):
+        msg.warn("drive not in state Tracking after 10sec")
+        return False
+
+    msg("waiting "+str(CalmDownTime)\
+            +"sec for drive to calm down and tracking to be stable")
+    time.sleep(CalmDownTime)
+    return True
+def TakePedestalOnRun( verbose = True ):
+    msg = MSG()
+    msg.output = verbose
+    if not IsReadyForDataTaking( verbose=False ):
+        msg.fail("System not Ready for DataTaking")
+        IsReadyForDataTaking( verbose=True )
+        return False
+    mcp.start(-1,1000,'pedestal\0')
+    if not fad.wait(8, 10):
+        msg.warn("FAD not in Writing Data after 10seconds")
+        return False
+    msg("... taking ped: 1000evts @25Hz")
+    if not fad.wait(4, 50):
+        msg.warn("FAD did not return to Connected, after 50 seconds")
+        return False
+    return True
+    
+def TakeExtLpRun( verbose = True ):
+    msg = MSG()
+    msg.output = verbose
+    if not IsReadyForDataTaking( verbose=False ):
+        msg.fail("System not Ready for DataTaking")
+        IsReadyForDataTaking( verbose=True )
+        return False
+    mcp.start(-1,1000,'light-pulser-ext\0')
+    if not fad.wait(8, 10):
+        msg.warn("FAD not in Writing Data after 10seconds")
+        return False
+    msg("... taking light-pulser-ext: 1000evts @25Hz")
+    if not fad.wait(4, 50):
+        msg.warn("FAD did not return to Connected, after 50 seconds")
+        return False
+    return True
+
+def TakeData( verbose = True):
+    msg = MSG()
+    msg.output = verbose
+    TakePedestalOnRun()
+    TakeExtLpRun()
+    for i in range(4):
+        i +=1
+        msg("Taking Data Run "+str(i)+" of 4")
+        TakeDataRun()
+
+def Take( time=0, events=0, runtype='drs-pedestal', verbose=True):
+    msg = MSG()
+    msg.output = verbose
+    fad = fad_control
+    runtype += '\0'
+    if not fad.wait(4, 10):
+        msg.warn("fad not connected after 10sec")
+        return False
+    mcp.start( time, events, runtype)
+    if not fad.wait(8, 30):
+        msg.warn("fad not Writing Data after 30sec")
+        return False
+    timeout = float('inf')
+    if time != -1:
+        timeout = time*1.1
+    if not fad.wait(4, timeout):
+        msg.warn("Data Writing not finished after "+str(timeout)+"sec")
+        return False
+    return True
+
+
+def BlinkenLights(verbose = True):
+    msg = MSG(verbose)
+    fad = fad_control
+
+    for i in range(10):
+        fad.set_file_format(2)
+        time.sleep(1)
+        fad.set_file_format(0)
+        time.sleep(1)
+
+
+
+
+#==============================================================================
+def Connect():
+    prepare_ftm_control()
+    prepare_fsc_control()
+    feedback.stop()
+    prepare_bias_control()
+    prepare_feedback()
+    prepare_data_logger()
+
+def prepare_fsc_control( verbose = True, timeout = 10, delay = 0.2):
+    msg = MSG( verbose )
+    fsc = fsc_control
+    start_time = time.time()
+    if timeout == None:
+        timeout = float('inf')
+    if delay < 0.:
+        delay = 0.
+    
+    while not fsc.stn == 2: #Connected
+        if time.time() > start_time + timeout:
+            return False
+    
+        if (fsc.stn <= 0) or (fsc.stn >= 256):
+            msg.fail("FSC_CONTROL is in state "+fsc.sts)
+            msg.fail(prepare_fsc_control.__name__ + "does not know how to handle this")
+            return False
+        elif fsc.stn == 1: # Disconnected
+            fsc.reconnect()
+    return True
+    
+def prepare_ftm_control( verbose = True, timeout = 10, delay = 0.2):
+    msg = MSG( verbose )
+    ftm = ftm_control
+    start_time = time.time()
+    if timeout == None:
+        timeout = float('inf')
+    if delay < 0.:
+        delay = 0.
+    
+    while not ftm.stn == 3:
+        if time.time() > start_time + timeout:
+            return False
+    
+        if (ftm.stn <= 0) or (ftm.stn >= 256):
+            msg.fail("FMT_CONTROL is in state "+ftm.sts)
+            msg.fail("ftm_to_Idle() does not know how to handle this")
+            return False
+        elif ftm.stn == 1: # Disconnected
+            ftm.reconnect()
+        elif ftm.stn == 2: #Connected
+            # just wait a second
+            time.sleep(1)
+        elif ftm.stn == 4: #TriggerOn
+            ftm.enable_trigger(0) #switch trigger off
+        elif ftm.stn in [5,6,7]: # some Configure state
+            ftm.reset_configure()
+    
+    return True
+    
+def prepare_data_logger( verbose = True, timeout = 10, delay = 0.2):
+    msg = MSG(verbose)
+    dl = data_logger
+    if timeout == None:
+        timeout = float('inf')
+    if delay < 0.:
+        delay = 0.
+    start_time = time.time()
+    raise NotImplementedError('prepare_data_logger() is not yet implemented')
+
+def prepare_fad_control( verbose = True, timeout = 10, delay = 0.2):
+    msg = MSG(verbose)
+    fad = fad_control
+    ftm = ftm_control
+    if timeout == None:
+        timeout = float('inf')
+    if delay < 0.:
+        delay = 0.
+    start_time = time.time()
+
+    while not fad.stn == 4:
+        # Timeout
+        if time.time() > start_time + timeout:
+            msg.fail("Timeout in " + prepare_fad_control.__name__)
+            return False
+        # Strange States
+        if (fad.stn <= 0) or (fad.stn >= 256):
+            msg.fail("FAD_CONTROL is in state "+fad.sts)
+            msg.fail(prepare_fad_control.__name__ + "does not know how to handle this")
+            return False
+        elif fad.stn == 1: # Disengaged
+            fad.start()
+        elif fad.stn == 2: # Disconnected
+            fad.start()
+        elif fad.stn == 3: # Connecting
+            # it might just need time
+            if time.time() - fad.last_st_change < 5:
+                time.sleep(2)
+                timeout += 1
+            else:
+            # there might be a problem with one of the boards
+            conns = map( ord, fad.connections()[0] )
+            problems = {}
+            for fad,conn in enumerate(conns):
+                if conn < 255:
+                    print "FAD:", fad, "has a problem"
+                    if not fad/10 in problems:
+                        problems[fad/10] = []
+                    else:
+                        problems[fad/10].append( fad%10 )
+            
+            for fad in range(10):
+                for crate in problems.keys():
+                    fad.disconnect(crate*10+fad)
+                    ftm.toggle_ftu(crate*10+fad)
+            for crate in problems.keys():
+                time.sleep(1)
+                ftm.reset_crate(crate)
+                
+            for fad in range(10):
+                for crate in problems.keys():
+                    time.sleep(3.5)
+                    fad.connect(crate*10+fad)
+                    ftm.toggle_ftu(crate*10+fad)
+        
+        elif fad.stn == 5: # Configuring1
+            if time.time() - fad.last_st_change < 5:
+                time.sleep(1)
+            else:
+                msg.warn("FAD is in Configuring1 since more than 5sec")
+                
+        elif fad.stn == 6: # Configuring2 
+            if time.time() - fad.last_st_change < 5:
+                time.sleep(1)
+            else:
+                msg.warn("FAD is in Configuring2 since more than 5sec")
+        
+        elif fad.stn == 7: # Configured
+            if time.time() - fad.last_st_change < 5:
+                time.sleep(1)
+            else:
+                msg.warn("FAD is in Configuring2 since more than 5sec")
+        
+        elif fad.stn == 8: #WritingData
+            # I don't know how to get from WritingData to Connected
+            # well. .. one could wait for a timeout, but I hate that.
+            fad.close_open_files()
+        
+        
+        time.sleep(delay)
+    return True
+
+def prepare_bias_control( verbose = True, timeout = 10, delay = 0.2):
+    msg = MSG(verbose)
+    bias = bias_control
+    
+    if timeout == None:
+        timeout = float('inf')
+    if delay < 0.:
+        delay = 0.
+    start_time = time.time()
+
+    while (bias.stn != 4) and (bias.stn != 7): #Connected or VoltageOff
+        # Timeout
+        if time.time() > start_time + timeout:
+            msg.fail("Timeout in " + prepare_bias_control.__name__)
+            return False
+        # Strange States
+        if (bias.stn <= 0) or (bias.stn >= 256):
+            msg.fail("BIAS_CONTROL is in state "+bias.sts)
+            msg.fail(prepare_bias_control.__name__ + "does not know how to handle this")
+            return False
+        elif bias.stn == 1: # Disconnected
+            bias.reconnect()
+        elif bias.stn == 2: # Connecting
+            if time.time() - bias.last_st_change < 5:
+                time.sleep(1)
+            else:
+                msg.warn("BIAS_CONTROL is in Connecting since more than 5sec")
+        elif bias.stn == 3: # Initializing
+            if time.time() - bias.last_st_change < 5:
+                time.sleep(1)
+            else:
+                msg.warn("BIAS_CONTROL is in Initializing since more than 5sec")
+        elif bias.stn == 5: #Ramping
+            if time.time() - bias.last_st_change < 10:
+                time.sleep(1)
+            else:
+                msg.warn("BIAS_CONTROL is in Ramping since more than 10sec")
+                bias.stop()
+        elif bias.stn == 6: #OverCurrent
+            time.sleep(0.5)
+            bias.set_zero_voltage()
+            time.sleep(0.5)
+            bias.reset_over_current_status()
+            time.sleep(0.5)
+        elif bias.stn == 8: #NotReferenced
+            time.sleep(0.5)
+            bias.set_zero_voltage()
+            time.sleep(0.5)
+        elif bias.stn == 9: # VoltageOn
+            time.sleep(0.5)
+            bias.set_zero_voltage()
+            time.sleep(0.5)
+        elif bias.stn == 10: # ExpoertMode
+            msg.fail("BIAS is in ExportMode ... wtf")
+            return False
+        
+        time.sleep(delay)
+    return True
+    
+def prepare_feedback( verbose = True, timeout = 10, delay = 0.2):
+    msg = MSG(verbose)
+    fb = feedback
+    if timeout == None:
+        timeout = float('inf')
+    if delay < 0.:
+        delay = 0.
+    start_time = time.time()
+
+    while not fb.stn == 6: #Connected 
+        # Timeout
+        if time.time() > start_time + timeout:
+            msg.fail("Timeout in " + prepare_feedback.__name__)
+            return False
+        # Strange States
+        if (fb.stn <= 1) or (fb.stn >= 256):
+            msg.fail("FEEDBACK is in state "+fb.sts)
+            msg.fail(prepare_feedback.__name__ + "does not know how to handle this")
+            return False
+        elif fb.stn in [2,3,4,5]:
+            if time.time() - fb.last_st_change < 10:
+                time.sleep(1)
+            else:
+                msg.warn("BIAS_CONTROL is in "+fb.sts+" since more than 10sec")
+        
+        elif fb.stn in [7,8,9]:
+            fb.stop()
+
+        elif fb.stn in [10,11,12]:
+            fb.enable_output(0)
+            fb.stop()
+        
+        elif fb.stn == 13:
+            # maybe waiting helps
+            if time.time() - fb.last_st_change < 20:
+                time.sleep(1)
+            else:
+                msg.warn("FEEDBACK is in "+fb.sts+" since more than 20sec \n sending STOP")
+                fb.stop()
+        
+        time.sleep(delay)
+    return True
+
+
+
+#==============================================================================
+def TakeDrsAmplitudeCalibration( roi = None, verbose = True):
+    """ Takes DRS Amplitude Calibration
+        *roy* integer: 300, 1024 or 
+        *roy* string : 'both'
+        in case of both, the roi=300 calibration is done last.
+        
+        after each complete AmpliteCalibration a 4th pedestal run of the same 
+        roi is taken, for crosschecking.
+        """
+    msg = MSG( verbose )
+    bias = bias_control
+    fad = fad_control
+    if not roi in [300,1024,'both']:
+        raise ValueError("roi must be 300,1024 or the string 'both'")
+
+
+    bias.set_zero_voltage()
+    if not bias.wait(7, 10):
+        msg.warn("bias has not switched of after 10sec")
+        return False
+
+    fad.start_drs_calibration()
+    Take( -1, 1000, 'drs-pedestal')
+    Take( -1, 1000, 'drs-gain')
+    if roi == 300:
+        Take( -1, 1000, 'pedestal')
+        fad.set_file_format(2)
+        Take( -1, 1000, 'pedestal')
+    elif roi == 1024:
+        Take( -1, 1000, 'drs-pedestal')
+        fad.set_file_format(2)
+        Take( -1, 1000, 'drs-pedestal')
+    elif roi == 'both':
+        Take( -1, 1000, 'drs-pedestal')
+        fad.set_file_format(2)
+        Take( -1, 1000, 'drs-pedestal')
+        fad.reset_secondary_drs_baseline()
+        Take( -1, 1000, 'pedestal')
+        fad.set_file_format(2)
+        Take( -1, 1000, 'pedestal')
+
+
+def TakeDrsTimeCalibration( mode = None, verbose = True):
+    """ Takes DRS Time Calibration
+        *mode* can be 'upshifted', 'old' or 'both'
+    """
+    msg = MSG( verbose )
+    bias = bias_control
+    fad = fad_control
+    if not mode in ['upshifted', 'old', 'both']:
+        raise ValueError("mode must be: 'upshifted','old' or 'both'")
+
+    bias.set_zero_voltage()
+    if not bias.wait(7, 10):
+        msg.warn("bias has not switched of after 10sec")
+        return False
+
+    fad.set_file_format(2)
+    if mode == 'old':
+        Take(-1, 1000, 'drs-time')
+    if mode == 'upshifted':
+        Take(-1, 1000, 'drs-time-upshifted')
+    if mode == 'both':
+        Take(-1, 1000, 'drs-time')
+        Take(-1, 1000, 'drs-time-upshifted')
+
+
+def VoltageOn( mode = None, Watchdog = None, verbose = True):
+    msg = MSG( verbose )
+    bias = bias_control
+    fb = feedback
+
+    if not mode in ['temperature', 'current', 'feedback']:
+        raise ValueError("mode must be 'temperature', 'current' or 'feedback'")
+    
+    feedback.start(..... blaaaaa .....)
+    hier muss noch ne menge passieren
+    
+    bias.set_global_dac(1)
+    if not bias.wait(9, 10):
+        msg.warn("bias not in Voltage ON after 10sec")
+        return False
+    if not bias.wait(5, 10):
+        msg.warn("bias not Ramping after 10sec")
+        return False
+    if not bias.wait(9, 30):
+        msg.warn("bias not fully ramped up after 30sec")
+        return False
+
+    msg("waiting 45sec...")    
+    time.sleep(45)
+    return True
+
+# standard watchdogs:
+def std_bias_watchdog( state, verbose=True ):
+    msg = MSG(verbose)
+    if state == 1: #Disconnected
+        msg.warn("BIAS just DISCONNECTED .. trying to reconnect")
+        msg.warn("current runnumber:"+fad_control.runnumber() )
+        bias.reconnect()
+        time.sleep(1)
+        bias.set_zero_voltage()
+        # TODO: This should work, but it is stupid.
+        bias.reset_over_current_status()
+        bias.reset_over_current_status()
+        bias.set_zero_voltage()
+        bias.reset_over_current_status()
+        bias.set_global_dac(1)
+
+# create introduction:
+class INTRO(object):
+    def __init__(self):
+        # nothing to do
+        pass
+        
+    def __repr__(self):
+        print "welcome to PyDimCtrl V0.1:"
+        print "--------------------------"
+        print "If the hardware is ON but not all the software is connected try:"
+        print "      Connect()"
+        print "If all the programs are already up and running, you might want to"
+        print "     TakeDrsAmplitudeCalibration(roi=1024) or "
+        print "     TakeDrsAmplitudeCalibration(roi=300)"
+        print "         i.e. ped, gain, trigger_offset + extra ped(for X-check)"
+        print "     TakeDrsTimeCalibration( type='upshifted' ) or "
+        print "     TakeDrsTimeCalibration( type='old' ) or "
+        print "     "
+        print "In case you would like to ramp up the Bias voltage try:"
+        print "     VoltageOn( mode='temperature' ) or"
+        print "     VoltageOn( mode='current' ) or"
+        print "     VoltageOn( mode='light_pulser' )"
+        print "Switch off with:"
+        print "     VoltageOff()"
+        print ""
+        print "In case you would like a Watchdog to check, if the Voltage is up"
+        print "and the BiasCrate is not disconnected, then try:"
+        print "     VoltageOn( mode='--see above--', Watchdog=True )"
+        print "PLEASE NOTE: The Watchdog will monitor the State of BIAS_CONTROL"
+        print "and in case of a connection loss, it will: "
+        print "     * print a warning"
+        print "     * issue a the RECONNECT command" 
+        print "     * issue SET_ZERO_VOLTAGE - since this is the only way to get referenced"
+        print "     * Ramp up again, using the same settings as before"
+        print "     * possible OverCurrent situation will be treated as usual"
+        print "The Watchdog will not react on any other state change, like OverCurrent or VoltageOff"
+        print ""
+        print ""
+        return ""
+        
+
+intro = INTRO()
+
+if __name__ == '__main__':
+    print "welcome:"
+    print " type: intro"
+    print " for a short introduction"
+
+    
+    #IsReadyForDataTaking()
+    #TrackSource( Shift=0.6, Angle=50, SrcName='Crab', verbose=True)
+    #WaitForTracking( CalmDownTime = 30, verbose = True)
+    #TakeDataRun()
+    #StopTracking()
Index: ct/tools/PyDimCtrl/service.py
===================================================================
--- /fact/tools/PyDimCtrl/service.py	(revision 13807)
+++ 	(revision )
@@ -1,597 +1,0 @@
-#!/usr/bin/python -tti
-from fpydim import *
-
-
-
-def IsReadyForDataTaking( verbose = True ):
-    drive = drive_control
-    bias = bias_control
-    fad = fad_control
-    
-    msg = MSG()
-    msg.output = verbose
-    msg("Checking if System isready for data taking... ")
-
-    ok = True
-    if not drive() == 7:
-        msg.warn( drive.state()[0] + "  NOT ok")
-        ok = False
-    if not feedback() == 12:
-        msg.warn( feedback.state()[0] + "  NOT ok")
-        ok = False
-    if not bias() == 9:
-        msg.warn( bias.state()[0] + "  NOT ok")
-        ok = False
-    if not fad() == 4:
-        msg.warn( fad.state()[0] + "  NOT ok")
-        ok = False
-    
-    if ok:
-        msg.ok( " all ok " )
-
-    return ok
-
-def StopTracking( verbose = True ):
-    msg = MSG()
-    msg.output = verbose
-
-    # defining a shortcut 
-    drive = drive_control
-
-    drive.stop()
-    if not drive.wait(5, 10):
-        msg.warn("drive did not reach state 5 after 10 seconds")
-        msg.warn( drive.state()[0].rstrip('\x00') )
-        return False
-
-    return True
-
-def TakeDataRun( verbose = True ):
-    fad = fad_control    
-    msg = MSG()
-    msg.output = verbose
-    if not IsReadyForDataTaking( verbose=False ):
-        msg.fail("System not Ready for DataTaking")
-        IsReadyForDataTaking( verbose=True )
-        return False
-    mcp.start(300,-1,'data\0')
-    if not fad.wait(8, 10):
-        msg.warn("FAD not in Writing Data after 10seconds")
-        return False
-    msg("... taking data: 300 seconds - normal data run")
-    if not fad.wait(4, 330):
-        msg.warn("FAD did not return to Connected, after 330 seconds")
-        return False
-    return True
-
-def TrackSource( Shift=0.6, Angle=50, SrcName='Crab', verbose=True):
-    drive = drive_control
-    
-    msg = MSG()
-    msg.output = verbose
-
-    if not drive.wait(5, 10):
-        msg.warn("drive not ready after 10sec")
-        msg.warn( drive.state()[0].rstrip('\x00') )
-        return False
-
-    SrcName += '\0'
-    drive.track_source( Shift, Angle, SrcName)
-    
-    return True
-
-def WaitForTracking( CalmDownTime = 30, verbose = True):
-    drive = drive_control
-
-    msg = MSG()
-    msg.output = verbose
-
-    if not drive.wait(6, 10):
-        msg.warn("drive not in state moving after 10sec")
-        return False
-
-    if not drive.wait(7, 10):
-        msg.warn("drive not in state Tracking after 10sec")
-        return False
-
-    msg("waiting "+str(CalmDownTime)\
-            +"sec for drive to calm down and tracking to be stable")
-    time.sleep(CalmDownTime)
-    return True
-def TakePedestalOnRun( verbose = True ):
-    msg = MSG()
-    msg.output = verbose
-    if not IsReadyForDataTaking( verbose=False ):
-        msg.fail("System not Ready for DataTaking")
-        IsReadyForDataTaking( verbose=True )
-        return False
-    mcp.start(-1,1000,'pedestal\0')
-    if not fad.wait(8, 10):
-        msg.warn("FAD not in Writing Data after 10seconds")
-        return False
-    msg("... taking ped: 1000evts @25Hz")
-    if not fad.wait(4, 50):
-        msg.warn("FAD did not return to Connected, after 50 seconds")
-        return False
-    return True
-    
-def TakeExtLpRun( verbose = True ):
-    msg = MSG()
-    msg.output = verbose
-    if not IsReadyForDataTaking( verbose=False ):
-        msg.fail("System not Ready for DataTaking")
-        IsReadyForDataTaking( verbose=True )
-        return False
-    mcp.start(-1,1000,'light-pulser-ext\0')
-    if not fad.wait(8, 10):
-        msg.warn("FAD not in Writing Data after 10seconds")
-        return False
-    msg("... taking light-pulser-ext: 1000evts @25Hz")
-    if not fad.wait(4, 50):
-        msg.warn("FAD did not return to Connected, after 50 seconds")
-        return False
-    return True
-
-def TakeData( verbose = True):
-    msg = MSG()
-    msg.output = verbose
-    TakePedestalOnRun()
-    TakeExtLpRun()
-    for i in range(4):
-        i +=1
-        msg("Taking Data Run "+str(i)+" of 4")
-        TakeDataRun()
-
-def Take( time=0, events=0, runtype='drs-pedestal', verbose=True):
-    msg = MSG()
-    msg.output = verbose
-    fad = fad_control
-    runtype += '\0'
-    if not fad.wait(4, 10):
-        msg.warn("fad not connected after 10sec")
-        return False
-    mcp.start( time, events, runtype)
-    if not fad.wait(8, 30):
-        msg.warn("fad not Writing Data after 30sec")
-        return False
-    timeout = float('inf')
-    if time != -1:
-        timeout = time*1.1
-    if not fad.wait(4, timeout):
-        msg.warn("Data Writing not finished after "+str(timeout)+"sec")
-        return False
-    return True
-
-
-def BlinkenLights(verbose = True):
-    msg = MSG(verbose)
-    fad = fad_control
-
-    for i in range(10):
-        fad.set_file_format(2)
-        time.sleep(1)
-        fad.set_file_format(0)
-        time.sleep(1)
-
-
-
-
-#==============================================================================
-def Connect():
-    prepare_ftm_control()
-    prepare_fsc_control()
-    feedback.stop()
-    prepare_bias_control()
-    prepare_feedback()
-    prepare_data_logger()
-
-def prepare_fsc_control( verbose = True, timeout = 10, delay = 0.2):
-    msg = MSG( verbose )
-    fsc = fsc_control
-    start_time = time.time()
-    if timeout == None:
-        timeout = float('inf')
-    if delay < 0.:
-        delay = 0.
-    
-    while not fsc.stn == 2: #Connected
-        if time.time() > start_time + timeout:
-            return False
-    
-        if (fsc.stn <= 0) or (fsc.stn >= 256):
-            msg.fail("FSC_CONTROL is in state "+fsc.sts)
-            msg.fail(prepare_fsc_control.__name__ + "does not know how to handle this")
-            return False
-        elif fsc.stn == 1: # Disconnected
-            fsc.reconnect()
-    return True
-    
-def prepare_ftm_control( verbose = True, timeout = 10, delay = 0.2):
-    msg = MSG( verbose )
-    ftm = ftm_control
-    start_time = time.time()
-    if timeout == None:
-        timeout = float('inf')
-    if delay < 0.:
-        delay = 0.
-    
-    while not ftm.stn == 3:
-        if time.time() > start_time + timeout:
-            return False
-    
-        if (ftm.stn <= 0) or (ftm.stn >= 256):
-            msg.fail("FMT_CONTROL is in state "+ftm.sts)
-            msg.fail("ftm_to_Idle() does not know how to handle this")
-            return False
-        elif ftm.stn == 1: # Disconnected
-            ftm.reconnect()
-        elif ftm.stn == 2: #Connected
-            # just wait a second
-            time.sleep(1)
-        elif ftm.stn == 4: #TriggerOn
-            ftm.enable_trigger(0) #switch trigger off
-        elif ftm.stn in [5,6,7]: # some Configure state
-            ftm.reset_configure()
-    
-    return True
-    
-def prepare_data_logger( verbose = True, timeout = 10, delay = 0.2):
-    msg = MSG(verbose)
-    dl = data_logger
-    if timeout == None:
-        timeout = float('inf')
-    if delay < 0.:
-        delay = 0.
-    start_time = time.time()
-    raise NotImplementedError('prepare_data_logger() is not yet implemented')
-
-def prepare_fad_control( verbose = True, timeout = 10, delay = 0.2):
-    msg = MSG(verbose)
-    fad = fad_control
-    ftm = ftm_control
-    if timeout == None:
-        timeout = float('inf')
-    if delay < 0.:
-        delay = 0.
-    start_time = time.time()
-
-    while not fad.stn == 4:
-        # Timeout
-        if time.time() > start_time + timeout:
-            msg.fail("Timeout in " + prepare_fad_control.__name__)
-            return False
-        # Strange States
-        if (fad.stn <= 0) or (fad.stn >= 256):
-            msg.fail("FAD_CONTROL is in state "+fad.sts)
-            msg.fail(prepare_fad_control.__name__ + "does not know how to handle this")
-            return False
-        elif fad.stn == 1: # Disengaged
-            fad.start()
-        elif fad.stn == 2: # Disconnected
-            fad.start()
-        elif fad.stn == 3: # Connecting
-            # it might just need time
-            if time.time() - fad.last_st_change < 5:
-                time.sleep(2)
-                timeout += 1
-            else:
-            # there might be a problem with one of the boards
-            conns = map( ord, fad.connections()[0] )
-            problems = {}
-            for fad,conn in enumerate(conns):
-                if conn < 255:
-                    print "FAD:", fad, "has a problem"
-                    if not fad/10 in problems:
-                        problems[fad/10] = []
-                    else:
-                        problems[fad/10].append( fad%10 )
-            
-            for fad in range(10):
-                for crate in problems.keys():
-                    fad.disconnect(crate*10+fad)
-                    ftm.toggle_ftu(crate*10+fad)
-            for crate in problems.keys():
-                time.sleep(1)
-                ftm.reset_crate(crate)
-                
-            for fad in range(10):
-                for crate in problems.keys():
-                    time.sleep(3.5)
-                    fad.connect(crate*10+fad)
-                    ftm.toggle_ftu(crate*10+fad)
-        
-        elif fad.stn == 5: # Configuring1
-            if time.time() - fad.last_st_change < 5:
-                time.sleep(1)
-            else:
-                msg.warn("FAD is in Configuring1 since more than 5sec")
-                
-        elif fad.stn == 6: # Configuring2 
-            if time.time() - fad.last_st_change < 5:
-                time.sleep(1)
-            else:
-                msg.warn("FAD is in Configuring2 since more than 5sec")
-        
-        elif fad.stn == 7: # Configured
-            if time.time() - fad.last_st_change < 5:
-                time.sleep(1)
-            else:
-                msg.warn("FAD is in Configuring2 since more than 5sec")
-        
-        elif fad.stn == 8: #WritingData
-            # I don't know how to get from WritingData to Connected
-            # well. .. one could wait for a timeout, but I hate that.
-            fad.close_open_files()
-        
-        
-        time.sleep(delay)
-    return True
-
-def prepare_bias_control( verbose = True, timeout = 10, delay = 0.2):
-    msg = MSG(verbose)
-    bias = bias_control
-    
-    if timeout == None:
-        timeout = float('inf')
-    if delay < 0.:
-        delay = 0.
-    start_time = time.time()
-
-    while (bias.stn != 4) and (bias.stn != 7): #Connected or VoltageOff
-        # Timeout
-        if time.time() > start_time + timeout:
-            msg.fail("Timeout in " + prepare_bias_control.__name__)
-            return False
-        # Strange States
-        if (bias.stn <= 0) or (bias.stn >= 256):
-            msg.fail("BIAS_CONTROL is in state "+bias.sts)
-            msg.fail(prepare_bias_control.__name__ + "does not know how to handle this")
-            return False
-        elif bias.stn == 1: # Disconnected
-            bias.reconnect()
-        elif bias.stn == 2: # Connecting
-            if time.time() - bias.last_st_change < 5:
-                time.sleep(1)
-            else:
-                msg.warn("BIAS_CONTROL is in Connecting since more than 5sec")
-        elif bias.stn == 3: # Initializing
-            if time.time() - bias.last_st_change < 5:
-                time.sleep(1)
-            else:
-                msg.warn("BIAS_CONTROL is in Initializing since more than 5sec")
-        elif bias.stn == 5: #Ramping
-            if time.time() - bias.last_st_change < 10:
-                time.sleep(1)
-            else:
-                msg.warn("BIAS_CONTROL is in Ramping since more than 10sec")
-                bias.stop()
-        elif bias.stn == 6: #OverCurrent
-            time.sleep(0.5)
-            bias.set_zero_voltage()
-            time.sleep(0.5)
-            bias.reset_over_current_status()
-            time.sleep(0.5)
-        elif bias.stn == 8: #NotReferenced
-            time.sleep(0.5)
-            bias.set_zero_voltage()
-            time.sleep(0.5)
-        elif bias.stn == 9: # VoltageOn
-            time.sleep(0.5)
-            bias.set_zero_voltage()
-            time.sleep(0.5)
-        elif bias.stn == 10: # ExpoertMode
-            msg.fail("BIAS is in ExportMode ... wtf")
-            return False
-        
-        time.sleep(delay)
-    return True
-    
-def prepare_feedback( verbose = True, timeout = 10, delay = 0.2):
-    msg = MSG(verbose)
-    fb = feedback
-    if timeout == None:
-        timeout = float('inf')
-    if delay < 0.:
-        delay = 0.
-    start_time = time.time()
-
-    while not fb.stn == 6: #Connected 
-        # Timeout
-        if time.time() > start_time + timeout:
-            msg.fail("Timeout in " + prepare_feedback.__name__)
-            return False
-        # Strange States
-        if (fb.stn <= 1) or (fb.stn >= 256):
-            msg.fail("FEEDBACK is in state "+fb.sts)
-            msg.fail(prepare_feedback.__name__ + "does not know how to handle this")
-            return False
-        elif fb.stn in [2,3,4,5]:
-            if time.time() - fb.last_st_change < 10:
-                time.sleep(1)
-            else:
-                msg.warn("BIAS_CONTROL is in "+fb.sts+" since more than 10sec")
-        
-        elif fb.stn in [7,8,9]:
-            fb.stop()
-
-        elif fb.stn in [10,11,12]:
-            fb.enable_output(0)
-            fb.stop()
-        
-        elif fb.stn == 13:
-            # maybe waiting helps
-            if time.time() - fb.last_st_change < 20:
-                time.sleep(1)
-            else:
-                msg.warn("FEEDBACK is in "+fb.sts+" since more than 20sec \n sending STOP")
-                fb.stop()
-        
-        time.sleep(delay)
-    return True
-
-
-
-#==============================================================================
-def TakeDrsAmplitudeCalibration( roi = None, verbose = True):
-    """ Takes DRS Amplitude Calibration
-        *roy* integer: 300, 1024 or 
-        *roy* string : 'both'
-        in case of both, the roi=300 calibration is done last.
-        
-        after each complete AmpliteCalibration a 4th pedestal run of the same 
-        roi is taken, for crosschecking.
-        """
-    msg = MSG( verbose )
-    bias = bias_control
-    fad = fad_control
-    if not roi in [300,1024,'both']:
-        raise ValueError("roi must be 300,1024 or the string 'both'")
-
-
-    bias.set_zero_voltage()
-    if not bias.wait(7, 10):
-        msg.warn("bias has not switched of after 10sec")
-        return False
-
-    fad.start_drs_calibration()
-    Take( -1, 1000, 'drs-pedestal')
-    Take( -1, 1000, 'drs-gain')
-    if roi == 300:
-        Take( -1, 1000, 'pedestal')
-        fad.set_file_format(2)
-        Take( -1, 1000, 'pedestal')
-    elif roi == 1024:
-        Take( -1, 1000, 'drs-pedestal')
-        fad.set_file_format(2)
-        Take( -1, 1000, 'drs-pedestal')
-    elif roi == 'both':
-        Take( -1, 1000, 'drs-pedestal')
-        fad.set_file_format(2)
-        Take( -1, 1000, 'drs-pedestal')
-        fad.reset_secondary_drs_baseline()
-        Take( -1, 1000, 'pedestal')
-        fad.set_file_format(2)
-        Take( -1, 1000, 'pedestal')
-
-
-def TakeDrsTimeCalibration( mode = None, verbose = True):
-    """ Takes DRS Time Calibration
-        *mode* can be 'upshifted', 'old' or 'both'
-    """
-    msg = MSG( verbose )
-    bias = bias_control
-    fad = fad_control
-    if not mode in ['upshifted', 'old', 'both']:
-        raise ValueError("mode must be: 'upshifted','old' or 'both'")
-
-    bias.set_zero_voltage()
-    if not bias.wait(7, 10):
-        msg.warn("bias has not switched of after 10sec")
-        return False
-
-    fad.set_file_format(2)
-    if mode == 'old':
-        Take(-1, 1000, 'drs-time')
-    if mode == 'upshifted':
-        Take(-1, 1000, 'drs-time-upshifted')
-    if mode == 'both':
-        Take(-1, 1000, 'drs-time')
-        Take(-1, 1000, 'drs-time-upshifted')
-
-
-def VoltageOn( mode = None, Watchdog = None, verbose = True):
-    msg = MSG( verbose )
-    bias = bias_control
-    fb = feedback
-
-    if not mode in ['temperature', 'current', 'feedback']:
-        raise ValueError("mode must be 'temperature', 'current' or 'feedback'")
-    
-    feedback.start(..... blaaaaa .....)
-    hier muss noch ne menge passieren
-    
-    bias.set_global_dac(1)
-    if not bias.wait(9, 10):
-        msg.warn("bias not in Voltage ON after 10sec")
-        return False
-    if not bias.wait(5, 10):
-        msg.warn("bias not Ramping after 10sec")
-        return False
-    if not bias.wait(9, 30):
-        msg.warn("bias not fully ramped up after 30sec")
-        return False
-
-    msg("waiting 45sec...")    
-    time.sleep(45)
-    return True
-
-# standard watchdogs:
-def std_bias_watchdog( state, verbose=True ):
-    msg = MSG(verbose)
-    if state == 1: #Disconnected
-        msg.warn("BIAS just DISCONNECTED .. trying to reconnect")
-        msg.warn("current runnumber:"+fad_control.runnumber() )
-        bias.reconnect()
-        time.sleep(1)
-        bias.set_zero_voltage()
-        # TODO: This should work, but it is stupid.
-        bias.reset_over_current_status()
-        bias.reset_over_current_status()
-        bias.set_zero_voltage()
-        bias.reset_over_current_status()
-        bias.set_global_dac(1)
-
-# create introduction:
-class INTRO(object):
-    def __init__(self):
-        # nothing to do
-        pass
-        
-    def __repr__(self):
-        print "welcome to PyDimCtrl V0.1:"
-        print "--------------------------"
-        print "If the hardware is ON but not all the software is connected try:"
-        print "      Connect()"
-        print "If all the programs are already up and running, you might want to"
-        print "     TakeDrsAmplitudeCalibration(roi=1024) or "
-        print "     TakeDrsAmplitudeCalibration(roi=300)"
-        print "         i.e. ped, gain, trigger_offset + extra ped(for X-check)"
-        print "     TakeDrsTimeCalibration( type='upshifted' ) or "
-        print "     TakeDrsTimeCalibration( type='old' ) or "
-        print "     "
-        print "In case you would like to ramp up the Bias voltage try:"
-        print "     VoltageOn( mode='temperature' ) or"
-        print "     VoltageOn( mode='current' ) or"
-        print "     VoltageOn( mode='light_pulser' )"
-        print "Switch off with:"
-        print "     VoltageOff()"
-        print ""
-        print "In case you would like a Watchdog to check, if the Voltage is up"
-        print "and the BiasCrate is not disconnected, then try:"
-        print "     VoltageOn( mode='--see above--', Watchdog=True )"
-        print "PLEASE NOTE: The Watchdog will monitor the State of BIAS_CONTROL"
-        print "and in case of a connection loss, it will: "
-        print "     * print a warning"
-        print "     * issue a the RECONNECT command" 
-        print "     * issue SET_ZERO_VOLTAGE - since this is the only way to get referenced"
-        print "     * Ramp up again, using the same settings as before"
-        print "     * possible OverCurrent situation will be treated as usual"
-        print "The Watchdog will not react on any other state change, like OverCurrent or VoltageOff"
-        print ""
-        print ""
-        return ""
-        
-
-intro = INTRO()
-
-if __name__ == '__main__':
-    print "welcome:"
-    print " type: intro"
-    print " for a short introduction"
-
-    
-    #IsReadyForDataTaking()
-    #TrackSource( Shift=0.6, Angle=50, SrcName='Crab', verbose=True)
-    #WaitForTracking( CalmDownTime = 30, verbose = True)
-    #TakeDataRun()
-    #StopTracking()
