1#!/usr/bin/env python
2
3# portable serial port access with python
4# this is a wrapper module for different platform implementations of the
5# port enumeration feature
6#
7# (C) 2011-2013 Chris Liechti <cliechti@gmx.net>
8# this is distributed under a free software license, see license.txt
9
10"""\
11This module will provide a function called comports that returns an
12iterable (generator or list) that will enumerate available com ports. Note that
13on some systems non-existent ports may be listed.
14
15Additionally a grep function is supplied that can be used to search for ports
16based on their descriptions or hardware ID.
17"""
18
19import sys, os, re
20
21# chose an implementation, depending on os
22#~ if sys.platform == 'cli':
23#~ else:
24import os
25# chose an implementation, depending on os
26if os.name == 'nt': #sys.platform == 'win32':
27    from serial.tools.list_ports_windows import *
28elif os.name == 'posix':
29    from serial.tools.list_ports_posix import *
30#~ elif os.name == 'java':
31else:
32    raise ImportError("Sorry: no implementation for your platform ('%s') available" % (os.name,))
33
34# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
35
36def grep(regexp):
37    """\
38    Search for ports using a regular expression. Port name, description and
39    hardware ID are searched. The function returns an iterable that returns the
40    same tuples as comport() would do.
41    """
42    r = re.compile(regexp, re.I)
43    for port, desc, hwid in comports():
44        if r.search(port) or r.search(desc) or r.search(hwid):
45            yield port, desc, hwid
46
47
48# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
49def main():
50    import optparse
51
52    parser = optparse.OptionParser(
53        usage = "%prog [options] [<regexp>]",
54        description = "Miniterm - A simple terminal program for the serial port."
55    )
56
57    parser.add_option("--debug",
58            help="print debug messages and tracebacks (development mode)",
59            dest="debug",
60            default=False,
61            action='store_true')
62
63    parser.add_option("-v", "--verbose",
64            help="show more messages (can be given multiple times)",
65            dest="verbose",
66            default=1,
67            action='count')
68
69    parser.add_option("-q", "--quiet",
70            help="suppress all messages",
71            dest="verbose",
72            action='store_const',
73            const=0)
74
75    (options, args) = parser.parse_args()
76
77
78    hits = 0
79    # get iteraror w/ or w/o filter
80    if args:
81        if len(args) > 1:
82            parser.error('more than one regexp not supported')
83        print "Filtered list with regexp: %r" % (args[0],)
84        iterator = sorted(grep(args[0]))
85    else:
86        iterator = sorted(comports())
87    # list them
88    for port, desc, hwid in iterator:
89        print("%-20s" % (port,))
90        if options.verbose > 1:
91            print("    desc: %s" % (desc,))
92            print("    hwid: %s" % (hwid,))
93        hits += 1
94    if options.verbose:
95        if hits:
96            print("%d ports found" % (hits,))
97        else:
98            print("no ports found")
99
100# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
101# test
102if __name__ == '__main__':
103    main()
104