programing

Python에서 사용 가능한 포트 나열

abcjava 2023. 8. 19. 09:41
반응형

Python에서 사용 가능한 포트 나열

저는 PC에서 사용 가능한 모든 컴포트를 나열할 수 있는 간단한 방법을 찾고 있습니다.

이 방법을 찾았지만 Windows 전용입니다. Windows에서 직렬(COM) 포트를 나열하시겠습니까?

Windows 7 PC에서 PySerial과 함께 Python 3을 사용하고 있습니다.

저는 pySerial API(http://pyserial.sourceforge.net/pyserial_api.html) 에서 함수를 찾았습니다.serial.tools.list_ports.comports()(정확히 내가 원하는 것)이 나열됩니다.

import serial.tools.list_ports
print(list(serial.tools.list_ports.comports()))

하지만 그것은 작동하지 않는 것 같습니다.USB-COM 게이트웨이가 PC에 연결되어 있는 경우(장치 관리자에 COM5가 표시됨) 이 COM 포트는 반환된 목록에 포함되지 않습니다.list_ports.comports()대신 모뎀에 연결된 것 같은 COM4만 표시됩니다(장치 관리자의 COM&LPT 섹션에는 표시되지 않습니다)!

왜 안 되는지 알아요?시스템에 특정되지 않은 다른 솔루션이 있습니까?

이것이 제가 사용하는 코드입니다.

Windows 8.1 x64, Windows 10 x64, Mac OS X 10.9.x / 10.10.x / 10.11.x 및 Ubuntu 14.04 / 14.10 / 15.04 / 15.10에서 Python 3을 모두 사용하여 성공적으로 테스트되었습니다.

import sys
import glob
import serial


def serial_ports():
    """ Lists serial port names

        :raises EnvironmentError:
            On unsupported or unknown platforms
        :returns:
            A list of the serial ports available on the system
    """
    if sys.platform.startswith('win'):
        ports = ['COM%s' % (i + 1) for i in range(256)]
    elif sys.platform.startswith('linux') or sys.platform.startswith('cygwin'):
        # this excludes your current terminal "/dev/tty"
        ports = glob.glob('/dev/tty[A-Za-z]*')
    elif sys.platform.startswith('darwin'):
        ports = glob.glob('/dev/tty.*')
    else:
        raise EnvironmentError('Unsupported platform')

    result = []
    for port in ports:
        try:
            s = serial.Serial(port)
            s.close()
            result.append(port)
        except (OSError, serial.SerialException):
            pass
    return result


if __name__ == '__main__':
    print(serial_ports())

기본적으로 이는 물리적 문서에서 언급되었습니다. https://pyserial.readthedocs.io/en/latest/tools.html#module-serial.tools.list_ports

import serial.tools.list_ports
ports = serial.tools.list_ports.comports()

for port, desc, hwid in sorted(ports):
        print("{}: {} [{}]".format(port, desc, hwid))

결과:

COM1: 통신 포트(COM1) [ACPI\]PNP0501\1]

COM7: 미디어Tek USB 포트(COM7) [USB VID:PID=0E8D:0003 SER=6 LOCATION=1-2.1]

사용할 수 있는 항목:

python -c "import serial.tools.list_ports;print serial.tools.list_ports.comports()"

알려진 포트로 필터링:python -c "import serial.tools.list_ports;print [port for port in serial.tools.list_ports.comports() if port[2] != 'n/a']"

자세한 내용은 여기를 참조하십시오. https://pyserial.readthedocs.org/en/latest/tools.html#module-serial.tools.list_ports

pySerial 패키지가 포함된 한 줄 솔루션.

python -m serial.tools.list_ports

Thomas의 훌륭한 답변에 대한 가능한 개선 사항은 Linux와 OSX를 사용하여 포트를 열고 열 수 있는 포트만 반환하는 것입니다.Linux는 적어도 포트의 보트 로드를 /dev/의 파일로 나열하지만 아무 것에도 연결되지 않기 때문입니다.터미널에서 실행 중인 경우 /dev/tty는 작업 중인 터미널이며 열기 및 닫기로 인해 명령줄이 잘못될 수 있으므로 Glob은 그렇게 하지 않도록 설계되었습니다.코드:

    # ... Windows code unchanged ...

    elif sys.platform.startswith ('linux'):
        temp_list = glob.glob ('/dev/tty[A-Za-z]*')

    result = []
    for a_port in temp_list:

        try:
            s = serial.Serial(a_port)
            s.close()
            result.append(a_port)
        except serial.SerialException:
            pass

    return result

Thomas 코드에 대한 이 수정 사항은 Ubuntu 14.04에서만 테스트되었습니다.

moylop260의 답변에 대한 개선:

import serial.tools.list_ports
comlist = serial.tools.list_ports.comports()
connected = []
for element in comlist:
    connected.append(element.device)
print("Connected COM ports: " + str(connected))

사용 중인 포트를 포함하여 하드웨어에 존재하는 포트가 나열됩니다. 목록에는 물리적 도구 설명서에 따라 훨씬 더 많은 정보가 있습니다.

아마 늦겠지만 도움이 필요한 사람을 도울 수도 있습니다.

import serial.tools.list_ports


class COMPorts:

    def __init__(self, data: list):
        self.data = data

    @classmethod
    def get_com_ports(cls):
        data = []
        ports = list(serial.tools.list_ports.comports())

        for port_ in ports:
            obj = Object(data=dict({"device": port_.device, "description": port_.description.split("(")[0].strip()}))
            data.append(obj)

        return cls(data=data)

    @staticmethod
    def get_description_by_device(device: str):
        for port_ in COMPorts.get_com_ports().data:
            if port_.device == device:
                return port_.description

    @staticmethod
    def get_device_by_description(description: str):
        for port_ in COMPorts.get_com_ports().data:
            if port_.description == description:
                return port_.device


class Object:
    def __init__(self, data: dict):
        self.data = data
        self.device = data.get("device")
        self.description = data.get("description")


if __name__ == "__main__":
    for port in COMPorts.get_com_ports().data:
        print(port.device)
        print(port.description)

    print(COMPorts.get_device_by_description(description="Arduino Leonardo"))
    print(COMPorts.get_description_by_device(device="COM3"))

다음 코드를 사용해 보십시오.

import serial
ports = serial.tools.list_ports.comports(include_links=False)
for port in ports :
    print(port.device)

먼저 직렬 포트 통신을 위해 패키지를 가져와야 하므로 다음과 같습니다.

import serial

그런 다음 현재 사용 가능한 모든 직렬 포트 목록을 생성합니다.

ports = serial.tools.list_ports.comports(include_links=False)

그런 다음 전체 목록을 따라 이동하면 예를 들어 포트 이름을 인쇄할 수 있습니다.

for port in ports :
    print(port.device)

이것은 포트 목록을 가져오고 포트 이름을 인쇄하는 방법의 예에 불과하지만 이 데이터를 사용하여 수행할 수 있는 몇 가지 다른 옵션이 있습니다.다음에 다른 변형을 인쇄해 보십시오.

항구.

간단한 거지만 많이 써요.

import serial.tools.list_ports as ports

com_ports = list(ports.comports()) # create a list of com ['COM1','COM2'] 
    for i in com_ports:            
        print(i.device) # returns 'COMx'        

이 코드를 사용해 보세요.

import serial.tools.list_ports
for i in serial.tools.list_ports.comports():
    print(i) 

그것은 돌아옵니다.

COM1 - Port de communication (COM1)
COM5 - USB-SERIAL CH340 (COM5)

예를 들어 COM1의 포트 이름을 원하지 않는 경우

import serial.tools.list_ports
for i in serial.tools.list_ports.comports():
    print(str(i).split(" ")[0])

그것은 돌아옵니다.

COM1
COM5

내 경우처럼 py 3.7 64비트.

Windows에서만 작동:

import winreg
import itertools

def serial_ports() -> list:
    path = 'HARDWARE\\DEVICEMAP\\SERIALCOMM'
    key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, path)

    ports = []
    for i in itertools.count():
        try:
            ports.append(winreg.EnumValue(key, i)[1])
        except EnvironmentError:
            break

    return ports

if __name__ == "__main__":
    ports = serial_ports()

한 가지 주의할 점은 다음과 같은 코드입니다.

for i in serial.tools.list_ports.comports():
print(i) 

다음을 반환합니다.

COM7 - Standard Serial over Bluetooth link (COM7) COM1 - Communications Port (COM1) COM8 - Standard Serial over Bluetooth link (COM8) COM4 - USB-SERIAL CH340 (COM4)

포트를 순서대로 나열하고 사용자가 사용할 수 있는 포트만 나열하려면 다음을 시도하십시오.(credit to tfeldmann)

   def serial_ports():
    """ Lists serial port names

        :raises EnvironmentError:
            On unsupported or unknown platforms
        :returns:
            A list of the serial ports available on the system
    """
    if sys.platform.startswith('win'):
        ports = ['COM%s' % (i + 1) for i in range(256)]
    elif sys.platform.startswith('linux') or sys.platform.startswith('cygwin'):
        # this excludes your current terminal "/dev/tty"
        ports = glob.glob('/dev/tty[A-Za-z]*')
    elif sys.platform.startswith('darwin'):
        ports = glob.glob('/dev/tty.*')
    else:
        raise EnvironmentError('Unsupported platform')

    result = []
    for port in ports:
        try:
            s = serial.Serial(port)
            s.close()
            result.append(port)
        except (OSError, serial.SerialException):
            pass
    return result

그러면 다음이 반환됩니다.

['COM1', 'COM4', 'COM8']

결과가 ['COM7', 'COM1', 'COM8', 'COM4'인 첫 번째 예와 달리 이번에는 모든 포트를 순서대로 정렬하고 사용 가능한 포트만 제공합니다.순서대로 필요한 경우 매우 편리하며, 사용 가능한지 테스트를 거쳤습니다.

몇 가지 옵션을 사용할 수 있습니다.

모든 DOS 장치를 나열하려면 NULL lpDeviceName을 사용하여 QueryDosDevice를 호출합니다.그런 다음 CreateFile 및 GetCommConfig를 각 장치 이름과 함께 차례로 사용하여 직렬 포트인지 확인합니다.

ClassGuid가 GUID_DEVINTERFACTOR인 SetupDiGetClassDevs를 호출합니다.

WMI는 C/C++ 프로그램에서도 사용할 수 있습니다.

win32 뉴스 그룹과 코드 프로젝트에 대한 대화가 있습니다. 어, 프로젝트.

언급URL : https://stackoverflow.com/questions/12090503/listing-available-com-ports-with-python

반응형