Проблема з декількома ідентичними 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-портом) незалежно від її номера відео.