<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>DOMOSYS.ORG</title><link href="https://www.domosys.org/" rel="alternate"/><link href="https://www.domosys.org/feeds/all.atom.xml" rel="self"/><id>https://www.domosys.org/</id><updated>2026-03-30T00:00:00+02:00</updated><entry><title>Matrix RSS</title><link href="https://www.domosys.org/matrix_rss.html" rel="alternate"/><published>2026-03-30T00:00:00+02:00</published><updated>2026-03-30T00:00:00+02:00</updated><author><name>Damien ULRICH</name></author><id>2026-03-30T00:00:00+02:00-Matrix RSS</id><summary type="html">&lt;p&gt;Un article pour valider la config du widget Element d&amp;rsquo;affichage RSS&lt;/p&gt;</summary><content type="html">&lt;h2 id="cest-un-article-bidon"&gt;c&amp;rsquo;est un article bidon&lt;/h2&gt;
&lt;p&gt;Dans Element (application de messagerie instantannée sécurisée sur le réseau Matrix), il y a la possiblité d&amp;rsquo;ajouter des widgets à base d&amp;rsquo;URL fournies, notamment pour les flux RSS&lt;/p&gt;
&lt;p&gt;Or il s&amp;rsquo;avère que le site www.domosys.org a un flux RSS d&amp;rsquo;intégré.&lt;/p&gt;
&lt;p&gt;Voilà pourquoi j&amp;rsquo;écris cet article : pour voir la réaction à la création du présent article&lt;/p&gt;
&lt;p&gt;C&amp;rsquo;est juste un test, quoi ^^&amp;rsquo;&lt;/p&gt;
&lt;h2 id="pareil-mais-mieux"&gt;Pareil, mais mieux&lt;/h2&gt;
&lt;p&gt;Donc : ça fonctionne bien :&lt;/p&gt;
&lt;p&gt;&lt;img alt="Screenshot" src="/images/matrix-rss/element-snap.jpg"&gt;&lt;/p&gt;
&lt;p&gt;Maintenant, le mieux est quand même de faire un template un peu plus &lt;a href="https://matrix-org.github.io/matrix-hookshot/latest/setup/feeds.html#feed-templates" target="_blank" rel="noopener noreferrer"&gt;évolué&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Sans trop charger non plus&lt;/p&gt;
&lt;/blockquote&gt;</content><category term="Articles"/><category term="Domosys"/><category term="Element"/><category term="Matrix"/></entry><entry><title>Emails et PGP</title><link href="https://www.domosys.org/pgp.html" rel="alternate"/><published>2026-02-27T00:00:00+01:00</published><updated>2026-02-27T00:00:00+01:00</updated><author><name>Damien ULRICH</name></author><id>2026-02-27T00:00:00+01:00-Emails et PGP</id><summary type="html">&lt;p&gt;Des dispositions de sécurité nécessaires et suffisantes.&lt;/p&gt;</summary><content type="html">&lt;h2 id="introduction"&gt;Introduction&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;Personne ne signe ni ne chiffre ses e-mails. Je ne comprends pas.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Comme nous l&amp;rsquo;avons vu, l&amp;rsquo;ordinateur est l&amp;rsquo; &lt;a href="/pages/ordinateur.html#loutil-de-traitement-de-linformation"&gt;Outil de Traitement de l&amp;rsquo;Information&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;En ce sens que : les mails sont formés selon des conventions d&amp;rsquo;écriture du contenu, comme du protocole de communication, afin d&amp;rsquo;en assurer l&amp;rsquo;échange.&lt;/p&gt;
&lt;p&gt;Les standards sont publiés à l&amp;rsquo;&lt;a href="https://www.ietf.org/" target="_blank" rel="noopener noreferrer"&gt;IETF&lt;/a&gt; :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://datatracker.ietf.org/doc/rfc5322/" target="_blank" rel="noopener noreferrer"&gt;RFC 5322&lt;/a&gt; – Format des messages Internet (en-têtes, corps, etc.)&lt;/li&gt;
&lt;li&gt;&lt;a href="https://datatracker.ietf.org/doc/rfc5321/" target="_blank" rel="noopener noreferrer"&gt;RFC 5321&lt;/a&gt; – Simple Mail Transfer Protocol (SMTP)&lt;/li&gt;
&lt;li&gt;etc&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Mais il est alors facile de se faire passer pour quelqu&amp;rsquo;un d&amp;rsquo;autre lors de l&amp;rsquo;envoi du mail, en changeant simplement la clause &amp;lsquo;From:&amp;rsquo;.&lt;/p&gt;
&lt;p&gt;C&amp;rsquo;est là qu&amp;rsquo;intervient le PGP (&lt;a href="https://fr.wikipedia.org/wiki/Pretty_Good_Privacy" target="_blank" rel="noopener noreferrer"&gt;&lt;em&gt;Pretty Good Privacy&lt;/em&gt;&lt;/a&gt;), de Philip Zimmermann, depuis 1991.&lt;/p&gt;
&lt;details&gt;
&lt;summary&gt;Commentaire&lt;/summary&gt;
&lt;hr&gt;
Oui oui : '91 !😳&lt;br/&gt;
Càd : on a tout ce qu'il faut depuis des lustres, mais on magouille de nouveaux "services", ou des retours de mail en confirmation&lt;br/&gt;
et autres "entrez votre code reçu par mail/SMS"&lt;br/&gt;
&lt;br/&gt;
"Est-ce bien vous qui avez envoyé le mail ?"&lt;br/&gt;
- Oui c'est moi ! Mon mail est signé.&lt;br/&gt;
&lt;br/&gt;
On a déjà un code : PGP : il est unique et vérifiable.&lt;br/&gt;
&lt;br/&gt;
C'est un peu comme TOUT dans cette société ... Du Climat aux pesticides, en passant par les "services", on ajoute des rustines à des problèmes qu'on a nous-mêmes engendrés, quitte à les aggraver, en ayant balayé d'un revers de main la base des connaissances ... 👍️ 
&lt;/details&gt;

&lt;p&gt;Mais qui de mieux que les spécialistes des mails sécurisés pour vous en expliquer le procédé : &lt;a href="https://proton.me/fr/blog/what-is-pgp-encryption" target="_blank" rel="noopener noreferrer"&gt;Proton Mail&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Mais il n&amp;rsquo;y a aucun problème à ce que vous puissiez faire ça vous-même, au contraire : personne ne peut/doit le faire à votre place : votre clé privée doit rester entre vos mains et lisible par personne d&amp;rsquo;autre.&lt;/p&gt;
&lt;h2 id="gnu-privacy-guard"&gt;GNU Privacy Guard&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class="w"&gt; &lt;/span&gt;apt&lt;span class="w"&gt; &lt;/span&gt;install&lt;span class="w"&gt; &lt;/span&gt;gpg
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content><category term="Articles"/><category term="Securite"/><category term="Email"/><category term="Identite"/><category term="Chiffrement"/></entry><entry><title>Hack caméra PTZ</title><link href="https://www.domosys.org/ptz.html" rel="alternate"/><published>2026-02-25T00:00:00+01:00</published><updated>2026-02-25T00:00:00+01:00</updated><author><name>Damien ULRICH</name></author><id>2026-02-25T00:00:00+01:00-Hack caméra PTZ</id><summary type="html">&lt;p&gt;Une vieille caméra n&amp;rsquo;a jamais rêvé de ça !&lt;/p&gt;</summary><content type="html">&lt;h2 id="introduction"&gt;Introduction&lt;/h2&gt;
&lt;p&gt;J&amp;rsquo;avais fait l&amp;rsquo;acquisition, il y a longtemps, d&amp;rsquo;une caméra-dôme PTZ (Pan-Tilt-Zoom) de surveillance, sur IP ethernet -pas WIFI-, placée à l&amp;rsquo;extérieur, à l&amp;rsquo;angle du toit pour un angle de vue maximal.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Caméra" src="/images//ptz/camera.jpg"&gt;&lt;/p&gt;
&lt;p&gt;Problème : son interface de gestion est en Java, et je n&amp;rsquo;ai jamais eu l&amp;rsquo;intention de faire tourner du java sur mes PC.&lt;/p&gt;
&lt;p&gt;Par chance, cette caméra possède un accès SSH.&lt;/p&gt;
&lt;p&gt;J&amp;rsquo;ai donc entrepris d&amp;rsquo;investiguer son fonctionnement.&lt;/p&gt;
&lt;h2 id="fonctionnement-interne"&gt;Fonctionnement interne&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Sans la moindre surprise : c&amp;rsquo;est du Linux !&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;parfeu iptables&lt;/li&gt;
&lt;li&gt;connexion SSH&lt;/li&gt;
&lt;li&gt;flux caméra rtsp (avec login/passwd)&lt;/li&gt;
&lt;li&gt;Pilotage PTZ sur DBus&lt;/li&gt;
&lt;li&gt;Commandes internes CGI, pour la partie http&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="http"&gt;HTTP&lt;/h3&gt;
&lt;p&gt;Au début, j&amp;rsquo;avais juste fait un hack en &amp;ldquo;auditant&amp;rdquo; les commandes passées par http sur le site&lt;/p&gt;
&lt;p&gt;Bilan : la session est renégociée à chaque fois, ce qui fait que le temps de réaction est assez pénible.&lt;/p&gt;
&lt;h3 id="ssh"&gt;SSH&lt;/h3&gt;
&lt;p&gt;Même chose : une commande passée individuellement, renégocie le login (ça reste une petite machine) → latence importante.&lt;/p&gt;
&lt;h3 id="dbus"&gt;DBus&lt;/h3&gt;
&lt;p&gt;Il y a de quoi faire :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$&lt;span class="w"&gt; &lt;/span&gt;grep&lt;span class="w"&gt; &lt;/span&gt;-E&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&amp;lt;(interface|method|property|signal)&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;PTZ.Coordinator.xml
&lt;span class="w"&gt;  &lt;/span&gt;&amp;lt;interface&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;org.freedesktop.DBus.Introspectable&amp;quot;&lt;/span&gt;&amp;gt;
&lt;span class="w"&gt;    &lt;/span&gt;&amp;lt;method&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Introspect&amp;quot;&lt;/span&gt;&amp;gt;
&lt;span class="w"&gt;  &lt;/span&gt;&amp;lt;interface&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;org.freedesktop.DBus.Properties&amp;quot;&lt;/span&gt;&amp;gt;
&lt;span class="w"&gt;    &lt;/span&gt;&amp;lt;method&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Get&amp;quot;&lt;/span&gt;&amp;gt;
&lt;span class="w"&gt;    &lt;/span&gt;&amp;lt;method&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Set&amp;quot;&lt;/span&gt;&amp;gt;
&lt;span class="w"&gt;    &lt;/span&gt;&amp;lt;method&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;GetAll&amp;quot;&lt;/span&gt;&amp;gt;
&lt;span class="w"&gt;  &lt;/span&gt;&amp;lt;interface&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;com.axis.PTZ.Coordinator&amp;quot;&lt;/span&gt;&amp;gt;
&lt;span class="w"&gt;    &lt;/span&gt;&amp;lt;method&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Command&amp;quot;&lt;/span&gt;&amp;gt;
&lt;span class="w"&gt;    &lt;/span&gt;&amp;lt;method&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;UpdateStaticProperties&amp;quot;&lt;/span&gt;&amp;gt;
&lt;span class="w"&gt;    &lt;/span&gt;&amp;lt;method&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;GetStaticProperties&amp;quot;&lt;/span&gt;&amp;gt;
&lt;span class="w"&gt;    &lt;/span&gt;&amp;lt;method&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;RegisterDriver&amp;quot;&lt;/span&gt;&amp;gt;
&lt;span class="w"&gt;    &lt;/span&gt;&amp;lt;method&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Queue&amp;quot;&lt;/span&gt;&amp;gt;
&lt;span class="w"&gt;    &lt;/span&gt;&amp;lt;method&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;GetDriverName&amp;quot;&lt;/span&gt;&amp;gt;
&lt;span class="w"&gt;    &lt;/span&gt;&amp;lt;method&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;GetSupportParameters&amp;quot;&lt;/span&gt;&amp;gt;
&lt;span class="w"&gt;    &lt;/span&gt;&amp;lt;method&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;SetDevicePreset&amp;quot;&lt;/span&gt;&amp;gt;
&lt;span class="w"&gt;    &lt;/span&gt;&amp;lt;method&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;RemovePresetNumber&amp;quot;&lt;/span&gt;&amp;gt;
&lt;span class="w"&gt;    &lt;/span&gt;&amp;lt;method&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;RemovePresetName&amp;quot;&lt;/span&gt;&amp;gt;
&lt;span class="w"&gt;    &lt;/span&gt;&amp;lt;method&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;UpdatePreset&amp;quot;&lt;/span&gt;&amp;gt;
&lt;span class="w"&gt;    &lt;/span&gt;&amp;lt;method&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;CreatePreset&amp;quot;&lt;/span&gt;&amp;gt;
&lt;span class="w"&gt;    &lt;/span&gt;&amp;lt;method&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;SetPresetNumber&amp;quot;&lt;/span&gt;&amp;gt;
&lt;span class="w"&gt;    &lt;/span&gt;&amp;lt;method&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;SetPresetName&amp;quot;&lt;/span&gt;&amp;gt;
&lt;span class="w"&gt;    &lt;/span&gt;&amp;lt;method&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;OsdMenu&amp;quot;&lt;/span&gt;&amp;gt;
&lt;span class="w"&gt;    &lt;/span&gt;&amp;lt;method&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;FieldAngles&amp;quot;&lt;/span&gt;&amp;gt;
&lt;span class="w"&gt;    &lt;/span&gt;&amp;lt;method&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;QueryZoomDelim&amp;quot;&lt;/span&gt;&amp;gt;
&lt;span class="w"&gt;    &lt;/span&gt;&amp;lt;method&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;QueryPosition&amp;quot;&lt;/span&gt;&amp;gt;
&lt;span class="w"&gt;    &lt;/span&gt;&amp;lt;method&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;QueryPresets&amp;quot;&lt;/span&gt;&amp;gt;
&lt;span class="w"&gt;    &lt;/span&gt;&amp;lt;method&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;QuerySpeed&amp;quot;&lt;/span&gt;&amp;gt;
&lt;span class="w"&gt;    &lt;/span&gt;&amp;lt;method&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;AreaZoom&amp;quot;&lt;/span&gt;&amp;gt;
&lt;span class="w"&gt;    &lt;/span&gt;&amp;lt;method&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;GetAuxiliary&amp;quot;&lt;/span&gt;&amp;gt;
&lt;span class="w"&gt;    &lt;/span&gt;&amp;lt;method&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Auxiliary&amp;quot;&lt;/span&gt;&amp;gt;
&lt;span class="w"&gt;    &lt;/span&gt;&amp;lt;method&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Image&amp;quot;&lt;/span&gt;&amp;gt;
&lt;span class="w"&gt;    &lt;/span&gt;&amp;lt;method&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;GotoHome&amp;quot;&lt;/span&gt;&amp;gt;
&lt;span class="w"&gt;    &lt;/span&gt;&amp;lt;method&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;GotoDevicePreset&amp;quot;&lt;/span&gt;&amp;gt;
&lt;span class="w"&gt;    &lt;/span&gt;&amp;lt;method&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;GotoPresetNumber&amp;quot;&lt;/span&gt;&amp;gt;
&lt;span class="w"&gt;    &lt;/span&gt;&amp;lt;method&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;GotoPresetName&amp;quot;&lt;/span&gt;&amp;gt;
&lt;span class="w"&gt;    &lt;/span&gt;&amp;lt;method&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;MoveLL&amp;quot;&lt;/span&gt;&amp;gt;
&lt;span class="w"&gt;    &lt;/span&gt;&amp;lt;method&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;MoveCmd&amp;quot;&lt;/span&gt;&amp;gt;
&lt;span class="w"&gt;    &lt;/span&gt;&amp;lt;method&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Move&amp;quot;&lt;/span&gt;&amp;gt;
&lt;span class="w"&gt;    &lt;/span&gt;&amp;lt;method&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;MovePTZ&amp;quot;&lt;/span&gt;&amp;gt;
&lt;span class="w"&gt;    &lt;/span&gt;&amp;lt;signal&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;PtzStaticPropsUpdated&amp;quot;&lt;/span&gt;&amp;gt;
&lt;span class="w"&gt;    &lt;/span&gt;&amp;lt;signal&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;PtzParametersSetup&amp;quot;&lt;/span&gt;&amp;gt;
&lt;span class="w"&gt;    &lt;/span&gt;&amp;lt;signal&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;DriverUninstalled&amp;quot;&lt;/span&gt;&amp;gt;
&lt;span class="w"&gt;    &lt;/span&gt;&amp;lt;signal&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;DriverState&amp;quot;&lt;/span&gt;&amp;gt;
&lt;span class="w"&gt;    &lt;/span&gt;&amp;lt;signal&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;DriverCapabilities&amp;quot;&lt;/span&gt;&amp;gt;
&lt;span class="w"&gt;    &lt;/span&gt;&amp;lt;signal&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;SpeedControlEnable&amp;quot;&lt;/span&gt;&amp;gt;
&lt;span class="w"&gt;    &lt;/span&gt;&amp;lt;signal&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;DefaultSpeed&amp;quot;&lt;/span&gt;&amp;gt;
&lt;span class="w"&gt;    &lt;/span&gt;&amp;lt;signal&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;PtzPreset&amp;quot;&lt;/span&gt;&amp;gt;
&lt;span class="w"&gt;    &lt;/span&gt;&amp;lt;signal&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;PtzAction&amp;quot;&lt;/span&gt;&amp;gt;
&lt;span class="w"&gt;    &lt;/span&gt;&amp;lt;signal&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;PtzMoveEnabledChanged&amp;quot;&lt;/span&gt;&amp;gt;
&lt;span class="w"&gt;    &lt;/span&gt;&amp;lt;signal&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;PtzLockedChanged&amp;quot;&lt;/span&gt;&amp;gt;
&lt;span class="w"&gt;    &lt;/span&gt;&amp;lt;signal&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;PtzEnabledChanged&amp;quot;&lt;/span&gt;&amp;gt;
&lt;span class="w"&gt;    &lt;/span&gt;&amp;lt;signal&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;CamPort&amp;quot;&lt;/span&gt;&amp;gt;
&lt;span class="w"&gt;    &lt;/span&gt;&amp;lt;signal&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;TiltFlipped&amp;quot;&lt;/span&gt;&amp;gt;
&lt;span class="w"&gt;    &lt;/span&gt;&amp;lt;signal&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;PanFlipped&amp;quot;&lt;/span&gt;&amp;gt;
&lt;span class="w"&gt;    &lt;/span&gt;&amp;lt;signal&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;CtlQueueEnabled&amp;quot;&lt;/span&gt;&amp;gt;
&lt;span class="w"&gt;    &lt;/span&gt;&amp;lt;property&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;TiltFlipped&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;b&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;access&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;read&amp;quot;&lt;/span&gt;/&amp;gt;
&lt;span class="w"&gt;    &lt;/span&gt;&amp;lt;property&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;PanFlipped&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;b&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;access&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;read&amp;quot;&lt;/span&gt;/&amp;gt;
&lt;span class="w"&gt;    &lt;/span&gt;&amp;lt;property&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;DriverExtraCapabilities&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;i&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;access&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;read&amp;quot;&lt;/span&gt;/&amp;gt;
&lt;span class="w"&gt;    &lt;/span&gt;&amp;lt;property&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;DriverMoveCapabilities&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;i&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;access&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;read&amp;quot;&lt;/span&gt;/&amp;gt;
&lt;span class="w"&gt;    &lt;/span&gt;&amp;lt;property&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Name&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;s&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;access&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;readwrite&amp;quot;&lt;/span&gt;/&amp;gt;
&lt;span class="w"&gt;    &lt;/span&gt;&amp;lt;property&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;PTZEnabled&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;b&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;access&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;readwrite&amp;quot;&lt;/span&gt;/&amp;gt;
&lt;span class="w"&gt;    &lt;/span&gt;&amp;lt;property&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;PTZLocked&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;b&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;access&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;readwrite&amp;quot;&lt;/span&gt;/&amp;gt;
&lt;span class="w"&gt;    &lt;/span&gt;&amp;lt;property&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;CamPort&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;i&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;access&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;readwrite&amp;quot;&lt;/span&gt;/&amp;gt;
&lt;span class="w"&gt;    &lt;/span&gt;&amp;lt;property&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Various&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;s&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;access&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;write&amp;quot;&lt;/span&gt;/&amp;gt;
&lt;span class="w"&gt;    &lt;/span&gt;&amp;lt;property&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Support&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;s&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;access&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;write&amp;quot;&lt;/span&gt;/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id="methode"&gt;Méthode&lt;/h3&gt;
&lt;p&gt;Je créé donc une instance SSH persistante (avec échange de clés), à partir d&amp;rsquo;un petit script bash, appelé par mon appli Python/GTK :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="ch"&gt;#!/bin/sh&lt;/span&gt;
&lt;span class="nv"&gt;START_CMD&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;ssh -M -S ~/.ssh/cam_mux -fNT user@cam&amp;#39;&lt;/span&gt;
&lt;span class="nv"&gt;STOP_CMD&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;ssh -S ~/.ssh/cam_mux -O exit user@cam&amp;#39;&lt;/span&gt;
&lt;span class="k"&gt;case&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;in&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;start&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;eval&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$START_CMD&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;stop&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nb"&gt;eval&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$STOP_CMD&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;*&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;usage: &lt;/span&gt;&lt;span class="nv"&gt;$0&lt;/span&gt;&lt;span class="s2"&gt; [start|stop]&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;exit&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;;;&lt;/span&gt;
&lt;span class="k"&gt;esac&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Dans l&amp;rsquo;application :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;cmd&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;ssh -S &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ssh_socket&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s1"&gt; &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s1"&gt;@&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s1"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="s1"&gt;            dbus-send --system &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;command_line&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Et voilà !&lt;/p&gt;
&lt;h3 id="ia-de-detection"&gt;IA de détection&lt;/h3&gt;
&lt;p&gt;En ce qui concerne l&amp;rsquo;IA de détection, j&amp;rsquo;utilise tensorflow, avec le modèle très light :&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;ssd_mobilenet_v2_coco_quant_postprocess.tflite    6,2M &lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;à cette adresse :&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/google-coral/edgetpu/tree/master/test_data" target="_blank" rel="noopener noreferrer"&gt;https://github.com/google-coral/edgetpu/tree/master/test_data&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Pour mon petit ordi, ça fait le taf, sans être trop gourmand en ressources (sur CPU -pas de GPU-)&lt;/p&gt;
&lt;h3 id="le-code"&gt;Le Code&lt;/h3&gt;
&lt;p&gt;Aujourd&amp;rsquo;hui, j&amp;rsquo;ai au final une interface GTK de pilotage complet, avec IA de détection de présence et identification⁽¹⁾, tracking automatique, tours de garde, enregistrement automatique et alerte via un bot sur mobile avec &lt;em&gt;snapshot&lt;/em&gt; (capture d&amp;rsquo;image).&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;⁽¹⁾ Je ne fais pas pour l&amp;rsquo;heure de véritable contrôle d&amp;rsquo;identité automatisée (ça reste encore intrusif et peu légal). Uniquement de l&amp;rsquo;identification de formes : chat/chien/voiture/personne/&amp;hellip;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img alt="Cat" src="/images/ptz/cat.jpg"&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;y&amp;rsquo;a écrit &amp;ldquo;cat&amp;rdquo; - &amp;lsquo;faut que je change la couleur 😋 -&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="ameliorations-en-cours"&gt;Améliorations en cours&lt;/h3&gt;
&lt;p&gt;En ayant installé sur mon &lt;a href="#" title="Virtual Private Server"&gt;VPS&lt;/a&gt; un serveur matrix-synapse (matrix.domosys.org), j&amp;rsquo;ai pu développer un &lt;a href="#" title="Robot connecté en messagerie instantannée"&gt;bot&lt;/a&gt; en Python pour l&amp;rsquo;y connecter.&lt;/p&gt;
&lt;p&gt;Ainsi, à détection de présence, le bot nous envoit un message via l&amp;rsquo;application Element sur mobile, avec une capture d&amp;rsquo;image.
Nous pouvons alors lui passer un appel en Visio-conférence, et nous avons la caméra en direct.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Bot" src="/images/ptz/visio-bot.jpg"&gt;&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Évidemment la caméra d&amp;rsquo;origine ne faisait pas tout ça, et le modèle n&amp;rsquo;est même plus vendu, ni même mis à jour&amp;hellip; Merci !&lt;/p&gt;
&lt;p&gt;J&amp;rsquo;étais bon pour en acheter une autre, alors qu&amp;rsquo;elle fonctionne parfaitement et que j&amp;rsquo;ai pas les moyens !&lt;/p&gt;
&lt;p&gt;Finalement, je me suis tout simplement retrouvé dans la même situation que &lt;a href="https://korben.info/richard-stallman-revolution-logiciel-libre.html" target="_blank" rel="noopener noreferrer"&gt;Richard Stallman avec sa Xerox&lt;/a&gt; -histoire bien connue des Libristes : c&amp;rsquo;est la base de tout !-.&lt;/p&gt;
&lt;p&gt;Et enfin, mon obligation morale tiendrait de fournir le code de mon hack, sous licence GNU/GPL. Il me faudra m&amp;rsquo;employer à le finaliser et le poster en ligne, afin que d&amp;rsquo;autres personnes dans le Monde possesseur du même modèle, bénéficient de ce travail. &lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;NON : pas sur Github qui appartient à Micro$oft qui a donc là une mine de travail et d&amp;rsquo;idées gratuits, pour vous vendre ses produits -payés avec vos impôts- !&lt;/p&gt;
&lt;/blockquote&gt;</content><category term="Realisations"/><category term="Hack"/><category term="Caméra"/><category term="Interface"/><category term="GTK"/><category term="IA"/></entry><entry><title>Maison Ossature Bois</title><link href="https://www.domosys.org/mob.html" rel="alternate"/><published>2026-02-24T00:00:00+01:00</published><updated>2026-02-24T00:00:00+01:00</updated><author><name>Damien ULRICH</name></author><id>2026-02-24T00:00:00+01:00-Maison Ossature Bois</id><summary type="html">&lt;p&gt;Une maison écolo en DoItYourself&lt;/p&gt;</summary><content type="html">&lt;h2 id="preambule"&gt;Préambule&lt;/h2&gt;
&lt;p&gt;Nous avons eu à déménager 5 fois en une seule et même année.&lt;/p&gt;
&lt;p&gt;Alors nous avons décidé de faire nous-mêmes notre lieu de vie.&lt;/p&gt;
&lt;h2 id="conception-3d"&gt;Conception 3D&lt;/h2&gt;
&lt;p&gt;Nous avons entrepris de construire notre propre maison.&lt;/p&gt;
&lt;p&gt;Le premier modèle 3D, comprenait un salon à l&amp;rsquo;étage, un escalier en colimaçon, une coursive panoramique, des fenêtres à hublot style bateau, et tout un tas d&amp;rsquo;autres idées farfelues.&lt;/p&gt;
&lt;p&gt;Dans l&amp;rsquo;ensemble, je m&amp;rsquo;essayais surtout à la conception sous Blender, qui n&amp;rsquo;était pas vraiment fait pour à l&amp;rsquo;époque, mais qui pour moi, promettait &lt;em&gt;monts et merveilles&lt;/em&gt;. (Aujourd&amp;rsquo;hui, de nombreuses améliorations faciliteraient grandement le travail !)&lt;/p&gt;
&lt;p&gt;Mais problème primaire : le budget.&lt;/p&gt;
&lt;p&gt;Une fois chiffré, j&amp;rsquo;ai repris tous les plans, pour faire quelque-chose de beaucoup plus simple, de moins cher, et de réalisable en autonomie sans y laisser tout notre temps, ni nous ruiner. (minimaliste, donc)&lt;/p&gt;
&lt;p&gt;Après 2ans de conception, de budgétisation, et avoir trouvé un terrain, nacquis ce plan final.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;J&amp;rsquo;avais un bon PC à l&amp;rsquo;époque&amp;hellip;&lt;/p&gt;
&lt;p&gt;Aujourd&amp;rsquo;hui, avec l&amp;rsquo;équipement que j&amp;rsquo;ai, je ne peux plus me permettre de tels projets&amp;hellip;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Tout est pensé :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;légèreté de l&amp;rsquo;ensemble (solivages, et pas de tuiles), adapté à la structure du terrain (pur argile)&lt;/li&gt;
&lt;li&gt;souplesse tout bois (pour pallier aux rétractions/gonflements de l&amp;rsquo;argile)&lt;/li&gt;
&lt;li&gt;isolation maximale (fibre de bois dans les murs, ouate de cellulose toit et sol, plaques de lin-chanvre dans les cloisons intérieures -isolation phonique-)&lt;/li&gt;
&lt;li&gt;toit membrane blanche (réverbération du soleil)&lt;/li&gt;
&lt;li&gt;mur de refend pour le solivage au sol, où le poêle de masse a été disposé en conséquence, avec orientation 45° pour optimiser le rayonnement infrarouge.&lt;/li&gt;
&lt;li&gt;portée des poutres au plafond, calculée à l&amp;rsquo;aide d&amp;rsquo;un logiciel spécialisé en bureau d&amp;rsquo;études.&lt;/li&gt;
&lt;li&gt;positions des pièces N-S/E-O, en fonction du confort voulu (ex: chambre au Nord-ouest pour plus de fraîcheur)&lt;/li&gt;
&lt;li&gt;toilettes dites-sèches (Toilettes à litière bio-maîtrisée) -économie d&amp;rsquo;eau-&lt;/li&gt;
&lt;li&gt;phyto-épuration -élaboration d&amp;rsquo;un dossier complet destiné au SPANC, avec contrôle-&lt;/li&gt;
&lt;li&gt;parfaitement ajustée et aux mesures du plan du cadastre (projection sur un scan).&lt;/li&gt;
&lt;li&gt;la terrasse a été conçue à postériori, ses angles sont une optimisation pour un total de 27m²&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;J&amp;rsquo;avais l&amp;rsquo;idée d&amp;rsquo;un toit végétalisé, mais niveau budget, ça m&amp;rsquo;obligeait à doubler l&amp;rsquo;ossature.&lt;/p&gt;
&lt;p&gt;&lt;img alt="MOB" src="/images/mob/3D-v1.2.jpg"&gt;&lt;/p&gt;
&lt;h3 id="orientation-au-soleil"&gt;Orientation au Soleil&lt;/h3&gt;
&lt;p&gt;J&amp;rsquo;avais fait une animation en simulation des 3 courses du Soleil pour visualiser les projections d&amp;rsquo;ombres et ensoleillement résultant -économies de chauffage-&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Solstice d&amp;rsquo;été&lt;/li&gt;
&lt;li&gt;Équinoxe&lt;/li&gt;
&lt;li&gt;Solstice d&amp;rsquo;hiver&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;Oui le Dérèglement Climatique nous rattrape. Heureusement que j&amp;rsquo;ai opté pour une membrane PVC/EPDM blanche pour le toit.&lt;/p&gt;
&lt;p&gt;D&amp;rsquo;ailleurs le site &lt;a href="lot.cadastre-solaire.fr"&gt;lot.cadastre-solaire.fr&lt;/a&gt; nous considère comme un parking de castine&amp;hellip; Amusant&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="plan"&gt;Plan&lt;/h3&gt;
&lt;p&gt;La précision des cotes a permis de tout ajuster sans erreur (cloisons et autres dépendances), au centimètre près.&lt;/p&gt;
&lt;p&gt;J&amp;rsquo;avais fait une édition des plans résultants sous QCAD, sur un eeePC qui est resté sur le chantier tout le long des travaux.&lt;/p&gt;
&lt;p&gt;&lt;img alt="MOB" src="/images/mob/3D-v1.2-scr.jpg"&gt;&lt;/p&gt;
&lt;h3 id="visite-virtuelle"&gt;Visite virtuelle&lt;/h3&gt;
&lt;p&gt;À l&amp;rsquo;époque Blender avait encore des briques logiques d&amp;rsquo;interraction. (Même si j&amp;rsquo;ai beaucoup &amp;ldquo;&lt;em&gt;scripté&lt;/em&gt;&amp;rdquo; en Python -gestion plus exhaustive-)&lt;/p&gt;
&lt;p&gt;J&amp;rsquo;avais donc fait un &amp;ldquo;bonhomme&amp;rdquo; -rapide, pas un personnage complet-, qui nous permettait de nous déplacer dans la maison, donc de nous projeter pour mieux évaluer les déplacements fonctionnels quotidiens.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;accéder à la cuisine avec les courses&lt;/li&gt;
&lt;li&gt;aérer les toilettes le cas échéant (nous n&amp;rsquo;avions encore aucune expérience pratique pour les toilettes-sèches)&lt;/li&gt;
&lt;li&gt;accès aux toilettes depuis l&amp;rsquo;extérieur -pour éviter de patauger-, et à part du reste de la maison&lt;/li&gt;
&lt;li&gt;concevoir intelligemment le sens des ouvertures des portes&lt;/li&gt;
&lt;li&gt;etc&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="mobilier"&gt;Mobilier&lt;/h3&gt;
&lt;p&gt;Les meubles / objets (que nous avions déjà et ceux rapportés) ont été modélisés sur mesure.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Tabouret" src="/images/mob/3D-tabouret.jpg"&gt;&lt;/p&gt;
&lt;h3 id="cuisine"&gt;Cuisine&lt;/h3&gt;
&lt;p&gt;La cuisine, a été élaborée en partenariat avec une cuisiniste.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;une promo, évidemment&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;La 3D a été ajoutée à posteriori, avec des photos des matériaux, pour les textures.&lt;/p&gt;
&lt;p&gt;Il manque les crédences et des pourtours de fenêtres.&lt;/p&gt;
&lt;p&gt;&lt;img alt="3D Cuisine" src="/images/mob/3D-cuisine.jpg"&gt;&lt;/p&gt;
&lt;h4 id="reel"&gt;Réel&lt;/h4&gt;
&lt;p&gt;le 8 août 2014:&lt;/p&gt;
&lt;p&gt;J&amp;rsquo;ai inversé la porte du frigo et finalisé le montage de la hotte aspirante après la photo&amp;hellip; :-)&lt;/p&gt;
&lt;p&gt;&lt;img alt="Cuisine" src="/images/mob/cuisine.jpg"&gt;&lt;/p&gt;
&lt;h3 id="salon"&gt;Salon&lt;/h3&gt;
&lt;p&gt;Il manque quelques détails dans cette vue du salon.&lt;br/&gt;
ex: la plaque de protection sous le poêle.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Salon" src="/images/mob/3D-salon.jpg"&gt;&lt;/p&gt;
&lt;h2 id="travaux"&gt;Travaux&lt;/h2&gt;
&lt;p&gt;Nous avons fait, avec mon épouse, tout l&amp;rsquo;intérieur, à livraison de l&amp;rsquo;ossature.&lt;/p&gt;
&lt;h3 id="17-mars-2011"&gt;17 mars 2011&lt;/h3&gt;
&lt;p&gt;&lt;img alt="2011-03-17" src="/images/mob/20110317.jpg"&gt;&lt;/p&gt;
&lt;h3 id="2-avril-2011"&gt;2 avril 2011&lt;/h3&gt;
&lt;p&gt;&lt;img alt="2011-04-02" src="/images/mob/20110402.jpg"&gt;&lt;/p&gt;
&lt;h3 id="5-avril-2011"&gt;5 avril 2011&lt;/h3&gt;
&lt;p&gt;&lt;img alt="2011-04-05" src="/images/mob/20110405.jpg"&gt;&lt;/p&gt;
&lt;h3 id="20-avril-2011"&gt;20 avril 2011&lt;/h3&gt;
&lt;p&gt;Oui : on a abandonné le garage : tout simplement pas les moyens -on a tout misé sur l&amp;rsquo;isolation-.&lt;/p&gt;
&lt;p&gt;Évidemment, on ne peut pas accueillir grand-monde, et niveau matériel, tout est également minimaliste.&lt;/p&gt;
&lt;p&gt;La porte d&amp;rsquo;accès est donc condamnée de l&amp;rsquo;intérieur, en attente de moyens&amp;hellip;&lt;/p&gt;
&lt;p&gt;&lt;img alt="2011-04-20" src="/images/mob/20110420.jpg"&gt;&lt;/p&gt;
&lt;h3 id="18-mai-2011"&gt;18 mai 2011&lt;/h3&gt;
&lt;p&gt;&lt;img alt="2011-05-18" src="/images/mob/20110518.jpg"&gt;&lt;/p&gt;
&lt;h3 id="27-mai-2011"&gt;27 mai 2011&lt;/h3&gt;
&lt;p&gt;&lt;img alt="2011-05-27" src="/images/mob/20110527.jpg"&gt;&lt;/p&gt;
&lt;h3 id="9-juin-2011"&gt;9 juin 2011&lt;/h3&gt;
&lt;p&gt;Avec les moyens du bord : mon fil à plomb : un tournevis percé par le manche, des rondelles en lestage, au bout d&amp;rsquo;une ficelle&amp;hellip; Ça marche !&lt;/p&gt;
&lt;p&gt;Un soin particulièrement apporté à ne pas percer inconsidérément le pare-vapeur.&lt;/p&gt;
&lt;p&gt;NB: aujourd&amp;rsquo;hui, on fait de meilleurs matériaux de pare-vapeur&amp;hellip;
&lt;img alt="2011-06-09" src="/images/mob/20110609.jpg"&gt;&lt;/p&gt;
&lt;h3 id="10-juin-2011"&gt;10 juin 2011&lt;/h3&gt;
&lt;p&gt;&lt;img alt="2011-06-10" src="/images/mob/20110610.jpg"&gt;&lt;/p&gt;
&lt;h3 id="18-juillet-2011"&gt;18 juillet 2011&lt;/h3&gt;
&lt;p&gt;Quand j&amp;rsquo;ai reçu les plaques, j&amp;rsquo;étais seul.&lt;/p&gt;
&lt;p&gt;Déposées dehors, il s&amp;rsquo;est mis à pleuvoir.&lt;/p&gt;
&lt;p&gt;Je les ai toutes rentrées en 4ème vitesse, mais de part d&amp;rsquo;autre du mur de refend.&lt;/p&gt;
&lt;p&gt;Je me suis rendu compte que ça fléchissait sous le poids.&lt;/p&gt;
&lt;p&gt;Je les ai toutes remanipulées pour le répartir.&lt;/p&gt;
&lt;h1 id="exercice"&gt;Exercice&lt;/h1&gt;
&lt;p&gt;&lt;img alt="2018-07-18" src="/images/mob/20110718.jpg"&gt;&lt;/p&gt;
&lt;h3 id="28-juillet-2011"&gt;28 juillet 2011&lt;/h3&gt;
&lt;p&gt;Le poêle bien positionné sur le mur de refend central, tout tournera autour&amp;hellip;&lt;/p&gt;
&lt;p&gt;Les premiers rails des cloisons, sont fixés selon les plans -décalage dû à la pente de toit, prévu-.&lt;/p&gt;
&lt;p&gt;Les gaines: vers les prises et interrupteurs &amp;hellip;&lt;/p&gt;
&lt;p&gt;&lt;img alt="2011-07-28" src="/images/mob/20110728.jpg"&gt;&lt;/p&gt;
&lt;h3 id="30-juillet-2011"&gt;30 juillet 2011&lt;/h3&gt;
&lt;p&gt;Protection supplémentaire en laine-de-roche spécifique.&lt;/p&gt;
&lt;p&gt;(j&amp;rsquo;ai déjà travaillé dans la pose de cheminées/inserts&amp;hellip; dans la charpente/couverture aussi&amp;hellip;)&lt;/p&gt;
&lt;p&gt;&lt;img alt="2011-07-30" src="/images/mob/20110730.jpg"&gt;&lt;/p&gt;
&lt;h3 id="3-aout-2011"&gt;3 août 2011&lt;/h3&gt;
&lt;p&gt;&lt;img alt="2011-08-03" src="/images/mob/20110803.jpg"&gt;&lt;/p&gt;
&lt;h3 id="14-aout-2011"&gt;14 août 2011&lt;/h3&gt;
&lt;p&gt;Tout est prévu.
&lt;img alt="2011-08-14" src="/images/mob/20110814.jpg"&gt;&lt;/p&gt;
&lt;h3 id="29-aout-2011"&gt;29 août 2011&lt;/h3&gt;
&lt;p&gt;Ça prend tournure&amp;hellip;
&lt;img alt="2011-08-29" src="/images/mob/20110829.jpg"&gt;&lt;/p&gt;
&lt;h3 id="1er-septembre-2011"&gt;1er septembre 2011&lt;/h3&gt;
&lt;p&gt;Oui : la longueur des plaques de BA13 était anticipée.&lt;/p&gt;
&lt;p&gt;De même que le type : &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ignifuge et isolation laine de roche derrière le poêle.&lt;/li&gt;
&lt;li&gt;hydrofuge et isolation lin-chanvre pour la salle de bain&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt="2011-09-01" src="/images/mob/20110901.jpg"&gt;&lt;/p&gt;
&lt;h3 id="8-septembre-2011"&gt;8 septembre 2011&lt;/h3&gt;
&lt;p&gt;Décrochage en faux-plafond esthétique, mais également en passage de gaines et ventilation&amp;hellip;
&lt;img alt="2011-09-08" src="/images/mob/20110908.jpg"&gt;&lt;/p&gt;
&lt;h3 id="12-septembre-2011"&gt;12 septembre 2011&lt;/h3&gt;
&lt;p&gt;&amp;hellip; en pensant cantonner les odeurs de cuisine à une zone cubique.
&lt;img alt="2011-09-12" src="/images/mob/20110912.jpg"&gt;&lt;/p&gt;
&lt;h3 id="8-novembre-2011"&gt;8 novembre 2011&lt;/h3&gt;
&lt;p&gt;Pose parquet &amp;hellip; à 3 jours de l&amp;rsquo;installation&amp;hellip;&lt;/p&gt;
&lt;p&gt;&lt;img alt="2011-11-09" src="/images/mob/20111108.jpg"&gt;&lt;/p&gt;
&lt;h3 id="12-novembre-2011"&gt;12 novembre 2011&lt;/h3&gt;
&lt;p&gt;Oui : nous nous sommes installés le 11-11-11&amp;hellip; presque.
&lt;img alt="2011-11-12" src="/images/mob/20111112.jpg"&gt;&lt;/p&gt;
&lt;h3 id="24-decembre-2011"&gt;24 décembre 2011&lt;/h3&gt;
&lt;p&gt;Mieux vaut un bain que de tenter de mitiger la température de l&amp;rsquo;eau&amp;hellip;
&lt;img alt="2011-12-24" src="/images/mob/20111224.jpg"&gt;&lt;/p&gt;
&lt;h3 id="5-fevrier-2012"&gt;5 février 2012&lt;/h3&gt;
&lt;p&gt;Première fois qu&amp;rsquo;il neige autant dans ma région (de mémoire -la mienne-)&amp;hellip;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Le Dérèglement Climatique se manifeste&amp;hellip;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img alt="2012-02-05" src="/images/mob/20120205.jpg"&gt;&lt;/p&gt;
&lt;h3 id="7-fevrier-2015"&gt;7 février 2015&lt;/h3&gt;
&lt;p&gt;Bref : nous y sommes.&lt;/p&gt;
&lt;p&gt;&lt;img alt="2015-02-07" src="/images/mob/20150207.jpg"&gt;&lt;/p&gt;
&lt;p&gt;Sur le même thème :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;la &lt;a href="/articles/terrasse.html"&gt;terrasse&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;les &lt;a href="/articles/tlb.html" title="toilettes à litière bio-maîtrisée"&gt;toilettes-sèches&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;la &lt;a href="/articles/phyto.html"&gt;phyto-épuration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;le &lt;a href="/articles/bassin.html"&gt;bassin&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content><category term="Realisations"/><category term="Construction"/><category term="Blender"/><category term="3D"/><category term="DIY"/></entry><entry><title>Sprite</title><link href="https://www.domosys.org/sprite.html" rel="alternate"/><published>2026-02-24T00:00:00+01:00</published><updated>2026-02-24T00:00:00+01:00</updated><author><name>Damien ULRICH</name></author><id>2026-02-24T00:00:00+01:00-Sprite</id><summary type="html">&lt;p&gt;Un amas de pixels&amp;hellip;&lt;/p&gt;</summary><content type="html">&lt;h2 id="pas-une-boisson"&gt;Pas une boisson&lt;/h2&gt;
&lt;p&gt;Il me semble intéressant de connaître ce concept, tant je trouve amusant d&amp;rsquo;avoir conscience de la façon dont ont été formalisés les modes d&amp;rsquo;affichage d&amp;rsquo;éléments à l&amp;rsquo;écran.&lt;/p&gt;
&lt;h1 id="todo"&gt;TODO&lt;/h1&gt;</content><category term="Articles"/><category term="Histoire"/><category term="Connaissance"/></entry><entry><title>Fstrim</title><link href="https://www.domosys.org/fstrim.html" rel="alternate"/><published>2026-02-23T00:00:00+01:00</published><updated>2026-02-23T00:00:00+01:00</updated><author><name>Damien ULRICH</name></author><id>2026-02-23T00:00:00+01:00-Fstrim</id><summary type="html">&lt;p&gt;Optimiser le fonctionnement d&amp;rsquo;un disque-dur SSD&lt;/p&gt;</summary><content type="html">&lt;h2 id="introduction"&gt;Introduction&lt;/h2&gt;
&lt;p&gt;Un disque SSD (&lt;a href="https://fr.wikipedia.org/wiki/SSD" target="_blank" rel="noopener noreferrer"&gt;Solid State Disk&lt;/a&gt;), comme les disques M.2 (&lt;a href="https://iboysoft.com/fr/nouvelles/m2-sata-vs-m2-nvme.html" target="_blank" rel="noopener noreferrer"&gt;SATA ou NVMe&lt;/a&gt;), ne sont pas forcément synchronisés entre le contrôleur et votre kernel.&lt;/p&gt;
&lt;p&gt;La commande fstrim permet donc d&amp;rsquo;informer le contrôleur que certains blocs logiques (NAND) sont libres.&lt;/p&gt;
&lt;h2 id="controle-de-disque"&gt;Contrôle de disque&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$&lt;span class="w"&gt; &lt;/span&gt;lsblk&lt;span class="w"&gt; &lt;/span&gt;--discard
NAME&lt;span class="w"&gt;              &lt;/span&gt;DISC-ALN&lt;span class="w"&gt; &lt;/span&gt;DISC-GRAN&lt;span class="w"&gt; &lt;/span&gt;DISC-MAX&lt;span class="w"&gt; &lt;/span&gt;DISC-ZERO
sda&lt;span class="w"&gt;                      &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="w"&gt;        &lt;/span&gt;0B&lt;span class="w"&gt;       &lt;/span&gt;0B&lt;span class="w"&gt;         &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;
└─sda1&lt;span class="w"&gt;                   &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="w"&gt;        &lt;/span&gt;0B&lt;span class="w"&gt;       &lt;/span&gt;0B&lt;span class="w"&gt;         &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;
sdb&lt;span class="w"&gt;                      &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="w"&gt;      &lt;/span&gt;512B&lt;span class="w"&gt;       &lt;/span&gt;2G&lt;span class="w"&gt;         &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;
├─sdb1&lt;span class="w"&gt;                   &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="w"&gt;      &lt;/span&gt;512B&lt;span class="w"&gt;       &lt;/span&gt;2G&lt;span class="w"&gt;         &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;
└─sdb2&lt;span class="w"&gt;                   &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="w"&gt;      &lt;/span&gt;512B&lt;span class="w"&gt;       &lt;/span&gt;2G&lt;span class="w"&gt;         &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;├─vgsteel-sys&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="w"&gt;      &lt;/span&gt;512B&lt;span class="w"&gt;       &lt;/span&gt;2G&lt;span class="w"&gt;         &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;├─vgsteel-swap&lt;span class="w"&gt;         &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="w"&gt;      &lt;/span&gt;512B&lt;span class="w"&gt;       &lt;/span&gt;2G&lt;span class="w"&gt;         &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;├─vgsteel-home&lt;span class="w"&gt;         &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="w"&gt;      &lt;/span&gt;512B&lt;span class="w"&gt;       &lt;/span&gt;2G&lt;span class="w"&gt;         &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;└─vgsteel-local&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="w"&gt;      &lt;/span&gt;512B&lt;span class="w"&gt;       &lt;/span&gt;2G&lt;span class="w"&gt;         &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;
sdc&lt;span class="w"&gt;                      &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="w"&gt;        &lt;/span&gt;0B&lt;span class="w"&gt;       &lt;/span&gt;0B&lt;span class="w"&gt;         &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;
└─sdc1&lt;span class="w"&gt;                   &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="w"&gt;        &lt;/span&gt;0B&lt;span class="w"&gt;       &lt;/span&gt;0B&lt;span class="w"&gt;         &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;
sr0&lt;span class="w"&gt;                      &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="w"&gt;        &lt;/span&gt;0B&lt;span class="w"&gt;       &lt;/span&gt;0B&lt;span class="w"&gt;         &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Ici, mon disque sdb présente :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;DISC-GRAN (Discard Granularity)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;👉 Taille minimale que le périphérique accepte pour une opération TRIM.
Il accepte des TRIM à partir de 512 octets minimum. (c&amp;rsquo;est très précis)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;DISC-MAX (Discard Maximum)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;👉 Taille maximale qu’on peut envoyer en une seule commande TRIM. 
Le kernel peut envoyer jusqu’à 2 Go de discard en une seule commande. (c&amp;rsquo;est bien)&lt;/p&gt;
&lt;p&gt;Les autres disques sont des disques-durs classiques (à disques magnétiques), et ne sont donc pas concernés.&lt;/p&gt;
&lt;h2 id="sous-debian"&gt;sous Debian&lt;/h2&gt;
&lt;p&gt;Debian a un contrôle programmé, pré-installé :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$&lt;span class="w"&gt; &lt;/span&gt;systemctl&lt;span class="w"&gt; &lt;/span&gt;status&lt;span class="w"&gt; &lt;/span&gt;fstrim.timer
○&lt;span class="w"&gt; &lt;/span&gt;fstrim.timer&lt;span class="w"&gt; &lt;/span&gt;-&lt;span class="w"&gt; &lt;/span&gt;Discard&lt;span class="w"&gt; &lt;/span&gt;unused&lt;span class="w"&gt; &lt;/span&gt;filesystem&lt;span class="w"&gt; &lt;/span&gt;blocks&lt;span class="w"&gt; &lt;/span&gt;once&lt;span class="w"&gt; &lt;/span&gt;a&lt;span class="w"&gt; &lt;/span&gt;week
&lt;span class="w"&gt;     &lt;/span&gt;Loaded:&lt;span class="w"&gt; &lt;/span&gt;loaded&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;/usr/lib/systemd/system/fstrim.timer&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;enabled&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;preset:&lt;span class="w"&gt; &lt;/span&gt;enabl&amp;gt;
&lt;span class="w"&gt;     &lt;/span&gt;Active:&lt;span class="w"&gt; &lt;/span&gt;inactive&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;dead&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;Job:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;163&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;Trigger:&lt;span class="w"&gt; &lt;/span&gt;n/a
&lt;span class="w"&gt;   &lt;/span&gt;Triggers:&lt;span class="w"&gt; &lt;/span&gt;●&lt;span class="w"&gt; &lt;/span&gt;fstrim.service
&lt;span class="w"&gt;       &lt;/span&gt;Docs:&lt;span class="w"&gt; &lt;/span&gt;man:fstrim
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="na"&gt;$ systemctl cat fstrim.timer&lt;/span&gt;
&lt;span class="c1"&gt;# /usr/lib/systemd/system/fstrim.timer&lt;/span&gt;
&lt;span class="k"&gt;[Unit]&lt;/span&gt;
&lt;span class="na"&gt;Description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;Discard unused filesystem blocks once a week&lt;/span&gt;
&lt;span class="na"&gt;Documentation&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;man:fstrim&lt;/span&gt;
&lt;span class="na"&gt;ConditionVirtualization&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;!container&lt;/span&gt;
&lt;span class="na"&gt;ConditionPathExists&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;!/etc/initrd-release&lt;/span&gt;

&lt;span class="k"&gt;[Timer]&lt;/span&gt;
&lt;span class="na"&gt;OnCalendar&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;weekly&lt;/span&gt;
&lt;span class="na"&gt;AccuracySec&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;1h&lt;/span&gt;
&lt;span class="na"&gt;Persistent&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;true&lt;/span&gt;
&lt;span class="na"&gt;RandomizedDelaySec&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;100min&lt;/span&gt;

&lt;span class="k"&gt;[Install]&lt;/span&gt;
&lt;span class="na"&gt;WantedBy&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;timers.target&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;On peut voir ici, qu&amp;rsquo;il est exécuté une fois par semaine.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;[Timer]&lt;/span&gt;
&lt;span class="na"&gt;OnCalendar&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;weekly&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2 id="conclusion"&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Debian se charge de ce nettoyage, mais la raison pour laquelle j&amp;rsquo;en suis venu à investiguer en ce sens, provient du fait que mon propre disque commence à montrer des signes de faiblesse :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$&lt;span class="w"&gt; &lt;/span&gt;sudo&lt;span class="w"&gt; &lt;/span&gt;smartctl&lt;span class="w"&gt; &lt;/span&gt;-a&lt;span class="w"&gt; &lt;/span&gt;/dev/sdb&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;grep&lt;span class="w"&gt; &lt;/span&gt;-E&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;197|198|194&amp;quot;&lt;/span&gt;
&lt;span class="m"&gt;194&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;Temperature_Celsius&lt;span class="w"&gt;     &lt;/span&gt;0x0022&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;042&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;051&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;000&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;Old_age&lt;span class="w"&gt;  &lt;/span&gt;Always&lt;span class="w"&gt;  &lt;/span&gt;-&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;42&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;18&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="m"&gt;197&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;Current_Pending_Sector&lt;span class="w"&gt;  &lt;/span&gt;0x0012&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;100&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;100&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;000&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;Old_age&lt;span class="w"&gt;  &lt;/span&gt;Always&lt;span class="w"&gt;  &lt;/span&gt;-&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;
&lt;span class="m"&gt;198&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;Offline_Uncorrectable&lt;span class="w"&gt;   &lt;/span&gt;0x0010&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;100&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;100&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;000&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;Old_age&lt;span class="w"&gt;  &lt;/span&gt;Offline&lt;span class="w"&gt; &lt;/span&gt;-&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;2 &lt;em&gt;Pending Sectors&lt;/em&gt; → Pas bon !&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$&lt;span class="w"&gt; &lt;/span&gt;sudo&lt;span class="w"&gt; &lt;/span&gt;fstrim&lt;span class="w"&gt; &lt;/span&gt;-v&lt;span class="w"&gt; &lt;/span&gt;/
/&lt;span class="w"&gt; &lt;/span&gt;:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;21&lt;/span&gt;,9&lt;span class="w"&gt; &lt;/span&gt;GiB&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="m"&gt;23496540160&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;octets&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;réduits
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$&lt;span class="w"&gt; &lt;/span&gt;sudo&lt;span class="w"&gt; &lt;/span&gt;smartctl&lt;span class="w"&gt; &lt;/span&gt;-a&lt;span class="w"&gt; &lt;/span&gt;/dev/sdb&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;grep&lt;span class="w"&gt; &lt;/span&gt;-E&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;197|198|194&amp;quot;&lt;/span&gt;
&lt;span class="m"&gt;194&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;Temperature_Celsius&lt;span class="w"&gt;     &lt;/span&gt;0x0022&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;042&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;051&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;000&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;Old_age&lt;span class="w"&gt;  &lt;/span&gt;Always&lt;span class="w"&gt;  &lt;/span&gt;-&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;42&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;18&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="m"&gt;197&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;Current_Pending_Sector&lt;span class="w"&gt;  &lt;/span&gt;0x0012&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;100&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;100&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;000&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;Old_age&lt;span class="w"&gt;  &lt;/span&gt;Always&lt;span class="w"&gt;  &lt;/span&gt;-&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;
&lt;span class="m"&gt;198&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;Offline_Uncorrectable&lt;span class="w"&gt;   &lt;/span&gt;0x0010&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;100&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;100&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;000&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;Old_age&lt;span class="w"&gt;  &lt;/span&gt;Offline&lt;span class="w"&gt; &lt;/span&gt;-&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;→ Récupérés ! Soulagé !&lt;/p&gt;
&lt;p&gt;Oui un disque qui montre des signes de faiblesse de la sorte, j&amp;rsquo;ai déjà connu ça : quand le crash se profile, sans &lt;a href="/pages/sauvegardes.html"&gt;sauvegardes&lt;/a&gt;, c&amp;rsquo;est le drame !&lt;/p&gt;</content><category term="Articles"/><category term="Admin"/><category term="DD"/><category term="Terminal"/><category term="Matériel"/></entry><entry><title>Espion Chinois</title><link href="https://www.domosys.org/espion-chinois.html" rel="alternate"/><published>2026-02-21T00:00:00+01:00</published><updated>2026-02-21T00:00:00+01:00</updated><author><name>Damien ULRICH</name></author><id>2026-02-21T00:00:00+01:00-Espion Chinois</id><summary type="html">&lt;p&gt;Un routeur 4G aux relents de sniffeur d&amp;rsquo;activité internautique.&lt;/p&gt;</summary><content type="html">&lt;h2 id="un-routeur-mal-route"&gt;un Routeur mal-routé&lt;/h2&gt;
&lt;p&gt;En 2024, après 6 mois de relances chez Free pour obtenir une connexion fibre chez moi, j&amp;rsquo;ai finit par couper les ponts.&lt;/p&gt;
&lt;p&gt;J&amp;rsquo;ai alors décidé d&amp;rsquo;opter pour une connexion Internet via le réseau 4G, qui avec les smartphones, dépassait largement notre connexion ADSL en terme de débit.&lt;/p&gt;
&lt;p&gt;Me voilà parti pour m&amp;rsquo;enquérir d&amp;rsquo;un routeur 4G.&lt;/p&gt;
&lt;p&gt;Vu les prix, je finis par opter pour un &lt;a href="https://www.amazon.fr/dp/B09M2LNDC1?ref=ppx_yo2ov_dt_b_fed_asin_title" target="_blank" rel="noopener noreferrer"&gt;routeur Tenda sur Amazon&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Je reçois l&amp;rsquo;appareil, jusque-là, tout va bien.&lt;/p&gt;
&lt;h2 id="installation-et-configuration"&gt;Installation et configuration&lt;/h2&gt;
&lt;p&gt;Je le connecte, suit la procédure pour le trouver sur le réseau, et commence à le configurer.&lt;/p&gt;
&lt;p&gt;Puis là, je commence à déceler des comportements étranges !&lt;/p&gt;
&lt;p&gt;En particulier, sur mon réseau, en ce qui concerne les requêtes DNS.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Quand vous tapez une adresse dans votre navigateur, la première étape est d&amp;rsquo;obtenir l&amp;rsquo;adresse IP correspondante, afin que votre navigateur puisse s&amp;rsquo;y rendre.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;SAUF QUE : pour n&amp;rsquo;importe quel nom tapé (google.com ou n&amp;rsquo;importe quoi d&amp;rsquo;autre), la réponse était la même !&lt;/p&gt;
&lt;p&gt;j&amp;rsquo;ai fait une capture d&amp;rsquo;écran :&lt;/p&gt;
&lt;p&gt;&lt;img alt="Requête DNS" src="/images/espion-chinois/capture-dns.png" title="Requête DNS sur le Routeur"&gt;&lt;/p&gt;
&lt;p&gt;Curieux de l&amp;rsquo;affaire, ne comprenant pas ce qu&amp;rsquo;il se passe, je me dis que le mieux est de savoir à qui appartient cette adresse IP !&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;sur Internet, pour savoir à qui appartient une adresse IP, il suffit de faire une requête &amp;lsquo;whois &amp;lt;adresse&amp;gt;&amp;lsquo;, mais on peut faire la recherche directement sur des sites spécialisés&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Voilà donc la capture d&amp;rsquo;écran de la requête &amp;lsquo;whois&amp;rsquo; sur un site dédié :&lt;/p&gt;
&lt;p&gt;&lt;img alt="Capture d'écran WHOIS" src="/images/espion-chinois/whois.png" title="Capture de la page WHOIS"&gt;&lt;/p&gt;
&lt;h2 id="lespion-chinois"&gt;l&amp;rsquo;Espion Chinois&lt;/h2&gt;
&lt;p&gt;Même si cette requête pourraît ne se faire que pour une pré-configuration de l&amp;rsquo;appareil, -ce qui reste une possibilité-, lorsque vous le branchez chez vous sans chercher à comprendre, vous annoncez donc directement votre présence à ce centre de recherche universitaire chinois !&lt;/p&gt;
&lt;p&gt;Personnellement, je n&amp;rsquo;ai rien demandé !!&lt;/p&gt;
&lt;p&gt;De plus, l&amp;rsquo;appareil s&amp;rsquo;impose directement sur le réseau : il me faisait sauter mes configurations DHCP locales !&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;le DHCP est un serveur qui fournit une adresse IP libre (ou fixée), sur votre réseau, en se chargeant de fournir les adresses de serveurs DNS, de l&amp;rsquo;adresse IP du routeur qui fera passerelle vers l&amp;rsquo;Internet, etc&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Alors me voilà parti pour investiguer plus avant !&lt;/p&gt;
&lt;p&gt;Je scanne alors les ports du routeur. -commençant vraiment à avoir de fameux doutes quant à la sécurité du fait de la présence de cette machine chez moi !&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Une adresse IP possède 65 536 ports sur lesquels différents services (serveurs) peuvent écouter. Il y a des ports réservés -standards- et des ports aléatoirement choisis au-delà du port 1024. Ces ports aléatoires, sont ouverts pour le retour de communication avec les serveurs (en gros). &lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Et qu&amp;rsquo;est-ce que je découvre !? &lt;/p&gt;
&lt;p&gt;Le port 12345 netbus est ouvert, disponible à la connexion !&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;le port &lt;a href="https://www.pentestpad.com/port-exploit/port-12345-netbus-netbus-trojan" target="_blank" rel="noopener noreferrer"&gt;12345 netbus&lt;/a&gt; est historiquement un port utilisé pour ce que l&amp;rsquo;on appelle : une &lt;a href="https://fr.wikipedia.org/wiki/Porte_d%C3%A9rob%C3%A9e" target="_blank" rel="noopener noreferrer"&gt;backdoor&lt;/a&gt; -porte dérobée pour &lt;a href="https://fr.wikipedia.org/wiki/Cheval_de_Troie_(informatique)" target="_blank" rel="noopener noreferrer"&gt;Trojan&lt;/a&gt;-&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Encore une piste que cet appareil est dangereux !!!&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Même si on peut faire écouter n&amp;rsquo;importe quoi sur n&amp;rsquo;importe quel port, ce n&amp;rsquo;est de surcroît pas le seul&amp;hellip;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="securisation"&gt;Sécurisation&lt;/h2&gt;
&lt;p&gt;Alors je l&amp;rsquo;ai isolé de mon réseau en le plaçant sur un &lt;a href="https://fr.wikipedia.org/wiki/R%C3%A9seau_local_virtuel" target="_blank" rel="noopener noreferrer"&gt;VLAN tagué&lt;/a&gt;, à l&amp;rsquo;aide de mon &lt;a href="https://fr.wikipedia.org/wiki/Commutateur_r%C3%A9seau" title="Commutateur réseau" target="_blank" rel="noopener noreferrer"&gt;switch manageable&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Verrouillé toute connexion provenant directement de son IP avec le &lt;a href="https://fr.wikipedia.org/wiki/Pare-feu_(informatique)" target="_blank" rel="noopener noreferrer"&gt;parefeu&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Et tout désactivé dessus : DNS, DHCP, WIFI, &amp;hellip; TOUT sauf la connexion Internet !
(qu&amp;rsquo;il serve quand même à quelque-chose, sinon je n&amp;rsquo;avais plus le Net&amp;hellip;🙄😬 )&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Quand on achète des appareils dits-noname (qui ne sont pas garantis par une grande marque qui y perdrait toute légitimité), on se retrouve confronté à de graves enjeux de sécurité chez soi !&lt;/p&gt;
&lt;p&gt;J&amp;rsquo;ai tenté d&amp;rsquo;alerter en écrivant un commentaire sur Amazon &amp;hellip;&lt;/p&gt;
&lt;p&gt;Il n&amp;rsquo;a jamais été accepté malgré mes insistances !&lt;/p&gt;
&lt;p&gt;Et vous pouvez lire vous-mêmes les commentaires des autres possesseurs sur le site :&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;ldquo;Ça marche !&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&amp;ndash; Oui oui&amp;hellip; &amp;ldquo;ça marche&amp;rdquo;&lt;/p&gt;
&lt;p&gt;Mais personne ne sait par où passent ses données (moi non plus malgré mes réglages -je ne peux pas faire mieux-), et je doute fortement qu&amp;rsquo;elles passent les tuyaux en toute transparence !&lt;/p&gt;
&lt;p&gt;J&amp;rsquo;ai alerté l&amp;rsquo;ARCOM&amp;hellip; J&amp;rsquo;attends toujours une réaction&amp;hellip;&lt;/p&gt;
&lt;p&gt;Alors je vous invite à vous informer sur &lt;a href="/pages/ordinateur.html"&gt;ce qu&amp;rsquo;est un ordinateur&lt;/a&gt;.&lt;/p&gt;</content><category term="Articles"/><category term="router"/><category term="espion"/><category term="sécurité"/><category term="informatique"/></entry><entry><title>Dépannage Souris</title><link href="https://www.domosys.org/depannage-mx-master.html" rel="alternate"/><published>2026-02-11T00:00:00+01:00</published><updated>2026-02-11T00:00:00+01:00</updated><author><name>Damien ULRICH</name></author><id>2026-02-11T00:00:00+01:00-Dépannage Souris</id><summary type="html">&lt;p&gt;Une souris Logitech MX Master qui ne bouge plus&amp;hellip; si on s&amp;rsquo;en sert !&amp;hellip;&lt;/p&gt;</summary><content type="html">&lt;h2 id="introduction"&gt;Introduction&lt;/h2&gt;
&lt;p&gt;J&amp;rsquo;avais une vieille souris MX Master de chez Logitech, (du temps où j&amp;rsquo;avais tous les services en ligne possibles), en panne.&lt;/p&gt;
&lt;h2 id="diagnostic"&gt;Diagnostic&lt;/h2&gt;
&lt;p&gt;Le curseur ne bougeait plus à l&amp;rsquo;écran.
Pourtant, tous les boutons, eux, fonctionnaient.
Donc : pas de problème d&amp;rsquo;alimentation, ni de communication avec le PC.&lt;/p&gt;
&lt;p&gt;Typiquement un seul élément hors service.&lt;/p&gt;
&lt;p&gt;2 possibilités pour une défaillance du dispositif de suivi du mouvement :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;soit la carte électronique (PCB / chipset / &amp;hellip;)&lt;/li&gt;
&lt;li&gt;soit une des 2 LEDs (émission/réception)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Après démontage, rien d&amp;rsquo;anormal à l&amp;rsquo;intérieur.
Pas de possibilité directe d&amp;rsquo;observer la LED émettrice (invisible : non rouge)&lt;/p&gt;
&lt;p&gt;Après une simple observation, je vois, sous l&amp;rsquo;emplacement du support du pouce :
une petite carte (PCB), avec indiqué dessus :
&amp;ldquo;Hidden PCB&amp;rdquo;, soit &amp;ldquo;carte cachée&amp;rdquo;. (Amusant)&lt;/p&gt;
&lt;p&gt;J&amp;rsquo;ai remarqué que le curseur se remettait à fonctionner, si je prenais garde de ne pas appuyer le pouce à son emplacement.&lt;/p&gt;
&lt;p&gt;Après dévissage de la carte : effectivement, elle comporte un mini-interrupteur, qui, lorsqu&amp;rsquo;on appuie dessus, bloque le mouvement du curseur à l&amp;rsquo;écran.&lt;/p&gt;
&lt;h2 id="depannage"&gt;Dépannage&lt;/h2&gt;
&lt;p&gt;J&amp;rsquo;ai tout simplement shunté l&amp;rsquo;interrupteur, et ma souris est repartie pour me servir quelques années encore !&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Je ne vois pas d&amp;rsquo;autre explication qu&amp;rsquo;un énième dispositif d&amp;rsquo;obsolescence programmée. (en espérant me tromper !)&lt;/p&gt;</content><category term="Realisations"/><category term="Reparation"/><category term="obsolescence"/><category term="seconde-vie"/></entry><entry><title>TuxKatana</title><link href="https://www.domosys.org/katana.html" rel="alternate"/><published>2025-08-29T00:00:00+02:00</published><updated>2025-08-29T00:00:00+02:00</updated><author><name>Damien ULRICH</name></author><id>2025-08-29T00:00:00+02:00-TuxKatana</id><summary type="html">&lt;p&gt;Une appli, pour lui tirer les vers du nez !&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;img alt="TuxKatana" src="images/katana/tuxkatana_128.png"&gt;&lt;/p&gt;
&lt;h2 id="introduction"&gt;Introduction&lt;/h2&gt;
&lt;p&gt;Je possède un ampli guitare Boss Katana MK-II.&lt;/p&gt;
&lt;p&gt;Les boutons d&amp;rsquo;interface permettent des réglages de base.&lt;/p&gt;
&lt;p&gt;Mais en fait, il y a à l&amp;rsquo;intérieur tout un tas de programmes non référencés !&lt;/p&gt;
&lt;p&gt;Pour les exploiter, il y a plusieurs applications :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;l&amp;rsquo;application officielle (sous Window$) &lt;a href="https://support.roland.com/hc/en-us/articles/4404525824411-BOSS-TONE-STUDIO-Where-can-I-get-BOSS-TONE-STUDIO" target="_blank" rel="noopener noreferrer"&gt;Boss Tone Studio&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;l&amp;rsquo;application mobile (Android) &lt;a href="https://play.google.com/store/apps/details?id=com.appsforamps.katana&amp;amp;hl=en-US" target="_blank" rel="noopener noreferrer"&gt;Librarian&lt;/a&gt; -notamment-&lt;/li&gt;
&lt;li&gt;l&amp;rsquo;application sous Linux : &lt;a href="https://sourceforge.net/projects/fxfloorboard/" target="_blank" rel="noopener noreferrer"&gt;FxFloorBoard&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Bilan : évidemment, pour faire tourner l&amp;rsquo;application officielle, sous Linux, on peut le faire avec wine, mais c&amp;rsquo;est quelque-chose que je ne fais plus : me battre avec des systèmes que j&amp;rsquo;aborre : j&amp;rsquo;ai abdiqué.&lt;/p&gt;
&lt;p&gt;J&amp;rsquo;utilisais alors Librarian sur une tablette Android.&lt;/p&gt;
&lt;p&gt;Mais le sujet est quelque peu le même : une tablette Android, on ne maîtrise rien du tout. Même si j&amp;rsquo;avoue que cette aplication est plutôt bien faite.&lt;/p&gt;
&lt;p&gt;Quant à FxFloorBoard, d&amp;rsquo;abord son aspect m&amp;rsquo;est assez peu ragoutant, mais surtout, elle fait chauffer mon CPU pour des raisons que j&amp;rsquo;ignore.&lt;/p&gt;
&lt;p&gt;Alors j&amp;rsquo;ai décidé de développer ma propre application en #Python.&lt;/p&gt;
&lt;h2 id="la-methode"&gt;La méthode&lt;/h2&gt;
&lt;p&gt;J&amp;rsquo;ai tout d&amp;rsquo;abord fait fonctionner FxFloorBoard sur mon PC, connecté en USB au Boss Katana.&lt;/p&gt;
&lt;p&gt;Ensuite, j&amp;rsquo;ai utilisé WireShark pour littéralement sniffer les communications entre les deux.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Snif" src="/images/katana/snif.jpg"&gt;&lt;/p&gt;
&lt;p&gt;J&amp;rsquo;ai ensuite fait du reverse-engineering sur les trames enregistrées, en faisant plusieurs scripts me permettant de relever les variations et corrélations, jusqu&amp;rsquo;à pouvoir en déduire le fonctionnement du protocole.&lt;/p&gt;
&lt;p&gt;&lt;img alt="SysEx" src="/images/katana/sysex.jpg"&gt;&lt;/p&gt;
&lt;h2 id="developpement"&gt;Développement&lt;/h2&gt;
&lt;p&gt;Ceci fait, je n&amp;rsquo;ai plus eu qu&amp;rsquo;à créer des classes d&amp;rsquo;objet (notamment MIDI -128bits- en messages SysEx spécifiques)&lt;/p&gt;
&lt;details&gt;
&lt;summary&gt;class MIDI_Bytes&lt;/summary&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;logging&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;lib.log_setup&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;LOGGER_NAME&lt;/span&gt;
&lt;span class="n"&gt;log&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getLogger&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;LOGGER_NAME&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MIDIBytes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="fm"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mb&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;mb&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="n"&gt;mb&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bytes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;isinstance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mb&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;length&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="n"&gt;length&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bit_length&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;//&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;mb&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;int_to_hexstring&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mb&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;isinstance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mb&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="n"&gt;mb&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot; &amp;quot;&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;02X&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;mb&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;parts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;split&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;parts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bytes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt;
        &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;vals&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;parts&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="ne"&gt;ValueError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="ne"&gt;ValueError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Invalid Hex byte: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;parts&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;vals&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mh"&gt;0x7F&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="ne"&gt;ValueError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Invalid MIDI byte: 0 &amp;lt; &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; &amp;lt; 0x7F&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;length&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vals&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;diff&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;length&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vals&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;vals&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;diff&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;vals&lt;/span&gt;
            &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;length&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bytes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;vals&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="fm"&gt;__str__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot; &amp;quot;&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;02X&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bytes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="fm"&gt;__repr__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="vm"&gt;__class__&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="vm"&gt;__name__&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;(&amp;#39;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="fm"&gt;__str__&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#39;)&amp;quot;&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="fm"&gt;__eq__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;other&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="nb"&gt;isinstance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;other&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Address&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;MIDIBytes&lt;/span&gt;&lt;span class="p"&gt;,)):&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;NotImplemented&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bytes&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;other&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bytes&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="fm"&gt;__lt__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;other&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="nb"&gt;isinstance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;other&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;MIDIBytes&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;NotImplemented&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_int&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;other&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_int&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="fm"&gt;__le__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;other&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="nb"&gt;isinstance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;other&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;MIDIBytes&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;NotImplemented&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_int&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;other&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_int&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="fm"&gt;__gt__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;other&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="nb"&gt;isinstance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;other&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;MIDIBytes&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;NotImplemented&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_int&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;other&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_int&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="fm"&gt;__ge__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;other&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="nb"&gt;isinstance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;other&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;MIDIBytes&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;NotImplemented&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_int&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="n"&gt;other&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_int&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="fm"&gt;__add__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;other&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="nb"&gt;isinstance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;other&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;MIDIBytes&lt;/span&gt;&lt;span class="p"&gt;,)):&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;NotImplemented&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;isinstance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;other&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
                &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_int&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;other&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;MIDIBytes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;from_int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bytes&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
            &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;MIDIBytes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bytes&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;other&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bytes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="fm"&gt;__getitem__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bytes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="fm"&gt;__setitem__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;isinstance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;isinstance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;MIDIBytes&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
                &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bytes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bytes&lt;/span&gt;
            &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="nb"&gt;isinstance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
                &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bytes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;
            &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="ne"&gt;TypeError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;slice assignment requires list or MIDIBytes&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;isinstance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mh"&gt;0x7F&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
                    &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="ne"&gt;ValueError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;MIDI byte must be in 0..127&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bytes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;
            &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="ne"&gt;TypeError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;single item must be int&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="fm"&gt;__len__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bytes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="fm"&gt;__iter__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;iter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bytes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="nd"&gt;@property&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_int&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="nd"&gt;@property&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="nb"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bytes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="ne"&gt;ValueError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Cannot convert multi-byte &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; to bool&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bytes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;warning&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;midi_bytes.py:108- len(self.bytes) == 0&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bytes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;

    &lt;span class="nd"&gt;@property&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;to_gtype&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;val_type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="c1"&gt;# log.debug(f&amp;quot;{val_type=}&amp;quot;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;val_type&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;gboolean&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bool&lt;/span&gt;
        &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;val_type&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;gint&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;int&lt;/span&gt;
        &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;val_type&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;gchararray&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;str&lt;/span&gt;
        &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;val_type&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;gdouble&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;warning&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;midi_bytes.py:127-Not recognized GType: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;val_type&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;to_int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
        &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bytes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;enumerate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bytes&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="n"&gt;shift&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;|=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="mh"&gt;0x7F&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;shift&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;to_chars&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;chars&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;chr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bytes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;chars&lt;/span&gt;

    &lt;span class="nd"&gt;@staticmethod&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;int_to_hexstring&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="nb"&gt;isinstance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="ne"&gt;TypeError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;value must be int&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="ne"&gt;ValueError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;value must be &amp;gt;= 0&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;maxval&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="n"&gt;maxval&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="ne"&gt;OverflowError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;value &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; not containing in &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; 7bits bytes&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="n"&gt;parts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="n"&gt;shift&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;parts&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;shift&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="mh"&gt;0x7F&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot; &amp;quot;&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;02X&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;parts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="nd"&gt;@classmethod&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;from_int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;cls&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;length&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;length&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bit_length&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;//&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;cls&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;cls&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;int_to_hexstring&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Address&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MIDIBytes&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="fm"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;addr&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;isinstance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;addr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Address&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;debug&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Double declaration of &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;addr&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt;
        &lt;span class="nb"&gt;super&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="fm"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;addr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="fm"&gt;__add__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;other&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="nb"&gt;isinstance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;other&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;MIDIBytes&lt;/span&gt;&lt;span class="p"&gt;,)):&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;NotImplemented&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;isinstance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;other&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_int&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;other&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Address&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;from_int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bytes&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;isinstance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;other&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;MIDIBytes&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;MIDIBytes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bytes&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;other&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bytes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="fm"&gt;__hash__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;int&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="fm"&gt;__sub__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;other&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;isinstance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;other&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Address&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="n"&gt;val_s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_int&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="n"&gt;val_o&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;other&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_int&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;abs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;val_s&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;val_o&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="nb"&gt;isinstance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;other&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_int&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;other&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Address&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;from_int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bytes&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;NotImplemented&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;/details&gt;

&lt;p&gt;le plus pénible en fait, c&amp;rsquo;est surtout l&amp;rsquo;organisation de l&amp;rsquo;interface, et le passage de messages entre classes, pour la prise en compte de tous les changements en messages Glib.&lt;/p&gt;
&lt;p data-no-instant rel="noopener" target="_blank"&gt;&lt;a href="/images/katana/work_bench.jpg"&gt;&lt;img alt="Work Bench" src="/images/katana/work_bench.jpg"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="disclaimer"&gt;Disclaimer&lt;/h2&gt;
&lt;p&gt;Je n&amp;rsquo;ai pas totalement terminé : les enregistrement de presets ne sont pas fonctionnels, mais je m&amp;rsquo;en sers régulièrement en direct, pour me faire des réglages sur le vif, et ça fonctionne plutôt bien !&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;le petit plus miraculeux, étant le Tuner intégré !&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="publication"&gt;Publication&lt;/h2&gt;
&lt;p&gt;&lt;img alt="Screenshot" src="/images/katana/snapshot.jpg"&gt;&lt;/p&gt;
&lt;p&gt;le code est ici : &lt;a href="https://framagit.org/s4mdf0o1/TuxKatana" target="_blank" rel="noopener noreferrer"&gt;https://framagit.org/s4mdf0o1/TuxKatana&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;et la doc générée par IA, ici : &lt;a href="https://deepwiki.com/s4mdf0o1/TuxKatana" target="_blank" rel="noopener noreferrer"&gt;https://deepwiki.com/s4mdf0o1/TuxKatana&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Il y a bien une &lt;a href="https://www.youtube.com/watch?v=bfD31DUedUE" target="_blank" rel="noopener noreferrer"&gt;vidéo de démo&lt;/a&gt;, mais de très très mauvaise qualité. Je voulais juste tenter, c&amp;rsquo;est pas du tout un truc qui m&amp;rsquo;amuse, donc&amp;hellip; Peut-être que je retenterai un jour&amp;hellip;&lt;/p&gt;
&lt;h2 id="postface"&gt;Postface&lt;/h2&gt;
&lt;p&gt;le code du Tuner, qui peut être utilisé à part, est ici :
&lt;a href="https://framagit.org/s4mdf0o1/guit_tunix" target="_blank" rel="noopener noreferrer"&gt;Guit_tunix&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;(j&amp;rsquo;en avais fait une version dans le terminal)&lt;/p&gt;</content><category term="Realisations"/><category term="Code"/><category term="Hack"/><category term="GTK"/><category term="Python"/><category term="Dev"/><category term="Guitare"/></entry><entry><title>Iso-tuteur</title><link href="https://www.domosys.org/isotuteur.html" rel="alternate"/><published>2023-01-09T00:00:00+01:00</published><updated>2023-01-09T00:00:00+01:00</updated><author><name>Damien ULRICH</name></author><id>2023-01-09T00:00:00+01:00-Iso-tuteur</id><summary type="html">&lt;p&gt;Structure support de plante à base d&amp;rsquo; &lt;em&gt;icosphere&lt;/em&gt; sous Blender, en impression 3D&lt;/p&gt;</summary><content type="html">&lt;h2 id="passion-geodesique"&gt;Passion Géodésique&lt;/h2&gt;
&lt;p&gt;J&amp;rsquo;ai un goût prononcé pour les &lt;a href="https://fr.wikipedia.org/wiki/D%C3%B4me_g%C3%A9od%C3%A9sique" target="_blank" rel="noopener noreferrer"&gt;structures géodésiques&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;En effet, ce sont des structures, dont la légèreté par rapport à la solidité est sans égal.&lt;/p&gt;
&lt;p&gt;Le principe étant une conception &lt;a href="https://fr.wikipedia.org/wiki/Icosa%C3%A8dre" target="_blank" rel="noopener noreferrer"&gt;isocaédrique&lt;/a&gt; permettant une répartition parfaite des charge.&lt;/p&gt;
&lt;p&gt;J&amp;rsquo;aimerais bien faire une serre-dôme, mais pour les tests, il me fallait faire une maquette, et tant qu&amp;rsquo;à faire : utile.&lt;/p&gt;
&lt;p&gt;J&amp;rsquo;ai alors pensé à faire un support pour plante (ici un simple potos).&lt;/p&gt;
&lt;p&gt;Tout ce qu&amp;rsquo;il me restait à faire, c&amp;rsquo;est concevoir les pièces sous #Blender, afin de pouvoir les imprimer en 3D.&lt;/p&gt;
&lt;h2 id="tests"&gt;Tests&lt;/h2&gt;
&lt;p&gt;D&amp;rsquo;abord quelques test de solidité d&amp;rsquo;accroche sur les baguettes bois sélectionnées (baguettes de ~2m en magasin de bricolage)&lt;/p&gt;
&lt;p&gt;&lt;img alt="Test accroche" src="/images/isotuteur/1er-test.jpg"&gt;&lt;/p&gt;
&lt;h2 id="modelisation-3d"&gt;Modélisation 3D&lt;/h2&gt;
&lt;p&gt;Le diamètre des baguettes mesuré au pied à coulisse numérique, la longueur déterminée en fonction des étages voulus. &lt;/p&gt;
&lt;p&gt;Et modélisation des supports en mesurant l&amp;rsquo;épaisseur et le diamètre du pot destinataire, modélisé, lui aussi :&lt;/p&gt;
&lt;p&gt;NB: les couleurs sont celles dont je disposais en filament.&lt;/p&gt;
&lt;p&gt;Capture d&amp;rsquo;écran de la modélisation sous #Blender :
&lt;img alt="Modélisation3D" src="/images/isotuteur/3D.jpg"&gt;&lt;/p&gt;
&lt;p&gt;Et on peut évidemment, monter à l&amp;rsquo;infini.
&lt;img alt="Infini" src="/images/isotuteur/infini.jpg"&gt;&lt;/p&gt;
&lt;h2 id="impression-3d"&gt;Impression 3D&lt;/h2&gt;
&lt;p&gt;Les pièces résultantes :&lt;/p&gt;
&lt;p&gt;NB: j&amp;rsquo;ai passé un temps fou à tailler les impressions-support au cutter !&lt;/p&gt;
&lt;p&gt;&lt;img alt="Pièces brutes" src="/images/isotuteur/pieces-brutes.jpg"&gt;&lt;/p&gt;
&lt;h2 id="montage"&gt;Montage&lt;/h2&gt;
&lt;p&gt;Les pièces destinées à être posées sur le rebord du pot, en pointe pour entrer dans la terre.&lt;/p&gt;
&lt;p&gt;NB: j&amp;rsquo;ai pas forcé sur la qualité des impressions : le temps a déjà été bien assez conséquent (quand la pièce ne se décollait pas du plateau → au rebus !)&lt;/p&gt;
&lt;p&gt;&lt;img alt="Ground Zero" src="/images/isotuteur/embase0.jpg"&gt;&lt;/p&gt;
&lt;p&gt;J&amp;rsquo;ai retiré la pièce rouge : le filament, un peu trop vieux, s&amp;rsquo;était chargé en humidité, et a fait des micro-bulles et des fils à l&amp;rsquo;impression, rendant la pièce cassante.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Embase" src="/images/isotuteur/embase.jpg"&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt="Progression" src="/images/isotuteur/progress.jpg"&gt;&lt;/p&gt;
&lt;h2 id="final"&gt;Final&lt;/h2&gt;
&lt;p&gt;Résultat au 23 janvier 2023&lt;/p&gt;
&lt;p&gt;NB: les pièces blanches sont en fait phosphorescentes&amp;hellip; Très pratique à l&amp;rsquo;extinction des feux ^^&amp;rsquo;&lt;/p&gt;
&lt;p&gt;&lt;img alt="Résultat" src="/images/isotuteur/resultat.jpg"&gt;&lt;/p&gt;
&lt;p&gt;Aujourd&amp;rsquo;hui, ça a poussé ! (j&amp;rsquo;irai prendre une photo&amp;hellip;)&lt;/p&gt;</content><category term="Realisations"/><category term="Impression3D"/><category term="Blender"/><category term="Géodésique"/><category term="Nature"/></entry><entry><title>Perchoir Béziers</title><link href="https://www.domosys.org/perchoir.html" rel="alternate"/><published>2017-01-20T00:00:00+01:00</published><updated>2017-01-20T00:00:00+01:00</updated><author><name>Damien ULRICH</name></author><id>2017-01-20T00:00:00+01:00-Perchoir Béziers</id><summary type="html">&lt;p&gt;Un perchoir un peu trop perché&amp;hellip;&lt;/p&gt;</summary><content type="html">&lt;h2 id="simple-experimentation"&gt;Simple expérimentation&lt;/h2&gt;
&lt;p&gt;En conception 3D sous Blender, il y a les courbes de Béziers.&lt;/p&gt;
&lt;p&gt;Je les utilisait peu, j&amp;rsquo;ai juste voulu tester en y trouvant une utilité pratique.&lt;/p&gt;
&lt;p&gt;Au final, pour les oiseaux, ce n&amp;rsquo;est pas si pratique&amp;hellip; Trop petit 😕&lt;/p&gt;
&lt;p&gt;&lt;img alt="Georges perché" src="/images/perchoir/perchoir.jpg"&gt;&lt;/p&gt;</content><category term="Realisations"/><category term="Impression3D"/><category term="Blender"/><category term="Nature"/></entry><entry><title>Hack Roomba</title><link href="https://www.domosys.org/roomba.html" rel="alternate"/><published>2016-02-06T00:00:00+01:00</published><updated>2016-02-06T00:00:00+01:00</updated><author><name>Damien ULRICH</name></author><id>2016-02-06T00:00:00+01:00-Hack Roomba</id><summary type="html">&lt;p&gt;Au doigt et à l&amp;rsquo;oeil, l&amp;rsquo;aspirateur &amp;ldquo;autonome&amp;rdquo; !&lt;/p&gt;</summary><content type="html">&lt;h2 id="introduction"&gt;Introduction&lt;/h2&gt;
&lt;p&gt;On avait acheté un des premiers aspirateurs dits-autonomes : &lt;/p&gt;
&lt;p&gt;un Roomba de chez I-robot.&lt;/p&gt;
&lt;p&gt;Pas mal : il tournait dans la maison, seul, selon un parcours quelque-peu aléatoire, sans autre capteur que celui du choc frontal, et retournant à sa base de chargement, à partir de rayons infrarouges. (un truc du genre)&lt;/p&gt;
&lt;p&gt;Sauf que : nos tabourets hauts (que vous pouvez voir dans la &lt;a href="/mob.html#mobilier"&gt;3D&lt;/a&gt;), ont un pied circulaire au sol, dans lequels il avait tendance à se bloquer.&lt;/p&gt;
&lt;p&gt;Sans compter, certainement un de mes pricipaux défauts : les câbles !&lt;/p&gt;
&lt;p&gt;&amp;hellip; une fâcheuse tendance à &amp;ldquo;avaler&amp;rdquo; les câbles. 😒&lt;/p&gt;
&lt;p&gt;Dans cet esprit, je voulais voir s&amp;rsquo;il n&amp;rsquo;était pas possible d&amp;rsquo;améliorer son parcours &amp;hellip; en le guidant moi-même.&lt;/p&gt;
&lt;h2 id="experience"&gt;Expérience&lt;/h2&gt;
&lt;p&gt;Je ne me souviens plus exactement, mais il me semble que j&amp;rsquo;avais trouvé sur Internet son protocole et le câblage de sa prise DIN d&amp;rsquo;administration sur le dessus.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Câblage" src="/images/roomba/cablage.jpg"&gt;&lt;/p&gt;
&lt;h2 id="composants"&gt;Composants&lt;/h2&gt;
&lt;p&gt;C&amp;rsquo;était en février 2016 : il y avait encore peu de matériel Libre de disponible.&lt;/p&gt;
&lt;p&gt;Mais j&amp;rsquo;avais sous la main une Rasperry Pi (model B, je crois), avec un dongle Wifi, alimentée par un adaptateur d&amp;rsquo;allume-cigare/USB de voiture (oui il y a un semblant de 12V continu de disponible à partir des batteries, et la Raspberry s&amp;rsquo;alimente en 5V via USB&amp;hellip;).&lt;/p&gt;
&lt;p&gt;Pour finir, un simple adaptateur USB-Serial TTL Arduino, le tout branché sur la DIN, et voilà !&lt;/p&gt;
&lt;h2 id="programme"&gt;Programme&lt;/h2&gt;
&lt;p&gt;J&amp;rsquo;ai retrouvé le code dans les &amp;ldquo;oldies&amp;rdquo; 😁&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;~src/oldies/hack_roomba/&lt;span class="w"&gt; &lt;/span&gt;$&lt;span class="w"&gt; &lt;/span&gt;tree&lt;span class="w"&gt; &lt;/span&gt;pycreate/
pycreate/
├──&lt;span class="w"&gt; &lt;/span&gt;controller.py
├──&lt;span class="w"&gt; &lt;/span&gt;create.py
├──&lt;span class="w"&gt; &lt;/span&gt;dance.py
├──&lt;span class="w"&gt; &lt;/span&gt;graphics.py
├──&lt;span class="w"&gt; &lt;/span&gt;light.py
├──&lt;span class="w"&gt; &lt;/span&gt;move.py
├──&lt;span class="w"&gt; &lt;/span&gt;readme.rst
├──&lt;span class="w"&gt; &lt;/span&gt;sense.py
├──&lt;span class="w"&gt; &lt;/span&gt;sound.py
├──&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;test&lt;/span&gt;
│&lt;span class="w"&gt;   &lt;/span&gt;├──&lt;span class="w"&gt; &lt;/span&gt;test_dance.py
│&lt;span class="w"&gt;   &lt;/span&gt;├──&lt;span class="w"&gt; &lt;/span&gt;test_light.py
│&lt;span class="w"&gt;   &lt;/span&gt;├──&lt;span class="w"&gt; &lt;/span&gt;test_move.py
│&lt;span class="w"&gt;   &lt;/span&gt;├──&lt;span class="w"&gt; &lt;/span&gt;test_sense.py
│&lt;span class="w"&gt;   &lt;/span&gt;├──&lt;span class="w"&gt; &lt;/span&gt;test_sound.py
│&lt;span class="w"&gt;   &lt;/span&gt;└──&lt;span class="w"&gt; &lt;/span&gt;test_via.py
├──&lt;span class="w"&gt; &lt;/span&gt;test.py
├──&lt;span class="w"&gt; &lt;/span&gt;via.py
└──&lt;span class="w"&gt; &lt;/span&gt;wander.py

&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;directories,&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;18&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;files
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Un simple PySerial, qui envoit les codes appropriés.&lt;/p&gt;
&lt;p&gt;Aujourd&amp;rsquo;hui, les équipements sont plus élaborés (et plus compliqués d&amp;rsquo;accès pour certains totalement fermés), mais la démarche est la même : c&amp;rsquo;est faisable !&lt;/p&gt;
&lt;h2 id="demo"&gt;Démo&lt;/h2&gt;
&lt;p&gt;Je sais qu&amp;rsquo;on a une vidéo filmée par mon épouse, sur laquelle je le démarre de mon PC portable&amp;hellip; si je remets la main dessus&amp;hellip;&lt;/p&gt;</content><category term="Realisations"/><category term="Hack"/><category term="Domestique"/><category term="Electronique"/></entry></feed>