125 votes

Lister les ports de communication disponibles avec Python

Je cherche une méthode simple pour lister tous les ports de communication disponibles sur un PC.

J'ai trouvé cette méthode mais elle est spécifique à Windows : Lister les ports série (COM) sous Windows ?

J'utilise Python 3 avec pySerial sur un PC Windows 7.

J'ai trouvé dans l'API pySerial ( http://pyserial.sourceforge.net/pyserial_api.html ) une fonction serial.tools.list_ports.comports() qui liste les ports de communication (exactement ce que je veux).

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

Mais il semble que cela ne fonctionne pas. Lorsque ma passerelle USB vers COM est connectée au PC (je vois le COM5 dans le Gestionnaire de périphériques), ce port COM n'est pas inclus dans la liste renvoyée par la fonction list_ports.comports() . Au lieu de cela, je n'obtiens que COM4 qui semble être connecté à un modem (je ne le vois pas dans la section COM&LPT du gestionnaire de périphériques) !

Tu sais pourquoi ça ne marche pas ? Avez-vous une autre solution qui ne soit pas spécifique au système ?

190voto

attolee Points 131

Voici le code que j'utilise.

Testé avec succès sur Windows 8.1 x64, Windows 10 x64, Mac OS X 10.9.x / 10.10.x / 10.11.x et Ubuntu 14.04 / 14.10 / 15.04 / 15.10 avec Python 2 et 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())

62voto

Ozgur Oz Points 372

C'est mentionné dans la documentation de Pyserial. 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))

Résultat :

COM1 : Port de communication (COM1) [ACPI \PNP0501\1 ]

COM7 : Port USB MediaTek (COM7) [USB VID:PID=0E8D:0003 SER=6 LOCATION=1-2.1]

30voto

moylop260 Points 23

Vous pouvez utiliser :

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

Filtrer par port connu : python -c "import serial.tools.list_ports;print [port for port in serial.tools.list_ports.comports() if port[2] != 'n/a']"

Plus d'informations ici : https://pyserial.readthedocs.org/en/latest/tools.html#module-serial.tools.list_ports

20voto

Solution en une ligne avec le paquet pySerial.

python -m serial.tools.list_ports

12voto

Ngerf Points 111

Un raffinement possible de l'excellente réponse de Thomas est de faire en sorte que Linux et éventuellement OSX essaient également d'ouvrir des ports et ne renvoient que ceux qui ont pu être ouverts. Ceci est dû au fait que Linux, au moins, liste un grand nombre de ports comme des fichiers dans /dev/ qui ne sont pas connectés à quoi que ce soit. Si vous travaillez dans un terminal, /dev/tty est le terminal dans lequel vous travaillez et l'ouvrir et le fermer peut gâcher votre ligne de commande, donc le glob est conçu pour ne pas faire cela. Code :

    # ... 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

Cette modification du code de Thomas a été testée sur Ubuntu 14.04 uniquement.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X