RaspberryPiでUSBメモリを指したことを確認する
つい先日名古屋ではこういうイベントがありました。
発表もいろいろあったので自分ももう少し作品作りをしなければという気持ちになりました。ということで次回のイベント(?)に向けて自分も作ってみることにしました。(過去の焼き直しではありますが)
今回のエントリーでは、仮面ライダーWのダブルドライバーをRaspberryPiで実現に向けたものにしようと思います。昔作ったものはPCベースだったため、ベルト化(小型化)が難しかったのですが、今回はRaspberryPiでの実装ですのでバックル化も可能になると思います。最終ターゲットは腰に巻けるようにすることになります。
Wドライバーは以下のようなものです。
簡単にいうとUSBメモリを挿し、挿したものの種類を判別して音を鳴らすというものになります。Windows版については以下を参照してください。該当の組み合わせであれば変身音がなるというものです。
USBメモリを抜き差しを検出する。
ネットを色々と調べてみるとLinuxではudev
を使用することでデバイスの接続を確認することができるようです。
これによれば
udev(userspace device management)とは,カーネルがパソコンへの接続を検出したデバイスに対して,動的に「デバイス・ファイル」を作成して割り当てるための仕組みです。 Linuxは,システムに存在するあらゆるリソースをファイルとして扱うという特徴を持っています。
事前にlsusb
を使用してみる
とりあえずudev
を使用する前に、接続しようとする、USBメモリの認識を確認しておきます。USBの接続状況を確認するのは恒例のlsusb
コマンドになります。
【接続前の状態】
$ lsusb Bus 001 Device 005: ID 045e:075d Microsoft Corp. LifeCam Cinema Bus 001 Device 004: ID 0411:01ee BUFFALO INC. (formerly MelCo., Inc.) WLI-UC-GNM2 Wireless LAN Adapter [Ralink RT3070] Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp. SMSC9512/9514 Fast Ethernet Adapter Bus 001 Device 002: ID 0424:9514 Standard Microsystems Corp. Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
【接続後の状態】
$ lsusb Bus 001 Device 006: ID 090c:1000 Silicon Motion, Inc. - Taiwan (formerly Feiya Technology Corp.) Flash Drive Bus 001 Device 005: ID 045e:075d Microsoft Corp. LifeCam Cinema Bus 001 Device 004: ID 0411:01ee BUFFALO INC. (formerly MelCo., Inc.) WLI-UC-GNM2 Wireless LAN Adapter [Ralink RT3070] Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp. SMSC9512/9514 Fast Ethernet Adapter Bus 001 Device 002: ID 0424:9514 Standard Microsystems Corp. Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
以下のエントリーが追加されたUSBメモリの情報になります。
Bus 001 Device 006: ID 090c:1000 Silicon Motion, Inc. - Taiwan (formerly Feiya Technology Corp.) Flash Drive
IDの後につづいている値がVenderIDとProductID(ModelID)になります。もう少し固有の値がほしいのですが、このコマンドではここまでしか表示できませんでした。(後からわかったのですが-v
で詳細がでますので、それで詳細をみてもいいかもしれません。)
lsusb
コマンドでは認識されたUSBデバイスの状況のみが確認できるため、抜き差しのタイミングでの検知はできません。
udev
を使用してみる
次にudev
のコマンドインターフェースであるudevadm
を使ってUSBデバイスの挿抜状態をモニタリングしてみたいと思います。
udevadm
のモニタリングモードでは、KERNEL側の情報とUDEV側の情報をモニタリングできます。イベントとしては接続時のaddイベント、取り外し時のremoveイベントなどが見れます。このあたりはデバイスのクラスに依存するのでその他もありますが、詳細はドキュメントに記載されています。
実際に実行してみます。
$ udevadm monitor monitor will print the received events for: UDEV - the event which udev sends out after rule processing KERNEL - the kernel uevent KERNEL[1219.983660] add /devices/platform/soc/3f980000.usb/usb1/1-1/1-1.4 (usb) KERNEL[1219.986476] add /devices/platform/soc/3f980000.usb/usb1/1-1/1-1.4/1-1.4:1.0 (usb) KERNEL[1219.997083] add /devices/platform/soc/3f980000.usb/usb1/1-1/1-1.4/1-1.4:1.0/host0 (scsi) KERNEL[1219.997701] add /devices/platform/soc/3f980000.usb/usb1/1-1/1-1.4/1-1.4:1.0/host0/scsi_host/host0 (scsi_host) UDEV [1220.020340] add /devices/platform/soc/3f980000.usb/usb1/1-1/1-1.4 (usb) UDEV [1220.027171] add /devices/platform/soc/3f980000.usb/usb1/1-1/1-1.4/1-1.4:1.0 (usb) UDEV [1220.031344] add /devices/platform/soc/3f980000.usb/usb1/1-1/1-1.4/1-1.4:1.0/host0 (scsi) UDEV [1220.035723] add /devices/platform/soc/3f980000.usb/usb1/1-1/1-1.4/1-1.4:1.0/host0/scsi_host/host0 (scsi_host) KERNEL[1221.487617] add /devices/platform/soc/3f980000.usb/usb1/1-1/1-1.4/1-1.4:1.0/host0/target0:0:0 (scsi) KERNEL[1221.487880] add /devices/platform/soc/3f980000.usb/usb1/1-1/1-1.4/1-1.4:1.0/host0/target0:0:0/0:0:0:0 (scsi) KERNEL[1221.488153] add /devices/platform/soc/3f980000.usb/usb1/1-1/1-1.4/1-1.4:1.0/host0/target0:0:0/0:0:0:0/scsi_disk/0:0:0:0 (scsi_disk) KERNEL[1221.488541] add /devices/platform/soc/3f980000.usb/usb1/1-1/1-1.4/1-1.4:1.0/host0/target0:0:0/0:0:0:0/scsi_device/0:0:0:0 (scsi_device) KERNEL[1221.490362] add /devices/platform/soc/3f980000.usb/usb1/1-1/1-1.4/1-1.4:1.0/host0/target0:0:0/0:0:0:0/bsg/0:0:0:0 (bsg) UDEV [1221.491079] add /devices/platform/soc/3f980000.usb/usb1/1-1/1-1.4/1-1.4:1.0/host0/target0:0:0 (scsi) KERNEL[1221.493208] add /devices/virtual/bdi/8:0 (bdi) UDEV [1221.496802] add /devices/virtual/bdi/8:0 (bdi) KERNEL[1221.504379] add /devices/platform/soc/3f980000.usb/usb1/1-1/1-1.4/1-1.4:1.0/host0/target0:0:0/0:0:0:0/block/sda (block) KERNEL[1221.505020] add /devices/platform/soc/3f980000.usb/usb1/1-1/1-1.4/1-1.4:1.0/host0/target0:0:0/0:0:0:0/block/sda/sda1 (block) UDEV [1221.505249] add /module/sg (module) KERNEL[1221.505405] add /module/sg (module) UDEV [1221.505879] add /devices/platform/soc/3f980000.usb/usb1/1-1/1-1.4/1-1.4:1.0/host0/target0:0:0/0:0:0:0 (scsi) KERNEL[1221.506146] add /class/scsi_generic (class) KERNEL[1221.506620] add /devices/platform/soc/3f980000.usb/usb1/1-1/1-1.4/1-1.4:1.0/host0/target0:0:0/0:0:0:0/scsi_generic/sg0 (scsi_generic) UDEV [1221.507040] add /class/scsi_generic (class) UDEV [1221.512906] add /devices/platform/soc/3f980000.usb/usb1/1-1/1-1.4/1-1.4:1.0/host0/target0:0:0/0:0:0:0/scsi_device/0:0:0:0 (scsi_device) UDEV [1221.513143] add /devices/platform/soc/3f980000.usb/usb1/1-1/1-1.4/1-1.4:1.0/host0/target0:0:0/0:0:0:0/scsi_disk/0:0:0:0 (scsi_disk) UDEV [1221.516441] add /devices/platform/soc/3f980000.usb/usb1/1-1/1-1.4/1-1.4:1.0/host0/target0:0:0/0:0:0:0/bsg/0:0:0:0 (bsg) UDEV [1221.525971] add /devices/platform/soc/3f980000.usb/usb1/1-1/1-1.4/1-1.4:1.0/host0/target0:0:0/0:0:0:0/scsi_generic/sg0 (scsi_generic) UDEV [1221.589504] add /devices/platform/soc/3f980000.usb/usb1/1-1/1-1.4/1-1.4:1.0/host0/target0:0:0/0:0:0:0/block/sda (block) UDEV [1221.663788] add /devices/platform/soc/3f980000.usb/usb1/1-1/1-1.4/1-1.4:1.0/host0/target0:0:0/0:0:0:0/block/sda/sda1 (block) KERNEL[1242.032388] remove /devices/platform/soc/3f980000.usb/usb1/1-1/1-1.4/1-1.4:1.0/host0/target0:0:0/0:0:0:0/bsg/0:0:0:0 (bsg) KERNEL[1242.032573] remove /devices/platform/soc/3f980000.usb/usb1/1-1/1-1.4/1-1.4:1.0/host0/target0:0:0/0:0:0:0/scsi_generic/sg0 (scsi_generic) KERNEL[1242.032678] remove /devices/platform/soc/3f980000.usb/usb1/1-1/1-1.4/1-1.4:1.0/host0/target0:0:0/0:0:0:0/scsi_device/0:0:0:0 (scsi_device) KERNEL[1242.040388] remove /devices/platform/soc/3f980000.usb/usb1/1-1/1-1.4/1-1.4:1.0/host0/target0:0:0/0:0:0:0/scsi_disk/0:0:0:0 (scsi_disk) UDEV [1242.040618] remove /devices/platform/soc/3f980000.usb/usb1/1-1/1-1.4/1-1.4:1.0/host0/target0:0:0/0:0:0:0/bsg/0:0:0:0 (bsg) KERNEL[1242.040797] remove /devices/platform/soc/3f980000.usb/usb1/1-1/1-1.4/1-1.4:1.0/host0/target0:0:0/0:0:0:0/block/sda/sda1 (block) KERNEL[1242.040961] remove /devices/platform/soc/3f980000.usb/usb1/1-1/1-1.4/1-1.4:1.0/host0/target0:0:0/0:0:0:0/block/sda (block) KERNEL[1242.041102] remove /devices/platform/soc/3f980000.usb/usb1/1-1/1-1.4/1-1.4:1.0/host0/target0:0:0/0:0:0:0 (scsi) UDEV [1242.047234] remove /devices/platform/soc/3f980000.usb/usb1/1-1/1-1.4/1-1.4:1.0/host0/target0:0:0/0:0:0:0/scsi_generic/sg0 (scsi_generic) UDEV [1242.049023] remove /devices/platform/soc/3f980000.usb/usb1/1-1/1-1.4/1-1.4:1.0/host0/target0:0:0/0:0:0:0/block/sda/sda1 (block) UDEV [1242.051848] remove /devices/platform/soc/3f980000.usb/usb1/1-1/1-1.4/1-1.4:1.0/host0/target0:0:0/0:0:0:0/scsi_device/0:0:0:0 (scsi_device) UDEV [1242.053386] remove /devices/platform/soc/3f980000.usb/usb1/1-1/1-1.4/1-1.4:1.0/host0/target0:0:0/0:0:0:0/scsi_disk/0:0:0:0 (scsi_disk) UDEV [1242.063650] remove /devices/platform/soc/3f980000.usb/usb1/1-1/1-1.4/1-1.4:1.0/host0/target0:0:0/0:0:0:0/block/sda (block) UDEV [1242.070194] remove /devices/platform/soc/3f980000.usb/usb1/1-1/1-1.4/1-1.4:1.0/host0/target0:0:0/0:0:0:0 (scsi) KERNEL[1242.074278] remove /devices/virtual/bdi/8:0 (bdi) KERNEL[1242.074545] remove /devices/platform/soc/3f980000.usb/usb1/1-1/1-1.4/1-1.4:1.0/host0/target0:0:0 (scsi) KERNEL[1242.075798] remove /devices/platform/soc/3f980000.usb/usb1/1-1/1-1.4/1-1.4:1.0/host0/scsi_host/host0 (scsi_host) UDEV [1242.076003] remove /devices/virtual/bdi/8:0 (bdi) KERNEL[1242.076136] remove /devices/platform/soc/3f980000.usb/usb1/1-1/1-1.4/1-1.4:1.0/host0 (scsi) KERNEL[1242.076318] remove /devices/platform/soc/3f980000.usb/usb1/1-1/1-1.4/1-1.4:1.0 (usb) UDEV [1242.078805] remove /devices/platform/soc/3f980000.usb/usb1/1-1/1-1.4/1-1.4:1.0/host0/target0:0:0 (scsi) UDEV [1242.079279] remove /devices/platform/soc/3f980000.usb/usb1/1-1/1-1.4/1-1.4:1.0/host0/scsi_host/host0 (scsi_host) KERNEL[1242.079514] remove /devices/platform/soc/3f980000.usb/usb1/1-1/1-1.4 (usb) UDEV [1242.085069] remove /devices/platform/soc/3f980000.usb/usb1/1-1/1-1.4/1-1.4:1.0/host0 (scsi) UDEV [1242.089120] remove /devices/platform/soc/3f980000.usb/usb1/1-1/1-1.4/1-1.4:1.0 (usb) UDEV [1242.099753] remove /devices/platform/soc/3f980000.usb/usb1/1-1/1-1.4 (usb) KERNEL[1246.060791] add /devices/w1_bus_master1/00-980000000000 (w1) UDEV [1246.064646] add /devices/w1_bus_master1/00-980000000000 (w1)
一応、これでUSBメモリを挿抜ときの状態を確認できるようです。これをユーザープログラム上から検出できれば目的はほぼ達成となります。
udev
でデバイスの挿抜状態を検出する方法としては、pythonにpyudev
というモジュールがあるのでこれを使用することにします。
pyudev
とは
pyudev – pure Python libudev binding
https://pyudev.readthedocs.io/en/latest/
libudevの情報をpythonで取得できるようにしたモジュールになります。
pyudev
をインストールする
パッケージのインストール方法に従ってモジュールのインストールをしてみます。
$ pip install pyudev Downloading/unpacking pyudev Downloading pyudev-0.21.0.tar.gz (89kB): 89kB downloaded Running setup.py (path:/tmp/pip-build-jZcUeV/pyudev/setup.py) egg_info for package pyudev warning: no previously-included files matching '*.py' found under directory 'tests/.hypothesis' warning: no files found matching '*.c' under directory 'reproducers' warning: no files found matching '*.py' under directory 'reproducers' Requirement already satisfied (use --upgrade to upgrade): six in /usr/lib/python2.7/dist-packages (from pyudev) Installing collected packages: pyudev Running setup.py install for pyudev error: could not create '/usr/local/lib/python2.7/dist-packages/pyudev': Permission denied Complete output from command /usr/bin/python -c "import setuptools, tokenize;__file__='/tmp/pip-build-jZcUeV/pyudev/setup.py';exec(compile(getattr(tokenize, 'open', open)(__file__).read().replace('\r\n', '\n'), __file__, 'exec'))" install --record /tmp/pip-24vQet-record/install-record.txt --single-version-externally-managed --compile: running install running build running build_py creating build creating build/lib.linux-armv7l-2.7 creating build/lib.linux-armv7l-2.7/pyudev copying src/pyudev/_qt_base.py -> build/lib.linux-armv7l-2.7/pyudev copying src/pyudev/pyqt4.py -> build/lib.linux-armv7l-2.7/pyudev copying src/pyudev/version.py -> build/lib.linux-armv7l-2.7/pyudev copying src/pyudev/core.py -> build/lib.linux-armv7l-2.7/pyudev copying src/pyudev/__init__.py -> build/lib.linux-armv7l-2.7/pyudev copying src/pyudev/_util.py -> build/lib.linux-armv7l-2.7/pyudev copying src/pyudev/discover.py -> build/lib.linux-armv7l-2.7/pyudev copying src/pyudev/glib.py -> build/lib.linux-armv7l-2.7/pyudev copying src/pyudev/_compat.py -> build/lib.linux-armv7l-2.7/pyudev copying src/pyudev/pyqt5.py -> build/lib.linux-armv7l-2.7/pyudev copying src/pyudev/monitor.py -> build/lib.linux-armv7l-2.7/pyudev copying src/pyudev/wx.py -> build/lib.linux-armv7l-2.7/pyudev copying src/pyudev/pyside.py -> build/lib.linux-armv7l-2.7/pyudev creating build/lib.linux-armv7l-2.7/pyudev/device copying src/pyudev/device/_device.py -> build/lib.linux-armv7l-2.7/pyudev/device copying src/pyudev/device/_errors.py -> build/lib.linux-armv7l-2.7/pyudev/device copying src/pyudev/device/__init__.py -> build/lib.linux-armv7l-2.7/pyudev/device creating build/lib.linux-armv7l-2.7/pyudev/_ctypeslib copying src/pyudev/_ctypeslib/libc.py -> build/lib.linux-armv7l-2.7/pyudev/_ctypeslib copying src/pyudev/_ctypeslib/libudev.py -> build/lib.linux-armv7l-2.7/pyudev/_ctypeslib copying src/pyudev/_ctypeslib/_errorcheckers.py -> build/lib.linux-armv7l-2.7/pyudev/_ctypeslib copying src/pyudev/_ctypeslib/__init__.py -> build/lib.linux-armv7l-2.7/pyudev/_ctypeslib copying src/pyudev/_ctypeslib/utils.py -> build/lib.linux-armv7l-2.7/pyudev/_ctypeslib creating build/lib.linux-armv7l-2.7/pyudev/_os copying src/pyudev/_os/pipe.py -> build/lib.linux-armv7l-2.7/pyudev/_os copying src/pyudev/_os/poll.py -> build/lib.linux-armv7l-2.7/pyudev/_os copying src/pyudev/_os/__init__.py -> build/lib.linux-armv7l-2.7/pyudev/_os running install_lib creating /usr/local/lib/python2.7/dist-packages/pyudev error: could not create '/usr/local/lib/python2.7/dist-packages/pyudev': Permission denied ---------------------------------------- Cleaning up... Command /usr/bin/python -c "import setuptools, tokenize;__file__='/tmp/pip-build-jZcUeV/pyudev/setup.py';exec(compile(getattr(tokenize, 'open', open)(__file__).read().replace('\r\n', '\n'), __file__, 'exec'))" install --record /tmp/pip-24vQet-record/install-record.txt --single-version-externally-managed --compile failed with error code 1 in /tmp/pip-build-jZcUeV/pyudev Storing debug log for failure in /home/pi/.pip/pip.log
あれ?エラーです。内容としてはディレクトリが作成できない感じのメッセージなので、一般ユーザでは権限がないからなのかなと思います。
sudo
つきでpip
を行えば大丈夫そうなんですが、今回はapt-getでインストールしてみることにします。
一応、パッケージがあるか確認してみます。
$ apt-cache search pyudev python-pyudev - Python bindings for libudev python3-pyudev - Python3 bindings for libudev
aptのパッケージではVersion2系と3系があるようですので、今回は2系を入れます。(そろそろ3への以降も考えたいですが。)
$ sudo apt-get install python-pyudev パッケージリストを読み込んでいます... 完了 依存関係ツリーを作成しています 状態情報を読み取っています... 完了 以下のパッケージが自動でインストールされましたが、もう必要とされていません: ax25-node libax25 libllvm3.7 openbsd-inetd これを削除するには 'apt-get autoremove' を利用してください。 提案パッケージ: python-qt4 python-pyside.qtcore 以下のパッケージが新たにインストールされます: python-pyudev アップグレード: 0 個、新規インストール: 1 個、削除: 0 個、保留: 161 個。 31.6 kB のアーカイブを取得する必要があります。 この操作後に追加で 193 kB のディスク容量が消費されます。 取得:1 http://mirrordirector.raspbian.org/raspbian/ jessie/main python-pyudev all 0.16.1-2 [31.6 kB] 31.6 kB を 1秒 で取得しました (29.4 kB/s) 以前に未選択のパッケージ python-pyudev を選択しています。 (データベースを読み込んでいます ... 現在 130447 個のファイルとディレクトリがインストールされています。) .../python-pyudev_0.16.1-2_all.deb を展開する準備をしています ... python-pyudev (0.16.1-2) を展開しています... python-pyudev (0.16.1-2) を設定しています ...
無事にインストールできました。
念のためテストしてみると…
$ python Python 2.7.9 (default, Sep 17 2016, 20:26:04) [GCC 4.9.2] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import pyudev >>>
エラーがでていないのでインストールは無事に終わったようです。 ドキュメントに出ているサンプルを実行させてみます。
以下のサンプルは認識されているデバイスの一覧を表示させるものになります。
【sample.py】
#!/usr/bin/env python # -*- coding: utf-8 -*- import pyudev context = pyudev.Context() for device in context.list_devices(): print(device)
では、実行してみます。
$ python sample.py Device(u'/sys/devices/armv7_cortex_a7') Device(u'/sys/devices/breakpoint') Device(u'/sys/devices/platform/alarmtimer') Device(u'/sys/devices/platform/clocks') Device(u'/sys/devices/platform/clocks/clocks:clock@0') Device(u'/sys/devices/platform/clocks/clocks:clock@1') Device(u'/sys/devices/platform/clocks/clocks:clock@2') Device(u'/sys/devices/platform/clocks/clocks:clock@3') Device(u'/sys/devices/platform/clocks/clocks:clock@4') Device(u'/sys/devices/platform/clocks/clocks:clock@5') Device(u'/sys/devices/platform/clocks/clocks:clock@6') Device(u'/sys/devices/platform/lirc_rpi') (略)
udev
で認識されているデバイスが大量に出てきます。
あとは、USBメモリを指したことがモニタできれば次のステップにすすめます。
udevadm
のモニタ機能と同じものができればよいということになります。
メモリの細かい判別を行うために必要なパラメータとしては
- Action(挿した抜いたなどのイベントの種類)
- ID_MODEL_ID(デバイスのModelID)
- ID_MODEL_FROM_DATABASE(ModelIDから得られる製品のモデル名)
- ID_VENDOR_ID(デバイスのVentorID)
- ID_VENDOR_FROM_DATABASE(VentorIDから得られるベンダー(会社)名)
- ID_SERIAL_SHORT(製品の固有値の短縮形式)
- ID_SERIAL(製品の固有値 短縮形にメーカー名、モデル名などが入っていることがあります)
以上だと思います。 ではモニタリングを行うプログラムは以下のようになります。
【pyudev_event.py】
#!/usr/bin/env python # -*- coding: utf-8 -*- import pyudev context = pyudev.Context() monitor = pyudev.Monitor.from_netlink(context) monitor.filter_by(subsystem='usb') monitor.start() for device in iter(monitor.poll, None): print(device.action) print('MODEL : {0} -> {1}'.format(device.get('ID_MODEL_ID'), device.get('ID_MODEL_FROM_DATABASE'))) print('VENDOR : {0} -> {1}'.format(device.get('ID_VENDOR_ID'), device.get('ID_VENDOR_FROM_DATABASE'))) print('SERIAL : {0} -> {1}'.format(device.get('ID_SERIAL_SHORT'), device.get('ID_SERIAL'))) print('---')
pyudev
のMonitorオブジェクトを生成し、Contextを監視する様にしたのがサンプルとの大きな違いです。pyudev.Monitor.from_netlink(context)
と実行しているnetlinkに関してですがman pageによれば
netlink はカーネルモジュールとユーザー空間のプロセス間で 情報をやりとりするために用いられる。
とのことですので、pyudevはこれを経由して動的にデバイス情報を得ていることになります。
実行して、USBメモリを何本か挿抜してみます。(面倒なのでシリアル値はそのままにしました…)
$ python pyudev_event.py add ID_MODEL : 0098 -> None ID_VENDOR : 0411 -> BUFFALO INC. (formerly MelCo., Inc.) SERIAL : A000000000095409 -> BUFFALO_SiliconHardDisk_A000000000095409 --- add ID_MODEL : None -> None ID_VENDOR : None -> BUFFALO INC. (formerly MelCo., Inc.) SERIAL : None -> None --- remove ID_MODEL : None -> None ID_VENDOR : None -> BUFFALO INC. (formerly MelCo., Inc.) SERIAL : None -> None --- remove ID_MODEL : 0098 -> None ID_VENDOR : 0411 -> BUFFALO INC. (formerly MelCo., Inc.) SERIAL : A000000000095409 -> BUFFALO_SiliconHardDisk_A000000000095409 --- add ID_MODEL : 1000 -> Flash Drive ID_VENDOR : 090c -> Silicon Motion, Inc. - Taiwan (formerly Feiya Technology Corp.) SERIAL : None -> SMI_Corporation_USB_DISK --- add ID_MODEL : None -> Flash Drive ID_VENDOR : None -> Silicon Motion, Inc. - Taiwan (formerly Feiya Technology Corp.) SERIAL : None -> None --- remove ID_MODEL : None -> Flash Drive ID_VENDOR : None -> Silicon Motion, Inc. - Taiwan (formerly Feiya Technology Corp.) SERIAL : None -> None --- remove ID_MODEL : 1000 -> Flash Drive ID_VENDOR : 090c -> Silicon Motion, Inc. - Taiwan (formerly Feiya Technology Corp.) SERIAL : None -> SMI_Corporation_USB_DISK --- add ID_MODEL : 5583 -> None ID_VENDOR : 0781 -> SanDisk Corp. SERIAL : 4C531001520507123272 -> SanDisk_Ultra_Fit_4C531001520507123272 --- add ID_MODEL : None -> None ID_VENDOR : None -> SanDisk Corp. SERIAL : None -> None --- remove ID_MODEL : None -> None ID_VENDOR : None -> SanDisk Corp. SERIAL : None -> None --- remove ID_MODEL : 5583 -> None ID_VENDOR : 0781 -> SanDisk Corp. SERIAL : 4C531001520507123272 -> SanDisk_Ultra_Fit_4C531001520507123272 --- ^CTraceback (most recent call last): File "pyudev_sample.py", line 8, in <module> for device in iter(monitor.poll, None): File "/usr/lib/python2.7/dist-packages/pyudev/monitor.py", line 340, in poll rlist, _, _ = select.select([self], [], [], timeout) KeyboardInterrupt
今回の例では3メーカーのUSBメモリを挿してみたのですが、一回抜き差しをするごとに2回のイベントが表示されていました。また、USBメモリに固有値であるとされるID_SERIAL_SHORT
と'ID_SERIAL
が必ずしも入っていないことがわかりました。このあたりはメーカーのポリシーなのかもしれません。(価格が安いからとかそういう感じでもないようでした)
方針としては、値が取得できるときには判別にそれを使用し、無いときにはVenderIDとModelIDを使うことで代用したいと思います。
これでUSBの挿抜の認識の準備はできました。あともう少しですが今回はここまでにします。
おわりに
udev
をつかったデバイス検出の部分と、pythonからのudev
情報の呼び出し部分を作成の実験を行ってみました。後もう少しですが、次は組み合わせと音を鳴らす部分の処理を追加してプロトタイプを仕上げたいと思います。
やっているうちにもっと違う方法もあるのかなと思い始めたのですが、気が向いたらそれも試したいと考えています。