tag:linuxfr.org,2005:/tags/bricolage/publicLinuxFr.org : les contenus étiquetés avec « bricolage »2022-09-09T15:34:38+02:00/favicon.pngtag:linuxfr.org,2005:Bookmark/51272022-09-09T15:34:38+02:002022-09-09T15:52:01+02:00Un routeur ADSL bricolé pour donner de chouettes effets à la guitare électrique<a href="https://hackaday.com/2022/09/08/adsl-router-as-effects-pedal/">https://hackaday.com/2022/09/08/adsl-router-as-effects-pedal/</a> <p>
<strong>Commentaires :</strong>
<a href="//linuxfr.org/nodes/128707/comments.atom">voir le flux Atom</a>
<a href="https://linuxfr.org/users/ysabeau/liens/un-routeur-adsl-bricole-pour-donner-de-chouettes-effets-a-la-guitare-electrique#comments">ouvrir dans le navigateur</a>
</p>
Ysabeau 🧶 🧦https://linuxfr.org/nodes/128707/comments.atomtag:linuxfr.org,2005:Diary/399012021-09-02T22:45:50+02:002021-09-03T08:34:04+02:00Simuler un clic avec libevdev et uinputLicence CC By‑SA http://creativecommons.org/licenses/by-sa/4.0/deed.fr<h2 class="sommaire">Sommaire</h2>
<ul class="toc">
<li><a href="#toc-pr%C3%A9ambule">Préambule</a></li>
<li><a href="#toc-probl%C3%A8me-et-solution">Problème et solution</a></li>
<li>
<a href="#toc-libevdev--r%C3%A9cup%C3%A9rer-les-%C3%A9v%C3%A8nements-des-p%C3%A9riph%C3%A9riques-dentr%C3%A9e">libevdev – récupérer les évènements des périphériques d’entrée</a><ul>
<li><a href="#toc-ouverture-du-p%C3%A9riph%C3%A9rique-et-r%C3%A9ception-des-%C3%A9v%C3%A8nements-tactiles">Ouverture du périphérique et réception des évènements tactiles</a></li>
<li><a href="#toc-gestion-des-%C3%A9v%C3%A8nements">Gestion des évènements</a></li>
</ul>
</li>
<li><a href="#toc-uinput--g%C3%A9n%C3%A9rer-des-%C3%A9v%C3%A8nements">uinput – générer des évènements</a></li>
<li><a href="#toc-compilation-et-installation">Compilation et installation</a></li>
<li><a href="#toc-future-work">Future work</a></li>
<li><a href="#toc-conclusion">Conclusion</a></li>
</ul>
<h2 id="toc-préambule">Préambule</h2>
<p>Samedi 7 août, 14h UTC+2 : une pluie de tous les enfers se déchaîne. Il pleut tout l’après-midi, mais c’est la tempête surtout pendant une demi heure. Le sol est inondé. Les gens courent, l’imper sur lequel je comptais jette l’éponge, mon téléphone pas étanche dans la poche de l’imper pas étanche est mouillé et c’est le drame : il ne s’allume plus.</p>
<p>Dimanche 8 août. Le téléphone refonctionne (son module wifi et Bluetooth démarre bien quand bon lui semble, mais il finira par refonctionner normalement quelques jours plus tard. Ouf).</p>
<p>… mais une bande de l’écran ne répond plus au tactile. Cette bande correspond pile poil à la barre d’état de l’environnement graphique, Phosh. C’est la même qu’on trouve aussi sur iOS et Android, rien de remarquable : on en a besoin pour accéder aux différentes fonctionnalités activables et désactivables et il n’y a guère d’autres interactions possibles sur cette barre. Vous connaissez certainement.</p>
<p>Bon, c’est chiant, mais en même temps, je n’ai aucune envie de changer l’écran pour si peu. Alors, que faire ?</p>
<h2 id="toc-problème-et-solution">Problème et solution</h2>
<p>Sur Phosh, la seule interaction possible sur cette barre est un clic, pour la dérouler. L’idée n’a pas tardé à arriver : on pourrait simuler un clic déclenché par une autre interaction, par exemple en posant trois doigts n’importe où sur l’écran. Il se trouve que le téléphone tourne sur une Debian, adaptée pour mobile (Mobian), tout ce qu’il y a de plus classique à part ça. On doit bien pouvoir faire quelque chose sur un tel système bidouillable sans devoir télécharger des centaines de mégas de SDK et accepter des licences pénibles, non ?</p>
<p>Bien sûr que oui, sinon ce journal n’existerait pas !! Phosh est basé sur Wayland, donc les solutions basées sur un serveur X11 comme <code>xdotools</code> sont très vite écartées. Il va falloir taper plus bas dans la pile logicielle. Il nous faudra également une manière de surveiller les tapes tactiles pour détecter quand trois doigts sont appuyés sur l’écran.</p>
<h2 id="toc-libevdev--récupérer-les-évènements-des-périphériques-dentrée">libevdev – récupérer les évènements des périphériques d’entrée</h2>
<p>Une recherche « Komen kon fé pour détecté les tapes ? » me mène rapidement sur <a href="http://who-t.blogspot.com/2013/09/libevdev-handling-input-events.html">cet article</a> du blog de Peter Hutterer, alias Who-T, de chez Red Hat. Peter, c’est <em>le</em> monsieur input de l’écosystème libre. La référence ultime. Quand tu tombes sur son blog, tu sais que tu ne vas pas lire de conneries. Il a donné une présentation super intéressante à la linux.conf.au 2020 <a href="https://lca2020.linux.org.au/schedule/presentation/79/">"Write a single library to handle all input devices, it'll be easy" they said…</a>, que je vous recommande vivement si vous comprenez l’anglais. C’est assez accessible et beaucoup plus intéressant que ça en a l’air. D’ailleurs, il y annonce qu’il cherche désespérément des gens pour travailler avec lui dans le domaine et que le <a href="https://en.wikipedia.org/wiki/Bus_factor">bus factor</a> est dangereusement proche de 1, mais que ce n’est pas très sexy comme domaine, parce qu’il faut péniblement prendre en charge et tester manuellement chaque matériel avec ses spécificités pour que le reste du monde n’ait pas besoin de s’emmerder avec ça et que tout fonctionne <em>out of the box</em>, et que les gens préfèrent généralement travailler sur d’autres trucs. Donc si ce journal suscite des vocations, ne vous censurez pas, contactez-le…</p>
<p>Bref, il nous raconte que :</p>
<blockquote>
<p>libevdev is a wrapper library to access /dev/input/eventX devices and provide their events through a C API.</p>
</blockquote>
<p>Traduction :</p>
<blockquote>
<p>libevdev est une bibliothèque qui enrobe les périphériques /dev/input/eventX et fournit leurs évènements à travers une API C.</p>
</blockquote>
<p>Parfait, ça ! Bon, c’était en 2013, mais tout fonctionne encore pareil. Ouf !</p>
<blockquote>
<p>Why use a library though? The kernel interface is relatively simple, but it has a few pitfalls. For one, device data is accessed through ioctl(2) and can cause weird bugs [1]. Second, not all events work in the same way. e.g. EVIOCGABS doesn't work the same for multi-touch axes, simply because the slot protocol has different semantics than the normal EV_ABS protocol. EV_REP has different handling as EV_ABS, EV_SYN is a special case anyway, etc. libevdev tries to avoid having to think about the differences and does sanity checks for the various calls.</p>
</blockquote>
<p>Traduction (romancée) :</p>
<blockquote>
<p>Mais pourquoi utiliser une bibliothèque ? L’interface noyau est relativement simple, mais elle a quelques soucis. Ça va être chiant, franchement on s’est embêtés à faire une bibliothèque toute propre qui uniformise tous vos affreux périphériques tous les plus différents les uns que les autres, utilisez ça si vous ne voulez pas finir dans une pièce blanche avec une camisole. Pitié, on sait de quoi on parle, on s’est sacrifiés pour vous alors maintenant, faites-nous plaisir et utilisez libevdev.</p>
</blockquote>
<p>Bon, ça a l’air bien libevdev, on va utiliser ça. Peter nous explique en détail comment faire dans son article en s’appuyant sur <a href="https://gitlab.freedesktop.org/libevdev/libevdev/blob/master/tools/libevdev-events.c">cet exemple simple</a>. Pour votre plaisir je vais le faire de ma manière ici.</p>
<h3 id="toc-ouverture-du-périphérique-et-réception-des-évènements-tactiles">Ouverture du périphérique et réception des évènements tactiles</h3>
<p>Commençons donc par inclure les bons entêtes, et on va ouvrir le périphérique qui correspond à la dalle tactile de mon téléphone et écouter les évènements qui arrivent :</p>
<pre><code class="c"><span class="c1">// (Tout le code C dans ce journal est copyright 2013 Red Hat, Inc, copyright 2021 moi, licence MIT)</span>
<span class="cp">#include</span> <span class="cpf"><stdbool.h></span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf"><errno.h></span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf"><fcntl.h></span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf"><stdio.h></span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf"><string.h></span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf"><unistd.h></span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf"><libevdev/libevdev.h></span><span class="cp"></span>
<span class="kt">int</span> <span class="nf">main</span><span class="p">(</span><span class="kt">int</span> <span class="n">argc</span><span class="p">,</span> <span class="kt">char</span> <span class="o">**</span><span class="n">argv</span><span class="p">)</span>
<span class="p">{</span>
<span class="kt">int</span> <span class="n">rc</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
<span class="k">struct</span> <span class="n">libevdev</span> <span class="o">*</span><span class="n">dev</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
<span class="kt">int</span> <span class="n">fd</span> <span class="o">=</span> <span class="n">open</span><span class="p">(</span><span class="s">"/dev/input/by-path/platform-1c2ac00.i2c-event"</span><span class="p">,</span> <span class="n">O_RDONLY</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="n">fd</span> <span class="o"><</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
<span class="n">perror</span><span class="p">(</span><span class="s">"Failed to open device"</span><span class="p">);</span>
<span class="k">goto</span> <span class="n">out</span><span class="p">;</span>
<span class="p">}</span>
<span class="n">rc</span> <span class="o">=</span> <span class="n">libevdev_new_from_fd</span><span class="p">(</span><span class="n">fd</span><span class="p">,</span> <span class="o">&</span><span class="n">dev</span><span class="p">);</span>
<span class="k">do</span> <span class="p">{</span>
<span class="k">struct</span> <span class="n">input_event</span> <span class="n">ev</span><span class="p">;</span>
<span class="n">rc</span> <span class="o">=</span> <span class="n">libevdev_next_event</span><span class="p">(</span><span class="n">dev</span><span class="p">,</span> <span class="n">LIBEVDEV_READ_FLAG_NORMAL</span><span class="o">|</span><span class="n">LIBEVDEV_READ_FLAG_BLOCKING</span><span class="p">,</span> <span class="o">&</span><span class="n">ev</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="n">rc</span> <span class="o">==</span> <span class="n">LIBEVDEV_READ_STATUS_SUCCESS</span><span class="p">)</span> <span class="p">{</span>
<span class="n">handle_event</span><span class="p">(</span><span class="o">&</span><span class="n">ev</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span> <span class="k">while</span> <span class="p">(</span><span class="n">rc</span> <span class="o">==</span> <span class="n">LIBEVDEV_READ_STATUS_SYNC</span> <span class="o">||</span> <span class="n">rc</span> <span class="o">==</span> <span class="n">LIBEVDEV_READ_STATUS_SUCCESS</span> <span class="o">||</span> <span class="n">rc</span> <span class="o">==</span> <span class="o">-</span><span class="n">EAGAIN</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="n">rc</span> <span class="o">!=</span> <span class="n">LIBEVDEV_READ_STATUS_SUCCESS</span> <span class="o">&&</span> <span class="n">rc</span> <span class="o">!=</span> <span class="o">-</span><span class="n">EAGAIN</span><span class="p">)</span> <span class="p">{</span>
<span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">"Failed to handle events: %s</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">strerror</span><span class="p">(</span><span class="o">-</span><span class="n">rc</span><span class="p">));</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="n">rc</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
<span class="nl">out</span><span class="p">:</span>
<span class="k">if</span> <span class="p">(</span><span class="n">fd</span> <span class="o">></span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
<span class="n">close</span><span class="p">(</span><span class="n">fd</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">if</span> <span class="p">(</span><span class="n">dev</span> <span class="o">!=</span> <span class="nb">NULL</span><span class="p">)</span> <span class="p">{</span>
<span class="n">libevdev_free</span><span class="p">(</span><span class="n">dev</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">return</span> <span class="n">rc</span><span class="p">;</span>
<span class="p">}</span></code></pre>
<p>Décortiquons tout ça :</p>
<ol>
<li>on ouvre le périphérique qui correspond à la dalle tactile avec <code>open</code>
</li>
<li>on passe le périphérique à libevdev pour pouvoir l’utiliser à travers la bibliothèque, avec <code>libevdev_new_from_fd</code>
</li>
<li>on boucle sur les évènements qui arrivent, en récupérant le prochain évènement avec <code>libevdev_next_event</code> (appel bloquant)</li>
<li>on passe ces évènements à une fonction <code>handle_event</code> que nous nous apprêtons à construire</li>
</ol>
<p>Il y a toute la gestion des erreurs, avec l’entier <code>rc</code> qui contient le code de retour, initialisé à 1 comme ça par défaut on retourne une erreur et on le passera à 0 quand tout se sera bien passé. On groupe le nettoyage à la fin de la fonction, accessible par des <code>goto</code> (en cas d’erreur) avec l’étiquette <code>out</code> qui va bien.</p>
<p>Le fonctionnement normal du programme est de ne jamais s’arrêter de lui-même. On ne compte pas débrancher l’écran tactile en cours d’utilisation. On attend continuellement des évènements à traiter.</p>
<p>Le programme peut être lancé en tant qu’utilisateur simple, puisqu’un utilisateur simple peut accéder en lecture aux périphériques d’entrée. D’ailleurs, si vous vous disiez que Wayland vous protégeait des keyloggers parce que ça isole correctement les applications entre elles, eh bien c’est raté, la couche d’en dessous se charge de donner les accès.</p>
<p>Bon, alors, on se la fait cette gestion des évènements ??</p>
<p>Eh ben oui, allons-y…</p>
<h3 id="toc-gestion-des-évènements">Gestion des évènements</h3>
<p>Alors là, on implémente la fonction <code>handle_event</code> qui manque dans la section précédente. On cherche à repérer le moment où trois doigts sont posés sur l’écran, ni plus, ni moins.</p>
<pre><code class="c"><span class="k">static</span> <span class="kt">int</span> <span class="nf">handle_event</span><span class="p">(</span><span class="k">struct</span> <span class="n">input_event</span> <span class="o">*</span><span class="n">ev</span><span class="p">,</span> <span class="k">struct</span> <span class="n">libevdev_uinput</span><span class="o">*</span> <span class="n">uidev</span><span class="p">)</span>
<span class="p">{</span>
<span class="k">static</span> <span class="kt">int</span> <span class="n">max_finger_id</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="k">static</span> <span class="kt">bool</span> <span class="n">pressed</span> <span class="o">=</span> <span class="nb">false</span><span class="p">;</span>
<span class="k">static</span> <span class="kt">int</span> <span class="n">must_click_on_btn_release</span> <span class="o">=</span> <span class="nb">false</span><span class="p">;</span>
<span class="k">switch</span> <span class="p">(</span><span class="n">ev</span><span class="o">-></span><span class="n">type</span><span class="p">)</span> <span class="p">{</span>
<span class="k">case</span> <span class="nl">EV_ABS</span><span class="p">:</span>
<span class="k">if</span> <span class="p">(</span><span class="n">ev</span><span class="o">-></span><span class="n">code</span> <span class="o">==</span> <span class="n">ABS_MT_SLOT</span><span class="p">)</span> <span class="p">{</span>
<span class="n">max_finger_id</span> <span class="o">=</span> <span class="n">max</span><span class="p">(</span><span class="n">max_finger_id</span><span class="p">,</span> <span class="n">ev</span><span class="o">-></span><span class="n">value</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">break</span><span class="p">;</span>
<span class="k">case</span> <span class="nl">EV_KEY</span><span class="p">:</span>
<span class="k">if</span> <span class="p">(</span><span class="n">ev</span><span class="o">-></span><span class="n">code</span> <span class="o">==</span> <span class="n">BTN_TOUCH</span><span class="p">)</span> <span class="p">{</span>
<span class="n">pressed</span> <span class="o">=</span> <span class="n">ev</span><span class="o">-></span><span class="n">value</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">break</span><span class="p">;</span>
<span class="k">case</span> <span class="nl">EV_SYN</span><span class="p">:</span>
<span class="k">if</span> <span class="p">(</span><span class="n">max_finger_id</span> <span class="o">==</span> <span class="mi">2</span> <span class="o">&&</span> <span class="n">pressed</span><span class="p">)</span> <span class="p">{</span>
<span class="n">must_click_on_btn_release</span> <span class="o">=</span> <span class="nb">true</span><span class="p">;</span>
<span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">must_click_on_btn_release</span> <span class="o">&&</span> <span class="o">!</span><span class="n">pressed</span><span class="p">)</span> <span class="p">{</span>
<span class="n">simclick</span><span class="p">();</span>
<span class="n">must_click_on_btn_release</span> <span class="o">=</span> <span class="nb">false</span><span class="p">;</span>
<span class="p">}</span>
<span class="n">max_finger_id</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="k">break</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span></code></pre>
<p>La structure <code>input_event</code> qu’on reçoit a trois champs qui nous intéressent : <code>type</code>, <code>code</code> et <code>value</code>. Le premier donne le type général de l’évènement, le deuxième spécifie plus précisément et le troisième est une info qui dépend de l’évènement (par exemple, quelle touche de clavier a été enfoncée).</p>
<p>Trois évènements nous concernent :</p>
<ul>
<li>le type <code>EV_ABS</code>, avec le code <code>MT_SLOT</code>. <code>ABS</code>, c’est pour absolu. Ça concerne les évènements qui ont des coordonnées absolues comme les écrans tactiles, à l’opposé des évènements relatifs comme les déplacements de souris. <code>MT_SLOT</code>, pour <em>mutltitouch slot</em>, permet de pister un doigt sur un écran tactile. Chaque doigt a son numéro, par ordre d’arrivée sur l’écran, en commençant par 0, puis 1, puis… vous avez compris. Quand vous déplacez vos doigts sur l’écran, ça va générer plein d’évènements mais chaque doigt aura toujours le même numéro (<em>slot</em>). C’est bien pratique. Vous imaginez, s’il fallait re-déduire le numéro de chaque doigt, évènement par évènement ? Heureusement que c’est fait pour nous !!</li>
<li>le type <code>EV_KEY</code>, avec le code <code>BTN_TOUCH</code>. <code>BTN</code> pour <em>button</em>. Quand vous enfoncez un ou des doigt(s), ça génère un évènement <code>BTN_TOUCH</code> avec une valeur <code>true</code>, et quand vous le(s) relâchez, ça génère un évènement avec une valeur <code>false</code>.</li>
<li>le type <code>EV_SYN</code>. C’est un évènement particulier, de synchronisation. Quand vous faites quelque chose sur votre écran (ou tout autre périphérique d’entrée), ça peut générer plusieurs évènements, pour la même action. Par exemple : « il s’est passé quelque chose avec le doigt 1 (<code>EV_ABS</code>). Il a été retiré de l’écran (<code>EV_KEY</code>). Ces évènements seront alors regroupés entre deux évènements de synchronisation <code>EV_SYN</code>.</li>
</ul>
<p>Vous vous dites peut-être alors qu’il va falloir stocker tout un état entre plusieurs évènements, au moins jusqu’au prochain « <code>EV_SYN</code> », voire plus, pour réagir quand on a assez d’info. J’ai pour cela choisi d’utiliser des variables statiques, qui persistent entre deux appels de la fonction <code>handle_event</code>. Ultra pratique. C’est comme des globales, mais pas accessibles depuis les autres fonctions. Ça rend la fonction totalement impure et il faut faire attention, ça rend potentiellement les tests unitaires pour cette fonction compliqués (je suis tombé sur <a href="https://stackoverflow.com/questions/49387056/unit-test-in-a-c-function-with-a-static-variable">cet échange « amusant » avec un gars qui doit tester un code d’avion qu’il ne peut pas vraiment modifier</a> en rédigeant le journal, <a href="https://www.ibm.com/support/pages/component-testing-c-how-test-static-variable-function">il y a des astuces intéressantes chez IBM</a>), mais en même temps ça colle parfaitement avec ce que j’ai envie de faire et je n’ai pas prévu de faire de tests unitaires.</p>
<p>Bref, en gros, ça fonctionne comme ça :</p>
<ul>
<li>quand on reçoit un numéro de doigt on enregistre son numéro (slot), s’il est plus grand que le numéro qu’on connait déjà.</li>
<li>quand un (des) doigt(s) est (sont) appuyé(s) ou relâché(s), on stocke ça dans <code>pressed</code>
</li>
<li>quand la fin d’un bloc d’évènements arrive :
<ul>
<li>si on réalise que exactement 3 doigts on été pressés (<code>max_finger_id == 2 && pressed</code>), on enregistre le souhait de générer un clic quand les doigts sont relâchés (<code>must_click_on_btn_release</code>);</li>
<li>si on réalise que tous les doigts ont été relâchés et qu’on souhaitait générer le clic, on le génère en appelant la fonction <code>simclick</code> et on oublie le souhait de générer un clic</li>
<li>on réinitialise le numéro de doigts max.</li>
</ul>
</li>
</ul>
<p>Notes :</p>
<ul>
<li>en jouant avec libevdev, on peut avoir l’impression qu’il manque des évènements. En fait, si on s’attendait à avoir un évènement mais que celui-ci aurait eu la même valeur que le dernier évènement reçu du même type et du même code, on ne le reçoit pas une nouvelle fois. Ainsi, si vous voulez écrire des interactions compliquées, <em>il ne faudrait pas réinitialiser votre état après chaque évènement <code>EV_SYN</code></em>, ce serait une erreur. Il n’y a probablement qu’en pratiquant et en se payant le mur soi-même que ça devient clair.</li>
<li>Pourquoi attendre que les doigts soient relâchés ? Pourquoi ne pas simplement générer un clic dès qu’on voit que tous les doigts ont été pressés ? Eh bien parce que c’est plus intuitif à l’utilisation. Si vous alliez poser un 4ᵉ doigt par exemple, trop tard, vous avez déjà généré le clic qui correspond à 3 doigts (or, je vous montre une version simplifiée de <code>handle_event</code>, et j’ai effectivement une gestion différente pour un 4ᵉ doigt). Et aussi, à cause d’un problème dont je parle dans la section suivante.</li>
</ul>
<p>Notre détection des 3 doigts est maintenant complète. Youpeee ! C’est déjà ça ! Vous pourriez vous arrêter là. Si vous vouliez par exemple exécuter une commande quand trois doigts sont appuyés, vous avez gagné. Il suffit d’appeler <code>system</code> ou <code>fork</code> + une version de <code>exec</code>.</p>
<p>Mais nous, on veut simuler un clic, alors c’est parti.</p>
<h2 id="toc-uinput--générer-des-évènements">uinput – générer des évènements</h2>
<p>J’apprends rapidement que pour simuler des clics (donc produire des évènements d’entrée « fake »), on peut utiliser l’interface du noyau Linux uinput. Pour <a href="https://who-t.blogspot.com/2013/09/libevdev-creating-uinput-devices.html">citer Who-T</a> :</p>
<blockquote>
<p>uinput is the kernel interface to create evdev devices that, for most purposes, look the same as real devices </p>
</blockquote>
<p>Traduction :</p>
<blockquote>
<p>uinput est l’interface noyau pour créer des périphériques evdev qui, pour la plupart des situations, ressemblent comme deux gouttes d’eau à des périphériques réels</p>
</blockquote>
<p>Très bien !</p>
<p>On continue à lire :</p>
<blockquote>
<p>As the evdev interface, the uinput interface requires you to handle a few structs and ioctls, not necessarily in an obvious way. libevdev wraps that for you.</p>
</blockquote>
<p>Traduction :</p>
<blockquote>
<p>Comme pour l’interface evdev, l’interface uinput vous demande de gérer quelques structures et ioctls, pas forcément de manière évidente. libevdev vous enrobe tout ça pour vous.</p>
</blockquote>
<p>Traduction :</p>
<blockquote>
<p>Rendez-vous service, utilisez libevdev-uinput. Sérieux.</p>
</blockquote>
<p>Bon, très bien, nous allons utiliser libevdev-uinput pour simuler un clic. </p>
<p>Comme pour la section précédente, Peter fait une très bonne présentation sur son article, et je vais vous la faire à ma sauce. Les exemples d’utilisations de libevdev et libevdev-uinput ne courent pas spécialement les rues d’internet alors ça ne peut pas faire trop de mal.</p>
<p>On peut créer un périphérique d’entrée virtuel de zéro, en spécifiant toutes ses caractéristiques, et notamment les types d’évènement qu’il est capable de générer. Mais en fait, il y a une manière plus simple de faire : il est possible de copier un périphérique existant, tout simplement. Et ça tombe bien, parce qu’on en a déjà un sous la main qu’on utilise déjà : c’est l’écran tactile. En plus, ça permettra vraiment de simuler exactement ce qu’il se serait passé si on avait nous-même touché l’écran tactile au bon endroit (c’est-à-dire, là où il est mort, si vous suivez), et Phosh n’y verra que du feu.</p>
<p>On va reprendre la ligne qui charge notre dalle tactile :</p>
<pre><code class="c"> <span class="n">rc</span> <span class="o">=</span> <span class="n">libevdev_new_from_fd</span><span class="p">(</span><span class="n">fd</span><span class="p">,</span> <span class="o">&</span><span class="n">dev</span><span class="p">);</span></code></pre>
<p>Le périphérique est chargé dans la structure <code>dev</code> si l’opération a réussi.</p>
<p>On va lui donner un nom à l’aide de la fonction <code>libevdev_set_name</code> et le copier dans une nouvelle structure semblable, <code>uidev</code>, à l’aide de la fonction <code>libevdev_uinput_create_from_device</code>.</p>
<p>On déclare la structure au début de la fonction main avant toute utilisation de <code>goto</code> :</p>
<pre><code class="c"> <span class="k">struct</span> <span class="n">libevdev_uinput</span><span class="o">*</span> <span class="n">uidev</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span></code></pre>
<pre><code class="c"> <span class="n">libevdev_set_name</span><span class="p">(</span><span class="n">dev</span><span class="p">,</span> <span class="s">"Fake device clicking on the top of the screen"</span><span class="p">);</span>
<span class="n">rc</span> <span class="o">=</span> <span class="n">libevdev_uinput_create_from_device</span><span class="p">(</span><span class="n">dev</span><span class="p">,</span> <span class="n">LIBEVDEV_UINPUT_OPEN_MANAGED</span><span class="p">,</span> <span class="o">&</span><span class="n">uidev</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="n">rc</span> <span class="o"><</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
<span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">"Failed to create fake device (%s)</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">strerror</span><span class="p">(</span><span class="o">-</span><span class="n">rc</span><span class="p">));</span>
<span class="k">goto</span> <span class="n">out</span><span class="p">;</span>
<span class="p">}</span></code></pre>
<p>Faudra pas oublier de libérer le périphérique dans la section <code>out</code> de <code>main</code>:</p>
<pre><code> if (uidev != NULL) {
libevdev_uinput_destroy(uidev);
}
</code></pre>
<p>On va passer à uidev à <code>handle_event</code> pour qu’elle puisse la passer à simclick:</p>
<ul>
<li>
<code>handle_event(&ev);</code> devient <code>handle_event(&ev, uidev);</code>
</li>
<li>
<code>static int handle_event(struct input_event *ev)</code> devient <code>static int handle_event(struct input_event *ev, struct libevdev_uinput* uidev)</code>
</li>
<li>
<code>simclick();</code> devient <code>simclick(uidev);</code>
</li>
</ul>
<p>La fonction <code>simclick</code> est assez bête. J’ai pris le <a href="https://gitlab.freedesktop.org/libevdev/libevdev/blob/master/tools/libevdev-events.c">programme d’exemple de Peter</a>, je l’ai compilé, je l’ai lancé et j’ai appuyé sur mon écran tactile. J’ai pu voir tous les évènements qui étaient générés et j’ai bêtement copié tout ça en adaptant les coordonnées de l’évènement pour que ça clique au bon endroit. Petite subtilité avec le <em>tracking id</em> pour discerner les évènements générés :</p>
<pre><code class="c"><span class="k">static</span> <span class="kt">void</span> <span class="nf">simclick</span><span class="p">(</span><span class="k">struct</span> <span class="n">libevdev_uinput</span><span class="o">*</span> <span class="n">uidev</span><span class="p">)</span>
<span class="p">{</span>
<span class="k">static</span> <span class="kt">int</span> <span class="n">tracking_id</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
<span class="kt">int</span> <span class="n">x</span> <span class="o">=</span> <span class="mi">15</span><span class="p">;</span>
<span class="kt">int</span> <span class="n">y</span> <span class="o">=</span> <span class="mi">15</span><span class="p">;</span>
<span class="n">libevdev_uinput_write_event</span><span class="p">(</span><span class="n">uidev</span><span class="p">,</span> <span class="n">EV_ABS</span><span class="p">,</span> <span class="n">ABS_MT_SLOT</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span>
<span class="n">libevdev_uinput_write_event</span><span class="p">(</span><span class="n">uidev</span><span class="p">,</span> <span class="n">EV_ABS</span><span class="p">,</span> <span class="n">ABS_MT_TRACKING_ID</span><span class="p">,</span> <span class="n">tracking_id</span><span class="o">++</span><span class="p">);</span>
<span class="n">libevdev_uinput_write_event</span><span class="p">(</span><span class="n">uidev</span><span class="p">,</span> <span class="n">EV_ABS</span><span class="p">,</span> <span class="n">ABS_MT_POSITION_X</span><span class="p">,</span> <span class="n">x</span><span class="p">);</span>
<span class="n">libevdev_uinput_write_event</span><span class="p">(</span><span class="n">uidev</span><span class="p">,</span> <span class="n">EV_ABS</span><span class="p">,</span> <span class="n">ABS_MT_POSITION_Y</span><span class="p">,</span> <span class="n">y</span><span class="p">);</span>
<span class="n">libevdev_uinput_write_event</span><span class="p">(</span><span class="n">uidev</span><span class="p">,</span> <span class="n">EV_ABS</span><span class="p">,</span> <span class="n">ABS_MT_TOUCH_MAJOR</span><span class="p">,</span> <span class="mi">22</span><span class="p">);</span>
<span class="n">libevdev_uinput_write_event</span><span class="p">(</span><span class="n">uidev</span><span class="p">,</span> <span class="n">EV_ABS</span><span class="p">,</span> <span class="n">ABS_MT_WIDTH_MAJOR</span><span class="p">,</span> <span class="mi">22</span><span class="p">);</span>
<span class="n">libevdev_uinput_write_event</span><span class="p">(</span><span class="n">uidev</span><span class="p">,</span> <span class="n">EV_KEY</span><span class="p">,</span> <span class="n">BTN_TOUCH</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span>
<span class="n">libevdev_uinput_write_event</span><span class="p">(</span><span class="n">uidev</span><span class="p">,</span> <span class="n">EV_ABS</span><span class="p">,</span> <span class="n">ABS_X</span><span class="p">,</span> <span class="n">x</span><span class="p">);</span>
<span class="n">libevdev_uinput_write_event</span><span class="p">(</span><span class="n">uidev</span><span class="p">,</span> <span class="n">EV_ABS</span><span class="p">,</span> <span class="n">ABS_Y</span><span class="p">,</span> <span class="n">y</span><span class="p">);</span>
<span class="n">libevdev_uinput_write_event</span><span class="p">(</span><span class="n">uidev</span><span class="p">,</span> <span class="n">EV_SYN</span><span class="p">,</span> <span class="n">SYN_REPORT</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span>
<span class="n">libevdev_uinput_write_event</span><span class="p">(</span><span class="n">uidev</span><span class="p">,</span> <span class="n">EV_ABS</span><span class="p">,</span> <span class="n">ABS_MT_TRACKING_ID</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span><span class="p">);</span>
<span class="n">libevdev_uinput_write_event</span><span class="p">(</span><span class="n">uidev</span><span class="p">,</span> <span class="n">EV_KEY</span><span class="p">,</span> <span class="n">BTN_TOUCH</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span>
<span class="n">libevdev_uinput_write_event</span><span class="p">(</span><span class="n">uidev</span><span class="p">,</span> <span class="n">EV_SYN</span><span class="p">,</span> <span class="n">SYN_REPORT</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span>
<span class="p">}</span></code></pre>
<p>… C’est… laborieux, mais pas très compliqué.</p>
<p>Et voilà, on a fini !<br>
Si vous lancez le programme, si tout va bien, vous pourrez voir votre périphérique virtuel apparaitre dans la liste produite par la commande <code>libinput list-devices</code> :</p>
<pre><code>Device: Goodix Capacitive TouchScreen
Kernel: /dev/input/event2
Group: 3
Seat: seat0, default
Capabilities: keyboard touch
Tap-to-click: n/a
Tap-and-drag: n/a
Tap drag lock: n/a
Left-handed: n/a
Nat.scrolling: n/a
Middle emulation: n/a
Calibration: identity matrix
Scroll methods: none
Click methods: none
Disable-w-typing: n/a
Accel profiles: n/a
Rotation: n/a
…
Device: Fake device clicking on the top of the screen
Kernel: /dev/input/event6
Group: 6
Seat: seat0, default
Capabilities: keyboard touch
Tap-to-click: n/a
Tap-and-drag: n/a
Tap drag lock: n/a
Left-handed: n/a
Nat.scrolling: n/a
Middle emulation: n/a
Calibration: identity matrix
Scroll methods: none
Click methods: none
Disable-w-typing: n/a
Accel profiles: n/a
Rotation: n/a
</code></pre>
<p>Les plus attentifs et les plus attentives auront remarqué qu’on ne supprime jamais les évènements initiaux correspondant aux trois doigts appuyés sur l’écran tactile. Et, oui, il s’agit d’une limitation. Je ne sais pas (encore) faire. Il y a peut-être moyen d’enregistrer notre périphérique virtuel et de bloquer le vrai périphérique et de filtrer les bons évènements. Il ne faut probablement pas tous les filtrer, mais peut-être juste les évènements <code>BTN_TOUCH</code> par exemple si ça suffit (peut-être pas). Sinon, ça pourrait avoir des effets de bords indésirables. Donc oui, si je ne fais pas attention, je déclenche des clics dans les applications actuellement affichées sur l’écran.</p>
<p>Note : contrairement à juste capter des évènements, simuler un périphérique nécessite d’être root (ou peut-être d’appartenir au bon groupe, mais je n’ai pas trop creusé).</p>
<h2 id="toc-compilation-et-installation">Compilation et installation</h2>
<p>C’est pas le tout, mais maintenant, il faut que le programme tourne et se lance au démarrage. Déjà, il faut installer le paquet de développement de libevdev (libevdev-dev chez les debianeux, libevdev-devel chez les rpmistes).</p>
<p>Puis, on compile et on installe :</p>
<pre><code>gcc simclick.c $(pkg-config --libs --cflags libevdev) -o simclick
sudo cp simclick /usr/local/bin/simclick
</code></pre>
<p>On fait un service systemd :</p>
<pre><code class="bash">cat > /etc/systemd/system/simclick.service <span class="s"><<EOF</span>
<span class="s">[Unit]</span>
<span class="s">Description=Simulate top click using three fingers</span>
<span class="s">ConditionFileIsExecutable=/usr/local/bin/simclick</span>
<span class="s">After=phosh.service</span>
<span class="s">[Service]</span>
<span class="s">Type=simple</span>
<span class="s">ExecStart=/usr/local/bin/simclick</span>
<span class="s">RemainAfterExit=no</span>
<span class="s">[Install]</span>
<span class="s">WantedBy=multi-user.target</span>
<span class="s">EOF</span></code></pre>
<p>(je réalise qu’il faudra adapter ce <code>After=phosh.service</code>, d’ailleurs, et peut-être trouver une autre cible pour le rendre plus générique, là ça le rend spécifique à Phosh)</p>
<p>Et au redémarrage, ça marche tout seul.</p>
<h2 id="toc-future-work">Future work</h2>
<p>(J’aurais pu titrer « Pistes d’amélioration » mais allez, ça me fait plaisir de nommer cette section comme ça.)</p>
<p>Pour l’instant j’utilise Phosh, mais je compte à plus ou moins court terme passer à Plasma Mobile, qui est d’ailleurs maintenant l’environnement par défaut du PinePhone (quelques trucs bloquants mais de moins en moins, et tant mieux, parce ça me convient mieux. Mais du coup, l’interaction sur la barre d’état pour la dérouler est vraiment un glisser vers le bas comme sous Android, donc la fonction <code>simclick</code> sera autrement plus compliquée. Mais ça ne devrait pas être trop difficile à faire, surtout qu’on peut enregistrer les évènements et presque les copier bêtement dans le code.</p>
<p>On pourrait s’amuser à rendre l’interaction plus intuitive en permettant demandant à ce que l’utilisateur fasse un glissé, peut-être avec deux doigts seulement. On peut imaginer tout un tas d’interactions pratique qui ne sont pas fournies par l’environnement. Il faut cependant trouver le moyen de garder la fonction <code>handle_event</code> lisible et claire, parce que pour avoir un peu tester, ça devient vite le bronx. Ou organiser autrement : faire une fonction par interaction. Pas toujours simple parce que parfois il y a des conflits. Tout bêtement, après un glissé, vous ne voulez pas déclencher l’action déclenchée par un touché simple. </p>
<p>Bon, on ne va pas se mentir, tout ça, c’est pour susciter votre esprit bidouilleur, mais restons les pieds sur terre : m’amuser avec des interactions tactiles sur le téléphone passera certainement après un tas de trucs que j’ai envie de faire donc il est peu probable que j’y passe un temps fou. À la base, c’est juste pour contourner cette zone morte de mon écran :-)</p>
<h2 id="toc-conclusion">Conclusion</h2>
<p>J’espère que vous avez apprécié ce journal. Si vous avez des questions ou des remarques, n’hésitez pas. En tout cas, ça fait un mois que j’utilise ce petit programme, sans accros ! Ça tourne et ça ne plante pas (ou, en tout cas, moins fréquemment que le téléphone lui-même !), et je m’y suis fait, j’aime plutôt bien taper sur l’écran avec trois doigts pour dérouler ce menu ! </p>
<p>Références :</p>
<ul>
<li>Le code complet décrit dans ce journal : <a href="https://paste.chapril.org/?37aacff5e147e0b5#FbqoSBgy89n12jEd3anFNx4CEca8FY5tZ5qfcdD4Bw2L">https://paste.chapril.org/?37aacff5e147e0b5#FbqoSBgy89n12jEd3anFNx4CEca8FY5tZ5qfcdD4Bw2L</a>
</li>
<li><a href="http://who-t.blogspot.com/2013/09/libevdev-handling-input-events.html">libevdev – handling input events</a></li>
<li><a href="https://who-t.blogspot.com/2013/09/libevdev-creating-uinput-devices.html">libevdev – creating uinput devices</a></li>
<li>Le code d’exemple de départ : <a href="https://gitlab.freedesktop.org/libevdev/libevdev/blob/master/tools/libevdev-events.c">https://gitlab.freedesktop.org/libevdev/libevdev/blob/master/tools/libevdev-events.c</a>
</li>
</ul>
<div><a href="https://linuxfr.org/users/raphj/journaux/simuler-un-clic-avec-libevdev-et-uinput.epub">Télécharger ce contenu au format EPUB</a></div> <p>
<strong>Commentaires :</strong>
<a href="//linuxfr.org/nodes/125293/comments.atom">voir le flux Atom</a>
<a href="https://linuxfr.org/users/raphj/journaux/simuler-un-clic-avec-libevdev-et-uinput#comments">ouvrir dans le navigateur</a>
</p>
raphjhttps://linuxfr.org/nodes/125293/comments.atomtag:linuxfr.org,2005:Diary/398932021-08-24T21:28:14+02:002021-08-24T21:28:14+02:00J'ai mangé une pommeLicence CC By‑SA http://creativecommons.org/licenses/by-sa/4.0/deed.fr<h2 class="sommaire">Sommaire</h2>
<ul class="toc">
<li><a href="#toc-lapprenti-jardinier">L'apprenti jardinier</a></li>
<li><a href="#toc-les-insectes-sont-nos-amis">Les insectes sont nos amis</a></li>
<li><a href="#toc-lennemi-de-mon-ennemi-est-mon-ami">L'ennemi de mon ennemi est mon ami</a></li>
<li><a href="#toc-la-lutte">La lutte</a></li>
<li><a href="#toc-la-r%C3%A9colte">La récolte</a></li>
<li>
<a href="#toc-comment-manger-des-pommes">Comment manger des pommes</a><ul>
<li><a href="#toc-la-compote">La compote</a></li>
<li><a href="#toc-la-tarte-normande">La tarte normande</a></li>
</ul>
</li>
<li><a href="#toc-la-vie-en-dehors-de-linformatique">La vie en dehors de l'informatique</a></li>
</ul>
<p>C'était une pomme de mon jardin.</p>
<p>Bonjour 'nal !</p>
<p>Aujourd'hui j'ai envie de te parler de ce qu'il se passe au delà de la fenêtre. Non, pas celle que t'affiche ton écran, plutôt celle qui est dans le mur. Faite de verre et de bois, ou d'aluminium, ou de PVC, elle marque une séparation avec cet univers mystérieux connu sous le nom d'extérieur. Viens, je t'emmène dans mon jardin.</p>
<h2 id="toc-lapprenti-jardinier">L'apprenti jardinier</h2>
<p>Assez rapidement après nous être installés dans notre logement actuel, ma compagne et moi-même avons planté quelques arbres fruitiers : un cerisier, deux pommiers et un poirier. En plus des pruniers et du… euh… ahem, nectarinier… déjà sur place il y a de quoi se faire une belle salade de fruits.</p>
<p>Ah quel plaisir de se nourrir de sa propre terre, n'est-ce pas ? Quel sentiment d'autonomie, de liberté ; et quel pied de nez à l'industrialisation et au grand capital ! Après ça il ne reste plus qu'à cultiver des légumes, avoir quelques poules et autres animaux, produire de l'électricité, trouver de l'eau potable, assainir les eaux usées, miner des métaux, forger des outils, tisser des vêtements, etc. et hop, c'est l'autonomie complète ! Tranquille.</p>
<p>Bon ça dérive déjà. Revenons-en aux pommes, puisque c'est le sujet de ce journal.</p>
<p>Madame voulait des <a href="https://fr.wikipedia.org/wiki/Pink%20Lady" title="Définition Wikipédia">Pink Lady</a>. Pas de chance, il s'agit d'une variété protégée de chez protégée, donc introuvable en pépinière. Du coup nous avons pris de l'<a href="https://fr.wikipedia.org/wiki/Elstar" title="Définition Wikipédia">Elstar</a>\ (ou Gala, je ne sais plus) ; c'est rouge, c'est bon, et il suffit d'y coller un petit papier « Punk Lady » pour faire illusion. Pour le second pommier c'est de la <a href="https://fr.wikipedia.org/wiki/Golden%20Delicious" title="Définition Wikipédia">Golden Delicious</a> ; la pomme de base quoi.</p>
<p>Nous avons pris les versions palissées (tu sais, l'arbre qui ressemble à une fourche) parce que c'est pas trop encombrant et que ça avait bien fonctionné chez mes parents. Tu mets ça le long d'un mur ensoleillé et c'est bon. Si tu veux faire dans le détail tu peux planifier avec <a href="https://openjardin.eu/">OpenJardin</a> — on en parle <a href="//linuxfr.org/users/open04/journaux/openjardin-derniere-mise-a-jour-de-la-version-1-07-12">ici</a> — ou <a href="https://garden-party.experimentslabs.com/">Garden Party</a> — on en parle <a href="//linuxfr.org/news/gestion-de-jardin-garden-party">là</a>. Perso j'aménage plutôt le jardin au <em>feeling</em>, quitte à déplacer quelques petites plantes de temps en temps. Et puis si je vais au jardin c'est aussi un peu pour lâcher l'écran :)</p>
<p>Quand c'est enfin planté : profit. Profit ? Allez, dis-moi que ça va être simple…</p>
<p><img src="//img.linuxfr.org/img/68747470733a2f2f692e696d6775722e636f6d2f654236576f48742e6a706567/eB6WoHt.jpeg" alt="Image de pommiers bien rangés." title="Source : https://i.imgur.com/eB6WoHt.jpeg"><br>
<em>Là ça a l'air de bien se passer.</em></p>
<h2 id="toc-les-insectes-sont-nos-amis">Les insectes sont nos amis</h2>
<p>Le paradoxe du jardinage : si tu veux manger des fruits de ton jardin, tu vas devoir lutter <strong>contre</strong> la nature. Perso j'ai deux soucis : les vers et les pucerons.</p>
<p>J'ai bien effectué quelques recherche sur le web pour trouver une solution mais malheureusement quand il s'agit de jardin Google ne remonte que de la daube : sites de SEO, magazines conso, recettes de grand-mère (mélangez deux once de bicarbonate de soude et une demie-fiole de nectar d'orties, puis versez la mixture au pied des arbres, de préférence avant la saint Romélise pour une efficacité optimale !!). C'est laborieux. Mais il est où le StackOverflow du jardin ?</p>
<p>Pour les vers, je n'ai pas encore de solution. En attendant, pas moyen de croquer aveuglément dans une pomme ou une prune, il y a une chance sur deux pour qu'il y ait un vers dégoûtant dedans. Le pire c'est qu'il ne le sait même pas, lui, qu'il est dégoûtant.</p>
<p>Pour les pucerons, je crois que je commence à gérer. Vois-tu, vers le mois d'avril ces insectes commencent à coloniser les plantes. Ils débarquent sous la forme de petits moucherons (un petit point noir avec des ailes) puis perdent leurs ailes et se reproduisent. Niveau occupation de l'espace, ça commence chez moi par les bourgeons des rosiers, puis les fruitiers, puis des arbustes quelconques (des feuillers ou des fleuriers), et enfin sur les lauriers.</p>
<p>Là où tu vois que la nature est bien faite c'est qu'ils adoptent une couleur semblable à leur support, ce qui les rend bien discrets (sauf sur les feuilles de laurier, où ils font du jaune. Va savoir pourquoi). En plus ils ont tendance à se mettre sous la feuille, qui parfois s'enroule sur elle-même. Une fois qu'ils sont là, c'est difficile de les déloger. Ils consomment alors la sève dans la feuille, se multiplient exponentiellement, jusqu'à couvrir toutes les feuilles de l'arbre. Ce dernier s'épuise alors, ses feuilles ne lui donnant plus d'énergie. Il fait alors la tête, les fruits sont tout petits, tombent trop tôt, et je meurs de faim.</p>
<p><img src="//img.linuxfr.org/img/68747470733a2f2f692e696d6775722e636f6d2f6f6858736770642e6a706567/ohXsgpd.jpeg" alt="Image de feuille enroulée." title="Source : https://i.imgur.com/ohXsgpd.jpeg"><br>
<em>Des feuilles enroulées par l'attaque des pucerons.</em></p>
<p><img src="//img.linuxfr.org/img/68747470733a2f2f692e696d6775722e636f6d2f436d73704d36432e6a706567/CmspM6C.jpeg" alt="Image de pucerons dans une feuille enroulée." title="Source : https://i.imgur.com/CmspM6C.jpeg"><br>
<em>Des pucerons bien planqués dans une feuille, avec quelques-un en version moucheron.</em></p>
<p>Bref, le puceron est un parasite qui se comporte un peu comme cet autre animal là, tu sais, celui qui use toutes les ressources de son environnement et se reproduit pour tout envahir. Mais si ! Rhâââ ça va me revenir.</p>
<h2 id="toc-lennemi-de-mon-ennemi-est-mon-ami">L'ennemi de mon ennemi est mon ami</h2>
<p>Le principal prédateur des pucerons est la coccinelle. C'est sympa une coccinelle, c'est tout mimi, et ça se goinfre d'une centaine de pucerons par jour. Enfin ça c'est quand elles peuvent accéder à leur repas sans se faire tabasser par les fourmis.</p>
<p><img src="//img.linuxfr.org/img/68747470733a2f2f692e696d6775722e636f6d2f704236697372552e6a706567/pB6isrU.jpeg" alt="Une larve de coccinelle au boulot." title="Source : https://i.imgur.com/pB6isrU.jpeg"><br>
<em>Une larve de coccinelle au boulot dans les feuilles bousillées d'un prunier, avec une coccinelle cachée.</em></p>
<p>Et oui, les fourmis protègent les pucerons. Elles en font même une sorte d'élevage. En gros elles les <s>mastur</s> <s>tripotent</s> stimulent afin qu'ils produisent du miellat. Je trouve ça un peu fou perso, et aussi bizarrement humain. Imagine, t'es un puceron, tu débarque avec ta famille sur une terre vierge (une feuille), tu commences à récolter de la bouffe (le miellat) pour te nourrir, et soudain il y a quelqu'un qui ressemble à rien de ce que tu connais, qui débarque et te transforme en esclave, te faisant trimer pour ensuite te piquer tes récoltes… Non mais oh, si tu veux du miellat tu te le récoltes tout seul chez toi hé !</p>
<h2 id="toc-la-lutte">La lutte</h2>
<p>Bon c'est pas tout mais j'aimerais bien manger mes fruits moi. Ces dernières années je commandais des larves de coccinelles à un spécialiste pour qu'elles nettoient mes plantes, mais évidemment ça ne fonctionnait pas bien puisqu'elles se faisaient briser la mâchoire par les fourmis. Du coup cette année j'ai changé de tactique (et puis je trouvais ça un peu con de faire livrer des insectes qui sont déjà présent dans l'environnement).</p>
<p>Le but du jeu est d'éviter que les fourmis ne trouvent les pucerons, en espérant qu'ainsi les coccinelles pourront faire leur taf'.</p>
<p><img src="//img.linuxfr.org/img/68747470733a2f2f692e696d6775722e636f6d2f474955625364742e6a706567/GIUbSdt.jpeg" alt="Moult larves qui libèrent les feuilles." title="Source : https://i.imgur.com/GIUbSdt.jpeg"><br>
<em>Moult larves qui libèrent les feuilles.</em></p>
<p>Pendant le mois d'avril, je ne vois pas beaucoup de coccinelles, alors je fais le gros du boulot : je fais le tour des plantes avec mon jet d'eau ou du savon noir, et je dégage les premiers pucerons. Au passage je repère les trajets des fourmis.</p>
<p>Ensuite je bloque ces dernières en essayant de couper les chemins qui vont du sol aux feuilles, par exemple en coupant les branches qui touchent les murs. Comme je ne peux pas couper le tronc (ça serait contre-productif) j'y mets de la glu arboricole. C'est une sorte de pâte collante à étaler sur quelques centimètres autour du tronc pour faire iéch les insectes qui essayent de monter. Celle que je prends est de la glu Pelton en pot et s'étale à la spatule pour bien combler les trous dans l'écorce.</p>
<p>Après cela j'attends que les coccinelles arrivent et j'enlève encore quelques pucerons si ça se propage trop. Par contre dès que je vois des œufs ou des larves de coccinelles, je n'y touche plus.</p>
<p>Si malgré tout cela des fourmis continuent à se pointer, genre elles n'ont pas compris qu'elles n'étaient pas les bienvenues, je passe à l'attaque en mettant quelques pièges près des fourmilières.</p>
<p>Ces pièges sont de petites boites en plastique contenant un produit toxique pour les fourmis mais présenté comme quelque-chose de plaisant pour elles. Quand une fourmi tombe dessus, elle s'émerveille : « trop bien la réserve de bouffe que je viens de trouver, il faut absolument que je prévienne les autres ! » Elle en prend un échantillon puis l'amène à la fourmilière. À peine passé le seuil, elle crie « Hé, vous tous ! Venez voir le tas de nourriture pas du tout douteux que j'ai trouvé juste à côté de l'entrée ! » Vaguement intriguées, quelques camarades l'accompagnent puis doivent se rendre à l'évidence. « Whoa ! Bien joué Régis, on va se régaler ! »</p>
<p>Et c'est ainsi que les fourmis amenèrent le poison dans la fourmilière. Toute la colonie s'en nourrit jusqu'à en mourir. Fin.</p>
<h2 id="toc-la-récolte">La récolte</h2>
<p>Pfiou… Des milliers de pucerons et de fourmis décédées pour que je puisse avoir une cinquantaine de pommes ; quel bilan. Il ne faut pas être partisan de la cause animale si tu veux manger des fruits.</p>
<p>Si tout se passe bien, une fois les fourmis écartées les coccinelles se multiplient et éliminent les pucerons en quelques semaines. Ensuite il ne reste plus qu'à arroser les plantes deux fois : une fois pour chaque semaine sans pluie de nos étés actuels.</p>
<p><img src="//img.linuxfr.org/img/68747470733a2f2f692e696d6775722e636f6d2f744652576d67462e6a706567/tFRWmgF.jpeg" alt="Pommiers et poirier en fin d'été" title="Source : https://i.imgur.com/tFRWmgF.jpeg"><br>
<em>En fin d'été, il fait moche, les mauvaises herbes ont tout envahi, tout est sec, mais il y a des fruits.</em></p>
<p>Ce qui est bien cool avec les pommes c'est qu'elles peuvent rester longtemps sur l'arbre. Pas d'urgence à les cueillir, tu peux même te contenter de celles qui tombent toute seules en septembre.</p>
<p>Question thunes, économies et autres aspect financiers, disons qu'un arbre coûte une cinquantaine d'euros et produit environ 5 kg de pommes. À 2€ le kilo au supermarché, ça fait une rentabilité sur au moins cinq ans. Sans compter le temps et le matériel pour l'entretien, ni les années « sans » (par exemple, cette année nous n'avons que deux poires).</p>
<h2 id="toc-comment-manger-des-pommes">Comment manger des pommes</h2>
<p>Si tu cherches des idées de recettes à base de pommes sur le web, tu vas tomber sur des sites moisis qui vont te demander d'accepter des cookies douteux pour ensuite te montrer une recette mal fichue dans laquelle tu devras défiler de haut en bas et de bas en haut en boucle avec tes doigts collants. Avec un peu de chance tu auras même une vidéo qui va se lancer en arrivant puis rester dans un coin.</p>
<p>J'ai entendu dire qu'un certain logiciel nommé Woob avait un module pour accéder à ces recettes sans l'enrobage de caca, peut-être que ça pourrait t'aider. Pour ma part, en cuisine comme au jardin, je préfère me passer d'écran.</p>
<p>Je vais donc te donner deux petites <s>algorithmes</s> recettes, simples, directes et précises. Pas de thermostat 7-8 chez moi ; c'est soit 7, soit 8. Je t'invite à les noter sur papier pour les garder dans ta cuisine.</p>
<h3 id="toc-la-compote">La compote</h3>
<p>Matos : un économe, un couteau, un mixeur, une casserole, 5 pommes, de la cannelle, de la vanille liquide, de l'eau.</p>
<ol>
<li>prends <strong>5 pommes</strong> ;</li>
<li>épluche chaque pomme ;</li>
<li>coupe toutes les pommes en deux ;</li>
<li>enlève le cœur des dix demies pommes ;</li>
<li>coupe les dix demies pommes en dés ;</li>
<li>balance tout ça dans une casserole ;</li>
<li>mets <strong>10 cl. d'eau</strong> dans un verre ;</li>
<li>ajoute <strong>une cuiller à soupe de vanille</strong> liquide ;</li>
<li>envoie ça dans la casserole ;</li>
<li>ajoutes-y <strong>une pincée de cannelle</strong> ;</li>
<li>fais chauffer à fond 20 minutes en remuant régulièrement ;</li>
<li>mixe le résultat puis verse-le dans des pots hermétiques.</li>
</ol>
<p>Attention dans les étapes 2 à 5, prends bien soin de faire toutes les pommes d'une traite à chaque étape et non pas de faire les quatre étapes sur chaque pomme individuellement. Tu économiseras ainsi du temps de changement de contexte (changement d'outil et d'opération) au prix de quelques allers-retours peu chers avec la mémoire cache (la planche à découper et le plan de travail).</p>
<p>Quoi qu'il arrive, n'ajoute surtout pas de sucre. Tu pourrais trouver dans le commerce de grandes marques de compote qui ajoutent du sucre. Ce sont des idiots, ne suis pas leur modèle.</p>
<h3 id="toc-la-tarte-normande">La tarte normande</h3>
<p>Matos : un économe, un couteau, un saladier, un fouet, un plat à tarte, un four, 3 pommes, 20 cl. de crème fraîche épaisse, de la cannelle, 100 g. de sucre, de la cassonade, une pâte feuilletée.</p>
<ol>
<li>étale la pâte feuilletée dans le plat ;</li>
<li>prends <strong>3 pommes</strong> ;</li>
<li>épluche chaque pomme ;</li>
<li>coupe toutes les pommes en deux ;</li>
<li>enlève le cœur des six demies pommes ;</li>
<li>coupe les six demies pommes en lamelles de 5 mm. d'épaisseur ;</li>
<li>met le four à chauffer à 180°C ;</li>
<li>met les lamelles dans le plat, sur trois couches ;</li>
<li>attrape le saladier et jettes-y le contenu de <strong>3 œufs</strong>, <strong>100 g. de sucre</strong>, <strong>20 cl. de crème fraîche</strong> et <strong>une pincée de cannelle</strong> ;</li>
<li>fouette le contenu du saladier jusqu'à ce que ce soit homogène ;</li>
<li>verse ça dans le plat ;</li>
<li>saupoudre la tarte de <strong>cassonade</strong> ;</li>
<li>met au four pendant 30 minutes.</li>
<li>profite du temps de cuisson pour faire la vaisselle.</li>
</ol>
<p>Comme pour la compote, prend bien soin de faire toutes les pommes d'un coup pour chaque étape de 2 à 6. Éventuellement si tu as plusieurs cœurs (des humains consentants) tu peux répartir ces étapes sur plusieurs threads.</p>
<h2 id="toc-la-vie-en-dehors-de-linformatique">La vie en dehors de l'informatique</h2>
<p>Je suis parfois surpris de trouver des analogies avec le développement logiciel dans la vie de tous les jours.</p>
<p>Par exemple, quand je programme j'ai tendance à vouloir itérer rapidement : j'implémente un truc, je le teste, je l'évalue, je le modifie et je recommence. C'est assez rapide, et modifier du code ne coûte pas cher. Mais quand je teste des trucs au jardin, c'est juste impossible de faire ça rapidement. Chaque modification s'évalue sur plusieurs mois, voire une année. C'est comme si le process tournait sur un CPU monocœur à 30 nanohertz et ne pouvait être interrompu.</p>
<p>Un jour je te raconterai aussi la refacto de l'intérieur de ma maison. Là aussi il y a des similarités, mais le coût de la modification est incroyablement plus grand. Par exemple, si tu veux finalement ajouter une prise alors que t'as terminé la peinture, ça coûte un peu plus que de déplacer quelques lignes de code ici et là.</p>
<p>Et toi, manges-tu des fruits ? Cultives-tu ton jardin et pourquoi ? Vois-tu aussi des similarités entre tes interactions avec des logiciels et la vie en dehors de l'informatique, ou au contraire connais-tu des choses simples dans l'un mais compliquées dans l'autre ?</p>
<div><a href="https://linuxfr.org/users/julien_jorge/journaux/j-ai-mange-une-pomme.epub">Télécharger ce contenu au format EPUB</a></div> <p>
<strong>Commentaires :</strong>
<a href="//linuxfr.org/nodes/125214/comments.atom">voir le flux Atom</a>
<a href="https://linuxfr.org/users/julien_jorge/journaux/j-ai-mange-une-pomme#comments">ouvrir dans le navigateur</a>
</p>
Julien Jorgehttps://linuxfr.org/nodes/125214/comments.atomtag:linuxfr.org,2005:Diary/391372020-05-08T21:39:31+02:002020-05-08T21:39:31+02:00Avant la reprise et pour préparer la sortie : du bricolage avec un ch’tit peu d’informatiqueLicence CC By‑SA http://creativecommons.org/licenses/by-sa/4.0/deed.fr<h2 class="sommaire">Sommaire</h2>
<ul class="toc">
<li><a href="#toc-gestion-des-masques">Gestion des masques</a></li>
<li><a href="#toc-des-flacons-de-solution-hydroalcoolique-sous-la-main">Des flacons de solution hydroalcoolique sous la main</a></li>
<li><a href="#toc-des-visi%C3%A8res">Des visières</a></li>
<li><a href="#toc-des-biscuits-pour-aller-plus-loin">Des biscuits pour aller plus loin</a></li>
</ul>
<p>Salut les gens,</p>
<p>Le déconfinement signifie seulement qu’il y a de la place dans les unités de soins intensifs pour les prochains malades, pas qu’on est débarrassés du virus. Mais ça vous le saviez. Donc il faudra continuer à prendre nos précautions (garder nos distances physiques, se laver les mains tout ça quoi).</p>
<p>Et alors j’ai réfléchi aux problèmes très concrets que ça pose et qu’on n’évoque pas beaucoup.</p>
<h2 id="toc-gestion-des-masques">Gestion des masques</h2>
<p>Les masques qu’il est maintenant très conseillé de porter. Si vous avez opté pour la solution du masque en tissu réutilisable, il en faut au moins deux ou trois pour une journée de travail. Je suggère de prévoir <a href="http://pix.toile-libre.org/?img=1588969724.jpg">deux pochettes différentes</a> une en tissu (ou en ce que vous voulez après tout, c’est pour les masques de rechange), une en matériel imperméable pour les masques portés. Si vous avez une machine à coudre et un vieux parapluie, vous pouvez vous faire rapidement une pochette genre taie d’oreiller (en couture anglaise c'est encore plus facile), qui n’a donc pas besoin de système de fermeture.</p>
<p>Par ailleurs, les capacités de filtre du tissu se dégradent au fil des lavages. Le nombre de lavages est estimé à entre cinq et vingt (cela dépend des tissus, et probablement un peu d’estimations au doigt mouillé). Je me suis dit qu’il fallait donc suivre le nombre de lavages des masques. J’ai donc concocté deux types de documents : </p>
<ul>
<li>
<strong><a href="https://numericoach.net/Gestion-des-masques-en-tissu">une feuille de calcul</a></strong> qui permet de suivre la durée de plusieurs masques (jusqu’à 50, mais, évidemment, c’est modifiable), on remplit les cellules des jours au fur et à mesure (une lettre, une date, peu importe, l’essentiel est que la cellule ne soit pas vide), la deuxième colonne compte le nombre de jours d’utilisation et se noircit de plus en plus, la ligne devient rouge quand on arrive au 15e jour et noire au 20e, la classe suprême c’est que, si vous avez installé Collabora Office ou Andropen Office (ou n’importe quelle autre suite bureautique utilisant le format ods) vous pouvez la remplir avec votre téléphone ou tablette Android ;</li>
<li>
<a href="https://numericoach.net/Gestion-des-masques-en-tissu-modele-pour-papier">un fichier svg ou pdf à imprimer</a> qui contient six « blocs » à découper, chacun pour un masque, on coche les cases au fur et à mesure, et c’est tout. Ça c’est pour, par exemple, mettre sur le réfrigérateur. J’imagine qu’on peut probablement transformer cela en activité ludique pour les enfants.</li>
</ul>
<p>Techniquement, la feuille de calcul, qui peut être utilisée à d’autres fins, évidemment, repose sur une seule fonction, NBVAL, et sur trois formats conditionnels. Rien de compliqué, il faut simplement faire attention à l’ordre des conditions.</p>
<p>Concernant le document svg, pour avoir mes six blocs bien propres, j’ai commencé par en faire un « grand » de la taille du « formulaire » final. Puis un autre plus petit qui a servi de cadre de référence pour l’agencement de tous les éléments et qui, rempli de ces éléments, est centré dans le plus grand, facile et simple à faire donc. Ensuite, des copier-coller et une répartition sur la feuille et on a nos six blocs en place.</p>
<h2 id="toc-des-flacons-de-solution-hydroalcoolique-sous-la-main">Des flacons de solution hydroalcoolique sous la main</h2>
<p>Concernant les solutions hydroalcooliques : avoir son flacon dans une poche (mais laquelle ?) ou au fond d’un sac, n’est pas ce qu’il y a de plus pratique (j’ai vérifié plus d’une fois). Par contre, porté autour du cou dans un genre d’étui. <a href="https://aiguilles-magiques.com/Bricolages-covidiens?lang=fr">On peut s’en bricoler un</a>, plus ou moins classe, avec ce qu’on a sous la main (si vous avez enfants pas trop petits, à mon avis, ça devrait assez plaire) et, cerise sur le gâteau, même faire la promotion du logiciel libre (ou de ce que vous voulez) avec. </p>
<h2 id="toc-des-visières">Des visières</h2>
<p>On peut aussi avoir des visières pour se protéger plus, et c’est plutôt à conseiller pour les petits enfants. Elles interviennent en complément de masques. Si vous voulez la faire vous-même :</p>
<ul>
<li>
<a href="https://www.youtube.com/watch?v=NHbqQXlA-XM">cette vidéo</a> (youtube) est ce que j’ai trouvé de mieux, elle utilise des fournitures qu’on a assez facilement sous la main (couverture de documents, classeur ou dossier en plastique et agrafeuse), j’ai essayé d’innover en remplaçant les agrafes par des attaches parisiennes, c’était une très mauvaise idée ;</li>
<li>si vous avez une imprimante 3D, le site de <a href="http://3d4care.org/">3D4Care.org</a> est tout indiqué.</li>
</ul>
<h2 id="toc-des-biscuits-pour-aller-plus-loin">Des biscuits pour aller plus loin</h2>
<p>Des liens sur les dispositifs barrières, les masques, le savon.</p>
<ul>
<li>
<a href="https://www.geres.org/cadre-general-materiels-de-protection/les-dispositifs-barriere/">Les dispositifs barrière</a>, un dossier du GERES (Groupe d’Études sur le Risque d’Exposition des Soignants) ;</li>
<li>
<a href="https://www.pourlascience.fr/sr/idees-physique/comment-fonctionnent-les-masques-de-protection-respiratoire-19054.php">Comment fonctionnent les masques de protection respiratoire</a>, un article de Pour la Science ;</li>
<li>
<a href="https://www.ifth.org/2020/04/29/covid-19-publication-de-la-base-de-donnees-avec-caracterisation-matiere-pour-la-realisation-de-masques-de-protection/">COVID-19 – Cahier des charges et base de données pour la réalisation de masques « grand public »</a>; IFTH (Institut Français du textile et de l’Habillement), on peut télécharger des modèles pour diverses tailles sans avoir à donner une quelconque information personnelle ;</li>
<li>
<a href="https://www.sudouest.fr/2020/04/23/efficacite-fabrication-distribution-ce-que-l-on-sait-des-masques-grand-public-7433198-10861.php">Masques grand public : Quelle efficacité ? Comment en trouver ? Comment les fabriquer ?</a>, un article de Sud-Ouest ;</li>
<li>
<a href="https://www.aiguilles-magiques.com/Faire-son-propre-patron-de-masque?lang=fr">Faire son propre patron de masque</a>, pour l’adapter à sa morphologie, contient quelques remarques sur le lavage ; </li>
<li>
<a href="https://www.afnor.org/actualites/coronavirus-telechargez-le-modele-de-masque-barriere/">Coronavirus : téléchargez le modèle de masque barrière</a>, AFNOR, vous demandera plein d’informations personnelles ;</li>
<li>
<a href="http://lepharmachien.com/masques/">Masques maison : mieux que rien</a>, un article du Pharmachien ;</li>
<li>
<a href="https://www.sudouest.fr/2020/05/05/vos-questions-comment-eviter-la-buee-sur-les-lunettes-en-portant-un-masque-7461264-10988.php">Vos questions : comment éviter la buée sur les lunettes en portant un masque ?</a> Un article de Sud-Ouest, pour un masque en tissu, j’ai testé, plier le haut est efficace, ajouter un fil métallique et aussi le masque « coque » sur mesure ;<br>
</li>
<li>
<a href="http://lepharmachien.com/covid-19-savon-alcool">Savon Corona Killer</a>, un article du Pharmachien .</li>
</ul>
<div><a href="https://linuxfr.org/users/ysabeau/journaux/avant-la-reprise-et-pour-preparer-la-sortie-du-bricolage-avec-un-ch-tit-peu-d-informatique.epub">Télécharger ce contenu au format EPUB</a></div> <p>
<strong>Commentaires :</strong>
<a href="//linuxfr.org/nodes/120363/comments.atom">voir le flux Atom</a>
<a href="https://linuxfr.org/users/ysabeau/journaux/avant-la-reprise-et-pour-preparer-la-sortie-du-bricolage-avec-un-ch-tit-peu-d-informatique#comments">ouvrir dans le navigateur</a>
</p>
Ysabeau 🧶 🧦https://linuxfr.org/nodes/120363/comments.atomtag:linuxfr.org,2005:Diary/388252019-12-04T16:38:39+01:002019-12-10T14:24:38+01:00Saison de calendriers de l'AventLicence CC By‑SA http://creativecommons.org/licenses/by-sa/4.0/deed.fr<p>Salut les gens,</p>
<p>c’est la saison, j’y peux rien c’est comme ça.</p>
<p>L’année dernière, <a href="//linuxfr.org/news/un-calendrier-de-l-avent-sur-le-theme-du-logiciel-libre">si vous vous souvenez</a>, ou pas, j’avais commis un calendrier de l’Avent sur le thème du logiciel libre. Cette année, il y en a un sur tous mes sites toujours sur le thème du logiciel libre.</p>
<h2 id="toc-bricolages-et-sensibilisation">Bricolages et sensibilisation</h2>
<p>Donc, vous trouverez des modèles de tricots, aujourd’hui c’est <a href="https://aiguilles-magiques.com/Manchot?lang=fr">jour de manchot</a> soit dit en passant, et autres bricolages à concocter sur <a href="https://aiguilles-magiques.com">aiguilles-magiques</a>. Le tricot prédomine, désolée, mais c’est encore de cette façon que j’arrive le mieux à faire de la 3D (sans bruit et sans matériel coûteux et encombrant). Et vous constaterez que mes talents en photo sont pitoyables. Cette année, c’est plus pédagogique sur le logiciel libre que l’année dernière. Évidemment, j’ai trouvé un biais pour parler de <a href="https://www.mageia.org/fr/">ma distribution préférée</a>.</p>
<p>Et comme ça, vous saurez comment faire le gens libre qui me sert d'avatar (oui, on dit un gens libre, des gens libres, c'est comme ça).</p>
<p>Il n’empêche que, j’ai constaté avec mes grilles de l’année dernière que c’était une façon sympathique de sensibiliser au logiciel libre.</p>
<h2 id="toc-panorama-des-distributions-linux">Panorama des distributions Linux</h2>
<p>Pour mon site de <a href="https://dutailly.net/">tutoriels</a>, j’ai opté pour le principe : un jour, une distribution avec une petite notice suggérant pour quelle raison choisir cette distribution. Il y en a une que je me dois d’indiquer dans ce panorama dont l’ambition est de montrer l’étendue des différentes « sortes » de distributions et pour laquelle je ne sais absolument pas quoi dire. Et je remercie FantastIX pour un de ses commentaires sur un journal car il m’a donné des arguments pour présenter l’une des distributions de ce <a href="https://dutailly.net/-calendrier-de-l-avent-2019-">calendrier de l’Avent</a></p>
<p>Oui, bien sûr, il y aura ma distribution préférée au menu (meunon, je ne suis pas monomaniaque).</p>
<h2 id="toc-modèles-et-gribouillages">Modèles et gribouillages</h2>
<p>Et enfin, sur <a href="https://numericoach.net/">numericoach</a>, vous trouverez comme <a href="//linuxfr.org/news/tout-ce-que-vous-avez-voulu-savoir-sur-linux-avant-de-vous-y-mettre#toc-des-mod%C3%A8les-de-libreoffice-et-une-proposition">annoncé</a> un modèle ou un dessin par jour. Le premier a été le modèle de <a href="https://numericoach.net/Document-long-filets-verts">document long</a> du guide <a href="https://numericoach.net/Linux-une-introduction">Linux : une introduction</a>. Aujourd’hui, c’est un <a href="https://numericoach.net/CV-simple-photo">CV tout simple avec photo</a> et plutôt efficace. À chaque fois, les spécifications sont données sur le site et dans le document et ses Propriétés.</p>
<h2 id="toc-calendriers-chers-qui-se-sont-tus">Calendriers chers qui se sont tus</h2>
<p>Sinon, l’année dernière, j’avais aussi signalé le <a href="http://aventdudomainepublic.org/">calendrier de l’Avent du domaine public</a> qui ne semble pas (encore ?) en ligne. Et on m’avait indiqué celui de <a href="https://voidlinux.org/news/">voidlinux</a>. Cette année, il semble qu’il n’y en aura pas non plus, dommage.</p>
<h2 id="toc-les-autres-rajoutés-au-fil-de-lʼeau">Les autres, rajoutés au fil de lʼeau</h2>
<p>Avent du site <a href="https://clgdrouyn.fr/maths/calendrier.html">Maths au collège Léo Drouyn</a> avec des petits exercices de maths et de logique.</p>
<p>Des calendriers de l'Avent diversifiés en anglais</p>
<ul>
<li><a href="http://perladvent.org/2019/">Perl Advent Calendar 2019</a></li>
<li><a href="https://perl6advent.wordpress.com/">Raku Advent Calendar</a></li>
<li><a href="https://perlweeklychallenge.org/blog/advent-calendar-2019/">Perl Weekly Challenge Advent Calendar 2019</a></li>
<li><a href="https://adventofcode.com">Advent of Code</a></li>
<li><a href="https://tryhackme.com/christmas">Advent of Cyber</a></li>
<li><a href="https://andrewshitov.com/2019/11/25/a-language-a-day-advent-calendar-2019/">A Language a Day</a></li>
<li><a href="https://ml.christmas/">Machine Learning</a></li>
<li><a href="https://javascript.christmas/">Javascript</a></li>
</ul>
<p>Les calendriers Machine Learning et Javascript proposent aussi des liens vers d'autres calendriers, CSS, Cloud, etc. et <a href="https://opensource.christmas/"><strong>Open source</strong></a>.</p>
<p><a href="https://blog.mozfr.org/post/2019/12/Calendrier-Avent-2019-astuces-pour-Firefox-semaine-1">Calendrier de l'Avent de Mozilla francophone avec des astuces pour Firefox</a>.</p>
<h2 id="toc-des-suggestions">Des suggestions ?</h2>
<p>Si vous avez des suggestions de calendriers de l’Avent à ajouter à cette liste ou de bricolage (tricot, couture, papier, recyclage) et de modèles de documents à cette liste (mes calendriers ne sont pas figés, ni hum, finis), je suis preneuse.</p>
<p>Merci et bon mois de décembre.</p>
<div><a href="https://linuxfr.org/users/ysabeau/journaux/saison-de-calendriers-de-l-avent.epub">Télécharger ce contenu au format EPUB</a></div> <p>
<strong>Commentaires :</strong>
<a href="//linuxfr.org/nodes/118821/comments.atom">voir le flux Atom</a>
<a href="https://linuxfr.org/users/ysabeau/journaux/saison-de-calendriers-de-l-avent#comments">ouvrir dans le navigateur</a>
</p>
Ysabeau 🧶 🧦https://linuxfr.org/nodes/118821/comments.atomtag:linuxfr.org,2005:Diary/387602019-11-07T13:06:49+01:002019-11-07T13:06:49+01:00Le Guide pour Apprendre à Réparer ses Appareils ÉlectroMénagers et Électronique Soi-mêmeLicence CC By‑SA http://creativecommons.org/licenses/by-sa/4.0/deed.fr<p>le GARAEMES vient de sortir.</p>
<p><img src="//img.linuxfr.org/img/68747470733a2f2f6174656c69657068656d6572652e6f72672f7075626c69632f2e726563746f5f67756964655f6d2e6a7067/.recto_guide_m.jpg" alt="annonce de sortie" title="Source : https://ateliephemere.org/public/.recto_guide_m.jpg"></p>
<ul>
<li><a href="https://ateliephemere.org/?post/2016/11/04/Sortie-du-GARAEMES">https://ateliephemere.org/?post/2016/11/04/Sortie-du-GARAEMES</a></li>
</ul>
<p>Je ne l'ai pas eu entre les mains et je ne vois pas de version électronique, mais ça vaut bien un journal. On peut le commander, et il est consultable au <a href="http://remue-meninges.com/site/">Remue Méninges</a> à St Étienne.</p>
<div><a href="https://linuxfr.org/users/dzecniv/journaux/le-guide-pour-apprendre-a-reparer-ses-appareils-electromenagers-et-electronique-soi-meme.epub">Télécharger ce contenu au format EPUB</a></div> <p>
<strong>Commentaires :</strong>
<a href="//linuxfr.org/nodes/118566/comments.atom">voir le flux Atom</a>
<a href="https://linuxfr.org/users/dzecniv/journaux/le-guide-pour-apprendre-a-reparer-ses-appareils-electromenagers-et-electronique-soi-meme#comments">ouvrir dans le navigateur</a>
</p>
dzecnivhttps://linuxfr.org/nodes/118566/comments.atomtag:linuxfr.org,2005:Bookmark/6622019-05-24T10:44:59+02:002019-05-24T15:54:13+02:00Comment faire un sac avec tous les tours de cou achetés pour soutenir le libre ou récupérés<a href="https://www.instructables.com/id/Lanyard-Collage-Bag/">https://www.instructables.com/id/Lanyard-Collage-Bag/</a> <p>
<strong>Commentaires :</strong>
<a href="//linuxfr.org/nodes/117295/comments.atom">voir le flux Atom</a>
<a href="https://linuxfr.org/users/ysabeau/liens/comment-faire-un-sac-avec-tous-les-tours-de-cou-achetes-pour-soutenir-le-libre-ou-recuperes#comments">ouvrir dans le navigateur</a>
</p>
Ysabeau 🧶 🧦https://linuxfr.org/nodes/117295/comments.atomtag:linuxfr.org,2005:Diary/384202019-03-26T17:53:48+01:002019-03-26T17:53:48+01:00QCM et chaudron bouillonnant pour Libre en fêteLicence CC By‑SA http://creativecommons.org/licenses/by-sa/4.0/deed.fr<p>Ma petite participation à <a href="https://libre-en-fete.net/2019/">Libre en fête 2019</a>.</p>
<p>Au départ, j'avais l'idée de faire de*<em>s</em>* modèle*<em>s</em>* dédiées à l'enseignement, finalement j'ai réduit la voilure. Donc ma contribution à Libre en Fête consiste en : </p>
<ul>
<li>la publication d'un <a href="https://numericoach.net/Modele-de-QCM-au-format-OTS">modèle de classeur au format ots pour faire des QCM</a>, il pose les questions, donne les solutions dans une autre feuille si on a répondu et les scores accompagné d'un commentaire en fonction d'icelui dans une troisième feuille, pas de macros ;</li>
<li>un <a href="https://dutailly.net/un-qcm-avec-calc">tutoriel qui explique les objectifs et la structure du classeur ainsi que les fonctionnalités nécessaires</a>, il y a aussi deux-trois astuces pour mieux le tableur en général ;</li>
<li>un bricolage, qui n'a rien à voir avec le QCM ci-dessus mais tout à voir avec la plus chouette, la plus bleue et la plus magiques des distributions, à savoir Mageia, puisque <a href="https://aiguilles-magiques.com/Chaudron-de-papier?lang=fr">c'est une boite en forme de chaudron bouillonnant à faire en pailles de papier</a>.</li>
</ul>
<p>Concernant le QCM, si je précise « pas de macros » c'est, outre le fait que je ne connais pas de langage de macro, je pense qu'avant de penser « on va faire une macro pour faire ça » il vaut mieux se poser la question de ce que propose le logiciel et de voir quelles fonctionnalités et comment les utiliser pour arriver au résultat prévu. En fait, un bon nombre de macros existantes en bureautique ont été faites pour palier des fichiers (principalement des classeurs) mal conçus ou l'ignorance des utilisateurs et utilisatrices finaux. Ce qui finit par poser des problèmes sur le long terme : maintien des macros, compatibilité avec les évolutions du logiciel, évolution du document, sans oublier les histoires de sécurité.</p>
<p>Si c'est mon petit bricolage (oui je sais, maintenant on dit DIY, enfin écrit…) qui vous intéresse, a priori, on pourrait tout à fait faire un boitier pour Raspberry avec cette technique, voire un boitier et un pied pour le <a href="//linuxfr.org/news/le-terminal-libre-diskio-pi-renait-de-ses-cendres">Diskio Pi</a>. Et on n'est pas obligé de le faire en forme de chaudron. Même si le chaudron c'est mieux (soyons sérieux tout de même). On peut laisser cours à son imagination, je sais pas moi, faire un boitier en forme de poisson (j'ai cru comprendre que c'était un argument clé pour le choix d'un environnement de bureau), de chapeau, de poire, de manchot, de pomme, enfin ce qu'on veut quoi.</p>
<p>De toute façon, amusez-vous bien, c’est le plus important.</p>
<div><a href="https://linuxfr.org/users/ysabeau/journaux/qcm-et-chaudron-bouillonnant-pour-libre-en-fete.epub">Télécharger ce contenu au format EPUB</a></div> <p>
<strong>Commentaires :</strong>
<a href="//linuxfr.org/nodes/116782/comments.atom">voir le flux Atom</a>
<a href="https://linuxfr.org/users/ysabeau/journaux/qcm-et-chaudron-bouillonnant-pour-libre-en-fete#comments">ouvrir dans le navigateur</a>
</p>
Ysabeau 🧶 🧦https://linuxfr.org/nodes/116782/comments.atomtag:linuxfr.org,2005:News/366862015-09-11T00:40:44+02:002015-09-11T13:47:48+02:00Internet des objets l'ESP8266 et ma porte de garageLicence CC By‑SA http://creativecommons.org/licenses/by-sa/4.0/deed.fr<div><p>Dans ma maison, j'ai un garage dont la porte est motorisée ; avec une petite télécommande (433MHz) on peut l' ouvrir ou la fermer depuis la voiture, ce qui est bien pratique en hiver. Mais il y a deux problèmes : le premier c'est que la télécommande fonctionne aléatoirement (ce qui n'est pas pratique), le second c'est la sécurité du 433MHz.</p>
<p>Ayant un Arduino UNO qui traîne dans un coin, ma maison étant domotisée (serveur fait-maison tournant sur du Python, du PHP, des scripts shell et le tout reposant sur xpl-perl) je me suis dit que le serveur domotique pourrait piloter la porte.<br>
Il peut déjà lire l'état de la porte du garage avec un capteur d'ouverture. </p>
<p>Le moteur de la porte fournit un contact sec. Il suffit de ponter deux fils raccordés à un bornier pour actionner la porte : ouvrir si elle est fermée ou fermer si elle est ouverte.</p>
<p>Avec un Arduino et un relais on peut actionner sans problème la porte du garage. Je code vite fait un petit bout de script qui me permet d'activer un relais 1.5 seconde.<br>
Le problème : il faut donner les ordres par un câble USB à l'Arduino donc je pars en recherche d'une carte WI-FI pour l'Arduino et c'est là que je tombe sur l'ESP8266.</p></div><ul><li>lien nᵒ 1 : <a title="http://mchobby.be/wiki/index.php?title=Accueil" hreflang="fr" href="https://linuxfr.org/redirect/94949">Wiki de mchobby, plein de choses sur l'embarqué</a></li><li>lien nᵒ 2 : <a title="http://esp8266.co.uk/" hreflang="en" href="https://linuxfr.org/redirect/94950">Vendeur d'esp8266 avec tutoriel LUA</a></li><li>lien nᵒ 3 : <a title="http://www.chipandlove.ch/fr/" hreflang="fr" href="https://linuxfr.org/redirect/94951">Magasin suisse où j'ai commandé mes esp-01</a></li><li>lien nᵒ 4 : <a title="http://www.les-electroniciens.com/videos/arduino-ep16-installation-du-module-wifi-esp8266" hreflang="fr" href="https://linuxfr.org/redirect/94952">Présentation vidéo prog esp par arduino</a></li><li>lien nᵒ 5 : <a title="http://www.electrodragon.com/w/ESP8266" hreflang="en" href="https://linuxfr.org/redirect/94953">Page d'electrodragon sur l'esp8266</a></li><li>lien nᵒ 6 : <a title="https://www.arduino.cc/en/Main/Software" hreflang="en" href="https://linuxfr.org/redirect/94954">Dernière version de l'IDE Arduino</a></li></ul><div><h2 class="sommaire">Sommaire</h2>
<ul class="toc">
<li>
<a href="#pr%C3%A9sentation-de-lesp8266">Présentation de l'ESP8266</a><ul>
<li>
<a href="#premier-essai-avec-lesp-01-esp8266">Premier essai avec l'ESP-01 (ESP8266)</a><ul>
<li><a href="#premier-montage-%C3%A9chec">Premier montage échec</a></li>
<li><a href="#deuxi%C3%A8me-essai-concluant">Deuxième essai concluant</a></li>
</ul>
</li>
</ul>
</li>
<li>
<a href="#montage-d%C3%A9finitif">Montage définitif</a><ul>
<li><a href="#probl%C3%A8mes-techniques">Problèmes techniques</a></li>
<li><a href="#sch%C3%A9ma-technique">Schéma technique</a></li>
<li><a href="#programme-esp-01">Programme ESP-01</a></li>
<li><a href="#int%C3%A9gration-dans-la-domotique-existante">intégration dans la domotique existante</a></li>
</ul>
</li>
<li><a href="#s%C3%A9curit%C3%A9">Sécurité</a></li>
<li><a href="#conclusion">Conclusion</a></li>
</ul><h2 id="présentation-de-lesp8266">Présentation de l'ESP8266</h2>
<p>L'ESP8266 est un extraterrestre apparu dernièrement (vers 2014 me semble-t-il). <br>
C'est une toute petite carte (de la taille d'une pièce de 2€ approximativement) qui contient un processeur tournant à 80MHz, une puce WI-FI avec son antenne, un port série et deux gpio (pour la version ESP-01) ; il existe d'autres versions qui peuvent contenir beaucoup plus de gpio mais elles sont légèrement plus chères et plus grandes. Bref, dans notre cas, la version ESP-01 coûte dans les 5€ environ. </p>
<p><img src="//img.linuxfr.org/img/68747470733a2f2f6f776e636c6f75642e73656c6e65742e63682f696e6465782e7068702f617070732f66696c65735f73686172696e672f7075626c6963707265766965773f66696c653d2532462532465769466925323053657269616c2532305472616e736365697665722532304d6f64756c652e6a706726783d3139303226793d38383826613d7472756526743d7a6e5037384e714773394d44667078267363616c696e6775703d3026666f72636549636f6e3d30/publicpreview?file=%2F%2FWiFi%20Serial%20Transceiver%20Module.jpg&x=1902&y=888&a=true&t=znP78NqGs9MDfpx&scalingup=0&forceIcon=0" alt="ESP8266 version ESP-01" title="Source : https://owncloud.selnet.ch/index.php/apps/files_sharing/publicpreview?file=%2F%2FWiFi%20Serial%20Transceiver%20Module.jpg&x=1902&y=888&a=true&t=znP78NqGs9MDfpx&scalingup=0&forceIcon=0"></p>
<p>Il est semble-t-il opensource, compatible Arduino, vous pouvez le reflasher à votre guise, lui changer le bootloader. Vous pouvez lui faire tourner un firmware à base de Lua, ou de micro-Python (expérimental). Par défaut il se programme avec l'IDE de l'Arduino (attention à utiliser la dernière version depuis le site d'arduino). Vous pouvez même si vous le voulez ne pas le programmer et le configurer avec des commandes AT.</p>
<h3 id="premier-essai-avec-lesp-01-esp8266">Premier essai avec l'ESP-01 (ESP8266)</h3>
<p>Donc après avoir passer de longues soirées à chercher sur Internet (il y a tellement de possibilités) comment cela fonctionnait, je me décide à en commander un (comme je suis en Suisse j'en ai trouvé chez Chipandlove), pour 8,5 CHF, je ne prends pas beaucoup de risques.</p>
<p>La bête arrive le lendemain par la poste, le soir je le déballe et je commence à jouer avec.</p>
<p>Premier constat, l'Arduino fonctionne en 5V et l'ESP en 3.3V, c'est chiant il va falloir gérer une double alim (la sortie 3.3v de l'Arduino ne fournit que 30mA et l'ESP a besoin de 300mA environ), donc un montage avec un LF33CV fera l'affaire (régulateur de 3.3V).</p>
<h4 id="premier-montage-échec">Premier montage échec</h4>
<p>Je modifie mon programme Arduino, à la mise sous tension il programme l'ESP avec une série de commande AT, puis il écoute ce qu'il vient depuis l'ESP. Quand je fais une requête via le WI-FI sur l'ESP, il émet bien quelque chose sur l'Arduino mais ça ne marche pas toujours, peu concluant, surtout que le tout pour être opérationnel prend pas mal de temps (le temps que l'Arduino programme l'ESP avec les commandes AT).</p>
<h4 id="deuxième-essai-concluant">Deuxième essai concluant</h4>
<p>On garde le même câblage mais je remets mon logiciel d'origine dans l'Arduino, il ne s'occupe plus de l'ESP. Je programme avec l'IDE de l'Arduino, l'ESP je pars des exemples fournis. Quand je fais une requête <code>http://IP/garage</code> il envoie sur le port série la commande d'ouverture que l'Arduino exécute. Youpi ça marche.</p>
<p><img src="//img.linuxfr.org/img/68747470733a2f2f6f776e636c6f75642e73656c6e65742e63682f696e6465782e7068702f617070732f66696c65735f73686172696e672f7075626c6963707265766965773f66696c653d253246253246315f65737361692e6a706726783d3139323026793d39313826613d7472756526743d7a6e5037384e714773394d44667078267363616c696e6775703d3026666f72636549636f6e3d30/publicpreview?file=%2F%2F1_essai.jpg&x=1920&y=918&a=true&t=znP78NqGs9MDfpx&scalingup=0&forceIcon=0" alt="Montage commande garage avec arduino" title="Source : https://owncloud.selnet.ch/index.php/apps/files_sharing/publicpreview?file=%2F%2F1_essai.jpg&x=1920&y=918&a=true&t=znP78NqGs9MDfpx&scalingup=0&forceIcon=0"></p>
<p>Génial, mais l'Arduino ne sert à rien vu que l'ESP-01 a deux GPIO il pourrait bien piloter lui-même le garage.</p>
<h2 id="montage-définitif">Montage définitif</h2>
<p>Donc je supprime l'Arduino, je modifie le soft de l'ESP pour qu'il commande lui-même le garage</p>
<p><img src="//img.linuxfr.org/img/68747470733a2f2f6f776e636c6f75642e73656c6e65742e63682f696e6465782e7068702f617070732f66696c65735f73686172696e672f7075626c6963707265766965773f66696c653d2532462532466d6f6e746167655f6761726167652e6a706726783d3139323026793d39313826613d7472756526743d7a6e5037384e714773394d44667078267363616c696e6775703d3026666f72636549636f6e3d30/publicpreview?file=%2F%2Fmontage_garage.jpg&x=1920&y=918&a=true&t=znP78NqGs9MDfpx&scalingup=0&forceIcon=0" alt="Montage définitif" title="Source : https://owncloud.selnet.ch/index.php/apps/files_sharing/publicpreview?file=%2F%2Fmontage_garage.jpg&x=1920&y=918&a=true&t=znP78NqGs9MDfpx&scalingup=0&forceIcon=0"></p>
<h3 id="problèmes-techniques">Problèmes techniques</h3>
<p>L'ESP a au démarrage ses port gpio à +3.3V si vous l'utilisez pour la commande à niveau logique haut (+3.3V). Il suffirait d'une coupure de courant pour ouvrir le garage (sympa la sécurité). Donc j'utilise une commande inverse (mise à la masse).</p>
<p>L'ESP ne peut pas démarrer si la gpio est à la masse (même au travers d'une résistance et d'une diode (Base-Emetteur d'un transistor par exemple)) de ce fait nous allons utiliser un optocoupleur et la patte de masse de l'entrée de l'opto sera reliée à notre gpio. La patte d'entrée de l'opto étant reliée au travers d'une résistance au 3.3v. Comme ça lorsque l'ESP démarre la gpio est reliée au +3.3V</p>
<h3 id="schéma-technique">Schéma technique</h3>
<p>Je vous ai mis le schéma technique, j'utilise un opto-triac parce que j'avais pas d'opto-coupleur en stock mais un opto-coupleur fera bien l'affaire.</p>
<p>Comme alimentation j'utilise une alim USB de 5V 2A. Pour alimenter l'ESP j'utilise un régulateur LF33CV qui me sort du +3.3V 500mA. Attention si vous faîtes votre 3.3V depuis une alim de 12V par exemple veuillez prévoir un refroidissement pour le LF33CV.</p>
<p><img src="//img.linuxfr.org/img/68747470733a2f2f6f776e636c6f75642e73656c6e65742e63682f696e6465782e7068702f617070732f66696c65735f73686172696e672f7075626c6963707265766965773f66696c653d2532462532466761726167655f736368656d612e706e6726783d3139323026793d39313826613d7472756526743d7a6e5037384e714773394d44667078267363616c696e6775703d3026666f72636549636f6e3d30/publicpreview?file=%2F%2Fgarage_schema.png&x=1920&y=918&a=true&t=znP78NqGs9MDfpx&scalingup=0&forceIcon=0" alt="Schéma" title="Source : https://owncloud.selnet.ch/index.php/apps/files_sharing/publicpreview?file=%2F%2Fgarage_schema.png&x=1920&y=918&a=true&t=znP78NqGs9MDfpx&scalingup=0&forceIcon=0"></p>
<p>Je travaille en +5V parce que j'ai une carte relais de +5V mais rien ne vous empêche d'utiliser d'autres relais sous d'autres tensions. Attention si vous attaquez un relais en direct n'oubliez pas de le piloter depuis un transistor (l'opto ne supportera pas le courant consommé par le relais) et de mettre une diode inverse sur votre relais pour éviter de bousiller votre électronique.</p>
<h3 id="programme-esp-01">Programme ESP-01</h3>
<p>Voici le programme que j'ai injecté dans l'ESP depuis l'IDE de l'Arduino (attention prenez la dernière version sur le site, celle contenue dans les dépôts d'ubuntu 14.04 est trop vieille).</p>
<pre><code class="cpp"><span class="cp">#include <ESP8266WiFi.h></span>
<span class="cp">#include <WiFiClient.h></span>
<span class="cp">#include <ESP8266WebServer.h></span>
<span class="cp">#include <ESP8266mDNS.h></span>
<span class="k">const</span> <span class="kt">char</span><span class="o">*</span> <span class="n">ssid</span> <span class="o">=</span> <span class="s">"lereseauwifi"</span><span class="p">;</span>
<span class="k">const</span> <span class="kt">char</span><span class="o">*</span> <span class="n">password</span> <span class="o">=</span> <span class="s">"lacleewpa2"</span><span class="p">;</span>
<span class="k">const</span> <span class="kt">int</span> <span class="n">relais</span> <span class="o">=</span> <span class="mi">2</span><span class="p">;</span>
<span class="n">MDNSResponder</span> <span class="n">mdns</span><span class="p">;</span>
<span class="n">ESP8266WebServer</span> <span class="nf">server</span><span class="p">(</span><span class="mi">80</span><span class="p">);</span>
<span class="k">const</span> <span class="kt">int</span> <span class="n">led</span> <span class="o">=</span> <span class="mi">13</span><span class="p">;</span>
<span class="kt">void</span> <span class="nf">handleRoot</span><span class="p">()</span> <span class="p">{</span>
<span class="n">digitalWrite</span><span class="p">(</span><span class="n">led</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span>
<span class="n">server</span><span class="p">.</span><span class="n">send</span><span class="p">(</span><span class="mi">200</span><span class="p">,</span> <span class="s">"text/plain"</span><span class="p">,</span> <span class="s">"hello from esp8266!"</span><span class="p">);</span>
<span class="n">digitalWrite</span><span class="p">(</span><span class="n">led</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span>
<span class="p">}</span>
<span class="kt">void</span> <span class="nf">handleNotFound</span><span class="p">(){</span>
<span class="n">digitalWrite</span><span class="p">(</span><span class="n">led</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span>
<span class="n">String</span> <span class="n">message</span> <span class="o">=</span> <span class="s">"File Not Found</span><span class="se">\n\n</span><span class="s">"</span><span class="p">;</span>
<span class="n">message</span> <span class="o">+=</span> <span class="s">"URI: "</span><span class="p">;</span>
<span class="n">message</span> <span class="o">+=</span> <span class="n">server</span><span class="p">.</span><span class="n">uri</span><span class="p">();</span>
<span class="n">message</span> <span class="o">+=</span> <span class="s">"</span><span class="se">\n</span><span class="s">Method: "</span><span class="p">;</span>
<span class="n">message</span> <span class="o">+=</span> <span class="p">(</span><span class="n">server</span><span class="p">.</span><span class="n">method</span><span class="p">()</span> <span class="o">==</span> <span class="n">HTTP_GET</span><span class="p">)</span><span class="o">?</span><span class="s">"GET"</span><span class="o">:</span><span class="s">"POST"</span><span class="p">;</span>
<span class="n">message</span> <span class="o">+=</span> <span class="s">"</span><span class="se">\n</span><span class="s">Arguments: "</span><span class="p">;</span>
<span class="n">message</span> <span class="o">+=</span> <span class="n">server</span><span class="p">.</span><span class="n">args</span><span class="p">();</span>
<span class="n">message</span> <span class="o">+=</span> <span class="s">"</span><span class="se">\n</span><span class="s">"</span><span class="p">;</span>
<span class="k">for</span> <span class="p">(</span><span class="kt">uint8_t</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">i</span><span class="o"><</span><span class="n">server</span><span class="p">.</span><span class="n">args</span><span class="p">();</span> <span class="n">i</span><span class="o">++</span><span class="p">){</span>
<span class="n">message</span> <span class="o">+=</span> <span class="s">" "</span> <span class="o">+</span> <span class="n">server</span><span class="p">.</span><span class="n">argName</span><span class="p">(</span><span class="n">i</span><span class="p">)</span> <span class="o">+</span> <span class="s">": "</span> <span class="o">+</span> <span class="n">server</span><span class="p">.</span><span class="n">arg</span><span class="p">(</span><span class="n">i</span><span class="p">)</span> <span class="o">+</span> <span class="s">"</span><span class="se">\n</span><span class="s">"</span><span class="p">;</span>
<span class="p">}</span>
<span class="n">server</span><span class="p">.</span><span class="n">send</span><span class="p">(</span><span class="mi">404</span><span class="p">,</span> <span class="s">"text/plain"</span><span class="p">,</span> <span class="n">message</span><span class="p">);</span>
<span class="n">digitalWrite</span><span class="p">(</span><span class="n">led</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span>
<span class="n">Serial</span><span class="p">.</span><span class="n">println</span><span class="p">(</span><span class="s">"10"</span><span class="p">);</span>
<span class="p">}</span>
<span class="kt">void</span> <span class="nf">setup</span><span class="p">(</span><span class="kt">void</span><span class="p">){</span>
<span class="n">pinMode</span><span class="p">(</span><span class="n">led</span><span class="p">,</span> <span class="n">OUTPUT</span><span class="p">);</span>
<span class="n">pinMode</span><span class="p">(</span><span class="n">relais</span><span class="p">,</span> <span class="n">OUTPUT</span><span class="p">);</span>
<span class="n">digitalWrite</span><span class="p">(</span><span class="n">relais</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span>
<span class="n">digitalWrite</span><span class="p">(</span><span class="n">led</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span>
<span class="n">Serial</span><span class="p">.</span><span class="n">begin</span><span class="p">(</span><span class="mi">9600</span><span class="p">);</span>
<span class="n">WiFi</span><span class="p">.</span><span class="n">begin</span><span class="p">(</span><span class="n">ssid</span><span class="p">,</span> <span class="n">password</span><span class="p">);</span>
<span class="n">Serial</span><span class="p">.</span><span class="n">println</span><span class="p">(</span><span class="s">""</span><span class="p">);</span>
<span class="c1">// Wait for connection</span>
<span class="k">while</span> <span class="p">(</span><span class="n">WiFi</span><span class="p">.</span><span class="n">status</span><span class="p">()</span> <span class="o">!=</span> <span class="n">WL_CONNECTED</span><span class="p">)</span> <span class="p">{</span>
<span class="n">delay</span><span class="p">(</span><span class="mi">500</span><span class="p">);</span>
<span class="n">Serial</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="s">"."</span><span class="p">);</span>
<span class="p">}</span>
<span class="n">Serial</span><span class="p">.</span><span class="n">println</span><span class="p">(</span><span class="s">""</span><span class="p">);</span>
<span class="n">Serial</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="s">"Connected to "</span><span class="p">);</span>
<span class="n">Serial</span><span class="p">.</span><span class="n">println</span><span class="p">(</span><span class="n">ssid</span><span class="p">);</span>
<span class="n">Serial</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="s">"IP address: "</span><span class="p">);</span>
<span class="n">Serial</span><span class="p">.</span><span class="n">println</span><span class="p">(</span><span class="n">WiFi</span><span class="p">.</span><span class="n">localIP</span><span class="p">());</span>
<span class="k">if</span> <span class="p">(</span><span class="n">mdns</span><span class="p">.</span><span class="n">begin</span><span class="p">(</span><span class="s">"esp8266"</span><span class="p">,</span> <span class="n">WiFi</span><span class="p">.</span><span class="n">localIP</span><span class="p">()))</span> <span class="p">{</span>
<span class="n">Serial</span><span class="p">.</span><span class="n">println</span><span class="p">(</span><span class="s">"MDNS responder started"</span><span class="p">);</span>
<span class="p">}</span>
<span class="n">server</span><span class="p">.</span><span class="n">on</span><span class="p">(</span><span class="s">"/"</span><span class="p">,</span> <span class="n">handleRoot</span><span class="p">);</span>
<span class="n">server</span><span class="p">.</span><span class="n">on</span><span class="p">(</span><span class="s">"/garage"</span><span class="p">,</span> <span class="p">[](){</span>
<span class="n">server</span><span class="p">.</span><span class="n">send</span><span class="p">(</span><span class="mi">200</span><span class="p">,</span> <span class="s">"text/plain"</span><span class="p">,</span> <span class="s">"ok garage actionned"</span><span class="p">);</span>
<span class="n">Serial</span><span class="p">.</span><span class="n">println</span><span class="p">(</span><span class="s">"10"</span><span class="p">);</span>
<span class="n">digitalWrite</span><span class="p">(</span><span class="n">relais</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span>
<span class="n">delay</span><span class="p">(</span><span class="mi">1500</span><span class="p">);</span>
<span class="n">digitalWrite</span><span class="p">(</span><span class="n">relais</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span>
<span class="p">});</span>
<span class="n">server</span><span class="p">.</span><span class="n">onNotFound</span><span class="p">(</span><span class="n">handleNotFound</span><span class="p">);</span>
<span class="n">server</span><span class="p">.</span><span class="n">begin</span><span class="p">();</span>
<span class="n">Serial</span><span class="p">.</span><span class="n">println</span><span class="p">(</span><span class="s">"HTTP server started"</span><span class="p">);</span>
<span class="p">}</span>
<span class="kt">void</span> <span class="nf">loop</span><span class="p">(</span><span class="kt">void</span><span class="p">){</span>
<span class="n">server</span><span class="p">.</span><span class="n">handleClient</span><span class="p">();</span>
<span class="p">}</span></code></pre>
<h3 id="intégration-dans-la-domotique-existante">intégration dans la domotique existante</h3>
<p>Mon serveur domotique (écrit en Python et PHP) utilise des scripts bash pour exécuter des actions (soit lancer depuis PHP pour la partie télécommande web ou depuis Python suite à une instruction reçue en xpl, voir depuis la crontab), voici mon script qui actionne la porte du garage:</p>
<pre><code class="bash"><span class="c">#!/bin/sh</span>
wget http://10.1.74.80/garage -O /dev/null</code></pre>
<p>En fait c'est une simple requête http, j'ai mis /garage c'est pour éviter si quelqu'un dans mon réseau se connecte dessus par erreur qu'il ouvre la porte du garage (moi en l’occurrence)</p>
<h2 id="sécurité">Sécurité</h2>
<p>Alors c'est clair que la partie réseau est minimaliste, il n'y a aucune sécurité, donc la sécurité doit se faire en amont, par exemple en utilisant un réseau wifi dédié avec une clé wap2 longue.<br>
Ne pensez pas l'attaquer directement depuis Internet.</p>
<h2 id="conclusion">Conclusion</h2>
<p>Voilà j’espère avoir réussi à vous donner l'envie d'essayer ce joli petit circuit. J'ai déjà plein d'idées pour la suite. Je vais à terme remplacer mon réseau 433 (intertechno, chacon, oregon…) par des montages faits avec des ESP. J'avais essayé enocean qui est prometteur mais affreusement cher. <br>
J’espère que mon petit article pourra donner des réponses à certains qui butent sur des problèmes techniques. J'ai mis des liens sur quelques ressources qui m'ont aidé.</p></div><div><a href="https://linuxfr.org/news/internet-des-objets-l-esp8266-et-ma-porte-de-garage.epub">Télécharger ce contenu au format EPUB</a></div> <p>
<strong>Commentaires :</strong>
<a href="//linuxfr.org/nodes/106738/comments.atom">voir le flux Atom</a>
<a href="https://linuxfr.org/news/internet-des-objets-l-esp8266-et-ma-porte-de-garage#comments">ouvrir dans le navigateur</a>
</p>
Ecran PlatBenoît Sibaudpalm123Pierre JarillonOntologiahttps://linuxfr.org/nodes/106738/comments.atomtag:linuxfr.org,2005:Diary/359662015-06-26T14:07:09+02:002015-06-26T14:07:09+02:00PICOSCOPE : Oscilloscopes numériques sous LinuxLicence CC By‑SA http://creativecommons.org/licenses/by-sa/4.0/deed.fr<p>La société britannique <a href="https://www.picotech.com/" title="Site officiel"><em>Pico Technology</em></a> produit des oscilloscopes numériques, <em>data logger</em> et autres accessoires de mesure. Dans leur catalogue d'entrée de gamme, on trouve quelques petits oscilloscopes alimentés par USB à des tarifs très abordables et aux performances suffisantes pour le passionné. </p>
<p><img src="//img.linuxfr.org/img/68747470733a2f2f7777772e7069636f746563682e636f6d2f696d616765732f75706c6f6164732f70726f647563742d73656374696f6e2f6d6f6e69746f7232303030436f6d706163742e6a7067/monitor2000Compact.jpg" alt="Picoscope" title="Image commerciale de PicoTech | Source : https://www.picotech.com/images/uploads/product-section/monitor2000Compact.jpg"></p>
<p>Ce qui les distingue de la concurrence est que cette société annonce le support de Linux pour leur produit. C'était d'ailleurs ce qui avait guidé mon choix il a quelques années de cela. Mais j'avais vite déchanté, car en guise de support je n'avais eu que les drivers et un fichier d’entête h !</p>
<p>Leur logiciel de visualisation <em>PicoScope</em> n'était disponible que pour les plate-formes Windows et Mac OS. Certes, cela aurait pu être le début d'un projet de développement logiciel, mais c'est un peu contrariant pour un usage immédiat du produit. </p>
<p>Je viens de refaire un tour sur le site et, ô surprise, sur la <a href="https://www.picotech.com/downloads/linux" title="Page des téléchargements pour Linux de PicoTech">page des téléchargements pour Linux</a> on trouve désormais un lien vers les versions Linux de PicoScope.</p>
<p>Et on peut y lire : </p>
<p><em>Demand for Linux applications is growing steadily in the networking and scientific communities. Linux offers powerful networking and internet facilities, is very robust and there are no licence fees.</em></p>
<p>Certes ce n'est pas du logiciel libre et encore moins du matériel libre, mais c'est une bonne nouvelle pour la communauté. </p>
<p><em>PicoScope</em> pour Linux est distribué sous forme de dépot <em>deb</em>, <em>zypper</em> et <em>yum</em>. Le logiciel est encore en version en version Bêta, et j'ai pu constaté quelques régressions par rapport à la versions Windows. Gageons que tout n'a pas encore été porté. Mais l'essentiel y est. Vous pouvez vous faire une idée des fonctionnalités en installant le logiciel (gratuit) sur votre machine. Il simulera l'oscilloscope en son absence. </p><div><a href="https://linuxfr.org/users/binoyte-2/journaux/picoscope-oscilloscopes-numeriques-sous-linux.epub">Télécharger ce contenu au format EPUB</a></div> <p>
<strong>Commentaires :</strong>
<a href="//linuxfr.org/nodes/106184/comments.atom">voir le flux Atom</a>
<a href="https://linuxfr.org/users/binoyte-2/journaux/picoscope-oscilloscopes-numeriques-sous-linux#comments">ouvrir dans le navigateur</a>
</p>
binoytehttps://linuxfr.org/nodes/106184/comments.atomtag:linuxfr.org,2005:News/361752015-02-28T13:41:51+01:002015-02-28T13:41:51+01:00Le BIB hackerspace à Montpellier : Reloading !Licence CC By‑SA http://creativecommons.org/licenses/by-sa/4.0/deed.fr<div><p>Ce samedi 28 février de 14 h à 23 h, votre hackerspace montpelliérain vous accueille dans sa nouvelle peau, pour relancer le radeau d'émancipation technologique pour tous.</p>
<p>Le local est très largement en <a href="http://fr.wikipedia.org/wiki/Work_in_progress">WIP</a> (travaux en cours) mais c'est justement l'occasion pour venir découvrir, adhérer, aider, contempler, et assister éventuellement à la traditionnelle coupe du ruban RJ45 en guise d'inauguration. La dépêche est un peu "dernière minute" mais ça dure toute la journée, "come one, come all"</p>
<p><strong>Rendez-vous donc au 5 Avenue Georges Clémenceau, ce samedi 28 février de 14h à 23h.</strong></p></div><ul><li>lien nᵒ 1 : <a title="https://lebib.org" hreflang="fr" href="https://linuxfr.org/redirect/93227">Le site du BIB</a></li><li>lien nᵒ 2 : <a title="https://twitter.com/BIB_hackerspace" hreflang="fr" href="https://linuxfr.org/redirect/93228">Le twitter du BIB</a></li><li>lien nᵒ 3 : <a title="https://lebib.org/sites/default/files/news_files/bootloading_flyer.pdf" hreflang="fr" href="https://linuxfr.org/redirect/93229">Le flyer de samedi</a></li></ul><div><p>Ce que nous voulons faire de ce hackerspace ? </p>
<ul>
<li>Ateliers, projets collaboratifs, code, électronique, art, récup, détournements, fabrication, rencontres, débats, …</li>
<li>Soudure et électronique, informatique vulgarisée, logiciels libres, sécurité des données, audionumérique, Puredata, Processing, …</li>
<li>Récupération des épaves électroniques et numériques, conception de machines ou d'outils, ateliers artistiques et techniques de tous niveaux concernant : le logiciel, le matériel, les installations, etc.</li>
</ul><h3 id="le-partage-des-connaissances-et-des-ressources-est-la-règle">Le partage des connaissances et des ressources est la règle.</h3>
<p>Nous serons donc ravis d'accueillir toutes les bonnes volontés, pour discuter, échanger, se marrer et engager le plus d'équipiers possible pour faire de ce bateau votre bateau !</p>
<p>Amenez vos ateliers : vous voulez suggérer, proposer ou animer des ateliers autour des valeurs du BIB ? Bienvenue à bord, parlons-en :)</p>
<p>#datalove #SoManyCoolThingsToDo #SharingIsCaring</p>
<p>L'équipage du BIB</p></div><div><a href="https://linuxfr.org/news/le-bib-hackerspace-a-montpellier-reloading.epub">Télécharger ce contenu au format EPUB</a></div> <p>
<strong>Commentaires :</strong>
<a href="//linuxfr.org/nodes/104936/comments.atom">voir le flux Atom</a>
<a href="https://linuxfr.org/news/le-bib-hackerspace-a-montpellier-reloading#comments">ouvrir dans le navigateur</a>
</p>
lebibZeroHeurepalm123Benoît Sibaudhttps://linuxfr.org/nodes/104936/comments.atom