15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#!/usr/bin/env python 25d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 35d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)# portable serial port access with python 45d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)# this is a wrapper module for different platform implementations 55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)# 65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)# (C) 2001-2010 Chris Liechti <cliechti@gmx.net> 75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)# this is distributed under a free software license, see license.txt 85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)VERSION = '2.7' 105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)import sys 125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)if sys.platform == 'cli': 145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) from serial.serialcli import * 155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)else: 165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) import os 175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # chose an implementation, depending on os 185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if os.name == 'nt': #sys.platform == 'win32': 195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) from serial.serialwin32 import * 205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) elif os.name == 'posix': 215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) from serial.serialposix import * 225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) elif os.name == 'java': 235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) from serial.serialjava import * 245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) else: 255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) raise ImportError("Sorry: no implementation for your platform ('%s') available" % (os.name,)) 265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)protocol_handler_packages = [ 295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 'serial.urlhandler', 305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ] 315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)def serial_for_url(url, *args, **kwargs): 335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) """\ 345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Get an instance of the Serial class, depending on port/url. The port is not 355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) opened when the keyword parameter 'do_not_open' is true, by default it 365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) is. All other parameters are directly passed to the __init__ method when 375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) the port is instantiated. 385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) The list of package names that is searched for protocol handlers is kept in 405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ``protocol_handler_packages``. 415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) e.g. we want to support a URL ``foobar://``. A module 435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ``my_handlers.protocol_foobar`` is provided by the user. Then 445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ``protocol_handler_packages.append("my_handlers")`` would extend the search 455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) path so that ``serial_for_url("foobar://"))`` would work. 465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) """ 475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # check remove extra parameter to not confuse the Serial class 485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) do_open = 'do_not_open' not in kwargs or not kwargs['do_not_open'] 495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if 'do_not_open' in kwargs: del kwargs['do_not_open'] 505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # the default is to use the native version 515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) klass = Serial # 'native' implementation 525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # check port type and get class 535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) try: 545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) url_nocase = url.lower() 555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) except AttributeError: 565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # it's not a string, use default 575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pass 585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) else: 595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if '://' in url_nocase: 605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) protocol = url_nocase.split('://', 1)[0] 615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for package_name in protocol_handler_packages: 625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) module_name = '%s.protocol_%s' % (package_name, protocol,) 635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) try: 645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) handler_module = __import__(module_name) 655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) except ImportError: 665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pass 675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) else: 685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) klass = sys.modules[module_name].Serial 695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) break 705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) else: 715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) raise ValueError('invalid URL, protocol %r not known' % (protocol,)) 725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) else: 735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) klass = Serial # 'native' implementation 745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # instantiate and open when desired 755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) instance = klass(None, *args, **kwargs) 765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) instance.port = url 775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if do_open: 785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) instance.open() 795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return instance 80