Chargement de profils… selon l’endroit

Charger un profil colorimétrique selon l’endroit ousqu’on est. Oui, je sais, ça paraît bizarre : un ordinateur, un écran, un profil, et pis basta.

Sauf dans certains cas.

Il se trouve que je suis dans un de ces cas.

Historiquement, je travaillais le samedi et le dimanche. Histoire de ne pas être tout seul dans 200 m², et aussi pour m’éviter des heures inutiles de transport, je travaillais ces jours-là de chez moi. Et pour m’éviter les prises de tête genre « merde, j’ai besoin de ce fichier », je trimballais mon unité centrale avec moi.

En fait, j’utilise pour ce faire un ordinateur portable. Je le promène dans mon sac à dos quasiment en permanence, ce qui me permet de retrouver mon bureau et mes documents que je sois à la rédaction, à la maison ou en voyage. Mais un écran 15″ (1440×900 px), c’est un peu juste pour bosser : ce portable est donc, hormis en voyage, branché sur un écran.

À la rédaction comme chez moi, j’ai un Samsung F2380M, branché en DisplayPort-HDMI, et bosse en bi-écran avec le moniteur intégré du portable comme moniteur secondaire.

Or, bien que du même modèle, même avec des réglages identiques ou une calibration identique, les deux F2380M n’affichent pas la même chose. J’ai donc dû me résoudre à les étalonner séparément, n’ayant pu trouver de réglages donnant des résultats satisfaisants avec le même profil ICC. Je rentre pas dans le détail, il n’est pas exclu que ça fasse un article sur Lesnums un de ces quatre.

Le problème, ensuite, est simple : comment charger systématiquement, et aussi automatiquement que possible, le profil souhaité à chaque démarrage ? Comment faire que l’ordinateur choisisse le profil adapté au moniteur du bureau lorsqu’il j’y suis, au mien lorsque je me trouve à domicile, et pourquoi pas celui du portable quand je suis en voyage ?

La suite du billet est un long monologue geekesque et unixien. Ne lisez pas. Si vous lisez, ne vous plaignez pas. Vous êtes prévenus.

La réponse évidente serait : reconnaître le moniteur. Pour les voyages, pas de problème pour voir si le portable est seul : la taille de l’écran le dit.

Au bureau ou chez moi, en revanche, problème : l’écran externe est toujours un F2380M (et de toute façon, les pilotes propriétaires Nvidia masquent les moniteurs au système, qui ne voit qu’un « écran inconnu » de la taille cumulée des deux écrans branchés) et aucune différence de branchement ne permet de reconnaître lequel. Impossible donc d’identifier clairement le moniteur du bureau ou le mien, à moins que vous ne connaissiez un outil pour récupérer en ligne de commande le numéro de série du moniteur branché.

Il me faut donc un élément constant, différent chez moi et au bureau. Les périphériques pourraient l’être, mais je puis changer de souris ou de clavier plus ou moins régulièrement, donc ce n’est pas fiable.

J’ai jeté mon dévolu sur le réseau. En effet, le réseau des Nums est toujours le même, et mon réseau chez moi aussi ; l’un ou l’autre peut changer un jour (choix d’un autre FAI, interruption de service…), mais ça n’arrivera pas tous les quatre matins. Il y a différentes façons de savoir sur quel réseau on est, la plus simple étant de demander à des sites spécialisés qui vous diront tout, mais cette solution pose un problème potentiel (qui ne s’est jamais produit à ce jour, mais sait-on jamais) : si je me branche chez quelqu’un qui a le même FAI que moi ou la rédac et se situe géographiquement un peu près, il n’y a plus de moyen de les distinguer.

Un truc sûr, c’est donc : c’est qui ma box ?

À ce stade, l’objectif est simple : trouver l’adresse MAC de mon routeur. Cet identifiant ne change en principe pas et est spécifique à un modem donné.

C’est tout con, en fait, mais ça m’a demandé pas mal de recherches vu que j’ai pas une grande expérience de ce domaine (pour ceux qui ne l’auraient pas compris pas, ce billet est surtout une anti-sèche pour pas avoir à trop réfléchir si pour une raison quelconque je devais refaire ça). Pour récupérer l’adresse MAC du routeur, il suffit d’une seule commande sous Linux (doit marcher dans n’importe quel Unix, en fait, je pense) :

arp `route | grep default | awk '{print $2}'` | tail -n 1 | awk '{print $3}'

Pour ceux qui ne parlent pas le Bourne Shell couramment, décomposons :

La commande de base, c’est « route ». Elle permet de connaître les routages appliqués au réseau local, et en particulier la route par défaut (« grep default »). On va récupérer un truc du genre « default         192.168.0.1     0.0.0.0         UG    0      0        0 eth0 », qui dit : pour les adresses inconnues, demandez à la passerelle sur 192.168.0.1. Un petit coup de awk permet de récupérer juste l’adresse IP de la passerelle.

Mais une adresse IPv4 locale, c’est ambigu. Y’a sans doute plein de réseaux dont la passerelle répond à cette adresse. L’objectif, je l’ai dit, est d’identifier spécifiquement le routeur du bureau ou le routeur du studio, et rien d’autre.

Donc, on passe par « arp », qui permet de trouver l’adresse MAC (unique) associée à une adresse IP. Un coup de tail pour récupérer la dernière ligne (au-dessus, arp affiche un en-tête de tableau qui ne nous intéresse pas), puis un coup de awk pour n’avoir plus que l’adresse MAC, et ça y est : j’ai un identifiant de réseau qui non seulement n’est pas le même sur la Freebox du bureau et le modem de chez moi, mais ne sera pas la même sur une autre Freebox même située dans le bâtiment, et qui en revanche sera toujours la même pour la Freebox souhaitée même en cas de redémarrage.

Après, y’a plus qu’à habiller un peu tout ça, pour charger les profils qu’on veut selon les cas. À l’heure actuelle, le script complet, que j’ai rajouté dans la liste de lancement au démarrage de Gnome, ressemble à ça :

#!/bin/sh
sleep 10 #attendre que les préférences Nvidia soient chargées, sinon elles virent le profil... -_-
date >> .profil.log
if xrandr 2> /dev/null | grep "3360 x 900"
then
		echo "	Portable seul" >> .profil.log
		xcalib .color/icc/Screen 2 2010-11-22 max D6500 min natif 2.2 HQ 1xCurve+MTX.icc	#profil Dell
else
	until ifconfig eth0 | grep "inet adr:" > /dev/null	#attendre que le réseau soit connecté
	do
		sleep 5
	done

	macrouteur=`arp `route | grep default | awk '{print $2}'` | tail -n 1 | awk '{print $3}'`
	if test "$macrouteur" = "00:1f:33:xx.xx.xx"	#modem Numéricable
	then
		echo "	Réseau Meezon" >> .profil.log
		xcalib .color/icc/LPL 2010-12-14 max D6000 min natif 2.2 HQ 1xCurve+MTX.icc	#profil Samsung meezon
	elif test "$macrouteur" = "00:07:cb:xx.xx.xx"	#Freebox Lesnums
	then
		echo "	Réseau Free Lesnums" >> .profil.log
		xcalib .color/icc/LPL 2010-12-15 max D6000 min natif 2.2 HQ 1xCurve+MTX.icc	#profil Samsung boulot
	else
		echo "	Pas de position identifiée" >> .profil.log
		xcalib .color/icc/Screen 2 2010-11-22 max D6500 min natif 2.2 HQ 1xCurve+MTX.icc	#profil Dell
	fi
fi

Il y a peut-être plus élégant, mais ça fonctionne.