Il problema con più dispositivi USB identici
Ho un Rasperry Pi con quattro telecamere. Prendo pix con fswebcamche individua le telecamere come /dev/video0.. video3. A volte la fotocamera è video0, vide02, video4e video6ma possiamo dimenticare che per ora.
Ho bisogno di un ID persistente per identificare un numero di telecamera in modo che, ad esempio, video0sia sempre la stessa telecamera perché inserisco le didascalie delle immagini. Sfortunatamente questo non accade in modo affidabile: all'avvio, le telecamere vengono elencate come video0.. video3ma non sempre allo stesso modo.
Tutte le telecamere hanno lo stesso ID e numero di serie.
La soluzione a questo problema riguarda le regole di udev, ma ci sono anche molti ami.
Se si emette il comando
udevadm info –attribute-walk –path=/dev/video0
ottieni un massetto di output ma i bit salienti lo sono
KERNEL=”video0”, SUBSYSTEM=”video4linux” and KERNELS=”1:1.2.4:1.0”.
Il bit KERNELS è una porta hub USB. Con quattro telecamere ce ne sono quattro: non cambiano al riavvio, ma le video{x}porte associate possono cambiare.
Quindi abbiamo bisogno di una regola udev per legare un numero video a una porta hub USB - qualcosa del tipo:
KERNEL==”video0”,SUBSYSTEM=”video4linux”,KERNELS==”1:1.2.4:1.0”,SYMLINK+=”camera0”
Sembra semplice: accedi alla videocamera con
fswebcam –d $realpath /dev/camera0
Tranne che non funziona: se lo inserisci in una regola udev e il sistema ha allocato video0 (all'avvio) su una porta diversa, la regola udev viene ignorata. Il link simbolico /dev/camera0dice sostanzialmente no such device. Square one.
Ciò che vogliamo è associare un collegamento simbolico a un indirizzo hub USB, non a un video{x}numero. Ci è voluto un programma Python.
Il primo passo è stato correre
fswebcam –d /dev/video${x} tst.jpg
per xtra 1 e 8. L'esistenza di tst.jpgdopo ogni chiamata identifica se v'è una fotocamera a questo numero video. Da questo crea un elenco di numeri di video attivi. La mia esperienza è stata che è 0,1,2,3o 0,2,4,6per le fotocamere che ho usato.
Altri possono ovviamente compilare questo elenco usando un processo diverso.
Quindi, per ogni numero di video nell'elenco eseguire
udevadm info –attribute-walk –path=/dev/videox > dd
ed estrarre il KERNELS= lineda dd. Da questo processo si finisce con un elenco degli indirizzi delle porte USB per le telecamere. Ordina questo elenco in modo che al passaggio successivo, lo elabori sempre nello stesso ordine. Chiamalo "elenco indirizzi".
Esegui di udevadm … > ddnuovo la cosa e crea un elenco simile
KERNEL==”video0”, SUBSYSTEM=”video4linux”,KERNELS==”1:1.2.4:1.0 ”,SYMLINK+=”camerax”. Call this the “video list”.
Ora passa attraverso l'elenco degli indirizzi - per ogni voce trova la voce corrispondente dall'elenco dei video. Crea un nuovo elenco che assomigli a una raccolta di linee simili
KERNEL==”video0”, SUBSYSTEM=”video4linux”,KERNELS==”1:1.2.4:1.0 ”,SYMLINK+=”camera2”
La x (numero del collegamento simbolico) è sostituita dal numero di sequenza nell'elenco indirizzi.
Ora hai una regola udev che funziona. Un collegamento simbolico collegato a un indirizzo hub USB, indipendentemente dal numero di video assegnato a quella porta all'avvio.
Scrivi l'elenco finale in un file /etc/udev/rules.d/cam.rules. Esegui udevadm triggerper attivarlo e il lavoro è fatto. /dev/camera2sarà la stessa fotocamera (porta USB) indipendentemente dal suo numero video.