Проблема с несколькими идентичными USB-устройствами
У меня есть Rasperry Pi с четырьмя камерами. Я принимаю пикс с fswebcamкоторой идентифицирует камеры , как /dev/video0.. video3. Иногда камера video0, vide02, video4и , video6но мы можем забыть о том, что на данный момент.
Мне нужен постоянный идентификатор для идентификации номера камеры, чтобы, например video0, всегда была одна и та же камера, потому что я подписываю снимки. К сожалению, это не происходит надежно - при загрузке камеры перечисляются как video0... video3но не всегда одинаково.
Все камеры имеют одинаковый идентификатор и серийный номер.
Решение этой проблемы включает в себя правила udev, но там также есть много рыболовных крючков.
Если вы выполните команду
udevadm info –attribute-walk –path=/dev/video0
вы получаете разметку выходных данных, но выдающиеся биты
KERNEL=”video0”, SUBSYSTEM=”video4linux” and KERNELS=”1:1.2.4:1.0”.
Бит KERNELS - это порт USB-концентратора. С четырьмя камерами их четыре - они не меняются при перезагрузке, но video{x}связанные с портом могут измениться.
Поэтому нам нужно правило udev для привязки номера видео к порту USB-концентратора - что-то вроде:
KERNEL==”video0”,SUBSYSTEM=”video4linux”,KERNELS==”1:1.2.4:1.0”,SYMLINK+=”camera0”
Выглядит просто - доступ к камере с
fswebcam –d $realpath /dev/camera0
За исключением того, что это не работает - если вы поместите это в правило udev, и система выделит video0 (при загрузке) для другого порта, правило udev игнорируется. Символьная ссылка в /dev/camera0основном говорит no such device. Квадратная.
Мы хотим связать символическую ссылку с адресом USB-концентратора, а не с video{x}номером. Потребовалась программа на Python.
Первый шаг должен был бежать
fswebcam –d /dev/video${x} tst.jpg
для xмежду 1 и 8. Существование tst.jpgпосле каждого вызова идентифицирует есть ли камера на этом видео числом. Из этого сделайте список активных видео номеров. Мой опыт показывает, что это либо 0,1,2,3или 0,2,4,6для камер я использовал.
Другие могут, конечно, построить этот список, используя другой процесс.
Затем для каждого номера видео в списке запустить
udevadm info –attribute-walk –path=/dev/videox > dd
и извлечь KERNELS= lineиз dd. В результате вы получите список адресов портов USB для камер. Сортируйте этот список так, чтобы на следующем шаге вы всегда обрабатывали его в одном и том же порядке. Назовите это «список адресов».
Запустите udevadm … > ddвещь снова и создайте список, который выглядит как
KERNEL==”video0”, SUBSYSTEM=”video4linux”,KERNELS==”1:1.2.4:1.0 ”,SYMLINK+=”camerax”. Call this the “video list”.
Теперь пройдитесь по списку адресов - для каждой записи найдите соответствующую запись из списка видео. Создайте новый список, который выглядит как набор строк, таких как
KERNEL==”video0”, SUBSYSTEM=”video4linux”,KERNELS==”1:1.2.4:1.0 ”,SYMLINK+=”camera2”
Символ x (номер символической ссылки) заменяется порядковым номером в списке адресов.
Теперь у вас есть правило udev, которое работает. Символическая ссылка, привязанная к адресу концентратора USB, независимо от того, какой номер видео выделен этому порту при загрузке.
Запишите окончательный список в файл /etc/udev/rules.d/cam.rules. Запустите, udevadm triggerчтобы активировать его, и работа сделана. /dev/camera2будет одна и та же камера (порт USB) независимо от ее номера видео.