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