diff options
author | cliechti <cliechti@f19166aa-fa4f-0410-85c2-fa1106f25c8a> | 2011-08-05 03:55:12 +0000 |
---|---|---|
committer | cliechti <cliechti@f19166aa-fa4f-0410-85c2-fa1106f25c8a> | 2011-08-05 03:55:12 +0000 |
commit | ccdafe22ec795997484d2ccfaa7e3a5b60a5b80d (patch) | |
tree | f4260feaa6c8a63e735049f413e4b965fc1eec5e | |
parent | f3e5077d7a47ad81132c7864656a632a2ab787a3 (diff) | |
download | pyserial-ccdafe22ec795997484d2ccfaa7e3a5b60a5b80d.tar.gz |
- add serial.tools.list_ports, implement platform detection code and a main routine
- add code from 2912349 (scan for mac)
git-svn-id: http://svn.code.sf.net/p/pyserial/code/trunk/pyserial@408 f19166aa-fa4f-0410-85c2-fa1106f25c8a
-rw-r--r-- | CHANGES.txt | 2 | ||||
-rw-r--r-- | documentation/shortintro.rst | 23 | ||||
-rw-r--r-- | serial/tools/list_ports.py | 60 | ||||
-rw-r--r-- | serial/tools/list_ports_posix.py | 89 | ||||
-rw-r--r-- | serial/tools/list_ports_windows.py | 2 |
5 files changed, 170 insertions, 6 deletions
diff --git a/CHANGES.txt b/CHANGES.txt index fef89f1..77bfe58 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -404,6 +404,7 @@ New Features: - Moved some of the examples to serial.tools so that they can be used with ``python -m`` +- serial port enumeration now included as ``serial.tools.list_ports`` - URL handers for ``serial_for_url`` are now imported dynamically. This allows to add protocols w/o editing files. The list ``serial.protocol_handler_packages`` can be used to add or remove user @@ -418,6 +419,7 @@ Bugfixes: Bugfixes (posix): - [Patch 3316943] Avoid unneeded termios.tcsetattr calls in serialposix.py +- [Patch 2912349] Serial Scan as a Module with Mac Support Bugfixes (win32): diff --git a/documentation/shortintro.rst b/documentation/shortintro.rst index 01d9943..b9a8a8c 100644 --- a/documentation/shortintro.rst +++ b/documentation/shortintro.rst @@ -79,3 +79,26 @@ mode, it is advised to use io.TextIOWrapper_:: .. _io.TextIOWrapper: http://docs.python.org/library/io.html#io.TextIOWrapper + + +Testing ports +============= +Listing ports +------------- +``python -m serial.tools.list_ports`` will print a list of available ports. It +is also possible to add a regexp as first argument and the list will only +include entries that matched. + +.. note:: + + The enumeration may not work on all operating systems. It may be + incomplete, list unavailable ports or may lack detailed descriptions of the + ports. + +.. versionadded: 2.6 + +Accessing ports +--------------- +pySerial includes a small terminal console based terminal program called +:ref:`miniterm`. It ca be started with ``python -m serial.tools.miniterm <port name>`` +(use option ``-h`` to get a listing of all options). diff --git a/serial/tools/list_ports.py b/serial/tools/list_ports.py new file mode 100644 index 0000000..1eb0478 --- /dev/null +++ b/serial/tools/list_ports.py @@ -0,0 +1,60 @@ +#!/usr/bin/env python + +# portable serial port access with python +# this is a wrapper module for different platform implementations of the +# port enumeration feature +# +# (C) 2011 Chris Liechti <cliechti@gmx.net> +# this is distributed under a free software license, see license.txt + +"""\ +This module will provide a function called comports that returns an +iterable (generator or list) that will enumerate available com ports. Note that +on some systems non-existent ports may be listed. + +Additionally a grep function is supplied that can be used to search for ports +based on their descriptions or hardware ID. +""" + +import sys, os, re + +# chose an implementation, depending on os +#~ if sys.platform == 'cli': +#~ else: +import os +# chose an implementation, depending on os +if os.name == 'nt': #sys.platform == 'win32': + from list_ports_windows import * +elif os.name == 'posix': + from list_ports_posix import * +#~ elif os.name == 'java': +else: + raise ImportError("Sorry: no implementation for your platform ('%s') available" % (os.name,)) + + +def grep(regexp): + """\ + Search for ports using a regular expression. Port name, description and + hardware ID are searched. The function returns an iterable that returns the + same tuples as comport() would do. + """ + for port, desc, hwid in comports(): + if re.search(regexp, port) or re.search(regexp, desc) or re.search(regexp, hwid): + yield port, desc, hwid + +# test +if __name__ == '__main__': + hits = 0 + if len(sys.argv) > 1: + print "Filtered list with regexp: %r" % (sys.argv[1],) + for port, desc, hwid in sorted(grep(sys.argv[1])): + print "%-20s: %s [%s]" % (port, desc, hwid) + hits += 1 + else: + for port, desc, hwid in sorted(comports()): + print "%-20s: %s [%s]" % (port, desc, hwid) + hits += 1 + if hits: + print "%d ports found" % (hits,) + else: + print "no ports found" diff --git a/serial/tools/list_ports_posix.py b/serial/tools/list_ports_posix.py index be25b03..2fb655b 100644 --- a/serial/tools/list_ports_posix.py +++ b/serial/tools/list_ports_posix.py @@ -1,12 +1,91 @@ import glob
+import sys
-def comports():
- devices = glob.glob('/dev/ttyS*') + glob.glob('/dev/ttyUSB*') + glob.glob('/dev/ttyACM*')
- return [(d, d, d) for d in devices]
+# The comports function is expected to return an iterable that yields tuples of
+# 3 strings: port name, human readable description and a hardware ID.
+#
+# as currently no method is known to get the second two strings easily, they
+# are currently just identical to the port name.
+# try to detect the OS so that a device can be selected...
+plat = sys.platform.lower()
-if __name__ == '__main__':
- import serial
+if plat[:5] == 'linux': # Linux (confirmed)
+ def comports():
+ devices = glob.glob('/dev/ttyS*') + glob.glob('/dev/ttyUSB*') + glob.glob('/dev/ttyACM*')
+ return [(d, d, d) for d in devices]
+
+elif plat == 'cygwin': # cygwin/win32
+ def comports():
+ devices = glob.glob('/dev/com*')
+ return [(d, d, d) for d in devices]
+
+elif plat == 'openbsd3': # BSD
+ def comports():
+ devices = glob.glob('/dev/ttyp*')
+ return [(d, d, d) for d in devices]
+
+elif plat[:3] == 'bsd' or \
+ plat[:7] == 'freebsd' or \
+ plat[:7] == 'openbsd': # BSD
+
+ def comports():
+ devices = glob.glob('/dev/cuad*')
+ return [(d, d, d) for d in devices]
+
+elif plat[:6] == 'darwin': # OS X (confirmed)
+ def comports():
+ """scan for available ports. return a list of device names."""
+ devices = glob.glob('/dev/tty.*')
+ return [(d, d, d) for d in devices]
+
+elif plat[:6] == 'netbsd': # NetBSD
+ def comports():
+ """scan for available ports. return a list of device names."""
+ devices = glob.glob('/dev/dty*')
+ return [(d, d, d) for d in devices]
+
+elif plat[:4] == 'irix': # IRIX
+ def comports():
+ """scan for available ports. return a list of device names."""
+ devices = glob.glob('/dev/ttyf*')
+ return [(d, d, d) for d in devices]
+elif plat[:2] == 'hp': # HP-UX (not tested)
+ def comports():
+ """scan for available ports. return a list of device names."""
+ devices = glob.glob('/dev/tty*p0')
+ return [(d, d, d) for d in devices]
+
+elif plat[:5] == 'sunos': # Solaris/SunOS
+ def comports():
+ """scan for available ports. return a list of device names."""
+ devices = glob.glob('/dev/tty*c')
+ return [(d, d, d) for d in devices]
+
+elif plat[:3] == 'aix': # AIX
+ def comports():
+ """scan for available ports. return a list of device names."""
+ devices = glob.glob('/dev/tty*')
+ return [(d, d, d) for d in devices]
+
+else:
+ # platform detection has failed...
+ sys.stderr.write("""\
+don't know how to enumerate ttys on this system.
+! I you know how the serial ports are named send this information to
+! the author of this module:
+
+sys.platform = %r
+os.name = %r
+pySerial version = %s
+
+also add the naming scheme of the serial ports and with a bit luck you can get
+this module running...
+""" % (sys.platform, os.name, serial.VERSION))
+ raise ImportError("Sorry: no implementation for your platform ('%s') available" % (os.name,))
+
+# test
+if __name__ == '__main__':
for port, desc, hwid in sorted(comports()):
print "%s: %s [%s]" % (port, desc, hwid)
diff --git a/serial/tools/list_ports_windows.py b/serial/tools/list_ports_windows.py index 60fed5f..8f1e3fe 100644 --- a/serial/tools/list_ports_windows.py +++ b/serial/tools/list_ports_windows.py @@ -179,7 +179,7 @@ def comports(): SetupDiDestroyDeviceInfoList(g_hdi)
-
+# test
if __name__ == '__main__':
import serial
|