|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121 |
- #!/usr/bin/env python
- #
- # This is a helper module for the various platform dependent list_port
- # implementations.
- #
- # This file is part of pySerial. https://github.com/pyserial/pyserial
- # (C) 2015 Chris Liechti <cliechti@gmx.net>
- #
- # SPDX-License-Identifier: BSD-3-Clause
-
- from __future__ import absolute_import
-
- import re
- import glob
- import os
- import os.path
-
-
- def numsplit(text):
- """\
- Convert string into a list of texts and numbers in order to support a
- natural sorting.
- """
- result = []
- for group in re.split(r'(\d+)', text):
- if group:
- try:
- group = int(group)
- except ValueError:
- pass
- result.append(group)
- return result
-
-
- class ListPortInfo(object):
- """Info collection base class for serial ports"""
-
- def __init__(self, device, skip_link_detection=False):
- self.device = device
- self.name = os.path.basename(device)
- self.description = 'n/a'
- self.hwid = 'n/a'
- # USB specific data
- self.vid = None
- self.pid = None
- self.serial_number = None
- self.location = None
- self.manufacturer = None
- self.product = None
- self.interface = None
- # special handling for links
- if not skip_link_detection and device is not None and os.path.islink(device):
- self.hwid = 'LINK={}'.format(os.path.realpath(device))
-
- def usb_description(self):
- """return a short string to name the port based on USB info"""
- if self.interface is not None:
- return '{} - {}'.format(self.product, self.interface)
- elif self.product is not None:
- return self.product
- else:
- return self.name
-
- def usb_info(self):
- """return a string with USB related information about device"""
- return 'USB VID:PID={:04X}:{:04X}{}{}'.format(
- self.vid or 0,
- self.pid or 0,
- ' SER={}'.format(self.serial_number) if self.serial_number is not None else '',
- ' LOCATION={}'.format(self.location) if self.location is not None else '')
-
- def apply_usb_info(self):
- """update description and hwid from USB data"""
- self.description = self.usb_description()
- self.hwid = self.usb_info()
-
- def __eq__(self, other):
- return isinstance(other, ListPortInfo) and self.device == other.device
-
- def __hash__(self):
- return hash(self.device)
-
- def __lt__(self, other):
- if not isinstance(other, ListPortInfo):
- raise TypeError('unorderable types: {}() and {}()'.format(
- type(self).__name__,
- type(other).__name__))
- return numsplit(self.device) < numsplit(other.device)
-
- def __str__(self):
- return '{} - {}'.format(self.device, self.description)
-
- def __getitem__(self, index):
- """Item access: backwards compatible -> (port, desc, hwid)"""
- if index == 0:
- return self.device
- elif index == 1:
- return self.description
- elif index == 2:
- return self.hwid
- else:
- raise IndexError('{} > 2'.format(index))
-
-
- # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- def list_links(devices):
- """\
- search all /dev devices and look for symlinks to known ports already
- listed in devices.
- """
- links = []
- for device in glob.glob('/dev/*'):
- if os.path.islink(device) and os.path.realpath(device) in devices:
- links.append(device)
- return links
-
-
- # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- # test
- if __name__ == '__main__':
- print(ListPortInfo('dummy'))
|