Problem z wieloma identycznymi urządzeniami USB
Mam Rasperry Pi z czterema kamerami. Biorę pix z fswebcam
którym identyfikuje kamery jak /dev/video0
.. video3
. Czasami kamera jest video0
, vide02
, video4
a video6
jednak możemy zapomnieć o tym teraz.
Potrzebuję stałego identyfikatora, aby zidentyfikować numer kamery, aby np. video0
Zawsze był tym samym aparatem, ponieważ podpisuję zdjęcia. Niestety nie dzieje się to niezawodnie - przy starcie kamery są wyliczane jako video0
... video3
ale nie zawsze w ten sam sposób.
Wszystkie kamery mają ten sam identyfikator i numer seryjny.
Rozwiązaniem tego problemu są reguły udev, ale jest tam również wiele haczyków na ryby.
Jeśli wydasz polecenie
udevadm info –attribute-walk –path=/dev/video0
dostajesz wyrzutek wyjściowy, ale najważniejsze są
KERNEL=”video0”, SUBSYSTEM=”video4linux” and KERNELS=”1:1.2.4:1.0”.
Bit KERNELS jest portem koncentratora USB. Przy czterech kamerach są cztery z nich - nie zmieniają się przy ponownym uruchomieniu, ale video{x}
powiązanie z portem może się zmienić.
Potrzebujemy więc reguły udev, aby powiązać numer wideo z portem koncentratora USB - coś takiego:
KERNEL==”video0”,SUBSYSTEM=”video4linux”,KERNELS==”1:1.2.4:1.0”,SYMLINK+=”camera0”
Wygląda prosto - dostęp do kamery za pomocą
fswebcam –d $realpath /dev/camera0
Tyle że to nie działa - jeśli umieścisz to w regule udev, a system przydzieli wideo0 (podczas rozruchu) do innego portu, reguła udev zostanie zignorowana. Symlink do w /dev/camera0
zasadzie mówi no such device
. Punkt wyjścia.
Chcemy powiązać dowiązanie symboliczne z adresem koncentratora USB, a nie video{x}
liczbą. Zajęło to program w języku Python.
Pierwszym krokiem było biec
fswebcam –d /dev/video${x} tst.jpg
dla x
między 1 i 8. Istnienie tst.jpg
po każdej rozmowie Określa, czy tam jest kamera wideo na ten numer. Z tego stwórz listę aktywnych numerów wideo. Moje doświadczenie jest takie, że jest to albo 0,1,2,3
lub 0,2,4,6
kamer użyłem.
Inni mogą oczywiście zbudować tę listę przy użyciu innego procesu.
Następnie dla każdego numeru wideo na liście uruchom
udevadm info –attribute-walk –path=/dev/videox > dd
i wyodrębnij KERNELS= line
z dd
. Z tego procesu powstaje lista adresów portów USB kamer. Posortuj tę listę, aby w następnym kroku zawsze przetwarzać ją w tej samej kolejności. Nazwij to „listą adresów”.
Uruchom program udevadm … > dd
ponownie i stwórz listę, która wygląda
KERNEL==”video0”, SUBSYSTEM=”video4linux”,KERNELS==”1:1.2.4:1.0 ”,SYMLINK+=”camerax”. Call this the “video list”.
Teraz przejdź przez listę adresów - dla każdego wpisu znajdź odpowiedni wpis z listy filmów. Utwórz nową listę, która wygląda jak zbiór linii takich jak
KERNEL==”video0”, SUBSYSTEM=”video4linux”,KERNELS==”1:1.2.4:1.0 ”,SYMLINK+=”camera2”
X (numer dowiązania symbolicznego) zostaje zastąpiony numerem kolejnym na liście adresów.
Teraz masz regułę udev, która działa. Dowiązanie symboliczne powiązane z adresem koncentratora USB bez względu na numer wideo przypisany do tego portu podczas uruchamiania.
Napisz ostateczną listę do pliku /etc/udev/rules.d/cam.rules
. Uruchom, udevadm trigger
aby go aktywować, a zadanie zostanie wykonane. /dev/camera2
będzie tą samą kamerą (port USB) niezależnie od numeru wideo.