• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python
2#
3# Serial port enumeration. Console tool and backend selection.
4#
5# This file is part of pySerial. https://github.com/pyserial/pyserial
6# (C) 2011-2015 Chris Liechti <cliechti@gmx.net>
7#
8# SPDX-License-Identifier:    BSD-3-Clause
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
19from __future__ import absolute_import
20
21import sys
22import os
23import re
24
25# chose an implementation, depending on os
26#~ if sys.platform == 'cli':
27#~ else:
28if os.name == 'nt':  # sys.platform == 'win32':
29    from serial.tools.list_ports_windows import comports
30elif os.name == 'posix':
31    from serial.tools.list_ports_posix import comports
32#~ elif os.name == 'java':
33else:
34    raise ImportError("Sorry: no implementation for your platform ('{}') available".format(os.name))
35
36# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
37
38
39def grep(regexp, include_links=False):
40    """\
41    Search for ports using a regular expression. Port name, description and
42    hardware ID are searched. The function returns an iterable that returns the
43    same tuples as comport() would do.
44    """
45    r = re.compile(regexp, re.I)
46    for info in comports(include_links):
47        port, desc, hwid = info
48        if r.search(port) or r.search(desc) or r.search(hwid):
49            yield info
50
51
52# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
53def main():
54    import argparse
55
56    parser = argparse.ArgumentParser(description='Serial port enumeration')
57
58    parser.add_argument(
59        'regexp',
60        nargs='?',
61        help='only show ports that match this regex')
62
63    parser.add_argument(
64        '-v', '--verbose',
65        action='store_true',
66        help='show more messages')
67
68    parser.add_argument(
69        '-q', '--quiet',
70        action='store_true',
71        help='suppress all messages')
72
73    parser.add_argument(
74        '-n',
75        type=int,
76        help='only output the N-th entry')
77
78    parser.add_argument(
79        '-s', '--include-links',
80        action='store_true',
81        help='include entries that are symlinks to real devices')
82
83    args = parser.parse_args()
84
85    hits = 0
86    # get iteraror w/ or w/o filter
87    if args.regexp:
88        if not args.quiet:
89            sys.stderr.write("Filtered list with regexp: {!r}\n".format(args.regexp))
90        iterator = sorted(grep(args.regexp, include_links=args.include_links))
91    else:
92        iterator = sorted(comports(include_links=args.include_links))
93    # list them
94    for n, (port, desc, hwid) in enumerate(iterator, 1):
95        if args.n is None or args.n == n:
96            sys.stdout.write("{:20}\n".format(port))
97            if args.verbose:
98                sys.stdout.write("    desc: {}\n".format(desc))
99                sys.stdout.write("    hwid: {}\n".format(hwid))
100        hits += 1
101    if not args.quiet:
102        if hits:
103            sys.stderr.write("{} ports found\n".format(hits))
104        else:
105            sys.stderr.write("no ports found\n")
106
107# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
108# test
109if __name__ == '__main__':
110    main()
111