blob: 6d4d6c719d45511346e89d5065361d613701b201 [file] [log] [blame]
Steven Michalske2a9486d2015-08-06 22:35:21 -07001#!/usr/bin/env python
Chris Liechtifbdd8a02015-08-09 02:37:45 +02002#
cliechtifab09872009-02-07 00:25:44 +00003# portable serial port access with python
4# this is a wrapper module for different platform implementations
cliechti89b4af12002-02-12 23:24:41 +00005#
Chris Liechtifbdd8a02015-08-09 02:37:45 +02006# (C) 2001-2015 Chris Liechti <cliechti@gmx.net>
7#
8# SPDX-License-Identifier: BSD-3-Clause
cliechti89b4af12002-02-12 23:24:41 +00009
Chris Liechtibaec2a32015-08-07 14:42:15 +020010import importlib
cliechti0bfe5252008-06-21 01:36:52 +000011import sys
12
Chris Liechti033f17c2015-08-30 21:28:04 +020013from serial.serialutil import *
14#~ SerialBase, SerialException, to_bytes, iterbytes
15
16VERSION = '3.0a'
17
cliechti4ff97242008-06-21 18:14:46 +000018if sys.platform == 'cli':
Chris Liechti033f17c2015-08-30 21:28:04 +020019 from serial.serialcli import Serial
cliechti89b4af12002-02-12 23:24:41 +000020else:
cliechti4ff97242008-06-21 18:14:46 +000021 import os
cliechtifab09872009-02-07 00:25:44 +000022 # chose an implementation, depending on os
Chris Liechti033f17c2015-08-30 21:28:04 +020023 if os.name == 'nt': # sys.platform == 'win32':
24 from serial.serialwin32 import Serial
cliechti0bfe5252008-06-21 01:36:52 +000025 elif os.name == 'posix':
Chris Liechti033f17c2015-08-30 21:28:04 +020026 from serial.serialposix import Serial, PosixPollSerial
cliechti0bfe5252008-06-21 01:36:52 +000027 elif os.name == 'java':
Chris Liechti033f17c2015-08-30 21:28:04 +020028 from serial.serialjava import Serial
cliechti0bfe5252008-06-21 01:36:52 +000029 else:
cliechti330185e2011-08-18 22:45:17 +000030 raise ImportError("Sorry: no implementation for your platform ('%s') available" % (os.name,))
31
cliechti89b4af12002-02-12 23:24:41 +000032
cliechtie542b362011-03-18 00:49:16 +000033protocol_handler_packages = [
34 'serial.urlhandler',
35 ]
cliechti109486b2009-08-02 00:00:11 +000036
Chris Liechti033f17c2015-08-30 21:28:04 +020037
cliechtie3ab3532009-08-05 12:40:38 +000038def serial_for_url(url, *args, **kwargs):
cliechtie542b362011-03-18 00:49:16 +000039 """\
cliechti330185e2011-08-18 22:45:17 +000040 Get an instance of the Serial class, depending on port/url. The port is not
41 opened when the keyword parameter 'do_not_open' is true, by default it
42 is. All other parameters are directly passed to the __init__ method when
43 the port is instantiated.
cliechtie542b362011-03-18 00:49:16 +000044
45 The list of package names that is searched for protocol handlers is kept in
cliechti330185e2011-08-18 22:45:17 +000046 ``protocol_handler_packages``.
cliechtie542b362011-03-18 00:49:16 +000047
48 e.g. we want to support a URL ``foobar://``. A module
49 ``my_handlers.protocol_foobar`` is provided by the user. Then
50 ``protocol_handler_packages.append("my_handlers")`` would extend the search
51 path so that ``serial_for_url("foobar://"))`` would work.
52 """
cliechti9b1d3ad2009-08-02 23:47:04 +000053 # check remove extra parameter to not confuse the Serial class
54 do_open = 'do_not_open' not in kwargs or not kwargs['do_not_open']
Chris Liechti033f17c2015-08-30 21:28:04 +020055 if 'do_not_open' in kwargs:
56 del kwargs['do_not_open']
cliechtiaaf778a2009-08-05 17:59:15 +000057 # the default is to use the native version
58 klass = Serial # 'native' implementation
cliechti9b1d3ad2009-08-02 23:47:04 +000059 # check port type and get class
cliechtiaaf778a2009-08-05 17:59:15 +000060 try:
Chris Liechtibaec2a32015-08-07 14:42:15 +020061 url_lowercase = url.lower()
cliechtiaaf778a2009-08-05 17:59:15 +000062 except AttributeError:
cliechti2a6d5332011-03-04 02:08:32 +000063 # it's not a string, use default
cliechtiaaf778a2009-08-05 17:59:15 +000064 pass
cliechti109486b2009-08-02 00:00:11 +000065 else:
Chris Liechtibaec2a32015-08-07 14:42:15 +020066 if '://' in url_lowercase:
67 protocol = url_lowercase.split('://', 1)[0]
68 module_name = '.protocol_%s' % (protocol,)
cliechtie542b362011-03-18 00:49:16 +000069 for package_name in protocol_handler_packages:
Chris Liechtibaec2a32015-08-07 14:42:15 +020070 package = importlib.import_module(package_name)
cliechtie542b362011-03-18 00:49:16 +000071 try:
Chris Liechtibaec2a32015-08-07 14:42:15 +020072 handler_module = importlib.import_module(module_name, package_name)
cliechtie542b362011-03-18 00:49:16 +000073 except ImportError:
74 pass
75 else:
Chris Liechtibaec2a32015-08-07 14:42:15 +020076 klass = handler_module.Serial
cliechtie542b362011-03-18 00:49:16 +000077 break
cliechti2a6d5332011-03-04 02:08:32 +000078 else:
cliechtie542b362011-03-18 00:49:16 +000079 raise ValueError('invalid URL, protocol %r not known' % (protocol,))
cliechtiaaf778a2009-08-05 17:59:15 +000080 else:
81 klass = Serial # 'native' implementation
cliechti9b1d3ad2009-08-02 23:47:04 +000082 # instantiate and open when desired
cliechti109486b2009-08-02 00:00:11 +000083 instance = klass(None, *args, **kwargs)
84 instance.port = url
cliechti9b1d3ad2009-08-02 23:47:04 +000085 if do_open:
cliechti109486b2009-08-02 00:00:11 +000086 instance.open()
87 return instance