<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Le blog de fpicard.tech</title><description>Ce qui se monte dans mon lab : preuves de concept, infrastructure, auto-hébergement — et les idées qui ne sont encore que des idées.</description><link>https://blog.fpicard.tech/</link><language>fr-FR</language><copyright>CC BY-SA 4.0</copyright><item><title>Un panneau mural sans clavier</title><link>https://blog.fpicard.tech/articles/panneau-mural-sans-clavier/</link><guid isPermaLink="true">https://blog.fpicard.tech/articles/panneau-mural-sans-clavier/</guid><description>Une dalle bandeau de 1480 × 320 sur un mur, un Raspberry Pi derrière, et personne pour débuguer quand ça casse. Cette dernière contrainte a décidé de tout le reste.</description><pubDate>Fri, 23 Oct 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Le point de départ de ce projet n’est pas une idée. C’est une déception.&lt;/p&gt;
&lt;p&gt;Le &lt;strong&gt;&lt;a href=&quot;https://www.corsair.com/fr/fr/p/monitors/cc-9011357-ww/corsair-xeneon-edge-14-5-lcd-touchscreen-smoke-cc-9011357-ww&quot;&gt;Corsair Xeneon Edge&lt;/a&gt;&lt;/strong&gt;
m’a fait de l’œil pendant des semaines. Une dalle bandeau de 14,5 pouces,
2560 × 720 en 32:9, tactile cinq points, quatorze aimants intégrés pour la
coller sur n’importe quelle surface en acier, 259,90 €. Exactement l’objet que
je cherchais, fini, garanti trois ans.&lt;/p&gt;
&lt;figure class=&quot;media media--image&quot;&gt;&lt;img alt=&quot;Les deux dalles à l&amp;#39;échelle, et ce qu&amp;#39;il faut derrière chacune&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; width=&quot;1600&quot; height=&quot;875&quot; src=&quot;https://blog.fpicard.tech/_astro/deux-bandeaux.C_NlRhjS_1Qgawo.webp&quot;&gt;&lt;figcaption&gt;Les deux bandeaux, à l&apos;échelle de leurs diagonales annoncées. Le Corsair est le plus grand des deux — et c&apos;est la colonne de droite qui a décidé.&lt;/figcaption&gt;&lt;/figure&gt;
&lt;p&gt;Puis j’ai lu ce qu’il fait vraiment.&lt;/p&gt;
&lt;p&gt;Ce n’est pas un appareil, &lt;strong&gt;c’est un deuxième écran&lt;/strong&gt;. Corsair le classe
lui-même en &lt;em&gt;auxiliary display&lt;/em&gt; et en &lt;em&gt;secondary display&lt;/em&gt; : il a une entrée
HDMI, une entrée USB-C en DP Alt-Mode, et rien d’autre. Tout ce qu’il affiche
est calculé par une machine qui doit être allumée.&lt;/p&gt;
&lt;p&gt;Les widgets, alors ? Ils viennent d’iCUE. La FAQ de Corsair est d’une honnêteté
désarmante :&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;You do not need iCUE to use the XENEON EDGE.&lt;/em&gt; […] &lt;em&gt;Without iCUE, the XENEON
EDGE will simply work as an additional monitor.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Autrement dit : la couche qui en fait un tableau de bord &lt;strong&gt;est&lt;/strong&gt; iCUE. Sans
elle, c’est un moniteur. Et les widgets d’iCUE se téléchargent sur le marché
d’Elgato, où ils portent tous la même étiquette — &lt;strong&gt;Windows only&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Le compte est vite fait. Pour afficher l’heure sur un mur, il faut un PC
Windows allumé en permanence. L’écran, lui, ne sait rien faire seul : ni au
réveil, ni après une coupure, ni quand le PC est éteint.&lt;/p&gt;
&lt;aside class=&quot;encadre encadre--note&quot; role=&quot;note&quot;&gt;&lt;p class=&quot;encadre__titre&quot;&gt;Note&lt;/p&gt;&lt;p&gt;Je ne reproche pas à Corsair de mentir — leur documentation dit exactement ce
que fait le produit, et pour un joueur qui a déjà une tour Windows sous le
bureau à côté, l’objet est sans doute très bien.&lt;/p&gt;&lt;p&gt;Simplement, ce n’était pas mon besoin. Je ne voulais pas un deuxième écran. Je
voulais un &lt;strong&gt;appareil&lt;/strong&gt;.&lt;/p&gt;&lt;/aside&gt;
&lt;h2 id=&quot;donc-le-faire&quot;&gt;Donc, le faire&lt;/h2&gt;
&lt;p&gt;Il y a un mur dans mon bureau où il ne se passait rien, et je voulais un écran
qui tienne dessus sans avoir l’air d’un écran — autonome, allumé en
permanence, sans rien d’autre derrière.&lt;/p&gt;
&lt;p&gt;Le format, lui, ne se négociait pas : une dalle bandeau. J’ai pris une
&lt;strong&gt;Waveshare 11,9 pouces en DSI&lt;/strong&gt; à &lt;strong&gt;130,99 €&lt;/strong&gt; — 320 × 1480 natif, tournée en
paysage, donc &lt;strong&gt;1480 pixels de large sur 320 de haut&lt;/strong&gt;. Un ratio de 4,6 pour 1.
Pas de carte-mère, pas de logiciel, pas d’écosystème : une dalle nue et une
nappe, que le Raspberry Pi pilote directement.&lt;/p&gt;
&lt;p&gt;Le Raspberry Pi, je l’avais déjà — un 4B qui ne servait plus. Avec
l’alimentation officielle 27 W, 19,84 €, et on verra plus loin pourquoi elle
n’était pas facultative, le panneau m’aura donc coûté &lt;strong&gt;150,83 €&lt;/strong&gt; contre
259,90 € pour le Corsair.&lt;/p&gt;
&lt;p&gt;Ce n’est pas ce qui m’a décidé, et je ne compte pas les trois semaines. Mais
sortir une carte d’un tiroir pour obtenir l’objet qu’un produit fini ne savait
pas être, c’est une satisfaction à part.&lt;/p&gt;
&lt;p&gt;Rien n’est conçu pour ce format. Aucun thème, aucune grille, aucun tableau de
bord. Les projets de miroir connecté supposent tous un écran vertical ou un
16/9. J’ai donc écrit le mien.&lt;/p&gt;
&lt;figure class=&quot;media media--image&quot;&gt;&lt;img alt=&quot;Le panneau posé sur un bureau, entre une bouilloire et un pot à crayons&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; width=&quot;2000&quot; height=&quot;1500&quot; src=&quot;https://blog.fpicard.tech/_astro/panneau-echelle.CGsKdWL3_ZpqWeR.webp&quot;&gt;&lt;figcaption&gt;4,6 pour 1, sur un bureau ordinaire. C&apos;est la proportion qui explique tout le reste : trois tuiles de front, et rien au-dessus ni en dessous.&lt;/figcaption&gt;&lt;/figure&gt;
&lt;p&gt;Mais ce n’est pas le format qui a été structurant. C’est autre chose, que je
n’avais pas vu venir : &lt;strong&gt;l’appareil n’a pas de clavier&lt;/strong&gt;, et ses lecteurs
principaux sont mes enfants. Personne, devant ce mur, ne lira jamais un message
d’erreur pour en faire quelque chose.&lt;/p&gt;
&lt;aside class=&quot;encadre encadre--info&quot; role=&quot;note&quot;&gt;&lt;p class=&quot;encadre__titre&quot;&gt;Bon à savoir&lt;/p&gt;&lt;p&gt;Ce POC couvre le logiciel et l’assemblage électrique. Le &lt;strong&gt;boîtier imprimé&lt;/strong&gt; en
est absent : les cotes sont relevées, le dessin est en cours, ce sera un autre
article.&lt;/p&gt;&lt;p&gt;Ce qui veut dire que le panneau mural n’est, à l’heure où j’écris, &lt;strong&gt;pas encore
au mur&lt;/strong&gt;. Il fonctionne, il tourne tous les jours, et il est posé sur un socle
à smartphone en bois acheté chez Ikea. On fera avec.&lt;/p&gt;&lt;/aside&gt;
&lt;h2 id=&quot;trois-semaines-291-commits&quot;&gt;Trois semaines, 291 commits&lt;/h2&gt;
&lt;p&gt;Le dépôt commence le &lt;strong&gt;26 août 2026&lt;/strong&gt; et la dernière version date du
&lt;strong&gt;21 septembre&lt;/strong&gt;. Entre les deux, 291 commits — dont 49 le premier jour, 45 le
deuxième, 36 le troisième.&lt;/p&gt;
&lt;p&gt;Quarante-neuf commits en un jour, ça demande une explication, et je préfère la
donner tout de suite : &lt;strong&gt;je n’ai pas écrit ce code tout seul.&lt;/strong&gt; Je l’ai écrit
avec une IA, en conversation, pendant trois semaines. C’est ce qu’on appelle
maintenant du &lt;em&gt;vibecoding&lt;/em&gt;, et j’y reviens à la fin — parce que c’est sans doute
ce qu’il y a de plus intéressant dans ce projet.&lt;/p&gt;
&lt;p&gt;Le rythme a aussi une raison matérielle : &lt;strong&gt;la dalle n’est arrivée que le
4 septembre.&lt;/strong&gt; Pendant la première semaine, j’ai développé
contre une géométrie que je n’avais pas, dans une fenêtre de navigateur
redimensionnée à la main. Tout ce qui pouvait se décider sans le matériel a été
décidé à ce moment-là, et c’est probablement ce qui a sauvé le projet : quand la
dalle est arrivée, il restait &lt;strong&gt;un seul réglage&lt;/strong&gt; à faire, l’orientation.&lt;/p&gt;
&lt;p&gt;Les quatre lignes que j’avais écrites dans ma feuille de route avant la
livraison valent d’être relues avec ce qui s’est réellement passé :&lt;/p&gt;

























&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Ce qui était prévu&lt;/th&gt;&lt;th&gt;Ce qui s’est passé&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;Rotation par &lt;code&gt;video=HDMI-A-1:…rotate=90&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;écartée par la mesure&lt;/strong&gt; — trois voies essayées, aucune ne fonctionne en KMS&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Matrice de calibration tactile par règle udev&lt;/td&gt;&lt;td&gt;&lt;strong&gt;inutile&lt;/strong&gt; — le compositeur applique la même transformation au tactile&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Sous-tension à régler avant de brancher&lt;/td&gt;&lt;td&gt;&lt;strong&gt;disparue&lt;/strong&gt; — la dalle alimente le Pi&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;« La dalle tire son 5 V du rail du Pi »&lt;/td&gt;&lt;td&gt;&lt;strong&gt;faux&lt;/strong&gt; — la nappe DSI ne porte que la vidéo et l’I²C&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;Quatre prévisions, quatre erreurs. Aucune n’a coûté cher parce qu’aucune n’avait
été implémentée avant d’être mesurée.&lt;/p&gt;
&lt;h2 id=&quot;un-écran-sans-clavier-change-tout&quot;&gt;Un écran sans clavier change tout&lt;/h2&gt;
&lt;p&gt;C’est la règle dont tout découle, et je l’ai écrite en tête du dépôt :&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Dégradé, jamais blanc.&lt;/strong&gt; Une coupure réseau grise une tuile, elle ne vide
pas l’écran. Un layout fautif rend les tuiles valides et grise la fautive avec
son message. Un certificat absent laisse l’administration en HTTP plutôt que
de la rendre injoignable.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Formulé autrement : tout ce qui peut échouer doit échouer &lt;strong&gt;en affichant encore
quelque chose&lt;/strong&gt;. Sur un poste de travail, une page blanche est une invitation à
ouvrir la console. Sur un mur, c’est un appareil mort.&lt;/p&gt;
&lt;p&gt;J’ai appris la différence le 27 août, et de la pire manière.&lt;/p&gt;
&lt;aside class=&quot;encadre encadre--piege&quot; role=&quot;note&quot;&gt;&lt;p class=&quot;encadre__titre&quot;&gt;Le kiosque n’attendait pas que le serveur réponde&lt;/p&gt;&lt;p&gt;L’unité systemd du kiosque portait &lt;code&gt;After=caddy.service&lt;/code&gt;. Ça paraît suffisant.
Ça ne l’est pas : systemd considère Caddy démarré &lt;strong&gt;avant qu’il n’écoute&lt;/strong&gt;.&lt;/p&gt;&lt;p&gt;Chromium reçoit alors un refus de connexion, affiche « The site can’t be
reached »… et &lt;strong&gt;n’essaie plus jamais&lt;/strong&gt;.&lt;/p&gt;&lt;p&gt;Un déploiement a relancé le kiosque pendant un rechargement de Caddy. Le serveur
répondait &lt;code&gt;200&lt;/code&gt;. L’afficheur, lui, est resté sur son message d’erreur.&lt;/p&gt;&lt;p&gt;Sur un panneau mural sans clavier, après une coupure de courant, c’est un écran
mort &lt;strong&gt;jusqu’à intervention physique&lt;/strong&gt;.&lt;/p&gt;&lt;/aside&gt;
&lt;p&gt;La correction tient en trois lignes, et elle m’a coûté une soirée à comprendre :&lt;/p&gt;
&lt;figure class=&quot;bloc-code&quot;&gt;&lt;figcaption class=&quot;bloc-code__titre&quot;&gt;deploy/etc/kiosk.service&lt;/figcaption&gt;&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;ini&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;[Service]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# systemd considere Caddy demarre avant qu&apos;il n&apos;ecoute : on attend la&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# premiere reponse HTTP, pas le demarrage de l&apos;unite.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;ExecStartPre&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=/bin/sh -c &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;for i in $(seq 1 30); do curl -sf http://localhost/ &gt;/dev/null &amp;#x26;&amp;#x26; exit 0; sleep 1; done; exit 1&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;ExecStart&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=/usr/bin/chromium --kiosk http://localhost&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;Restart&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=always&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
&lt;p&gt;Le même raisonnement a produit le &lt;strong&gt;volet de maintenance&lt;/strong&gt;, qui descend du bord
haut comme sur un téléphone. Il porte l’état des sources, la carte d’identité
réseau de la machine — IP, MAC, SSID, passerelle, DNS, état de SSH — et trois
boutons : &lt;em&gt;Recharger&lt;/em&gt;, &lt;em&gt;Redémarrer&lt;/em&gt;, &lt;em&gt;Éteindre&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Il existe pour une seule raison : &lt;strong&gt;la page d’administration passe par le
réseau&lt;/strong&gt;. Le jour où le LAN tombe, elle est injoignable exactement quand on en a
besoin. Le volet, lui, parle à &lt;code&gt;127.0.0.1&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Et il se referme seul au bout de quinze secondes — faute de quoi un enfant qui
l’ouvre et s’en va laisserait le tableau caché.&lt;/p&gt;
&lt;figure class=&quot;media media--image&quot;&gt;&lt;img alt=&quot;La page « véhicule » : la tuile de la borne de recharge est hors ligne, les deux autres continuent&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; width=&quot;1480&quot; height=&quot;320&quot; src=&quot;https://blog.fpicard.tech/_astro/vehicule-hors-ligne.B0OctsPR_ZRHnkt.webp&quot;&gt;&lt;figcaption&gt;« Dégradé, jamais blanc », en situation : la borne ne répond pas, sa tuile le dit en rouge — et les deux tuiles voisines affichent toujours la dernière charge et la consommation du mois. Sur un poste de travail, on ouvrirait la console ; ici, il faut que la page reste lisible sans personne pour la réparer.&lt;/figcaption&gt;&lt;/figure&gt;
&lt;figure class=&quot;media media--image&quot;&gt;&lt;img alt=&quot;La page « école » : compte à rebours des vacances, semaine A ou B, et « pas d&amp;#39;école »&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; width=&quot;1480&quot; height=&quot;320&quot; src=&quot;https://blog.fpicard.tech/_astro/ecole-vacances._SuvI9XL_Z2vOiMc.webp&quot;&gt;&lt;figcaption&gt;Cinq des vingt-six tuiles ne servent qu&apos;à la famille. Celle de gauche compte les jours jusqu&apos;au retour, celle de droite répond à la seule question qui se pose à 7 h du matin.&lt;/figcaption&gt;&lt;/figure&gt;
&lt;h2 id=&quot;zéro-dépendance-zéro-build&quot;&gt;Zéro dépendance, zéro build&lt;/h2&gt;
&lt;p&gt;Le navigateur charge les fichiers tels qu’ils sont écrits. Pas de framework,
pas de bundler, pas de chaîne de build.&lt;/p&gt;
&lt;p&gt;Ce n’est pas du purisme. Un bundle React ici coûterait &lt;strong&gt;200 Ko pour afficher
douze chiffres&lt;/strong&gt;, et une chaîne de build à maintenir pour un appareil censé
tenir des mois sans intervention. La contrepartie est le genre de simplicité
qu’on ne regrette pas : &lt;code&gt;git pull&lt;/code&gt; sur le Pi &lt;strong&gt;est&lt;/strong&gt; le déploiement.&lt;/p&gt;
&lt;p&gt;Mais la règle a une exception, et c’est elle qui l’explique le mieux.&lt;/p&gt;
&lt;p&gt;Trois tuiles posent un &lt;strong&gt;emoji&lt;/strong&gt; en filigrane — météo, vacances, semaine A/B. Un
emoji n’est pas un fichier du dépôt : c’est un glyphe fourni par une police du
système. Raspberry Pi OS minimal n’en a aucune.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;fc-list&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; |&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; grep&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; -ci&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; emoji&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# 0&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Chromium ne dessine alors &lt;strong&gt;rien&lt;/strong&gt;. Pas d’erreur, pas de carré blanc, pas une
ligne en console. La tuile s’affiche, correctement, sans son filigrane — et on
peut passer à côté longtemps.&lt;/p&gt;
&lt;p&gt;La leçon est plus large que l’emoji : &lt;strong&gt;tout ce qui sort du dépôt doit être posé
par le script d’amorçage&lt;/strong&gt;, sinon une carte neuve arrive incomplète sans le
dire. &lt;code&gt;bootstrap.sh&lt;/code&gt; installe donc &lt;code&gt;fonts-noto-color-emoji&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&quot;le-runtime-possède-les-timers&quot;&gt;Le runtime possède les timers&lt;/h3&gt;
&lt;p&gt;Un widget n’appelle jamais &lt;code&gt;setInterval&lt;/code&gt;, &lt;code&gt;fetch&lt;/code&gt; ni &lt;code&gt;addEventListener&lt;/code&gt; sur
&lt;code&gt;window&lt;/code&gt;. Il passe par &lt;code&gt;ctx.every()&lt;/code&gt; et &lt;code&gt;ctx.on()&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Ça paraît cérémonieux pour un projet sans dépendances. C’est ce qui permet de
&lt;strong&gt;suspendre les pages non affichées&lt;/strong&gt; — sans quoi cinq pages de six widgets
feraient tourner trente collectes en permanence, sur un Pi qui porte déjà
Chromium.&lt;/p&gt;
&lt;h2 id=&quot;le-navigateur-ne-parle-jamais-à-une-source&quot;&gt;Le navigateur ne parle jamais à une source&lt;/h2&gt;
&lt;p&gt;Ni adresse, ni identifiant, ni jeton ne descendent dans la page. Le shell
demande &lt;code&gt;/relais/z420/data.json&lt;/code&gt; ; &lt;strong&gt;seul le serveur sait où cela mène&lt;/strong&gt;. Le
CORS se résout au passage, sans y penser.&lt;/p&gt;
&lt;p&gt;Quatre surfaces réseau, volontairement séparées :&lt;/p&gt;






























&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Port&lt;/th&gt;&lt;th&gt;Sert&lt;/th&gt;&lt;th&gt;Authentification&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;80&lt;/code&gt;&lt;/td&gt;&lt;td&gt;le shell, en clair — c’est ce que charge le kiosque&lt;/td&gt;&lt;td&gt;aucune&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;443&lt;/code&gt;&lt;/td&gt;&lt;td&gt;le même shell en HTTPS, si un certificat est configuré&lt;/td&gt;&lt;td&gt;aucune&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;8080&lt;/code&gt;&lt;/td&gt;&lt;td&gt;l’administration&lt;/td&gt;&lt;td&gt;mot de passe&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;8081&lt;/code&gt;&lt;/td&gt;&lt;td&gt;le service d’écriture&lt;/td&gt;&lt;td&gt;&lt;strong&gt;lié à &lt;code&gt;127.0.0.1&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;Le port qui alimente l’écran ne sert jamais de point d’écriture.&lt;/p&gt;
&lt;aside class=&quot;encadre encadre--note&quot; role=&quot;note&quot;&gt;&lt;p class=&quot;encadre__titre&quot;&gt;Note&lt;/p&gt;&lt;p&gt;Deux sources échappent au relais : &lt;code&gt;open-meteo&lt;/code&gt; et le calendrier scolaire du
ministère, appelées directement par le navigateur. Le relais est un adaptateur
du réseau local et &lt;strong&gt;refuse par construction toute cible extérieure&lt;/strong&gt;.&lt;/p&gt;&lt;p&gt;La règle qui tient réellement n’est donc pas « le navigateur ne sort jamais »,
mais « &lt;strong&gt;aucun secret ne descend dans la page&lt;/strong&gt; ». Ces deux-là n’en ont aucun à
protéger.&lt;/p&gt;&lt;/aside&gt;
&lt;h2 id=&quot;ce-que-le-matériel-a-coûté&quot;&gt;Ce que le matériel a coûté&lt;/h2&gt;
&lt;p&gt;C’est la partie où j’ai perdu le plus de temps, et pour une raison qui n’a rien
à voir avec le logiciel.&lt;/p&gt;
&lt;figure class=&quot;media media--image&quot;&gt;&lt;img alt=&quot;L&amp;#39;arrière de l&amp;#39;ensemble : le Raspberry Pi vissé sur la carte de la dalle&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; width=&quot;2000&quot; height=&quot;1500&quot; src=&quot;https://blog.fpicard.tech/_astro/assemblage-dos.BpTSf6nv_Z1CUFve.webp&quot;&gt;&lt;figcaption&gt;Tout l&apos;appareil, vu de dos. Le Pi est vissé sur la carte de la dalle, la nappe orange part sur la gauche. Il n&apos;y a rien d&apos;autre — pas de carte d&apos;alimentation, pas de convertisseur.&lt;/figcaption&gt;&lt;/figure&gt;
&lt;p&gt;Le Pi remontait des &lt;strong&gt;sous-tensions&lt;/strong&gt; en continu : de l’ordre de 160 par heure.
Le réflexe est d’accuser la puissance du chargeur. C’est faux.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;vcgencmd&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; get_throttled&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# 0x50005  -&gt; sous-tension detectee, et depuis le demarrage&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;J’ai commandé une alimentation officielle 27 W, puis mesuré une heure pleine,
kiosque en marche :&lt;/p&gt;
&lt;figure class=&quot;bloc-code&quot;&gt;&lt;figcaption class=&quot;bloc-code__titre&quot;&gt;mesure-alim.py — une heure, au repos&lt;/figcaption&gt;&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;text&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;fenêtre           : 3600 s&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;sous-tensions     : +0  (total 0)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;get_throttled     : 0x0&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;température       : 68,2 → 69,6 °C&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
&lt;p&gt;&lt;strong&gt;Zéro, contre une référence d’environ 160 par heure.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Et la cause est établie : &lt;strong&gt;c’est le câble, pas la puissance&lt;/strong&gt;. Les 22,5 W du
chargeur précédent suffisaient sur le papier ; c’est la chute de tension dans un
câble USB-C quelconque qui provoquait les sous-tensions. Le bloc officiel a un
câble captif dimensionné pour &lt;strong&gt;5 A&lt;/strong&gt;, qui n’en transporte que 1,5 — donc une
chute négligeable.&lt;/p&gt;
&lt;aside class=&quot;encadre encadre--piege&quot; role=&quot;note&quot;&gt;&lt;p class=&quot;encadre__titre&quot;&gt;Une alimentation 5 A n’aurait rien allumé sur un autre Pi&lt;/p&gt;&lt;p&gt;Un câble capable de 5 A est &lt;strong&gt;e-marked&lt;/strong&gt;. Or le Raspberry Pi 4 &lt;strong&gt;rev 1.1&lt;/strong&gt;
refuse de démarrer sur un tel câble — un défaut de ses broches CC, corrigé
depuis.&lt;/p&gt;&lt;p&gt;Le mien est une &lt;strong&gt;rev 1.4&lt;/strong&gt;, donc rien à signaler. Sur une rev 1.1, cette
alimentation très recommandable n’aurait produit aucune image, et j’aurais
cherché la panne ailleurs.&lt;/p&gt;&lt;/aside&gt;
&lt;figure class=&quot;media media--image&quot;&gt;&lt;img alt=&quot;L&amp;#39;alimentation officielle 27 W et son câble captif&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; width=&quot;1141&quot; height=&quot;856&quot; src=&quot;https://blog.fpicard.tech/_astro/dalle-alimentation.-QEyi4dX_Z13SeLx.webp&quot;&gt;&lt;figcaption&gt;Le câble est dimensionné pour 5 A et n&apos;en transporte que 1,5. C&apos;est tout l&apos;écart entre 160 sous-tensions par heure et zéro.&lt;/figcaption&gt;&lt;/figure&gt;
&lt;p&gt;Dernier retournement : la dalle &lt;strong&gt;n’est pas alimentée par le Pi&lt;/strong&gt;. La nappe DSI
ne porte que la vidéo et l’I²C ; le courant arrive par le Type-C de la dalle,
qui alimente le Pi à son tour. Toute mon inquiétude sur le rail 5 V portait sur
un circuit qui n’existe pas.&lt;/p&gt;
&lt;figure class=&quot;media media--image&quot;&gt;&lt;img alt=&quot;La nappe DSI, branchée sur le connecteur DISPLAY du Raspberry Pi&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; width=&quot;2000&quot; height=&quot;1500&quot; src=&quot;https://blog.fpicard.tech/_astro/nappe-dsi.DpYZY06D_18rTbQ.webp&quot;&gt;&lt;figcaption&gt;La nappe orange, et rien d&apos;autre. Vidéo et I²C — aucun conducteur de puissance. J&apos;ai porté trois semaines une inquiétude sur un circuit que cette photo dément.&lt;/figcaption&gt;&lt;/figure&gt;
&lt;h3 id=&quot;deux-réglages-et-un-seul-comptait&quot;&gt;Deux réglages, et un seul comptait&lt;/h3&gt;
&lt;p&gt;En DSI, il n’y a &lt;strong&gt;pas de &lt;code&gt;hdmi_timings&lt;/code&gt;&lt;/strong&gt; : la dalle s’annonce elle-même. La
rotation ne passe pas non plus par le noyau — trois voies essayées en KMS,
aucune ne fonctionne. C’est le compositeur qui tourne :&lt;/p&gt;
&lt;figure class=&quot;bloc-code&quot;&gt;&lt;figcaption class=&quot;bloc-code__titre&quot;&gt;~/.config/sway/config&lt;/figcaption&gt;&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;output DSI-1 transform 90&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
&lt;p&gt;Une ligne. Et le tactile suit sans rien demander : &lt;code&gt;sway&lt;/code&gt; lui applique la même
transformation, ce qui rend inutile la règle udev que j’avais prévue.&lt;/p&gt;
&lt;h2 id=&quot;le-résultat&quot;&gt;Le résultat&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Version 3.12.1&lt;/strong&gt;, en service sur sa dalle définitive.&lt;/p&gt;









































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;&lt;/th&gt;&lt;th&gt;&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;Hôte&lt;/td&gt;&lt;td&gt;Raspberry Pi 4B 2 Go, Raspberry Pi OS Lite Trixie&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Affichage&lt;/td&gt;&lt;td&gt;&lt;code&gt;sway&lt;/code&gt; + Chromium en kiosque sur &lt;code&gt;http://localhost&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Dalle&lt;/td&gt;&lt;td&gt;Waveshare 11.9” DSI, 320 × 1480 natif, tournée en paysage&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Serveur&lt;/td&gt;&lt;td&gt;Caddy — fichiers statiques et relais&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Démarrage&lt;/td&gt;&lt;td&gt;&lt;strong&gt;13,2 s&lt;/strong&gt;, &lt;code&gt;NRestarts=0&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Widgets&lt;/td&gt;&lt;td&gt;26&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Préréglages prêts à l’emploi&lt;/td&gt;&lt;td&gt;48&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Dépendances&lt;/td&gt;&lt;td&gt;&lt;strong&gt;aucune&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;Les tuiles vont de l’heure et la météo aux métriques d’un PC, un serveur
Minecraft, une borne de recharge, la supervision Zabbix — et cinq tuiles qui ne
servent qu’à la maison : les vacances scolaires, la semaine A ou B du collège,
ce qu’il faut prendre ce matin, quel bac sortir ce soir, et un « ça va où ? »
qui répond au toucher.&lt;/p&gt;
&lt;figure class=&quot;media media--image&quot;&gt;&lt;img alt=&quot;La page d&amp;#39;accueil à la géométrie native de la dalle&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; width=&quot;1480&quot; height=&quot;320&quot; src=&quot;https://blog.fpicard.tech/_astro/accueil.BwhOJxgj_Z2c9ymd.webp&quot;&gt;&lt;figcaption&gt;1480 × 320, taille réelle. L&apos;heure, la météo locale, la phase de lune — et c&apos;est à peu près tout ce qu&apos;une bande de 320 pixels de haut peut porter de front.&lt;/figcaption&gt;&lt;/figure&gt;
&lt;figure class=&quot;media media--image&quot;&gt;&lt;img alt=&quot;Les actualités, avec leur position dans le flux indiquée en en-tête&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; width=&quot;1480&quot; height=&quot;320&quot; src=&quot;https://blog.fpicard.tech/_astro/actualites.BKuWUabn_1VtVna.webp&quot;&gt;&lt;figcaption&gt;« 1/15 » en en-tête : la tuile dit toujours où elle en est. Sur un écran qu&apos;on ne pilote pas, une pagination muette est une pagination inutile.&lt;/figcaption&gt;&lt;/figure&gt;
&lt;p&gt;Le geste est la seule interface. Balayage horizontal pour changer de page,
vertical pour changer de variante, appui court pour suspendre la rotation, appui
long de 0,7 s pour épingler une page.&lt;/p&gt;
&lt;p&gt;Un détail m’a occupé plus longtemps qu’il ne devrait : &lt;strong&gt;l’axe se décide au
premier mouvement de 12 pixels, puis se fige&lt;/strong&gt;. Sans ce verrou, un geste
légèrement diagonal déclenchait les deux à la fois.&lt;/p&gt;
&lt;figure class=&quot;media media--image&quot;&gt;&lt;img alt=&quot;La page « déchets » : quel bac sortir ce soir, et un jeu de tri qui répond au toucher&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; width=&quot;1480&quot; height=&quot;320&quot; src=&quot;https://blog.fpicard.tech/_astro/collecte-tri.Brj-u36I_J8c2P.webp&quot;&gt;&lt;figcaption&gt;À gauche, le bac à sortir — « mercredi soir », avec la levée du lendemain. À droite, « Ça va où ? » : un objet, six destinations, la réponse au doigt. C&apos;est la seule tuile du panneau avec laquelle on joue.&lt;/figcaption&gt;&lt;/figure&gt;
&lt;h2 id=&quot;ce-que-je-naurais-pas-fait-seul&quot;&gt;Ce que je n’aurais pas fait seul&lt;/h2&gt;
&lt;p&gt;Il faut que je sois clair, parce que c’est la chose la plus honnête que je puisse
écrire sur ce projet : &lt;strong&gt;sans IA, je ne m’y serais jamais mis.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Je suis ingénieur systèmes et réseaux. Je lis du code, j’en corrige, j’en écris
quand il le faut. Mais vingt-six widgets en JavaScript sans framework, un moteur
de grille, un schéma de layout versionné, une page d’administration complète —
j’aurais estimé le chantier à plusieurs mois de soirées, et je ne l’aurais pas
commencé. Pas par incompétence : par &lt;strong&gt;arbitrage&lt;/strong&gt;. Le coût d’entrée était plus
élevé que l’envie.&lt;/p&gt;
&lt;p&gt;C’est exactement ce que l’IA a déplacé. Pas la compétence — l’&lt;strong&gt;accès&lt;/strong&gt;. Une
idée du samedi matin devient une maquette le samedi soir, et c’est au moment où
on la voit tourner qu’on décide si elle mérite trois semaines.&lt;/p&gt;
&lt;h3 id=&quot;il-faut-une-idée-et-quelquun-pour-trancher&quot;&gt;Il faut une idée, et quelqu’un pour trancher&lt;/h3&gt;
&lt;p&gt;Ce n’est pas de la dictée. Il faut une idée de départ — personne ne m’a soufflé
qu’un mur de mon bureau était vide — et il faut vérifier ce qui sort, étape par
étape.&lt;/p&gt;
&lt;p&gt;Ça n’est pas de l’hygiène de principe, c’est structurel : &lt;strong&gt;une IA produit une
réponse fausse avec exactement le même aplomb qu’une réponse juste.&lt;/strong&gt; Elle ne
sait pas qu’elle se trompe, donc elle ne le dit pas. Les quatre prévisions de ma
feuille de route plus haut, elle les aurait implémentées toutes les quatre sans
sourciller — c’est moi qui ai mesuré, et c’est la mesure qui les a démenties.&lt;/p&gt;
&lt;p&gt;Le corollaire est moins intuitif : &lt;strong&gt;une IA est complaisante&lt;/strong&gt;. Elle propose, et
ce qu’elle propose est presque toujours raisonnable &lt;em&gt;en général&lt;/em&gt;. Sur ce projet,
elle m’a proposé un framework, une chaîne de build, SQLite pour la
configuration, une règle udev pour calibrer le tactile. Quatre réponses
parfaitement défendables. Quatre réponses fausses &lt;strong&gt;ici&lt;/strong&gt; — pour un appareil
sans clavier qui doit tenir des mois et dont le déploiement doit rester un
&lt;code&gt;git pull&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Cadrer et trancher, c’est le vrai travail. Et ça ne se délègue pas, parce que
ça demande de savoir ce qu’on veut &lt;em&gt;vraiment&lt;/em&gt; — ce qu’une conversation ne
contient jamais entièrement.&lt;/p&gt;
&lt;h3 id=&quot;ce-quelle-na-pas-fait&quot;&gt;Ce qu’elle n’a pas fait&lt;/h3&gt;
&lt;p&gt;Il serait malhonnête de s’arrêter là, parce que la liste des choses que l’IA n’a
pas résolues est précisément celle des problèmes qui m’ont coûté du temps :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Les 160 sous-tensions par heure.&lt;/strong&gt; Aucune conversation ne les aurait
trouvées. Il a fallu brancher un wattmètre, lancer une mesure d’une heure, et
accepter que la réponse contredise l’hypothèse de départ.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Les trois voies de rotation en KMS.&lt;/strong&gt; Elles paraissaient toutes correctes
sur le papier. Aucune ne fonctionne.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Le kiosque qui n’essaie plus jamais.&lt;/strong&gt; Le défaut n’est visible que sur le
mur, après une coupure de courant, un soir.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;« La dalle tire son 5 V du rail du Pi ».&lt;/strong&gt; Une supposition que j’ai portée
trois semaines, et qu’une nappe DSI démentait depuis le début.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Le partage est net, et il n’a rien de décevant : &lt;strong&gt;l’IA a supprimé le coût
d’entrée du logiciel ; le monde physique a continué de facturer plein tarif.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Ce qui change vraiment, du coup, ce n’est pas la vitesse d’écriture. C’est que
le temps qu’on ne passe plus à produire du code, on le passe à &lt;strong&gt;mesurer&lt;/strong&gt; — et
c’est là que les vrais problèmes étaient.&lt;/p&gt;
&lt;h3 id=&quot;et-surtout-elle-na-rien-hébergé&quot;&gt;Et surtout : elle n’a rien hébergé&lt;/h3&gt;
&lt;p&gt;C’est le point que j’ai failli écrire comme une nuance, et c’est en fait le
cœur.&lt;/p&gt;
&lt;p&gt;Ce panneau affiche la supervision Zabbix de mon parc, Plex via Tautulli, un
serveur Minecraft, une borne de recharge, un agrégateur FreshRSS, qui est
connecté au VPN, les capteurs d’une station de travail. &lt;strong&gt;Rien de tout ça n’est
sorti d’une conversation.&lt;/strong&gt; Ce sont des années d’infrastructure montée chez moi,
supervisée, sauvegardée et maintenue — avec ses pannes, ses migrations et ses
nuits blanches.&lt;/p&gt;
&lt;p&gt;Sans ce substrat, le plus beau moteur de widgets du monde affiche l’heure et la
météo. Autrement dit : un réveil.&lt;/p&gt;
&lt;p&gt;Je n’ai pas fait écrire un tableau de bord. J’ai fait écrire &lt;strong&gt;une vitrine pour
quelque chose qui existait déjà&lt;/strong&gt;, et dont l’IA n’a pas posé une brique.&lt;/p&gt;
&lt;p&gt;C’est pour ça que la question « quelle part revient à qui ? » me paraît mal
posée. Ce n’est pas un pourcentage de lignes — ce serait mesurer un livre au
poids de son encre. C’est une &lt;strong&gt;antériorité&lt;/strong&gt; : il fallait que tout ça tourne
déjà, chez moi, pour qu’il y ait quoi que ce soit à afficher.&lt;/p&gt;
&lt;aside class=&quot;encadre encadre--note&quot; role=&quot;note&quot;&gt;&lt;p class=&quot;encadre__titre&quot;&gt;Note&lt;/p&gt;&lt;p&gt;Le même raisonnement vaut pour la documentation de ce dépôt : le &lt;code&gt;README&lt;/code&gt;, le
&lt;code&gt;CHANGELOG&lt;/code&gt; et un fichier &lt;code&gt;CONTEXTE.md&lt;/code&gt; qui garde les décisions qu’on serait
tenté de re-litiger. Je ne les aurais jamais tenus à ce niveau à la main. C’est
aussi grâce à eux que cet article a pu être écrit un mois plus tard sans que je
remette le nez dans le code.&lt;/p&gt;&lt;/aside&gt;
&lt;h2 id=&quot;ce-qui-reste&quot;&gt;Ce qui reste&lt;/h2&gt;
&lt;p&gt;Le &lt;strong&gt;boîtier&lt;/strong&gt; — cotes relevées, dessin en cours. C’est la seule chose qui
sépare ce panneau d’un objet fini, et ce sera un autre article.&lt;/p&gt;
&lt;p&gt;En attendant, l’ensemble tient debout sur un socle à smartphone en bois, de
ceux qu’on trouve chez Ikea pour trois euros. Ça n’a rien d’élégant, et ça a
une vertu que je n’avais pas prévue : &lt;strong&gt;ça empêche de considérer le projet
comme terminé&lt;/strong&gt;. Un appareil posé de travers sur un bout de hêtre se rappelle à
vous tous les matins.&lt;/p&gt;
&lt;p&gt;Et un &lt;strong&gt;agrégateur&lt;/strong&gt; : un service unique côté serveur qui collecte les sources
lentes et les expose en SSE. &lt;code&gt;EventSource&lt;/code&gt; reconnecte seul, avec un backoff
intégré — sur un appareil qui doit tenir des mois, c’est zéro logique de reprise
à écrire. L’articulation est déjà en place : le jour venu, &lt;strong&gt;aucun widget ne
changera&lt;/strong&gt;, seule la source à laquelle il s’abonne.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Ce que je retiens de ces trois semaines n’est pas une technique mais une
discipline : chaque fois que j’ai voulu régler un problème &lt;em&gt;avant&lt;/em&gt; de l’avoir
mesuré, je me suis trompé. Les quatre prévisions de la feuille de route, la
puissance du chargeur, la rotation par le noyau — quatre fois sur quatre, la
mesure disait autre chose.&lt;/p&gt;
&lt;p&gt;Un écran sans clavier ne pardonne pas les suppositions. Il les affiche.&lt;/p&gt;
&lt;p&gt;Et c’est peut-être la vraie leçon du &lt;em&gt;vibecoding&lt;/em&gt; : il rend le code bon marché,
ce qui laisse d’autant moins d’excuses pour ne pas aller mesurer le reste.&lt;/p&gt;</content:encoded><category>raspberry-pi</category><category>kiosk</category><category>auto-hebergement</category><category>linux</category><author>florian@fpicard.tech (Florian Picard)</author></item></channel></rss>