Python を使用してシリアル ポートを一覧表示する
 
この記事では、シリアル ポートまたは COM ポートを使用した通信について説明します。 システムの利用可能な通信ポートを取得するのに役立つように、Python パッケージを詳細に調べます。
後で、Python を使用して検索し、利用可能なシリアル ポートに関する詳細情報を取得するためのいくつかの手法を確認します。
COM ポートの簡単な紹介
COM ポートは、シリアル デバイスをコンピュータに接続できるようにする I/O インターフェイスです。 Communication Port の略です。
COM ポートは、シリアル ポートと呼ばれることもあります。 COM ポートは、新しいコンピューターやデバイスでは一般的に使用されなくなりましたが、多くの古いシリアル ポート デバイスはまだ使用されています。
したがって、シリアル通信を行い、いくつかのシリアル操作のためにこれらのポートをリストする必要がある場合があります。
Python で利用可能なシリアル ポートのリストを取得する
プログラミング中に、システムで使用可能な通信ポートに関する情報を取得する必要がある場合があります。 Python を使用してこれを行う方法について説明します。
Python は、シリアル ポートと関連情報へのアクセスを提供する pySerial モジュールを提供します。 まず、パッケージ pySerial をプロジェクトにインストールする必要があります。その後、その機能を簡単に使用できるようになります。
パッケージをインストールするには、Python コマンド ターミナルでpip install pyserialと入力し、Enter を押す必要があります。 パッケージが使用可能になります。
それでは、シリアル ポートを一覧表示する次のコードを見てみましょう。
import serial.tools.list_ports
ports = []
for port in serial.tools.list_ports.comports():
    ports.append(port.name)
print(ports)
出力:
['COM1']
コードで行ったことについて説明しましょう。 インストールされたパッケージを使用するには import serial と書く必要があります。
パッケージ pySerial には、利用可能な COM ポートのリストを返す comports() メソッドがあります。 このリストの各オブジェクトは、ListPortInfo タイプです。
この記事の後半で、この ListPortInfo オブジェクトが保持するものについて説明します。
comports() 関数は、tools にあるモジュール list_ports, にあります。 そのため、import serial.tools.list_ports を記述してモジュール全体をインポートします。
次に、comports() 関数によって返されたリストに対して for ループを実行し、ポートをリストに追加します。
上記のコードは、Python のリスト内包表記を使用すると、より簡単に記述できます。 出力は両方のコードで同じになります。 方法は次のとおりです。
import serial.tools.list_ports
print([port.device for port in serial.tools.list_ports.comports()])
シリアル ポートのリストとその詳細を取得する
説明したように、comports() 関数はポートのリストを返し、リスト内の各オブジェクトは ListPortInfo 型です。 このオブジェクトは、シリアル ポートに関する情報を保持し、シリアル ポートのデバイス (完全な名前/パス)、説明、および hwid を取得するためのインデックス付きアクセスを提供します。
インデックス 0 はデバイスの値を示し、説明はインデックス 1 にあり、インデックス 2 はポートの hwid を共有します。
以下は、ListPortInfo オブジェクトが提供する COM ポートに関する詳細情報です。
| 物体 | 説明 | 
|---|---|
| device | 完全なデバイス名/パス。 これは、インデックスによってアクセスされると、最初の要素として返されます。 | 
| name | 短いデバイス名。 | 
| description | 人間が読める説明。 これは、インデックスによってアクセスされると、2 番目の要素として返されます。 | 
| hwid | ハードウェア ID。 これは、インデックスによってアクセスされると、3 番目の要素として返されます。 | 
| vid | USB ベンダー ID。 | 
| pid | USB 製品 ID。 | 
| serial_number | 文字列としての USB シリアル番号。 | 
| location | USB デバイスの場所の文字列。 | 
| manufacturer | デバイスによって報告された USB メーカーの文字列。 | 
| product | デバイスによって報告された USB 製品文字列。 | 
| interface | インターフェイス固有の説明。 | 
注: サポートは一部のオペレーティング システムに限定されています。
descriptionとhwidは、すべてのシステムで利用できるわけではありません。
それでは、利用可能なすべての COM ポートのリストを、それらの name、description、manufacturer、および hwid とともに取得するコードを書きましょう。
import serial.tools.list_ports
port_data = []
for port in serial.tools.list_ports.comports():
    info = dict(
        {
            "Name": port.name,
            "Description": port.description,
            "Manufacturer": port.manufacturer,
            "Hwid": port.hwid,
        }
    )
    port_data.append(info)
print(port_data)
出力:
[{'Name': 'COM1', 'Description': 'Communications Port (COM1)', 'Manufacturer': '(Standard port types)',
  'Hwid': 'ROOT\\PORTS\\0000'}]
名前でシリアルポートを検索
この機能は、コンピューターに複数のポートがある場合に便利です。 特定のポートが必要な場合は、選択した名前または説明で検索できます。
与えられた名前のポートを返す関数を Python で作成しましょう。
import serial.tools.list_ports
def get_port_by_name(port_name):
    for port in serial.tools.list_ports.comports():
        if port.name == port_name:
            return port
print(get_port_by_name("COM1").description)
出力:
Communications Port (COM1)
コードは簡単に把握できます。 この関数では、comports() 関数によって返されたポートのリストに対して for ループが実行されます。
ループ内の各ポートの名前を検証して、ユーザー入力と一致するかどうかを確認します。 存在する場合は、そのポートを返します。
description に対しても同様の関数を作成できます。この関数は、説明をチェックしてポートを返します。