Das Problem mit mehreren identischen USB-Geräten
Ich habe einen Rasperry Pi mit vier Kameras. Ich nehme pix mit fswebcam
denen identifiziert die Kameras wie /dev/video0
.. video3
. Manchmal ist die Kamera video0
, vide02
, video4
und video6
doch können wir darüber jetzt vergessen.
Ich benötige eine persistente ID, um eine Kameranummer zu identifizieren, damit z. B. video0
immer die gleiche Kamera ist, da ich die Bilder beschrifte. Leider passiert dies nicht zuverlässig - beim Booten werden die Kameras mit video0
.. aufgelistet, video3
aber nicht immer auf die gleiche Weise.
Die Kameras haben alle die gleiche ID und Seriennummer.
Die Lösung für dieses Problem beinhaltet udev-Regeln, aber es gibt auch viele Angelhaken.
Wenn Sie den Befehl ausgeben
udevadm info –attribute-walk –path=/dev/video0
Sie erhalten einen Estrich der Ausgabe, aber die hervorstechenden Teile sind
KERNEL=”video0”, SUBSYSTEM=”video4linux” and KERNELS=”1:1.2.4:1.0”.
Das KERNELS-Bit ist ein USB-Hub-Port. Bei vier Kameras gibt es vier davon - sie ändern sich nicht beim Neustart, aber der video{x}
mit einem Port verknüpfte kann sich ändern.
Wir brauchen also eine udev-Regel, um eine Videonummer an einen USB-Hub-Port zu binden - so etwas wie:
KERNEL==”video0”,SUBSYSTEM=”video4linux”,KERNELS==”1:1.2.4:1.0”,SYMLINK+=”camera0”
Sieht einfach aus - greifen Sie mit auf die Kamera zu
fswebcam –d $realpath /dev/camera0
Außer es funktioniert nicht - wenn Sie dies in eine udev-Regel einfügen und das System video0 (beim Booten) einem anderen Port zugewiesen hat, wird die udev-Regel ignoriert. Der Symlink /dev/camera0
sagt im Grunde no such device
. Platz eins.
Wir möchten einen Symlink an eine USB-Hub-Adresse binden, nicht an eine video{x}
Nummer. Es dauerte ein Python-Programm.
Der erste Schritt war zu rennen
fswebcam –d /dev/video${x} tst.jpg
für x
zwischen 1 und 8. Das Vorhandensein tst.jpg
nach jedem Anruf gibt an, ob sich auf dieser Videonummer eine Kamera befindet. Daraus machen Sie eine Liste der aktiven Videonummern. Meine Erfahrung war, dass es entweder 0,1,2,3
oder 0,2,4,6
für Kameras ist, die ich benutzt habe.
Andere können diese Liste natürlich mit einem anderen Verfahren erstellen.
Dann für jede Videonummer in der Liste ausführen
udevadm info –attribute-walk –path=/dev/videox > dd
und extrahiere die KERNELS= line
aus dd
. Nach diesem Vorgang erhalten Sie eine Liste der USB-Anschlussadressen für die Kameras. Sortieren Sie diese Liste so, dass Sie sie im nächsten Schritt immer in der gleichen Reihenfolge bearbeiten. Nennen Sie dies die "Adressliste".
Führen Sie das udevadm … > dd
Ding erneut aus und erstellen Sie eine Liste, die aussieht
KERNEL==”video0”, SUBSYSTEM=”video4linux”,KERNELS==”1:1.2.4:1.0 ”,SYMLINK+=”camerax”. Call this the “video list”.
Blättern Sie nun durch die Adressliste - für jeden Eintrag finden Sie den entsprechenden Eintrag aus der Videoliste. Erstellen Sie eine neue Liste, die wie eine Sammlung von Zeilen aussieht
KERNEL==”video0”, SUBSYSTEM=”video4linux”,KERNELS==”1:1.2.4:1.0 ”,SYMLINK+=”camera2”
Das x (Symlink-Nummer) wird durch die laufende Nummer in der Adressliste ersetzt.
Jetzt haben Sie eine udev-Regel, die funktioniert. Ein Symlink, der an eine USB-Hub-Adresse gebunden ist, unabhängig davon, welche Videonummer diesem Port beim Start zugewiesen wird.
Schreiben Sie die endgültige Liste in eine Datei /etc/udev/rules.d/cam.rules
. Führen udevadm trigger
Sie den Befehl aus , um es zu aktivieren, und der Auftrag ist abgeschlossen. /dev/camera2
wird die gleiche Kamera (USB-Anschluss) sein, unabhängig von seiner Videonummer.