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