def test_with_basic_message(self):
     iSignalDispatcher = SignalDispatcher("test_channel")
     def signalHandler(signal=None,sender=None,realsender=None,data=None,time=None,*args,**kwargs):
         self.assertEquals(signal,"just a test message")
         self.assertEquals(sender,"test_channel")
     iSignalDispatcher.add_handler(channel="test_channel",handler=signalHandler)
     iSignalDispatcher.send_message("just a test message")
Beispiel #2
0
    def test_with_basic_message(self):
        iSignalDispatcher = SignalDispatcher("test_channel")

        def signalHandler(signal=None,
                          sender=None,
                          realsender=None,
                          data=None,
                          time=None,
                          *args,
                          **kwargs):
            self.assertEquals(signal, "just a test message")
            self.assertEquals(sender, "test_channel")

        iSignalDispatcher.add_handler(channel="test_channel",
                                      handler=signalHandler)
        iSignalDispatcher.send_message("just a test message")
Beispiel #3
0
class Driver(object):
    """
    Driver class: higher level handler of device connection that formats outgoing and incoming commands
     according to a spec before they get sent to the lower level connector.
     It actually mimics the way system device drivers work in a way.
     You can think of the events beeing sent out by the driver (dataRecieved etc) as interupts of sorts
     
      ConnectionModes :
        0:setup
        1:normal
        2:setId
        3:forced: to forcefully connect devices which have no deviceId stored 
     
    Thoughts for future evolution
    each driver will have a series of endpoints or slots/hooks, which represent the actual subdevices it handles
    for example for reprap type devices, there is a "position" endpoint (abstract), 3 endpoints for the 
    cartesian bot motors , at least an endpoint for head temperature , one for the heater etc
    or this could be in a hiearchy , reflecting the one off the nodes:
    variable endpoint : position, and sub ones for motors
    """
    def __init__(self,
                 deviceType="",
                 connectionType="",
                 hardware_interface_klass=None,
                 logicHandlerKlass=None,
                 protocol=None,
                 options={},
                 *args,
                 **kwargs):
        self.driverType = self.__class__.__name__.lower()
        self.deviceType = deviceType
        self.connectionType = connectionType
        self.extra_params = options
        self.protocol = protocol
        self.hardware_interface_klass = hardware_interface_klass
        self.logicHandlerKlass = logicHandlerKlass

        self.deviceId = None
        """will be needed to identify a specific device, as the system does not work base on ports"""

        self._signal_dispatcher = None
        self.signal_channel_prefix = ""
        self._signal_channel = ""

        self.isConfigured = False  #when the port association has not been set
        self.is_handshake_ok = False
        self.is_authentification_ok = False
        self.isConnected = False
        self.isPluggedIn = False
        self.autoConnect = False  #if autoconnect is set to true, the device will be connected as soon as a it is plugged in and detected

        self.connectionErrors = 0
        self.maxConnectionErrors = 2
        self.connectionTimeout = 4

        self.connectionMode = 1
        self.deferred = defer.Deferred()
        """just for future reference : this is not implemented but would be a declarative way to 
        define the different "configuration steps" of this driver"
        *basically a dictonary with keys beeing the connection modes, and values a list of strings
        representing the methods to call
        *would require a "validator"  of sorts (certain elements need to be mandatory : such as the
        validation/setting of device ids
        """
        configSteps = {}
        configSteps[0] = ["_handle_deviceHandshake", "_handle_deviceIdInit"]
        configSteps[1] = [
            "_handle_deviceHandshake", "_handle_deviceIdInit",
            "some_other_method"
        ]

        #just a test
        self._signal_dispatcher = SignalDispatcher("driver_manager")
        """for exposing capabilites"""
        self.endpoints = []

    def afterInit(self):
        """this is a workaround needed when loading a driver from db"""
        try:
            if not isinstance(self.extra_params, dict):
                self.extra_params = ast.literal_eval(self.extra_params)
        except Exception as inst:
            log.msg("Failed to load driver extra_params from db:",
                    inst,
                    system="Driver",
                    logLevel=logging.CRITICAL)

    @defer.inlineCallbacks
    def setup(self, *args, **kwargs):
        self.hardwareHandler = self.hardware_interface_klass(
            self, self.protocol, **self.extra_params)
        self.logicHandler = self.logicHandlerKlass(self, **self.extra_params)

        node = (yield self.node.get())
        env = (yield node.environment.get())
        self.signal_channel_prefix = "environment_" + str(
            env.id) + ".node_" + str(node.id)

        self._signal_dispatcher.add_handler(handler=self.send_command,
                                            signal="addCommand")
        log.msg("Driver of type",
                self.driverType,
                "setup sucessfully",
                system="Driver",
                logLevel=logging.INFO)

    def bind(self, port, setId=True):
        self.deferred = defer.Deferred()
        log.msg("Attemtping to bind driver",
                self,
                "with deviceId:",
                self.deviceId,
                "to port",
                port,
                system="Driver",
                logLevel=logging.DEBUG)
        self.hardwareHandler.connect(setIdMode=setId, port=port)
        return self.deferred

    def connect(self, mode=None, *args, **kwargs):
        if not self.isConnected:
            if mode is not None:
                self.connectionMode = mode
                log.msg("Connecting in mode:",
                        self.connectionMode,
                        system="Driver",
                        logLevel=logging.CRITICAL)
                if mode == 3:
                    """special case for forced connection"""
                    unboundPorts = DriverManager.bindings.get_unbound_ports()
                    if len(unboundPorts) > 0:
                        port = unboundPorts[0]
                        log.msg("Connecting in mode:",
                                self.connectionMode,
                                "to port",
                                port,
                                system="Driver",
                                logLevel=logging.CRITICAL)
                        DriverManager.bindings.bind(self, port)
                        self.pluggedIn(port)
                        self.hardwareHandler.connect(port=port)

                else:
                    self.hardwareHandler.connect()
            else:
                self.hardwareHandler.connect()

    def reconnect(self, *args, **kwargs):
        self.hardwareHandler.reconnect(*args, **kwargs)

    def disconnect(self, *args, **kwargs):
        self.hardwareHandler.disconnect(*args, **kwargs)

    def pluggedIn(self, port):
        self._send_signal("plugged_In", port)
        self.isPluggedIn = True
        if self.autoConnect:
            #slight delay, to prevent certain problems when trying to send data to the device too fast
            reactor.callLater(1, self.connect, 1)

    def pluggedOut(self, port):
        self.isConfigured = False
        self.is_handshake_ok = False
        self.is_authentification_ok = False
        self.isConnected = False
        self.isPluggedIn = False
        self._send_signal("plugged_Out", port)
        #self._signal_dispatcher.send_message("pluggedOut",{"data":port})

    def _send_signal(self, signal="", data=None):
        prefix = self.signal_channel_prefix + ".driver."
        self._signal_dispatcher.send_message(prefix + signal, self, data)

    def send_command(self, data, sender=None, callback=None, *args, **kwargs):
        # print("going to send command",data,"from",sender)
        if not self.isConnected:
            raise DeviceNotConnected()
        if self.logicHandler:
            self.logicHandler._handle_request(data=data,
                                              sender=sender,
                                              callback=callback)

    def _send_data(self, data, *arrgs, **kwargs):
        self.hardwareHandler.send_data(data)

    def _handle_response(self, data):
        if self.logicHandler:
            self.logicHandler._handle_response(data)

    """higher level methods"""

    def startup(self):
        pass

    def shutdown(self):
        pass

    def init(self):
        pass

    def get_firmware_version(self):
        pass

    def set_debug_level(self, level):
        pass

    def teststuff(self, params, *args, **kwargs):
        pass

    def variable_set(self, variable, params, sender=None, *args, **kwargs):
        pass

    def variable_get(self, variable, params, sender=None, *args, **kwargs):
        pass

    """
    ####################################################################################
                                Experimental
    """

    def start_command(self):
        pass

    def close_command(self):
        pass

    def get_endpoint(self, filter=None):
        """return a list of endpoints, filtered by parameters"""
        d = defer.Deferred()

        def filter_check(endpoint, filter):
            for key in filter.keys():
                if not getattr(endpoint, key) in filter[key]:
                    return False
            return True

        def get(filter):
            if filter:
                return [
                    endpoint for endpoint in self.endpoints
                    if filter_check(endpoint, filter)
                ]
            else:
                pass

        d.addCallback(get)
        reactor.callLater(0.5, d.callback, filter)
        return d
Beispiel #4
0
class Driver(BaseComponent):
    """
    Driver class: higher level handler of device connection that formats
    outgoing and incoming commands according to a spec before they get
    sent to the lower level connector.
     It actually mimics the way system device drivers work in a way.
     You can think of the events beeing sent out by the driver(dataRecieved...)
     as interupts of sorts
    """
    def __init__(self,
                 hardware_id=None,
                 auto_connect=False,
                 max_connection_errors=2,
                 connection_timeout=4,
                 do_hanshake=False,
                 do_authentification=False):
        """
        autoconnect:if autoconnect is True,device will be connected as soon as
        it is plugged in and detected
        max_connection_errors: the number of connection errors above which
        the driver gets disconnected
        connection_timeout: the number of seconds after which the driver
        gets disconnected (only in the initial , configuration phases by
        default)
        """
        BaseComponent.__init__(self, parent=None)
        self.auto_connect = auto_connect
        self.max_connection_errors = max_connection_errors
        self.connection_timeout = connection_timeout
        self.do_authentification = do_authentification
        self.do_handshake = do_hanshake
        self._hardware_interface = None
        self.hardware_id = hardware_id
        self.is_configured = False
        self.is_bound = False  # when port association has not been set
        self.is_handshake_ok = False
        self.is_authentification_ok = False
        self.is_connected = False
        self.is_bound = False
        self.is_busy = False

        self.errors = []
        self.connection_mode = 1
        self._connection_errors = 0
        self._connection_timeout = None
        self.deferred = defer.Deferred()

        self._signal_channel_prefix = ""
        self._signal_dispatcher = SignalDispatcher("driver_manager")

    def __eq__(self, other):
        return self.__class__ == other.__class__

    def __ne__(self, other):
        return not self.__eq__(other)

    def setup(self, *args, **kwargs):
        """do the driver setup phase"""
        self._signal_dispatcher.add_handler(handler=self.send_command,
                                            signal="addCommand")
        class_name = self.__class__.__name__.lower()
        log.msg("Driver of type",
                class_name,
                "setup sucessfully",
                system="Driver",
                logLevel=logging.INFO)

    def _send_signal(self, signal="", data=None):
        prefix = self._signal_channel_prefix + ".driver."
        self._signal_dispatcher.send_message(prefix + signal, self, data)

    @property
    def hardware_interface_class(self):
        """Get the current voltage."""
        return self._hardware_interface.__class__

    @property
    def connection_errors(self):
        """Get the current voltage."""
        return self._connection_errors

    @connection_errors.setter
    def connection_errors(self, value):
        self._connection_errors = value
        if self._connection_errors >= self.max_connection_errors:
            self.disconnect(clear_port=True)
            log.msg(
                "cricital error while (re-)starting serial connection : please check your driver settings and device id, as well as cables,  and make sure no other process is using the port ",
                system="Driver",
                logLevel=logging.CRITICAL)
            self.deferred.errback(self.errors[-1])
            #self._hardware_interface._connect()  #weird way of handling disconnect

    """
    ###########################################################################
    The following are the timeout related methods
    """

    def set_connection_timeout(self):
        """sets internal timeout"""
        if self.connection_timeout > 0:
            log.msg("Setting timeout at ",
                    time.time(),
                    system="Driver",
                    logLevel=logging.DEBUG)
            self._connection_timeout = reactor.callLater(
                self.connection_timeout, self._connection_timeout_check)

    def cancel_connection_timeout(self):
        """cancels internal timeout"""
        if self._connection_timeout is not None:
            try:
                self._connection_timeout.cancel()
                log.msg("Canceling timeout at ",
                        time.time(),
                        system="Driver",
                        logLevel=logging.DEBUG)
            except:
                pass

    def _connection_timeout_check(self):
        """checks the timeout"""
        log.msg("Timeout check at ", time.time(), logLevel=logging.DEBUG)
        self.cancel_connection_timeout()
        self.errors.append(TimeoutError())
        self.connection_errors += 1
        if self.connection_errors < self.max_connection_errors:
            self.reconnect()

    """
    ###########################################################################
    The following are the connection related methods
    """

    def connect(self, port=None, connection_mode=None):
        """
        connection_mode :
        0:setup
        1:normal
        2:forced: to forcefully connect devices which have no deviceId stored
        """
        if self.is_connected:
            raise Exception("Driver already connected")
        if connection_mode is None:
            raise Exception("Invalid connection mode")

        self.deferred = defer.Deferred()
        self.connection_mode = connection_mode
        self.errors = []
        self._connection_errors = 0
        self.is_busy = True

        mode_str = "Normal"
        if self.connection_mode == 1:
            mode_str = "Setup"
        log.msg("Connecting driver in %s mode:" % mode_str,
                system="Driver",
                logLevel=logging.CRITICAL)
        reactor.callLater(0.1, self._hardware_interface.connect, port)
        return self.deferred

    def reconnect(self, *args, **kwargs):
        """Reconnect driver"""
        self._hardware_interface.reconnect(*args, **kwargs)

    def disconnect(self, *args, **kwargs):
        """Disconnect driver"""
        log.msg("Disconnecting driver",
                system="Driver",
                logLevel=logging.CRITICAL)
        self.is_connected = False
        self.is_busy = False
        self.cancel_connection_timeout()
        self._hardware_interface.disconnect(*args, **kwargs)

    """
    ###########################################################################
    The following are the methods dealing with communication with the hardware
    """

    def send_command(self, command):
        """send a command to the physical device"""
        if not self.is_connected:
            raise DeviceNotConnected()
        self.command_deferred = defer.Deferred()
        reactor.callLater(0.01, self._hardware_interface.send_data, command)
        return self.command_deferred

    def _handle_response(self, data):
        """handle hardware response"""
        self.command_deferred.callback(data)

    """
    ###########################################################################
    The following are the higher level methods
    """

    def startup(self):
        """send startup command to hardware"""
        raise NotImplementedError()

    def shutdown(self):
        """send shutdown command to hardware"""
        raise NotImplementedError()

    def get_firmware_info(self):
        """retrieve firmware version from hardware"""
        raise NotImplementedError()

    def set_debug_level(self, level):
        """set hardware debug level, if any"""
        raise NotImplementedError()
Beispiel #5
0
class Driver(BaseComponent):
    """
    Driver class: higher level handler of device connection that formats
    outgoing and incoming commands according to a spec before they get
    sent to the lower level connector.
     It actually mimics the way system device drivers work in a way.
     You can think of the events beeing sent out by the driver(dataRecieved...)
     as interupts of sorts
    """
    def __init__(self, hardware_id=None, auto_connect=False,
        max_connection_errors=2, connection_timeout=4, do_hanshake=False,
        do_authentification=False):
        """
        autoconnect:if autoconnect is True,device will be connected as soon as
        it is plugged in and detected
        max_connection_errors: the number of connection errors above which
        the driver gets disconnected
        connection_timeout: the number of seconds after which the driver
        gets disconnected (only in the initial , configuration phases by
        default)
        """
        BaseComponent.__init__(self, parent=None)
        self.auto_connect = auto_connect
        self.max_connection_errors = max_connection_errors
        self.connection_timeout = connection_timeout
        self.do_authentification = do_authentification
        self.do_handshake = do_hanshake
        self._hardware_interface = None
        self.hardware_id = hardware_id
        self.is_configured = False
        self.is_bound = False  # when port association has not been set
        self.is_handshake_ok = False
        self.is_authentification_ok = False
        self.is_connected = False
        self.is_bound = False
        self.is_busy = False

        self.errors = []
        self.connection_mode = 1
        self._connection_errors = 0
        self._connection_timeout = None
        self.deferred = defer.Deferred()

        self._signal_channel_prefix = ""
        self._signal_dispatcher = SignalDispatcher("driver_manager")

    def __eq__(self, other):
        return self.__class__ == other.__class__

    def __ne__(self, other):
        return not self.__eq__(other)

    def setup(self, *args, **kwargs):
        """do the driver setup phase"""
        self._signal_dispatcher.add_handler(handler=self.send_command, signal="addCommand")
        class_name = self.__class__.__name__.lower()
        log.msg("Driver of type", class_name, "setup sucessfully", system="Driver", logLevel=logging.INFO)

    def _send_signal(self, signal="", data=None):
        prefix = self._signal_channel_prefix + ".driver."
        self._signal_dispatcher.send_message(prefix + signal, self, data)

    @property
    def hardware_interface_class(self):
        """Get the current voltage."""
        return self._hardware_interface.__class__

    @property
    def connection_errors(self):
        """Get the current voltage."""
        return self._connection_errors

    @connection_errors.setter
    def connection_errors(self, value):
        self._connection_errors = value
        if self._connection_errors >= self.max_connection_errors:
            self.disconnect(clear_port=True)
            log.msg("cricital error while (re-)starting serial connection : please check your driver settings and device id, as well as cables,  and make sure no other process is using the port ", system="Driver", logLevel=logging.CRITICAL)
            self.deferred.errback(self.errors[-1])
            #self._hardware_interface._connect()  #weird way of handling disconnect
    """
    ###########################################################################
    The following are the timeout related methods
    """
    def set_connection_timeout(self):
        """sets internal timeout"""
        if self.connection_timeout > 0:
            log.msg("Setting timeout at ", time.time(), system="Driver", logLevel=logging.DEBUG)
            self._connection_timeout = reactor.callLater(self.connection_timeout, self._connection_timeout_check)

    def cancel_connection_timeout(self):
        """cancels internal timeout"""
        if self._connection_timeout is not None:
            try:
                self._connection_timeout.cancel()
                log.msg("Canceling timeout at ", time.time(), system="Driver", logLevel=logging.DEBUG)
            except:
                pass

    def _connection_timeout_check(self):
        """checks the timeout"""
        log.msg("Timeout check at ", time.time(), logLevel=logging.DEBUG)
        self.cancel_connection_timeout()
        self.errors.append(TimeoutError())
        self.connection_errors += 1
        if self.connection_errors < self.max_connection_errors:
            self.reconnect()

    """
    ###########################################################################
    The following are the connection related methods
    """
    def connect(self, port=None, connection_mode=None):
        """
        connection_mode :
        0:setup
        1:normal
        2:forced: to forcefully connect devices which have no deviceId stored
        """
        if self.is_connected:
            raise Exception("Driver already connected")
        if connection_mode is None:
            raise Exception("Invalid connection mode")

        self.deferred = defer.Deferred()
        self.connection_mode = connection_mode
        self.errors = []
        self._connection_errors = 0
        self.is_busy = True

        mode_str = "Normal"
        if self.connection_mode == 1:
            mode_str = "Setup"
        log.msg("Connecting driver in %s mode:" % mode_str, system="Driver", logLevel=logging.CRITICAL)
        reactor.callLater(0.1, self._hardware_interface.connect, port)
        return self.deferred

    def reconnect(self, *args, **kwargs):
        """Reconnect driver"""
        self._hardware_interface.reconnect(*args, **kwargs)

    def disconnect(self, *args, **kwargs):
        """Disconnect driver"""
        log.msg("Disconnecting driver", system="Driver", logLevel=logging.CRITICAL)
        self.is_connected = False
        self.is_busy = False
        self.cancel_connection_timeout()
        self._hardware_interface.disconnect(*args, **kwargs)

    """
    ###########################################################################
    The following are the methods dealing with communication with the hardware
    """

    def send_command(self, command):
        """send a command to the physical device"""
        if not self.is_connected:
            raise DeviceNotConnected()
        self.command_deferred = defer.Deferred()
        reactor.callLater(0.01, self._hardware_interface.send_data, command)
        return self.command_deferred

    def _handle_response(self, data):
        """handle hardware response"""
        self.command_deferred.callback(data)

    """
    ###########################################################################
    The following are the higher level methods
    """
    def startup(self):
        """send startup command to hardware"""
        raise NotImplementedError()

    def shutdown(self):
        """send shutdown command to hardware"""
        raise NotImplementedError()

    def get_firmware_info(self):
        """retrieve firmware version from hardware"""
        raise NotImplementedError()

    def set_debug_level(self, level):
        """set hardware debug level, if any"""
        raise NotImplementedError()
Beispiel #6
0
class Driver(object):
    """
    Driver class: higher level handler of device connection that formats outgoing and incoming commands
     according to a spec before they get sent to the lower level connector.
     It actually mimics the way system device drivers work in a way.
     You can think of the events beeing sent out by the driver (dataRecieved etc) as interupts of sorts
     
      ConnectionModes :
        0:setup
        1:normal
        2:setId
        3:forced: to forcefully connect devices which have no deviceId stored 
     
    Thoughts for future evolution
    each driver will have a series of endpoints or slots/hooks, which represent the actual subdevices it handles
    for example for reprap type devices, there is a "position" endpoint (abstract), 3 endpoints for the 
    cartesian bot motors , at least an endpoint for head temperature , one for the heater etc
    or this could be in a hiearchy , reflecting the one off the nodes:
    variable endpoint : position, and sub ones for motors
    """
    
    def __init__(self,deviceType="",connectionType="",hardware_interface_klass=None,logicHandlerKlass=None,protocol=None,options={},*args,**kwargs):    
        self.driverType=self.__class__.__name__.lower()
        self.deviceType=deviceType
        self.connectionType=connectionType
        self.extra_params=options
        self.protocol=protocol
        self.hardware_interface_klass=hardware_interface_klass
        self.logicHandlerKlass=logicHandlerKlass

        self.deviceId=None
        """will be needed to identify a specific device, as the system does not work base on ports"""
     
        self._signal_dispatcher=None 
        self.signal_channel_prefix=""
        self._signal_channel=""
        
        self.isConfigured=False#when the port association has not been set
        self.is_handshake_ok=False
        self.is_authentification_ok=False
        self.isConnected=False
        self.isPluggedIn=False
        self.autoConnect=False#if autoconnect is set to true, the device will be connected as soon as a it is plugged in and detected
        
       
        self.connectionErrors=0
        self.maxConnectionErrors=2
        self.connectionTimeout=4
         
        self.connectionMode=1
        self.deferred=defer.Deferred()
        
        """just for future reference : this is not implemented but would be a declarative way to 
        define the different "configuration steps" of this driver"
        *basically a dictonary with keys beeing the connection modes, and values a list of strings
        representing the methods to call
        *would require a "validator"  of sorts (certain elements need to be mandatory : such as the
        validation/setting of device ids
        """
        configSteps={}
        configSteps[0]=["_handle_deviceHandshake","_handle_deviceIdInit"]
        configSteps[1]=["_handle_deviceHandshake","_handle_deviceIdInit","some_other_method"]
        
        #just a test
        self._signal_dispatcher=SignalDispatcher("driver_manager")
        
        """for exposing capabilites"""
        self.endpoints=[]
        
        
    def afterInit(self):
       
        """this is a workaround needed when loading a driver from db"""
        try:
            if not isinstance(self.extra_params,dict):
                self.extra_params=ast.literal_eval(self.extra_params)
        except Exception as inst:
            log.msg("Failed to load driver extra_params from db:",inst,system="Driver",logLevel=logging.CRITICAL)

    
    @defer.inlineCallbacks    
    def setup(self,*args,**kwargs):  
        self.hardwareHandler=self.hardware_interface_klass(self,self.protocol,**self.extra_params)
        self.logicHandler=self.logicHandlerKlass(self,**self.extra_params)  
        
        
        node= (yield self.node.get())
        env= (yield node.environment.get())
        self.signal_channel_prefix="environment_"+str(env.id)+".node_"+str(node.id)

        self._signal_dispatcher.add_handler(handler=self.send_command,signal="addCommand")
        log.msg("Driver of type",self.driverType ,"setup sucessfully",system="Driver",logLevel=logging.INFO)
        
    def bind(self,port,setId=True):
        self.deferred=defer.Deferred()
        log.msg("Attemtping to bind driver",self ,"with deviceId:",self.deviceId,"to port",port,system="Driver",logLevel=logging.DEBUG) 
        self.hardwareHandler.connect(setIdMode=setId,port=port)     
        return self.deferred
    
    def connect(self,mode=None,*args,**kwargs):
        if not self.isConnected:
            if mode is not None:
                self.connectionMode=mode
                log.msg("Connecting in mode:",self.connectionMode,system="Driver",logLevel=logging.CRITICAL) 
                if mode==3:
                    """special case for forced connection"""
                    unboundPorts=DriverManager.bindings.get_unbound_ports()
                    if len(unboundPorts)>0:
                        port=unboundPorts[0]
                        log.msg("Connecting in mode:",self.connectionMode,"to port",port,system="Driver",logLevel=logging.CRITICAL)
                        DriverManager.bindings.bind(self,port)
                        self.pluggedIn(port)
                        self.hardwareHandler.connect(port=port)
                        
                else:
                    self.hardwareHandler.connect()
            else:
                self.hardwareHandler.connect()
                
    def reconnect(self,*args,**kwargs):
        self.hardwareHandler.reconnect(*args,**kwargs)
    def disconnect(self,*args,**kwargs):
        self.hardwareHandler.disconnect(*args,**kwargs)
    
    def pluggedIn(self,port):    
        self._send_signal("plugged_In",port)
        self.isPluggedIn=True
        if self.autoConnect:
            #slight delay, to prevent certain problems when trying to send data to the device too fast
            reactor.callLater(1,self.connect,1)
           
    def pluggedOut(self,port):
        self.isConfigured=False  
        self.is_handshake_ok=False
        self.is_authentification_ok=False
        self.isConnected=False
        self.isPluggedIn=False
        self._send_signal("plugged_Out",port)
        #self._signal_dispatcher.send_message("pluggedOut",{"data":port})
    
    def _send_signal(self,signal="",data=None):
        prefix=self.signal_channel_prefix+".driver."
        self._signal_dispatcher.send_message(prefix+signal,self,data)
    
    def send_command(self,data,sender=None,callback=None,*args,**kwargs):
       # print("going to send command",data,"from",sender)
        if not self.isConnected:
            raise DeviceNotConnected()
        if self.logicHandler:
            self.logicHandler._handle_request(data=data,sender=sender,callback=callback)
    
    def _send_data(self,data,*arrgs,**kwargs):
        self.hardwareHandler.send_data(data)
         
    def _handle_response(self,data):
        if self.logicHandler:
            self.logicHandler._handle_response(data)
    
    """higher level methods""" 
    def startup(self):
        pass
    def shutdown(self):
        pass
    def init(self):
        pass
    def get_firmware_version(self):
        pass
    def set_debug_level(self,level):
        pass
    
    def teststuff(self,params,*args,**kwargs):
        pass
    
    def variable_set(self,variable,params,sender=None,*args,**kwargs):
        pass
    def variable_get(self,variable,params,sender=None,*args,**kwargs):
        pass
    
    """
    ####################################################################################
                                Experimental
    """ 
    def start_command(self):
        pass
    def close_command(self):
        pass
    
    def get_endpoint(self,filter=None):
        """return a list of endpoints, filtered by parameters"""
        d=defer.Deferred()
        
        def filter_check(endpoint,filter):
            for key in filter.keys():
                if not getattr(endpoint, key) in filter[key]:
                    return False
            return True
      
        def get(filter):
            if filter:
                return [endpoint for endpoint in self.endpoints if filter_check(endpoint,filter)]
            else:               
                pass
            
        d.addCallback(get)
        reactor.callLater(0.5,d.callback,filter)
        return d