Donner un nom persistant aux devices USB




Lorsqu'un équipement (device) USB est connecté au Raspberry, Linux attribue à ce dernier un nom équivalent à un nom de fichier dans le répertoire /dev. Par exemple ttyUSB0.
Ce nom permet au système d’accéder au matériel. Mais lorsque l'on reconnecte le device, ou quand le système reboot, ce nom peut changer. Ce qui peut engendrer des perturbations de notre serveur domoticz car ce dernier accède au matériel en utilisant ces noms donnés par le système.



Dans le cadre de mon programme de fiabilisation d'une solution domotique, je vais essayer de donner un nom persistant à chaque équipement connecté en USB, afin de pouvoir rebooter mon Raspberry (chéri) sans perturbations pour Domoticz. 


La suite après la réclame ...



Putty est notre ami



Il va falloir se connecter en SSH sur le raspberry car toutes les commandes vont se faire en mode console.

La commande à utiliser pour avoir des informations sur un périphérique connecté en USB est :
sudo udevadm info --query=all --name=/dev/DEVICE

Remplacer DEVICE par le nom du périphérique. Exemple : ttyUSB1.



On voit sur le résultat de cette commande que le champ ID_VENDOR correspond à RFXCOM. 
On peut donc facilement en déduire que ttyUSB1 correspond au matériel RFXtrx433e.


C'est à ce moment que je commence à me poser des questions.



Certains périphériques USB n'ont pas d'alias en ttyUSB mais sont parfois nommé:

  • /dev/sda : cas des équipements de stockage
  • /dev/ttyAMA ou /dev/ttyACM : cas des équipements connectés en USB mais échangeant des données sur la base de normes de communications spécifiques.



Après avoir fait quelques recherche sur la différence de nommage de ces périphériques USB, j'en ai déduit que c'est quelque chose d'assez technique et qui n'a pas vraiment d’intérêt dans le cadre de cet article car au final le comportement de chacun va être le même quel que soit le type d'alias attribué par le système.

La question qui se pose donc alors étant de savoir comment repérer tous les périphériques USB pour fixer leur nom dans le système.

Je n'ai pas trouvé de solution miracle ou automatisée. Il va donc falloir procéder à la main et par élimination.


Liste des périphériques USB


Pour commencer je vais établir la liste des périphériques dont je veux forcer le nommage.
Il s'agit tout simplement de tous les périphériques raccordés en USB sur mon RPI :

  • Une clé ZWAVE "Everspring SA413"
  • Un RFXCOM - Transmetteur RFXtrx433E
  • Un module USB Téléinformation EDF GCE Electronics
  • Un Hub USB BELKIN F5U021 sur lequel j'ai :
  • Une Clé USB 4G
  • Un Arduino
  • Un Samsug Naos.


Ce qui nous fait un total de 7 équipements.

Quand je fais la liste des périphériques identifiés sous ttyUSB, ttyAMA, ttyACM ou sda j'obtiens :

  • USB0 et USB1
  • ACM0, ACM1 et ACM2
  • AMA0
  • sda et sda1


Si je considère que sda1 est une partition de sda, donc le même équipement, j'obtiens 7 périphériques. Je les ais donc tous bien identifiés.


On commence par les devices en USB


Pour chacun des devices ttyUSB0 et ttyUSB1 je lance la commande udevadm vue ci-dessus.
Et dans les résultats j'essaie de chercher à quoi cela correspond.

Pour USB1 c'est simple car j'ai ID_VENDOR=RFXCOM. Il s'agit donc du module RFXtrx433E.

Pour USB0 c'est plus compliqué car les informations que je reçois ne correspondent à rien que je ne connaisse de ma solution. Par contre en regardant dans l'interface web domoticz je vois que le port ttyUSB0 est associé au module de téléinformation EDF.

J'ai donc réussi à identifier tous les devices en ttyUSB. Il va falloir maintenant leur donner un nom.

Pour cela il va falloir écrire des règles dans le fichier /etc/udev/rules.d/99-usb-serial.rules


Note du 12/11/2017 : J'ai choisi d'ajouter les regles de gestion dans le fichier nommé 99-usb-serial.rules car c'est ce nom qui ressortais le plus souvent sur les différents documents que j'ai lu.
Toutefois, le système va lire et traiter tous les fichiers qui se trouvent dans le répertoire rules.d par ordre alphabétique. J'aurais donc très bien pu choisir un autre nom comme par exemple : 10-domoticz.rules (merci à pigloox du forum domoticz).


En faisant des recherches il y a plusieurs formes possibles pour ces règles.
Je ne vais pas détailler ici ces mécanismes de gestion au niveau du système.
Ce qu'il faut savoir c'est que chaque règle doit déterminer de manière unique un device en précisant des attributs et ensuite elle permet d'affecter un alias.

Le type de regle qui me parait la plus précise et la plus fiable pour déterminer de manière unique le périphérique, se base sur les attributs idVendor, idProduct et serial. 
Ces attributs sont accessibles par la commande :
sudo lsusb -v |more

Pour retrouver les attributs qui correspondent à l'alias du device que nous avons identifié précédemment c'est un peu compliqué car il faut jongler entre les commande linux.
Pour ma part j'ai fait le lien sur la base de l'identifiant ID_SERIAL_SHORT de la commande udevadm et iSerial de la commande lsusb.

Au final j'ai réussi à trouver les élément suivants :

Port actuel = /dev/ttyUSB1
ID_SERIAL_SHORT = iSerial = A1LQ5BM
idVendor = 0403
idProduct = 6001

Remarque : cette manipulation en passant par l'identifiant iSerial est nécessaire car pour le device sur USB1 j'ai les mêmes codes Vendor et Product.

La ligne de commande que je vais ajouter au fichier /etc/udev/rules.d/99-usb-serial.rules sera :

SUBSYSTEM=="tty", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", ATTRS{serial}=="A1LQ5BM", SYMLINK+="ttyUSB-RFX433-1"


Note au 12/11/2017 : à priori c'est cette forme qu'il faut utiliser obligatoire sous Raspbian Stretch car le tag ENV{} ne fonctionne plus. 

J'ai ajouté cette ligne en début du fichier car lors d'un premier essais cela n'a pas fonctionné en l'ajoutant à la fin.

Ensuite on reboot :
sudo shutdown -r now

Une fois reconnecté avec la commande :
ls -al /dev/ttyUSB*

On voit :




Nous avons bien un lien. Il ne reste plus qu'à associer ce lien à l'équipement RFX dans l'interface web domoticz :




Je vais faire la même manipulation avec le port USB0 qui correspond au teleinfo EDF.


Port actuel = /dev/ttyUSB0
ID_SERIAL_SHORT = iSerial = A702OS2T
idVendor = 0403
idProduct = 6001

J'ajouterais donc la ligne dans le meme fichier en dessous de la première :
SUBSYSTEM=="tty", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", ATTRS{serial}=="A702OS2T", SYMLINK+="ttyUSB-EDF-1"

Et le tour est joué :





La suite après la réclame ...



Passons aux devices ACM


D'emblée on constate dans l'interface domoticz que le port ACM0 correspond à la clé ZWAVE.
Pourtant après les reboot successifs que j'ai réalisé, je constate que le bouton réglage est en rouge ! 
Ce qui signifie un problème sur le ZWAVE ! Voici par l'exemple ce que nous sommes en train de faire va corriger ! Au reboot, la clé zwave a été associée au port ACM1. Je le constate avec la commande udevcmd info sur ce port.
Par contre, avec lsusb, je ne récupère pas de code iSerial pour cet équipement. Il va donc falloir modifier un peu la règle pour n'utiliser que les identifiants idVendor et idProduct. Ce qui n'est pas génant car ce binome d'identifiants est unique.

Je vais donc ajouter :
SUBSYSTEM=="tty", ATTRS{idVendor}=="0658", ATTRS{idProduct}=="0200", SYMLINK+="ttyACM-Zwave-1"

Après reboot nous obtenons bien le lien dans /dev et sous domoticz nous pouvons associer à nouveau notre périphérique zwave à un port fixe :




Avec la commande udevadm je détermine que ACM0 correspond à mon arduino.
Je recherche les identifiants correspondants. J'obtiens :

Port actuel = /dev/ttyACM0
ID_SERIAL_SHORT = iSerial = 55639313633351D021E2
idVendor = 2341
idProduct = 0001

Et en regardant ACM2 :
D_SERIAL_SHORT = iSerial = 644203845c86
idVendor = 04e8
idProduct = 6877

Je vais ajouter les regles suivantes :
SUBSYSTEM=="tty", ATTRS{idVendor}=="2341", ATTRS{idProduct}=="0001", ATTRS{serial}=="55639313633351D021E2", SYMLINK+="ttyACM-Arduino-1"
SUBSYSTEM=="tty", ATTRS{idVendor}=="04e8", ATTRS{idProduct}=="6877", ATTRS{serial}=="644203845c86", SYMLINK+="ttyACM-Naos"

Et on reboot.

Au bilan nous avons quasiment identifié tous les équipements et attribué un port fixe.

  • Une clé ZWAVE "Everspring SA413" : ttyACM-Zwave-1
  • Un RFXCOM - Transmetteur RFXtrx433E : ttyUSB-RFX433-1
  • Un module USB Téléinformation EDF GCE Electronics : ttyUSB-EDF-1
  • Un Hub USB BELKIN F5U021 :
  • Une Clé USB 4G : sda
  • Un Arduino : ttyACM-Arduino-1
  • Un Samsug Naos : ttyACM-Naos



Et le port AMA ?



Parmis la liste des alias des équipement USB, il en reste un qui n'a pas été identifié : /dev/ttyAMA0.
Etant donné que le seul matériel connecté en USB qui n'a pas encore d'alias est le HUB USB, on peut supposer que ttyAMA0 correspond à ce dernier. Toutefois il n'est pas simple de vérifier que c'est bien le cas. Mais il n'est pas utile de donner un nom fixe pour cet équipement car il n'est pas vu par le serveur domoticz. Je ne pousserai donc pas plus loin mes recherches.


La conclusion



J'ai finalement réussi à attribuer un nom spécifique et parlant à chacun des ports des devices connectés en USB à mon RPI. Après plusieurs reboot on constate la stabilité du système qui reconnais désormais systématiquement les devices.

Pour finaliser ce premier pas dans l'amélioration de la fiabilité de la solution, il me reste à programmer un reboot du système régulier. Je n'ai pas encore défini la fréquence optimum de ce reboot. Pour commencer je vais le programmer toutes les nuits à 3h00.
Pour cela il faut ajouter la ligne suivante dans le fichier /etc/crontab :

# reboot a 3h00 tous les jours
0 3 * * * root /home/pi/Prog/Bash/amd_reboot.sh

Je précise qu'en fonction des systèmes utilisés, le système crontab peut être géré de manière différente. Par exemple, le fichier /etc/crontab n'existe peut etre pas et dans ce cas il faudra utiliser la commande : sudo crontab -e pour ajouter la ligne. En supprimant la référence à l'utilisateur root.

Dans cette ligne je demande à ce que le script amd_reboot.sh soit executé à 3h tous les jours.
Je préfère passer par un script car cela me permettra d'ajouter d'autres actions au reboot. 
Comme par exemple faire une sauvegarde du système.


Merci aux auteurs des sites suivants pour toutes les informations qui m'ont aidées à écrire cet article :


https://blog.domadoo.fr/34982-utilisation-de-domoticz-avec-le-z-wave/
https://www.latelierdugeek.fr/2015/02/02/domotique-partie-8-ajout-du-support-du-z-wave-dans-domoticz/
https://easydomoticz.com/mon-premier-peripherique-z-wave/
http://www.domoticz.com/wiki/PersistentUSBDevices
Note au 12/11/2017 : Pour plus d'informations sur le système de gestion des "udev rules" :
http://www.reactivated.net/writing_udev_rules.html




Soutenez la blogoculture ...


Le plus simplement du monde, si vous avez un achat à faire sur Amazon, accédez au site à partir de ce lien (que vous pouvez ajouter dans vos favoris)https://amzn.to/2nbe4sm





Soutenez la blogoculture ...


Le plus simplement du monde, si vous avez un achat à faire sur Amazon, accédez au site à partir de ce lien (que vous pouvez ajouter dans vos favoris)https://amzn.to/2nbe4sm


... mais aussi ...


Vous appréciez les articles frais et vitaminés de ce blog et vous voulez faire un geste pour encourager ce partage, saluer le travail, ou parce que vous y avez trouvé des choses utiles ( et que vous êtes sympa ) ?

... c'est possible et vous avez le choix !
Si vous avez un compte Paypal et quelques euros à offrir sans vous mettre sur la paille, subventionnez la culture domotique à l'ancienne !
Vous ne dépenserez pas un radis de plus en faisant un achat sur eBay à partir de ce lien.
Economisez du blé avec Amazon Prime ! Offre d'essais 1 mois gratuit (et renouvelable).
Soyez chou et aidez les petits producteurs de blog à se faire connaitre auprès de vos amis facebook !

Merci

Commentaires