Stavros' Stuff Latest Posts Latest posts on Stavros' Stuff. en-us Stavros Korokithakis Making the Strofara https://www.stavros.io/posts/making-the-strofara/ https://www.stavros.io/posts/making-the-strofara/ <div class="pull-quote">I made yet another silly thing</div><p>This is going to be pretty specific to a Greek audience, as it&#8217;s all based on a Greek meme video, but I&#8217;ll try to explain. <a href="https://www.youtube.com/watch?v=jAMdqfTuIIU">Watch the video</a> first so you know what I&#8217;m talking about while I describe it:</p> <p>Two guys are driving on a road near a remote village in Crete, and the guy on the passenger seat is excited about the prospect of speeding around the turn. At some point, he exclaims &#8220;wow, what a turn, come on Giorgi!&#8221;, and Giorgis speeds into the turn and they promptly crash and tumble, with perfect comedic timing. (They were both unharmed, by the way, and their friends made <a href="https://www.youtube.com/watch?v=GaaOnp9ZJD8">a joke video</a> commemorating the feat).</p> <h1>The idea</h1> <p>I recently saw the video, and thought it was pretty funny, so it was kind of stuck in my head. One day, while driving, I took a turn, and thought of the guy saying the phrase he became famous for, and then thought it would be funny if my car could, autonomously, encourage me in a similar way whenever I took a big turn. I realized that it would be fairly easy to detect turns, using an accelerometer, and I had a board that can play MP3 files off a MicroSD card, so I figured I&#8217;d cobble them all together and see if it worked.</p> <p>I didn&#8217;t want to play the audio through the car&#8217;s speakers, I wanted the audio to come from somewhere inside the car, so I decided to use a speaker and bury it somewhere in my car&#8217;s insides, to pleasantly surprise any second-hand owner that might eventually buy the car, long after I&#8217;ve forgotten that this thing is in its bowels.</p> <h1>The build</h1> <div class="clearfix"></div><div class="alignright"><div class="photo-container"><a href="driver.jpg" data-lightbox="gallery"><img src="driver-small.jpg"></a></div><span class="caption">Obligatory AI rendition of what it feels like to drive with the Strofara in your car.</span></div><p>I used an MPU-6050 accelerometer breakout board, it was <a href="https://randomnerdtutorials.com/esp8266-nodemcu-mpu-6050-accelerometer-gyroscope-arduino/">really easy to connect it to an ESP8266</a>, and with some sample code and existing libraries, I was quickly on my way to detecting turns. I used the X axis component of the accelerometer, as that&#8217;s the lateral acceleration component in the way I was planning to mount it, and wrote some code to detect whether I&#8217;m in a tight turn for longer than half a second.</p> <p>If both those conditions are true, then a <a href="https://www.petervis.com/Electronics_Kits/gpd2856a/gpd2856a-mp3-decoder-board.html">GPD2856A board</a> is used to play the actual audio file. The GPD2856A is pretty convenient if you want to make an MP3 player, as it includes all the volume/play/pause/repeat/whatever controls you need for a standalone player, but pretty inconvenient if you just want to use a microcontroller to play an audio file, as the GPD2856A won&#8217;t interface with the microcontroller at all. All it does is play files in sequence (and in a loop) when it starts up, forever.</p> <p>This wouldn&#8217;t do me any good, as I just want to play one file once, so I hooked it up to an N-MOSFET so I can turn it on and off with the ESP8266. When I want to play the file, I tell the MOSFET to turn on the entire board, and when I want to stop, I just tell it to turn off. This works decently, but the board has some timing issues that mean that it doesn&#8217;t always start playing from the very beginning of the file, but sometimes skips half a second at the start. This means that the &#8220;wow&#8221; at the beginning is cut off, which is less than ideal.</p> <p>The way I fixed that is to simply insert half a second of silence at the start of the audio file. This means that I consistently get the whole phrase, but there&#8217;s a half a second delay, which might mess with my comedic timing while driving. I&#8217;ll have to test that and see, but, if it doesn&#8217;t work, my only other alternative will be to use an ESP32 and a proper driver.</p> <p>The board plays over a fairly big speaker that my friend Agis salvaged from some twenty-year-old PC speakers he had, and it&#8217;s really loud. I thought the USB current wouldn&#8217;t be enough to drive any significant volume, but it&#8217;s loud enough to startle me the first time the audio played over the speaker.</p> <h1>Finishing everything off</h1> <div class="clearfix"></div><div class="alignright"><div class="photo-container"><a href="strofara.jpg" data-lightbox="gallery"><img src="strofara-small.jpg"></a></div><span class="caption">The finished Strofara.</span></div><p>After connecting the ESP8266, the accelerometer, the MP3 player, and the speaker together, the only thing that remained was an enclosure worthy of such a legendary device. I decided to not bother with that, and instead designed a simple square case, though I did emboss the immortal words all around it. I quickly printed the enclosure out, and after some creative glueing, lamenting that I had measured wrongly and it was 1mm too short to fit everything, and printing it again, the Strofara was complete!</p> <p>You can see a photo of it to the right, it looks every bit as regal in real life as it does in that photo. On the middle bottom of the right face, you will notice the USB connector that powers the device (and also gives me access to the ESP8266 if I need to reprogram it).</p> <h1>Tada!</h1> <p>Of course, what would this post be without a taste of the actual, finished product, complete with audio? Just text.</p> <p>Here&#8217;s a video demonstration, by yours truly, in Greek (you don&#8217;t really need to understand anything I&#8217;m saying, it&#8217;s all random filler anyway):</p> <p><lite-youtube videoid="eJq5FPpsaXw" playlabel="A live demo of the Strofara">&lt;/lite-youtube&gt;</p> <p>Amazing, isn&#8217;t it?</p> <h2>Epilogue</h2> <p>As with mostly everything else, the code is open source, though there isn&#8217;t really much code to speak of:</p> <p><a href="https://github.com/skorokithakis/strofara">https://github.com/skorokithakis/strofara</a></p> <p>If you have any comments or feedback, please <a href="https://twitter.com/intent/user?screen_name=Stavros">tweet</a> or <a href="https://mastodon.social/@stavros">toot</a> at me, or email me directly.</p> Sun, 11 Aug 2024 16:14:27 +0000 Saving SSH passphrases on KDE https://www.stavros.io/posts/saving-ssh-passphrases-on-kde/ https://www.stavros.io/posts/saving-ssh-passphrases-on-kde/ <div class="pull-quote">I hate technology</div><p>I now notice I haven&#8217;t written anything in almost a year, which nobody else seems to have noticed, so I guess it&#8217;s just as well. I have, though, broken my unintentional hiatus to post something that reminds me why I hate technology so much: All UX is bad.</p> <p>I&#8217;ve been a Linux user for more than a decade now, but the latest Ubuntu update decided to randomly break my system&#8217;s ability to remember SSH keys. No matter what I tried, SSH keys just would not be remembered. I saw a lot of guides online that said to install <code>ksshaskpass</code> and set the <code>SSH_ASKPASS</code> environment variable to it, but that didn&#8217;t work for me (I kept getting the password prompt in the cli).</p> <p>Basically, nothing I tried worked, not even startup scripts that people were advising to install, not even manually adding the keys to my SSH agent (that worked for the current shell session, but nothing else). Eventually, I <em>did</em> find something that worked, and this problem plagued me for so long that I just had to write the solution here for you to hopefully see.</p> <h2>What worked</h2> <p>What I did that finally worked was to set the <code>SSH_ASKPASS_REQUIRE</code> variable to <code>force</code> and SSH to my host:</p> <div class="highlight"><pre><span></span><span class="nb">export</span><span class="w"> </span><span class="nv">SSH_ASKPASS_REQUIRE</span><span class="o">=</span>force ssh<span class="w"> </span>some.host.that.needs.a.key </pre></div> <p>That forced KDE to pop up a KDE window asking me for my password, then I could click &#8220;save password&#8221;, which saved the password in the KDE keychain. After that, even though <code>SSH_ASKPASS_REQUIRE</code> is back to <code>prefer</code>, I don&#8217;t get asked for my key any more. I think KDE just needed to be forced to store my passphrase in the keyring.</p> <h2>Epilogue</h2> <p>That&#8217;s it! As always, if you have comments, <a href="https://twitter.com/intent/user?screen_name=Stavros">tweet</a> or <a href="https://mastodon.social/@stavros">toot</a> at me, or email me directly.</p> Sat, 10 Aug 2024 14:51:12 +0000 The UX people https://www.stavros.io/posts/the-ux-people/ https://www.stavros.io/posts/the-ux-people/ <div class="pull-quote">Who are they?</div><p>Today, at work, I was debating with other engineers on what the wording of the message should be, when a patient tries to register an already-registered blood test kit. The specifics (or the people) aren&#8217;t really important here, but what struck a chord was when someone said &#8220;this is up to the UX people&#8221;.</p> <p>We don&#8217;t <em>have</em> &#8220;UX people&#8221;. &#8220;UX people&#8221; <em>don&#8217;t exist</em>.</p> <h2>The UX people</h2> <p>The unspoken assumption here is that <!-- break --> there&#8217;s a group of people in the company who are responsible for the UX, and they&#8217;re the ones who should decide what the error message should be. The problem with this way of thinking is that &#8220;UX&#8221; is shorthand for &#8220;making a product that&#8217;s easy to use/feels nice/does what you want&#8221;. UX is <em>definitely not</em> about making things pretty, you can have the ugliest UI in the world, but stellar UX.</p> <p>When you think about that, it&#8217;s clear that there <em>are</em> no &#8220;UX people&#8221;. You&#8217;re not supposed to do &#8220;eh, whatever&#8221; and throw it over the wall to someone who will double-check all the decisions you&#8217;ve made, and come to you and say &#8220;this is hard for users to use&#8221;. It&#8217;s the responsibility of <em>every single person</em> in a company (from designers to engineers to PMs to HR) to think about how what they do affects the user&#8217;s experience, and to try to improve it. Obviously, the closer you are to the end result, the more it is your job to think about UX, and to try to ensure it&#8217;s good, but there&#8217;s no single person that runs around being the &#8220;Let&#8217;s Make the Product Great&#8221; person.</p> <h2>We have designers, why not UX people?</h2> <p>You may have &#8220;UX experts&#8221;, people who are more experienced in UX and can point out improvements, but they don&#8217;t absolve you of responsibility, because UX isn&#8217;t an isolated aspect of a product. You can&#8217;t point to something and say &#8220;here&#8217;s the backend, and here&#8217;s the UI, and here&#8217;s the UX&#8221;. UX is the sum total of the behaviour that your product exhibits as the user interacts with it.</p> <p>There&#8217;s nobody to whom you can offload the responsibility of having to think about your user. <em>Especially</em> as a developer, all the interactions your user will have with what you&#8217;re building are your responsibility <em>the most</em>, because you&#8217;re the ultimate decisionmaker for <em>how the service will behave</em>. Of course, as I said above, this is a shared responsibility, but the responsibility increases the closer you are to the implementation.</p> <h2>Whose job is it?</h2> <div class="clearfix"></div><div class="alignright"><div class="photo-container"><a href="swiss-army-phone.jpg" data-lightbox="gallery"><img src="swiss-army-phone-small.jpg"></a></div><span class="caption">The UX person was on holiday when designing the iPhone 13.</span></div><p>It&#8217;s very important to understand the above, especially in situations where you&#8217;re dividing up responsibilities. If you think of UX as some concrete aspect of the product, you might fall in the above trap, where UX is somehow not your responsibility, like the payments service isn&#8217;t your responsibility. This leads to the mindset that you can just do any old thing, and then a &#8220;UX person&#8221; will come along and correct you if you do it wrong, which is disastrous, because it results in a bad default.</p> <p>If you think that UX isn&#8217;t your responsibility, then you&#8217;re going to be making frustrating products until someone comes along, thinks about the user&#8217;s experience, and fixes some of it. This leads to mostly-frustrating products.</p> <p>If you think that UX is <em>everyone&#8217;s</em> responsibility, and think about how the user will perceive of the product, interact with it, feel while using it, then you make good products by default. Someone might <em>still</em> come along and propose improvements, but you&#8217;re going to start from a much better place.</p> <h2>Meraki</h2> <div class="clearfix"></div><div class="alignright"><div class="photo-container"><a href="bridge.jpg" data-lightbox="gallery"><img src="bridge-small.jpg"></a></div><span class="caption">Close enough.</span></div><p>In Greek, there&#8217;s a word for this approach to building, &#8220;meraki&#8221;. Unfortunately, it&#8217;s extremely hard to translate accurately, but it mostly means &#8220;taking pride in one&#8217;s work, putting in the time to polish it, doing it well&#8221;. It&#8217;s more or less the opposite of the Chinese <a href="https://www.chinaexpatsociety.com/culture/the-chabuduo-mindset">&#8220;cha bu duo&#8221;</a> (roughly &#8220;eh, close enough&#8221;).</p> <p>It&#8217;s up to you how you want to make the things you make, but, personally, I find that spending a few minutes to think about how the user might use the stuff you make doesn&#8217;t take much effort, and usually leads to much better results. It&#8217;s the difference between a menu item requiring one click instead of three, which will add up to hours saved many people have to click the same menu item, many times a day.</p> <h2>Epilogue</h2> <p>These were just some random thoughts I had on the matter, and I&#8217;m glad the golden age of blogs is over because it means I can jot stuff down without stressing about whether it&#8217;s good or not, cha bu duo.</p> <p>In retrospect, I&#8217;m happy that my coworker said what he said, because hearing it bothered me, and led to me spending a bit of time trying to think about what exactly it was that bothered me, which led to the realization that UX isn&#8217;t something that can be isolated. I hope this article changes how you approach UX as well.</p> <p>As always, <a href="https://twitter.com/intent/user?screen_name=Stavros">Tweet</a> or <a href="https://mastodon.social/@stavros">toot</a> at me, or email me directly.</p> Wed, 11 Oct 2023 16:09:36 +0000 Spam spammers back https://www.stavros.io/posts/spam-spammers-back/ https://www.stavros.io/posts/spam-spammers-back/ <div class="pull-quote">Now with added ChatGPT</div><p>I&#8217;m writing this post sleepless and with a headache, which I find is the best way to write posts, because it removes all the verbal guardrails, so, be forewarned.</p> <p>Back in 2016, a year before recorded history, I stole a simple idea: What if I wrote a bot to reply to spammers, pretending to be interested in their wares, and wasting their time? After <a href="/posts/spamnesty-waste-spammers-time/">some creating this</a>, it turned out that it was possible, and <a href="https://spa.mnesty.com/">Spamnesty</a> was born.</p> <p>Spamnesty was cleverly disguised as a company, <a href="https://www.mnesty.com/">Mnesty, LLC</a>, Asia&#8217;s premier maritime logistics company, strategically located in the land-locked Mongolia. Of course, this didn&#8217;t tip spammers off that the whole thing was fake, because why would they even care to look at the site? This resulted in untold amounts of entertainment, whiling the small hours of the morning away, reading about the likes of the hapless <a href="https://spa.mnesty.com/conversations/hehkkbwb/">Abdullah Ishaq</a>, whose attempt of selling LedTrading.com to my bot did not <!-- break -->go well.</p> <h2>The eventual end</h2> <div class="clearfix"></div><div class="alignright"><div class="photo-container"><a href="robot.jpg" data-lightbox="gallery"><img src="robot-small.jpg"></a></div><span class="caption">How it's made: Automated sales campaigns.</span></div><p>As with all good things, however, Spamnesty, too, had to come to an end. It didn&#8217;t, though it did become gradually less and less entertaining, as spammers decided that replying to people wasn&#8217;t economical, and opted to switch to scamming people with automated methods instead. This resulted in the emails being automated, and instead of highly-entertaining colloquies between a party with much to gain from the dialogue and a spammer, we ended up with bots spamming bots.</p> <p>As it turns out, this makes for <a href="https://spa.mnesty.com/conversations/baehezxx/">much less compelling reading</a>. Since spam didn&#8217;t end (that&#8217;s what I assume, anyway, as I haven&#8217;t opened my email since 2018), the world needed a new solution.</p> <h2>A new beginning</h2> <p>A few days ago, I received a spam email. To a layperson, it might have looked like a regular spam email, which they would have sent to the trash without a second thought. My trained eye, however, spotted the tiniest of details immediately: This email was in my inbox.</p> <p>Immediately I wondered how this email could have bypassed the spam filter, and inspected its raw headers.</p> <div class="highlight"><pre><span></span><span class="cs">X-Mail-from:</span><span class="cm"> spammer@aol.com</span> <span class="nt">Received:</span><span class="w"> </span>from<span class="w"> </span>mx1<span class="w"> </span>([<span class="mi">10.202.2.200</span>]) <span class="w"> </span>by<span class="w"> </span><span class="nf">compute4.internal</span><span class="w"> </span>(LMTPProxy);<span class="w"> </span><span class="nd">Fri, 28 Jul 2023 08:01:40 -0400</span> <span class="nt">Received:</span><span class="w"> </span>from<span class="w"> </span><span class="nf">mx1.messagingengine.com</span><span class="w"> </span>(localhost<span class="w"> </span>[<span class="mi">127.0.0.1</span>]) <span class="w"> </span>by<span class="w"> </span><span class="nf">mailmx.nyi.internal</span><span class="w"> </span>(Postfix)<span class="w"> </span>with<span class="w"> </span><span class="k">ESMTP</span><span class="w"> </span>id<span class="w"> </span>85CC123C0072 <span class="w"> </span>for<span class="w"> </span><span class="nl">&lt;info@me.com&gt;</span>;<span class="w"> </span><span class="nd">Fri, 28 Jul 2023 08:01:39 -0400</span><span class="w"> </span>(EDT) <span class="nt">Received:</span><span class="w"> </span>from<span class="w"> </span><span class="nf">mailmx.nyi.internal</span><span class="w"> </span>(localhost<span class="w"> </span>[<span class="mi">127.0.0.1</span>]) <span class="w"> </span>by<span class="w"> </span><span class="nf">mx1.messagingengine.com</span><span class="w"> </span>(Authentication<span class="w"> </span>Milter)<span class="w"> </span>with<span class="w"> </span><span class="k">ESMTP</span> <span class="w"> </span>id<span class="w"> </span><span class="nf">A6760957722.23F8823C008C</span>; <span class="w"> </span><span class="nd">Fri, 28 Jul 2023 08:01:39 -0400</span> <span class="nt">ARC-Seal:</span><span class="w"> </span>i=1;<span class="w"> </span>a=rsa-sha256;<span class="w"> </span>cv=none;<span class="w"> </span>d=<span class="nf">messagingengine.com</span>;<span class="w"> </span>s=fm3;<span class="w"> </span>t= <span class="w"> </span>1690545699;<span class="w"> </span>b=gC4GEHuuchzN5TtgSnkL6VmZEJgt+w5iltASfKE/cOgTVQg330 <span class="w"> </span>O9BbJ8suAAvWBBDhvQo2OWDEKEy0IVqttJT84rmjqotrneVpWQMD6ASEnH4/z9fq <span class="w"> </span>UimpGIGT4bPv1gpgbxo28sbmT0BxT7qdOtBjO7CuduW9RmUYSpRTq7dlazgqAFOV <span class="w"> </span>qlBdqganQiUMCdMlkr6ZXA3qqTk3mdpDgBPUhskO2NpTRo/5zqPEbawNgfOGv4jG <span class="w"> </span>1xpwwD3okjmDswRq96ZjJu0l6W816vzIh5vErLbzOr6zZ1uVq27vy2ToEmeFs13S <span class="w"> </span>S2nlO2OuEZF2Wv5/kfnl8kHrjrLnli6qfqEQ== </pre></div> <p>They looked like gibberish, so I stopped inspecting, and looked at the body of the message, where I noticed something equally surprising:</p> <p>This email was <em>written by a person</em>.</p> <h2>The email that was written by a person</h2> <div class="clearfix"></div><div class="alignright"><div class="photo-container"><a href="spammer.jpg" data-lightbox="gallery"><img src="spammer-small.jpg"></a></div><span class="caption">Peter was taken entirely aback when he realised the job posting was not for the canned meats industry.</span></div><p>This spammer was an <strong>actual person</strong>, with a name and a signature and, presumably, flesh and tooth enamel. Yes, the email was sent without my consent, without solicitation, and automatically, but there was an actual, human person at the other end, who would presumably reply if I indicated the slightest bit of sales interest.</p> <p>Due to my line of work, I am familiar with a little-known tool that is basically a person in a computer: ChatGPT. The wheels in my head immediately started turning: I would use this person-in-a-computer to reply to this person-next-to-a-computer, and potentially waste his time.</p> <p>Without any delay, and with exceeding haste, I began asking ChatGPT to write the code for me, creating what ChatGPT named <a href="https://github.com/skorokithakis/spamgpt"><strong>SpamGPT</strong></a>.</p> <h2>SpamGPT</h2> <div class="clearfix"></div><div class="alignright"><div class="photo-container"><a href="robots.jpg" data-lightbox="gallery"><img src="robots-small.jpg"></a></div><span class="caption">Two spammer robots, spamming each other.</span></div><p>SpamGPT is a simple program: It runs at a random minute every hour, opens my email, looks in a folder I&#8217;ve named <code>SpamGPT</code>, and replies to any emails in there that it hasn&#8217;t already replied to.</p> <p>All I have to do is find spam messages that looks like they were written by a person (mostly sales emails), and move them to the <code>SpamGPT</code> email folder, and SpamGPT will eventually reply to them. Its instructions are that it should pretend to be interested in whatever the spammer is selling, and do whatever it can to waste their time. This includes trying to set up meetings, pretending to have issues with its computer, insist that payment details are wrong, or that it has sent the payment, and whatever else it can conceive of.</p> <p>The result is as entertaining as ever.</p> <h2>Why not add ChatGPT to Spamnesty?</h2> <p>Many people have suggested that I add ChatGPT support to Spamnesty, as a natural next step, but there were two problems with this:</p> <ol> <li>As I said above, most spam is bots, and ChatGPT would compose long, detailed, and thoughtful replies to spam, only to receive a canned message back. Computer program or not, I couldn&#8217;t do this to something that can think more coherently than me.</li> <li>The amount of spam that is sent is massive, and the costs for having ChatGPT to reply to all of it (usually ineffectively, as per point #1) would be too much for me to pay.</li> </ol> <p>If we&#8217;re going to waste spammers&#8217; time and entertain ourselves at the same time, there needs to be a manual curation step. There needs to be someone at least glancing at the emails, making sure that they&#8217;re worth responding to. This is what SpamGPT does much better than Spamnesty.</p> <p>The other added benefit is that every user runs it for their own mailbox, so I neither get to see your email, nor pay for your spam countermeasures, which suits me fine.</p> <h2>Wider reach</h2> <p>Of course, one thing that Spamnesty had but SpamGPT was missing was the ability for other people to read the conversations. I couldn&#8217;t keep such entertaining material for myself, not when the answer lay, as always, a few lines of code away. So, I rolled up my sleeves, and got to work, asking ChatGPT to write the code to make the above a reality.</p> <p>Thus, <a href="https://thespamchronicles.stavros.io/welcome/">the Spam Chronicles</a> were born.</p> <p>The Spam Chronicles are a collection of all the emails that SpamGPT has responded to. It contains such gems as the conversation of <a href="https://thespamchronicles.stavros.io/emails/2023-08-02-meeting-now-with-advids/">the guy who tried for a week to set up a meeting with a bot</a>, or <a href="https://thespamchronicles.stavros.io/emails/2023-07-26-re-addthis-users/">the guy who tried in vain to get the bot to pay an invoice, and got told to &#8220;find more meaningful ways to contribute to society&#8221;</a>.</p> <p>I will keep updating this list as I get more messages, and, if enough people use SpamGPT, I might add a way to submit your spam emails to the Spam Chronicles automatically, for everyone to read. Hopefully I won&#8217;t get people submitting sales emails to the Spam Chronicles, even though spamming the anti-spam site would be delightful irony.</p> <h2>Epilogue</h2> <p>If you want to run SpamGPT for yourself, but missed the link above, you can find it on GitHub:</p> <p><a href="https://github.com/skorokithakis/spamgpt">https://github.com/skorokithakis/spamgpt</a></p> <p>Email is a sufficiently complicated and brittle protocol that I don&#8217;t have much faith that SpamGPT will work for all email servers, but it works for me, and if it doesn&#8217;t work for you, we&#8217;ll figure something out. In the mean time, if you do run SpamGPT, please drop me a line, I&#8217;d be interested to know how it works for you, and if you&#8217;re getting good results.</p> <p>I hope you enjoy messing with spammers, and make spamming expensive enough that they won&#8217;t bother us ever again, even if it means lining OpenAI&#8217;s pockets.</p> <p>As always, you can <a href="https://twitter.com/intent/user?screen_name=Stavros">Tweet</a> or <a href="https://mastodon.social/@stavros">toot</a> at me, or email me directly.</p> Sat, 05 Aug 2023 18:37:08 +0000 Use your Wii Balance Board as a scale (again) https://www.stavros.io/posts/use-your-wii-balance-board-as-a-scale-again/ https://www.stavros.io/posts/use-your-wii-balance-board-as-a-scale-again/ <div class="pull-quote">We did it again, internet</div><p>If you&#8217;ll recall, <a href="/posts/your-weight-online/">once upon a time I managed to get my Wii Balance Board to connect to my computer and function as a scale</a>. At some point throughout the years, Linux changed, and that method broke. It would still measure your weight fine, but you could no longer activate the balance board by tapping its front button, you had to flip it over, remove the battery compartment lid and press the red button every time. This was too much of a hassle, so I stopped using the board, hoping that a solution to this problem would arrive one day to liberate me from the scourge of adipose tissue.</p> <p>This day is today (well, a few months ago, actually, but I couldn&#8217;t be arsed writing about it until today, so). I received an email from a reader called Jawaad Mahmood, who had read my balance board article and spent a bit of time figuring out how to get the balance board to work, and packaged his work into <a href="https://github.com/jmahmood/bbev">a library called bbev</a>.</p> <p>I was initially sceptical because many people contacted me throughout the years, but nobody managed to get rid of the red button requirement. Talking to Jawaad for a bit, though, he confirmed that he could painlessly get the board to pair with his computer with the front button. Apparently something had changed in the Linux Bluetooth stack, and made pairing possible again, and he managed to figure out how.</p> <p>This was great news! However, <!-- break --> I wanted to make a few small changes to suit my use case, like disconnecting from the board after the measurement was done, running a command with the weight afterwards, etc.</p> <div class="clearfix"></div><div class="alignright"><div class="photo-container"><a href="wiiboard.jpg" data-lightbox="gallery"><img src="wiiboard-small.jpg"></a></div><span class="caption">What MidJourney thinks a balance board looks like.</span></div><p>I spent a bit of time writing some code, using most of the measurement code from Jawaad&#8217;s library, added the features I needed, and released it for your enjoyment:</p> <p><a href="https://pypi.org/project/weii/">https://pypi.org/project/weii/</a></p> <p>It&#8217;s a command-line application, but it&#8217;s fairly simple to use. You run <code>weii</code>, turn the balance board on, step on it, and a few seconds later you have your measurement and the board turns off.</p> <p>Pretty convenient!</p> <p>There isn&#8217;t really much more to say here, I just wanted to let you all know that we can finally once again weigh ourselves using our balance boards.</p> <h2>Epilogue</h2> <p>I&#8217;d like to thank Jawaad for figuring out how to solve the dreaded pairing problem, and for open-sourcing his code. I&#8217;m really glad I can finally use my board to conveniently weigh myself and <a href="/misc/weight/">post my weight online</a>, with one simple command.</p> <p>I hope you find <code>weii</code> as useful as I do!</p> <p>If you have any feedback, please <a href="https://twitter.com/intent/user?screen_name=Stavros">Tweet</a> or <a href="https://mastodon.social/@stavros">toot</a> at me, or email me directly.</p> Sat, 10 Jun 2023 22:53:36 +0000