<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>project on foosel.net</title><link>https://foosel.net/tags/project/</link><description>Recent content in project on foosel.net</description><generator>Hugo</generator><language>en-us</language><copyright>Gina Häußge (foosel)</copyright><lastBuildDate>Wed, 14 Feb 2024 00:00:00 +0000</lastBuildDate><atom:link href="https://foosel.net/tags/project/feed.xml" rel="self" type="application/rss+xml"/><item><title>Custom SteamDeck Buttons</title><link>https://foosel.net/blog/2023-01-19-custom-steamdeck-buttons/</link><pubDate>Thu, 19 Jan 2023 00:00:00 +0000</pubDate><guid>https://foosel.net/blog/2023-01-19-custom-steamdeck-buttons/</guid><description>Color coded for your convenience</description><content:encoded><![CDATA[<p><em><strong>Update from 2023-02-02</strong> To answer the most common question I&rsquo;ve gotten after publishing this right away: No, I do not plan on selling these. This is something I did for fun and out of love, I&rsquo;m not interested in making money off of it, and I frankly already have my hands full enough as is without adding a custom button business to the mix as well. I&rsquo;ve provided this write-up to give you an idea of how to do it yourself, and I hope you&rsquo;ll enjoy it.</em></p>
<p>My partner and I both got ourselves SteamDecks in 2022. Since then he&rsquo;s repeatedly mentioned that he&rsquo;d love to have
colored buttons on his, matching the XBox controller layout, as many PC games use these colors for their
button hints during quick time events and similar. But sadly, nothing like that is available yet.</p>
<p>With that in mind, and after losing my initial fear about opening up the deck thanks to swapping my fan and upgrading
my SSD on January 1st of this year, an idea for a surprise started to form in my head. I had watched a ton of videos
on silicone molding and resin casting, I have several 3d printers at my disposal, and there was just enough time left
in my vacation and until our anniversary to pull this off. So I went to work. In total secrecy.</p>
<h2 id="research--material-collection">Research &amp; material collection</h2>
<p>The first thing I jumped into was some research in order to be able to make a plan and know what to get.</p>
<p>I ran across <a href="https://bitbuilt.net/forums/index.php?threads/resin-casting-molding-buttons.2316/">this interesting thread</a>
on button casting which gave me a good idea of what I&rsquo;d need in terms of materials. It also taught me that I needed to
figure out what kind of mold I&rsquo;d even need to create for the buttons. Were they flat on the bottom in which case a single part
mold would suffice, or were they curved or otherwise featured, in which case I&rsquo;d need to create a two part mold? Instead of
disassembling my deck right away (too obvious with my partner being around) I decided to instead checkout
<a href="https://www.ifixit.com/Guide/Steam+Deck+Action+Buttons+(ABXY)+Replacement/148950">this excellent disassembly guide on iFixit</a>
which showed me that the buttons are indeed inset on the bottom, and so I&rsquo;d need a two part mold.</p>
<p>That in turn meant I needed to look into mold release for multi part silicone molds in addition to silicone and resin. The
material list in the thread sadly didn&rsquo;t help me - I couldn&rsquo;t get half of this stuff in Germany - but here&rsquo;s what I finally settled on:</p>
<ul>
<li><strong>Reschimica Silicone RPRO 30</strong> (silicone)</li>
<li><strong>Trollfactory Silicone Mold Separation Cream</strong> (two part mold release)</li>
<li><strong>clear two part epoxy resin</strong> (I got this from a friend who happened to have some collecting dust for several months, still sealed)</li>
<li><strong>food vacuumizer pump and container</strong> (to degass silicone and resin, based on an idea from <a href="https://hackaday.com/2019/12/19/degassing-epoxy-resin-on-the-very-cheap/">this hackaday article</a> - a real vaccum chamber and also a pressure pot would have been nice, but I didn&rsquo;t want to break the bank over a bunch of buttons here 😅)</li>
<li><strong>Mica powder</strong> (to color the resin)</li>
<li><strong>white 4mm rub on letters</strong> (to put the lettering on the buttons)</li>
<li><strong>clear UV resin</strong> (to seal the lettering in)</li>
<li><strong>wooden stir sticks</strong></li>
<li><strong>plastic mixing cups</strong></li>
<li><strong>small paper mixing cups</strong></li>
<li><strong>10ml syringes</strong> and <strong>14g blunt needles</strong> (for injecting the resin into the mold)</li>
<li><strong>plastillina clay</strong> (to fix the buttons during the silicone pour)</li>
</ul>
<p>Thanks to owning a resin printer, I already had <strong>a UV flashlight</strong>, <strong>nitrile gloves</strong> and a <strong>respirator</strong> on hand.</p>
<p>And at least one ready to go <strong>FDM 3d printer</strong> for helping me in the mold creation process.</p>
<p><img alt="Most of the materials and tools that I used for this project, as mentioned above." loading="lazy" src="/blog/2023-01-19-custom-steamdeck-buttons/materials.jpg"></p>
<h2 id="creating-a-two-part-silicone-mold">Creating a two part silicone mold</h2>
<p>Next step was to create my two part silicone mold and for that I first needed something to fix the buttons to, do the pour for the first
part of the mold, flip that over and create the second part of the mold. I did some more research and came across two
interesting videos, <a href="https://www.youtube.com/watch?v=mjKAkul-VDQ">&ldquo;How To Make Custom PS5 Controller Buttons&rdquo;</a> and
<a href="https://www.youtube.com/watch?v=DfbIYH3xauc">&ldquo;Upgrade Your PS5 Controller with DIY Resin Buttons - Better than the Original!&rdquo;</a>.
In both, EJ uses a 3d printed box with custom bottom to hold the buttons in place and create a keyed two part mold. So, I did
create just that as well. My mold box consists of several parts: two halves forming the box, a bottom for the first part (creating the
keying), a smooth bottom and a top brace for the second part. The bottoms slot into the box halves, the top brace is just friction
fit. Why the top brace? To hold some toothpick halves in place that create channels for resin to go in and air to go out when the
mold is closed.</p>
<p>I designed all this in FreeCAD<sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup> and this is how it looks:</p>
<p><img alt="The mold box configuration for the first pour. Both halves and the keyed bottom." loading="lazy" src="/blog/2023-01-19-custom-steamdeck-buttons/mold_case_part1.png"></p>
<p><img alt="The mold box configuration for the second pour. Both halves, the smooth bottom and the cross brace." loading="lazy" src="/blog/2023-01-19-custom-steamdeck-buttons/mold_case_part2.png"></p>
<p>You can find the STLs <a href="https://www.printables.com/model/374098-steamdeck-button-mold-case">here</a>. All of the parts were printed
on my heavily modified Prusa MK3 with a 0.6mm nozzle and a 0.3mm layer height in black extrudr PLA NX2 - you might have to adjust
the tolerances on other printers or with other filaments, which is why I also included the FreeCAD file (which could be cleaner,
but it worked for me).</p>
<p>Once I had the mold box ready it was time to disassemble the deck and get the buttons in my hand. So I waited until my partner
was out of the house and then got going.</p>
<p>First, I disassembled everything based on the <a href="https://www.ifixit.com/Guide/Steam+Deck+Action+Buttons+(ABXY)+Replacement/148950">aforementioned iFixit guide</a>. I attached the buttons to their spots on the keyed bottom plate of the mold box with some thin, rolled clay wormy
dealies and then thoroughly cleaned them with some q-tips and isopropyl alcohol. It is important to be <em>very</em> thorough here - any
dirt or even just a fingerprint <em>will</em> show up in the silicone mold and thus in the resin casting as well. I actually found that
the outlines of the letters molded into the original buttons left an impression. The level of details you can get from silicone
molds is astonishing!</p>
<p>Also make sure that you keep the lettering of the buttons oriented the same way, that way you will also
be able to re-use the mold later for buttons with inlayed lettering (which is my plan for version 2.0 of this project).</p>
<p><img alt="The four action buttons mounted to the keyed mold case bottom. My hand hovering over them with a q-tip, a bottle of isopropyl alcohol in reach. In the background the disassembled deck." loading="lazy" src="/blog/2023-01-19-custom-steamdeck-buttons/silicone_mold_step1.jpg"></p>
<p>I then slid the bottom plate into the grooves of the mold box halves, sealed the seam with some blue painters tape and just to be
safe also wrapped two rubber bands around it.</p>
<p><img alt="The assembled mold box for the first pour. The buttons are mounted to the bottom. The seems seasled with tape. Two rubber bands go around." loading="lazy" src="/blog/2023-01-19-custom-steamdeck-buttons/silicone_mold_step2.jpg"></p>
<p>Now came the time for the first pour. I weighed out 35g each of part A and B into a plastic mixing cup (my silicone gave instructions for mixing 1:1 by weight, stick to your instructions!) and then thoroughly mixed
it with a stir stick. Then I poured that into a <em>second</em> cup, from high above, in a thin stream - this is first to get some of
the bubbles out but more importantly to prevent any unmixed silicone from getting into the mold. This cup I then degassed. For my
first pour I actually used a power sander to vibrate the bubbles out, but for the second pour I went with the above mentioned
food vacuumizer - it&rsquo;s easier, you get way less shaky hands out of it, and the results also look better. So, into the food container,
lid on, pump on. I degassed until bubbles stop coming out. Then I slowly poured the silicone into a corner of the mold
box, once again in a thin stream from up high. Take your time here, the slower, the less risk of errant bubbles making it into
the mold. Then I degassed the mold again for a couple minutes and let it cure based on the instructions.</p>
<p><img alt="The box filled with silicone after the first pour." loading="lazy" src="/blog/2023-01-19-custom-steamdeck-buttons/silicone_mold_step3.jpg"></p>
<p>Next, I demolded the first part by removing rubber bands and the tape around the box and then carefully pulling the two halves
apart. I then slowly removed the bottom plate from the silicone part as well, being careful to keep the buttons inside<sup id="fnref:2"><a href="#fn:2" class="footnote-ref" role="doc-noteref">2</a></sup>.
I then cleaned them off of any leftover plastillina clay and any small bits of silicone.</p>
<p><img alt="The cured first part of the silicone mold, with the buttons still inside. The keying created by the bottom plate is visible." loading="lazy" src="/blog/2023-01-19-custom-steamdeck-buttons/silicone_mold_step4.jpg"></p>
<p>After that I placed the first part of the mold on the smooth bottom plate and slid that back into the mold box. I then applied a
generous coating of two part mold release. I used an old drybrush for that and liberately spread it all across the silicone and
box surfaces, making extra sure to get into all the corners and creases. I taped the box seams again and then put the top brace
in place. I broke four toothpicks in half, also broke off most of their tips, and then inserted one into each of the brace holds,
pushing into opposite ends of the buttons underneath. This was to create channels for the resin to flow into and air to push
out of the mold.</p>
<p><img alt="The first part of the silicone mold placed back into the mold box. The cross brace is installed and two toothpick halves lead to each button." loading="lazy" src="/blog/2023-01-19-custom-steamdeck-buttons/silicone_mold_step5.jpg"></p>
<p>I once again mixed 70g of silicone from 35g of each part A and B, moved into a second cup, degassed it and slowly poured it into
the mold. Then that was degassed as well and left to cure.</p>
<p><img alt="The mold box, once again filled with silicone, and placed in the vacuum container." loading="lazy" src="/blog/2023-01-19-custom-steamdeck-buttons/silicone_mold_step6.jpg"></p>
<p>Another 5h later I carefully demolded my two part mold. I once again removed tape, rubber bands and the top brace, pulling out
the toothpick halves in the process. I then carefully pulled the two halves of the box apart again and equally carefully peeled
the two parts of the mold apart from each other.<sup id="fnref:3"><a href="#fn:3" class="footnote-ref" role="doc-noteref">3</a></sup> I could now remove the buttons, clean them, place them back into the deck and
reassemble it. Then I cut off some of the silicone bits that had been sucked into the internal hollow structure of the buttons
which I <em>did</em> not want to replicate. I was very diligent here to not cut away too much. And then I was the proud owner of a two
part silicone mold for SteamDeck action buttons.</p>
<p><img alt="The finished two part mold, visibly keyed and interlockable." loading="lazy" src="/blog/2023-01-19-custom-steamdeck-buttons/silicone_mold_step7.jpg"></p>
<h2 id="resin-time-resin-time-do-do-do-do-resin-time">Resin time, resin time, do do do do, resin time</h2>
<p><em>Wear gloves and a respirator during this!</em></p>
<p>With the mold now ready for action, it was time to try my hand at resin casting. I first assembled the mold, securing the two
halves with four rubber bands. I also attached the mold to a piece of cardboard in the process on which I noted down the location
of each of the buttons inside the mold. This is really important to keep track of which button goes where. With everything being
mirrored thanks to the buttons basically lying on their faces in the mold you otherwise get terribly puzzled and end up with
buttons of the wrong color. Ask me how I know 😅 If you get confused on which button is which, take a close look at the
spaces they left in the mold. The B button of the deck is slightly curved on its outer side due to following the deck&rsquo;s case
curving, and that has helped me a ton to keep track of it and everything else in relation to it.</p>
<p>Next, I mixed up 40ml of resin, so 20ml of each part A and B (my resin gave instructions for mixing 1:1 by volume, check your
instructions!). I degassed it in the vacuum container and then spread it across
four small paper cups, roughly 10ml each. I then added red, greed, blue and yellow mica powder to each of the cups, mixing that
in thoroughly, before placing the cups into the vacuum container and degassing them again. Next, four syringes with blunt 14g
needles were filled with the four colors of resin and then the buttons were filled with the respective color. After getting
confused with the colors on my first try, I double and triple checked each color before filling it in on the second. I carefully inserted
the needle into the inner channel and then slowly pressed the resin in until it came out of the outer channel. On my first
try I made the mistake to overfill, which caused some unintentional color mixing, so be sure to really stop right when the
resin comes out of the air channel.</p>
<p><img alt="The button mold filled with the colored resin, the four small paper cups holding the unused resin sitting next to it in an aluminium tray." loading="lazy" src="/blog/2023-01-19-custom-steamdeck-buttons/resin_cast_step1.jpg"></p>
<p>I then let the buttons cure for 24h before taking a first peek.</p>
<p><img alt="The buttons after 24h of curing." loading="lazy" src="/blog/2023-01-19-custom-steamdeck-buttons/resin_cast_step2.jpg"></p>
<p>They looked great, but a quick fingernail test on one of the resin pots showed the stuff was not fully hardened yet. It turned
out to take 72h until I could proceed with the finishing steps.</p>
<h2 id="finishing-the-buttons">Finishing the buttons</h2>
<p>I kept the buttons attached to the mold for the final steps, as that helped a lot with keeping everything aligned and
less fiddly (it was fiddly enough as is). I carefully placed the sheet with rub on lettering I had bought over each button,
making sure to center the corresponding letter. Then I rubbed the letter on using the blunt tip of my letter opener. The stuff
didn&rsquo;t want to stick to the smooth top surface very well, which had the upside of allowing me to redo something if I messed up, but also
the downside of me having to be <em>very</em> careful to not mess things up that were already fine. In the end, it took me some tries
but I prevailed.</p>
<p>Then I got out the UV resin, put on the respirator and gloves, and with an old brush softly brushed on a thin layer of
resin on each button, careful not get any drops on the side or pooling, but sealing in the letter. I then cured that for several minutes
with the UV flashlight.</p>
<p>Once the resin was cured I carefully pulled out the buttons from the mold and then cut off the sprue with a flush cutter.</p>
<p><img alt="The four custom buttons sitting on a post-it note." loading="lazy" src="/blog/2023-01-19-custom-steamdeck-buttons/finished_buttons1.jpg"></p>
<p>A quick test fit in my deck showed that I needed some light sanding on one side of X, but that was quickly taken care of and
then I had a working set of custom SteamDeck buttons 👍</p>
<p><img alt="Colorful custom action buttons on the right side of a SteamDeck held up to the camera." loading="lazy" src="/blog/2023-01-19-custom-steamdeck-buttons/finished_buttons2.jpg"></p>
<h2 id="where-do-we-go-from-here">Where do we go from here?</h2>
<p>Considering that until Monday January 9th 2023 I had never before touched silicone or epoxy resin, and that by Monday January 16th 2023 I had four self-cast SteamDeck buttons in my hand that while far from perfect looked <em>great</em>, I&rsquo;m <em>very</em>
happy with the result. And the same goes for my partner, who really had absolutely no idea of this until I presented him the
finished buttons on our anniversary. He was and is in awe 😊</p>
<p>However, single colored buttons with rubbed on letters sealed in with UV resin is not my end goal here. After seeing the amazing results one can
achieve with inlaying in EJ&rsquo;s videos, I&rsquo;m really looking forward to trying that out. So the next step will be to cast some inlayed buttons
with the same mold. And I have already printed out the letters on my resin printer 😁</p>
<p><em><strong>Update from 2024-02-14</strong>: The buttons have now been in <strong>very heavy</strong> use by my partner for over a year, and they still look the same as on day 1! No changes on the letters that I rubbed on and sealed with UV resin, and no changes on the buttons themselves either. 👍</em></p>
<div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p>To be more precise, FreeCAD Link Branch version 2022.09.07&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:2">
<p>If one of the buttons slips out of the mold, you can just press it back in. Just make sure it really slots right back in
where it was, same orientation, full depth and everything. I actually had to do this a bunch of times due to the mold making
stretching over several days due to some issues (see next footnote), and having to reassemble the deck in between to keep
the project a secret from my partner. As a consequence, I can now disassemble and reassemble the deck down to the buttons in
around 20min without the guide 😄&#160;<a href="#fnref:2" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:3">
<p>I actually had to do the second pour thrice: The first time I didn&rsquo;t create the channels with toothpicks, thinking I could
punch them out afterwards - I couldn&rsquo;t. That led to the creation of the top brace. I then made the mistake to further secure the
toothpicks with superglue, which seems to have interacted with the curing process and caused the top layer of the silicone pour
to stay soft, smeary and sticky. So I did it a third time, exactly as described above, just relying on the friction fit of the
toothpicks, and this time everything cured as expected and I had usable channels 😅&#160;<a href="#fnref:3" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</div>
]]></content:encoded></item><item><title>TFA Dostmann meets ESPHome</title><link>https://foosel.net/blog/2022-01-03-tfa-dostmann-meets-esphome/</link><pubDate>Mon, 03 Jan 2022 00:00:00 +0000</pubDate><guid>https://foosel.net/blog/2022-01-03-tfa-dostmann-meets-esphome/</guid><description>Integrating a CO2 sensor into my HA setup</description><content:encoded><![CDATA[<p>I attended RC3 from December 27th until December 30th. While it was (once again)
only a virtual edition of the Chaos Communication Congress, at least this time
around I managed to have a similar experience to 36c3, as in, I spent the last two days
mostly hanging out with a bunch of fellow geeks in a fun location (a jitsi conference
that also included a camera pointing at an aquarium full of fish) and nerding out
while tinkering around with electronics.</p>
<p>And thus I finally integrated the CO2 sensor unit I bought a couple weeks ago into
my Home Automation setup, with the help of a Wemos D1 Mini and <a href="https://esphome.io">ESPHome</a>. At first
I went with an ESP12, a voltage regulator and a <a href="https://github.com/schinken/esp8266-co2monitor">different firmware</a>,
but that didn&rsquo;t work out due to the ESP not wanting to behave (my guess is I didn&rsquo;t wire the barebone module
up correctly or the voltage regulator was causing issues) and I also got some weird readings
reported by the firmware (20k ppm CO2 - I know the air in my office can get bad after a couple of hours of
coding, but not THAT bad).</p>
<p>The CO2 sensor is an &ldquo;AIRCO2NTROL MINI&rdquo; from TFA Dostmann, but it is also available under other names
with a very similar case and more or less the same internals, as I learned from the
<a href="https://esphome.io/components/sensor/zyaura.html">ESPHome docs</a>. Where my Dostmann edition seems to differ from the majority is the
pin order of the internal debug port, which turned out to have CLK and DATA swapped
in my case, which caused me quite the headache and a bit of frustration. So just for future reference,
the pin order I found in my device is 5V - Data - CLK - Gnd from left to right with the hose to the left:</p>
<p><img alt="The pinout of the sensor&rsquo;s debug port, 5V - Data - CLK - Gnd" loading="lazy" src="/blog/2022-01-03-tfa-dostmann-meets-esphome/tfa-dostmann-pinout.jpg"></p>
<p>I hooked these up to the Wemos D1 Mini (clone) like this:</p>
<p><img alt="A wiring diagram of how to hookup the Wemos D1 mini to the debug port, 5V to 5V, Gnd to Gnd, Data to D1 and CLK to D2" loading="lazy" src="/blog/2022-01-03-tfa-dostmann-meets-esphome/tfa-dostmann-wemos-d1-wiring.png"></p>
<p>So 5V to 5V, Gnd to Gnd, Data to D1 and CLK to D2.</p>
<p>The ESPHome config I then flashed to the D1 is the following:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-yaml" data-lang="yaml"><span style="display:flex;"><span><span style="color:#f92672">esphome</span>:
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">name</span>: <span style="color:#ae81ff">dostmann-office</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">platform</span>: <span style="color:#ae81ff">ESP8266</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">board</span>: <span style="color:#ae81ff">d1_mini</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">logger</span>:
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">mqtt</span>:
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">broker</span>: !<span style="color:#ae81ff">secret mqtt_iot_broker</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">ota</span>:
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">password</span>: !<span style="color:#ae81ff">secret ota_pass</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">wifi</span>:
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">ssid</span>: !<span style="color:#ae81ff">secret wifi_iot_ssid</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">password</span>: !<span style="color:#ae81ff">secret wifi_iot_pass</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">ap</span>:
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">ssid</span>: <span style="color:#e6db74">&#34;Dostmann Office Fallback&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">password</span>: !<span style="color:#ae81ff">secret fallback_pass</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">power_save_mode</span>: <span style="color:#ae81ff">high</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">captive_portal</span>:
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">sensor</span>:
</span></span><span style="display:flex;"><span>  - <span style="color:#f92672">platform</span>: <span style="color:#ae81ff">zyaura</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">clock_pin</span>: <span style="color:#ae81ff">D2</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">data_pin</span>: <span style="color:#ae81ff">D1</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">co2</span>:
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">name</span>: <span style="color:#e6db74">&#34;Office Dostmann CO2&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">temperature</span>:
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">name</span>: <span style="color:#e6db74">&#34;Office Dostmann Temperature&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  - <span style="color:#f92672">platform</span>: <span style="color:#ae81ff">wifi_signal</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">name</span>: <span style="color:#e6db74">&#34;Office Dostmann WiFi Signal&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">update_interval</span>: <span style="color:#ae81ff">60s</span>
</span></span></code></pre></div><p>(If you are wondering about the <code>!secret</code> stuff, those values are contained in
a <code>secret.yaml</code> file in my esphome folder, and you can read all about that
<a href="https://esphome.io/guides/faq.html#tips-for-using-esphome">in the ESPHome docs here</a>.)</p>
<p>And with that I could now see the sensor in my Home Assistant instance and forward the data
easily to my InfluxDB &amp; Grafana monitoring stack.</p>
<p>To put everything together physically, fully contained, I used <a href="https://www.thingiverse.com/thing:4225732">this alternative backplate</a>
by Stefan Kern.</p>
<p><img alt="The alternative backplate in place, closing up the sensor and containing the Wemos D1 Mini as well" loading="lazy" src="/blog/2022-01-03-tfa-dostmann-meets-esphome/tfa-dostmann-back.jpg"></p>
<p>However, I&rsquo;ve noticed a temperature increase of around 3°C with it and the ESP
in place, and I fear this might be screwing with the CO2 sensor&rsquo;s calibration (as the measurement
is temperature sensitive). I already mitigated this a bit by setting the chip to power save and adding some strategically placed aluminium tape,
but that&rsquo;s only improved things slightly. Due to that I plan to redesign the
backplate to have the ESP outside the sensor case, in its own compartment. I
hope that will solve the &ldquo;running hot&rdquo; issue for good then, but we&rsquo;ll see.</p>
<p><em>Update from January 27th 2022</em> I redesigned the backplate and now have a solution that seems to work better, based on the reported temperature and CO2. <a href="https://www.prusaprinters.org/prints/119968-airco2ntrol-mini-backplate-with-wemos-d1-mini">I&rsquo;ve published it here</a>.</p>
<p>In any case, for now I at least got a reliable indicator of my office&rsquo;s CO2 levels that also now
are trackable long term, and I have also forwarded the current values to my <a href="https://awtrixdocs.blueforcer.de/">AWTRIX mini</a>
via some NodeRED flow that also takes care of color coding. Further possibilities include
flashing the office lights or some audio cues, should just the visual warning turn out
to be insufficient in the long term 😉</p>
<p><img alt="CO2 sensor data graphed over two days" loading="lazy" src="/blog/2022-01-03-tfa-dostmann-meets-esphome/grafana-co2.png"></p>
]]></content:encoded></item><item><title>Hydroponics the Kratky way</title><link>https://foosel.net/blog/2021-09-12-hydroponics-the-kratky-way/</link><pubDate>Sun, 12 Sep 2021 00:00:00 +0000</pubDate><guid>https://foosel.net/blog/2021-09-12-hydroponics-the-kratky-way/</guid><description>How I found myself with way too much Basil on my hands</description><content:encoded><![CDATA[<p>Since my partner loves spicy food, earlier this year I got us a chili growing kit. What was meant as an experiment has since become a full blown pepper growing operation that has taken over my livingroom window sills and half the balcony and already yielded its first fruits. And because whenever I try something new I also tend to do way too much research on it, while getting the plants started the normal way in soil (and then promptly running into the first issues with fungus gnats) I started to look deeper into <a href="https://en.wikipedia.org/wiki/Hydroponics">hydroponics</a>.</p>
<p>I had heard of this approach before: growing plants in an inert grow medium instead of soil and feeding them with controlled nutrient solutions pumped around the roots. It&rsquo;s a fascinating rabbit hole to go down and it always tickled my interest (especially given the automation and sensoric evaluation possibilities), however it also felt way too involved to get started with unless I had some more actual space and some actual need to grow plants, what with all the lights and pumps and pipe systems that I saw associated with it. That is, until I came across the <a href="https://en.wikipedia.org/wiki/Kratky_method">Kratky method</a>.</p>
<p>The Kratky method is a pretty much passive approach to hydroponics. The idea is simple: you take an opaque container for your nutrient solution, cut a bunch of holes in the lid and then place your plants into netpots or similar in those holes so their roots reach into the solution. So far, so similar to the <a href="https://en.wikipedia.org/wiki/Deep_water_culture">Deep Water Culture</a> approach. But instead of now aerating the solution with an aquarium air stone or similar to give your roots the oxygen they need, you instead simply allow the level of your nutrient solution to drop, creating an air gap and leaving parts of the roots hanging in the air. That way the roots can get nutrients but can also breathe (which is important so they don&rsquo;t rot). You&rsquo;ll have to fill up the solution a bit if needed (always leaving an airgap), but apart from that the whole setup is completely self managed. No power needed, no moving parts. And easily set up in something as small as a mason jar.</p>
<p>This was intriguing to me, and I had wanted to try my luck with growing some basil and oregano for pizza and such anyhow, so I decided to give this approach a shot. I ordered a kitchen herb seed kit, some 1l mason jars, some rock wool cubes (as growing substrate) and some hydroponic fertilizer. Then I fired up FreeCAD and designed a small lid with integrated rock wool cube holder (STL <a href="quattro_stagioni_kratky_1l_36mm.v2.stl">here</a>, FreeCAD file <a href="quattro_stagioni_kratky_1l.FCStd">here</a>), printed a bunch of them and then went to work.</p>
<p><img alt="The lid design with rock wool cube holder in FreeCAD" loading="lazy" src="/blog/2021-09-12-hydroponics-the-kratky-way/lid-design.png"></p>
<p>The seeds were planted in the rock wool cubes, watered and then I waited. The first green soon showed up and thus I transferred the cubes into their holders, filled the jars with 1l water plus the recommended fertilizer amount (thus creating a nutrient solution) and then put the lids on. The cubes sat right in the solution and thus were kept watered. To keep light out of the container (to prevent algae growth and also to not have everything heat up so much) I simply wrapped some aluminium foil around the jars. If I&rsquo;m honest this was just meant as a temporary solution until I got around to sewing a little cover out of some light blocking fabric I have on hand, but I still haven&rsquo;t gotten around to do that and the foil works just fine 🤷‍♀️</p>
<p><img alt="The two baby Basil plants at the start of their Krakty journey" loading="lazy" src="/blog/2021-09-12-hydroponics-the-kratky-way/start.jpg"></p>
<p>That was on July 18th and since then I&rsquo;ve been able to witness some astonishing growth, especially on the Basil. Have a look at the progress:</p>
<p><img alt="Progress on July 27th, the two plants are around 5cm high." loading="lazy" src="/blog/2021-09-12-hydroponics-the-kratky-way/progress-07-27.jpg"></p>
<p><img alt="Progress on August 4th, around 12-15cm high." loading="lazy" src="/blog/2021-09-12-hydroponics-the-kratky-way/progress-08-04.jpg"></p>
<p><img alt="Progress on August 14th, around 20-25cm in height." loading="lazy" src="/blog/2021-09-12-hydroponics-the-kratky-way/progress-08-14.jpg"></p>
<p><img alt="Progress on August 27th, more than 30cm high." loading="lazy" src="/blog/2021-09-12-hydroponics-the-kratky-way/progress-08-27.jpg"></p>
<p><img alt="Progress on September 10th, the plants are now around 50cm height each." loading="lazy" src="/blog/2021-09-12-hydroponics-the-kratky-way/progress-09-10.jpg"></p>
<p>As of today, both Basil plants had reached a plant height of around 50cm. The Oregano also looks healthy, but sadly I accidentally got hold of a hanging variant, making everything a bit tricky in this setup 😅</p>
<p>Sadly, I had to emergency-harvest one of the Basil&rsquo;s today. While topping up the nutrient solution the other day I noticed the roots to be way darker than they should be. They didn&rsquo;t look particularly healthy. Some of the leaves also started to look a tad unhappy. I came to the conclusion that I might have caught myself some root rot on this plant. Doing some research I learned that with the Kratky method, if you grow for longer than 4-6 weeks you really should occasionally replace the nutrient solution completely and clean the container to keep bacteria from taking root in your roots (pun not intended). I guess this is what happened here. I tried to save the plant with a 2:1 water and 3% hydrogen peroxide bath yesterday, but either it was already too late or that was too much stress. This morning the leaves were hanging and the whole plant looked quite sorry so I decided it was time to harvest and now I have a jar of fresh pesto verde.</p>
<p><img alt="One small jar of freshly made pesto" loading="lazy" src="/blog/2021-09-12-hydroponics-the-kratky-way/pesto.jpg"></p>
<p>Further reading revealed that it&rsquo;s apparently an option to add a teeny tiny amount of 3% hydrogen peroxide to the nutrient solution itself to help keep any unwelcome guests away (and also help with aeration), so I&rsquo;ve now added 0.5ml to my freshly topped off jar of the other Basil and hope that won&rsquo;t do harm but rather good. Wish me luck 😉</p>
<p>All in all, I call this whole first dabbling with hydroponics a great success. The Kratky method allowed me to get up and running quickly without huge investments and space requirements, and the results were amazing. I&rsquo;ve also now planted some peppermint seeds and they are already sprouting, so my hopes are high for some amazing fresh teas later this fall! If you&rsquo;ve always wanted to experiment with hydroponics but it always felt way too involved, maybe take a look at the Kratky method 😊</p>
]]></content:encoded></item><item><title>Homelab uplink monitoring</title><link>https://foosel.net/blog/2021-03-28-homelab-uplink-monitoring/</link><pubDate>Sun, 28 Mar 2021 00:00:00 +0000</pubDate><guid>https://foosel.net/blog/2021-03-28-homelab-uplink-monitoring/</guid><description>Keeping an eye on my ISP&amp;#39;s performance</description><content:encoded><![CDATA[<p>For a bit more than two years now I&rsquo;ve been closely monitoring my network uplink. In the past I had a ton of issues with up- or download speeds not being what I paid for, packet loss issues and outright full blown outages. In order to put myself into a better position when reaching out to the ISP&rsquo;s support hotline I figured it would be good to be able to proof not only the existence of these issues but to also be able to determine the exact times they happened at and also to verify and show that in fact it was only external connections that were suffering and it was not an issue with my own internal network. Given that I don&rsquo;t trust the cable modem/router they force on me to be my edge router and instead have my own Unifi gear set up behind it (considering anything not exclusively under my control to be part of the hostile public internet) this otherwise will usually lead to endless attempts to blame my LAN when in fact the issue lies outside of my reach.</p>
<p>I already had an <a href="https://www.influxdata.com/">InfluxDB</a> and <a href="https://grafana.com/">Grafana</a> setup running anyhow for my <a href="https://home-assistant.io/">Home Assistant instance</a> to dump values from my home climate sensors into, so it was a logical next step to simply add some additional sensors to the mix.</p>
<h2 id="throughput">Throughput</h2>
<p>I currently run a speed test of the network throughput every 20min and log the results via MQTT into InfluxDB. I had to find out that neither the speed test integration in Home Assistant nor the official speedtest-cli tool were performing reliably enough for this &ndash; I was constantly getting dips in measured throughput and thus alerts, even when everything was completely fine with my uplink.</p>
<p>I solved this by turning to <a href="https://github.com/nelsonjchen/speedtest-rs">speedtest-rs</a> and a small shell script that parses the output and pushes it into MQTT to Home Assistant, which then processes it further for some visualization right on my dashboard but also forwards it further into InfluxDB. You can find the <code>Dockerfile</code> and the script plus some further info <a href="https://gist.github.com/foosel/ef98a5774d1a495ab3781eba8a157fee">in this gist</a>.</p>
<p>In Grafana I then use this data to provide me with some single stat panels for the current downstream, upstream and ping values as well as the averages over the selected time range:</p>
<p><img alt="Some single stat panels show current and average down- and upstream speed and measured ping" loading="lazy" src="/blog/2021-03-28-homelab-uplink-monitoring/currentspeed.png"></p>
<p>Additionally, I also plot the down- and upstream speed in a timeline, together with the current bandwidth consumption as extracted by Home Assistant from my ISP&rsquo;s cable modem/router (thanks to the <a href="https://www.home-assistant.io/integrations/fritzbox_netmonitor/">Fritzbox NetMonitor integration</a>). Together, this gives me a good picture of whether there is actually an issue when I see a dip in the measured values, or if it&rsquo;s just too high bandwidth utilization:</p>
<p><img alt="A graph showing measured up- and downstream speed vs consumed up- and downstream bandwidth utilization" loading="lazy" src="/blog/2021-03-28-homelab-uplink-monitoring/bandwidth.png"></p>
<p>You can see in these screenshots that I recently upgraded my plan with my ISP &ndash; from 200/20 to 500/50 MBit. The problem: The speedtest run by my monitoring setup doesn&rsquo;t hit the 500 mark, whereas running a manual test on speedtest.net works just fine. Looking at the <code>speedtest-rs</code> README it becomes apparent that this is a known issue with the legacy (open) Speedtest.net API:</p>
<blockquote>
<p>This tool currently only supports <a href="http://www.ookla.com/support/a84541858">HTTP Legacy Fallback</a> for testing.</p>
<p>High bandwidth connections higher than ~200Mbps may return incorrect results!</p>
<p>The testing operations are different from socket versions of tools connecting to speedtest.net infrastructure. In the many FOSS Go versions, tests are done to find an amount of data that can run for a default of 3 seconds over some TCP connection. In particular, <code>speedtest-cli</code> and <code>speedtest-rs</code> tests with what Ookla calls the <a href="http://www.ookla.com/support/a84541858">&ldquo;HTTP Legacy Fallback&rdquo;</a> for hosts that cannot establish a direct TCP connection.</p>
</blockquote>
<p>I fear I might have to look into reimplementing the current speedtest-to-mqtt setup with another container utilizing the official (and sadly proprietary) Speedtest CLI tool to mitigate this issue. Thankfully, it should be quite easy to build a drop-in replacement thanks to the modularization in effect.</p>
<p><em>Update from March 30th 2021</em> I&rsquo;ve now done that and <a href="https://gist.github.com/foosel/70ecbeade55cc852dbc0a4f7c4040adc">here&rsquo;s an updated gist</a> that works identically to the <code>speedtest-rs</code> approach, but instead utilizes <a href="https://www.speedtest.net/apps/cli">Ookla&rsquo;s official command line tool</a>. The results are stable numbers that reflect the expected bandwidth and also match the web based test results.</p>
<p><em>Update from March 31st, 2021</em> I wasn&rsquo;t too happy with running a proprietary tool for my speed testing, went looking for an OSS alternative, came across <a href="https://librespeed.org/">librespeed</a> and therefore have now <a href="https://gist.github.com/foosel/f7d9a08c0445454ab90d6c4974a9e316">replicated the setup again using that</a>. You might want to experiment a bit to find a server close to you and define that via <code>--server &lt;id&gt;</code>, the auto discovery appears to be a bit wonky. Or just use your own server list via <code>--server-json</code> or <code>--local-json</code>.</p>
<h2 id="latency-and-packet-loss">Latency and packet loss</h2>
<p>In addition to the available up- and downstream speeds, I constantly monitor latency and packet loss to a selected number of hosts both external and internal to my network as well. For this I ping some public DNS servers (Google, Cloudflare and Quadnine) and some of my own vservers for the remote side, and the ISP&rsquo;s Fritzbox, my managed network gear and internal servers for the LAN side. I used to do this via <a href="https://oss.oetiker.ch/smokeping/">Smokeping</a>, but when I set up my InfluxDB/Grafana stack I wanted to find a solution to have everything together in one place.</p>
<p>Thankfully I almost immediately found <a href="https://hveem.no/visualizing-latency-variance-with-grafana">this post by Tor Hveem</a> who solved this with a little custom Go tool to run <code>fping</code> against a number of configurable hosts and push the results right into InfluxDB. This was exactly what I wanted and thus I replicated the outlined setup, albeit with a slightly different color scheme.</p>
<p>I use a <a href="https://github.com/nickvanw/infping">modified version of Tor&rsquo;s <code>infping</code> tool maintained by Nick Van Wiggeren</a> and run that in a Docker container on my NAS. You can find everything needed to run this on your own <a href="https://gist.github.com/foosel/46804306d510d79f14117f95ed64b877">in this gist</a>.</p>
<p>As a result I get ping output for all hosts every 60 sec with times and packet loss information pushed right into InfluxDB. This is easily queried by Grafana and looks quite nice when visualized:</p>
<p><img alt="A graph showing min, avg and max latency and packet loss data for 8.8.8.8" loading="lazy" src="/blog/2021-03-28-homelab-uplink-monitoring/smokeping.png"></p>
<p>And on my network dashboard, I plot only the <code>avg</code> values across all hosts and a mean <code>loss</code> value into one single graph each for external and internal hosts:</p>
<p><img alt="A graph showing avg latency and packet loss data for all remote hosts" loading="lazy" src="/blog/2021-03-28-homelab-uplink-monitoring/latency.png"></p>
<p>This allows me a good overview of the current state of uplink and internal network at one glance.</p>
<h2 id="alerts">Alerts</h2>
<p>Since just graphs won&rsquo;t give me an immediate heads-up when something goes wrong, I have a bunch of alerts set up in Grafana:</p>
<ul>
<li>Measured download speed falls beneath 250MBit for more than one hour</li>
<li>Measured upload speed falls beneath 35MBit for more than one hour</li>
<li>Mean packet loss across all external hosts rises above 25% for more than ten minutes</li>
</ul>
<p>All of those trigger a notification to a private Discord server (via Grafana&rsquo;s own notification mechanism). In theory this notification should even include a screenshot of the panel for which the alert was triggered for, but I&rsquo;m having some problems with that still that I need to investigate.</p>
<p><img alt="An example alert and alert clearance notification in Discord" loading="lazy" src="/blog/2021-03-28-homelab-uplink-monitoring/discord.png"></p>
<p>This notification channel has an obvious problem: When the uplink goes out completely, I won&rsquo;t get the notification if my phone is in my LAN. I really need to add a local alert as well at some point 😅</p>
<p>Still, it usually will give me a heads-up in time for me to reach out to my ISP on short notice and request they start troubleshooting.</p>
<h2 id="conclusion">Conclusion</h2>
<p>This monitoring setup has proven valuable in debugging network performance issues and also getting an early heads-up about current ISP issues. I have successfully used screenshots for proving ongoing issues to my ISP, and also sped up the one or other troubleshooting session when there was in fact an issue with my LAN. In my book, that makes it absolutely worth the time it took me to set this up and maintain it. And: it kinda looks cool 😎</p>
<p>If you want to give this a go yourself, this might be of interest to you:</p>
<ul>
<li><a href="https://gist.github.com/foosel/f7d9a08c0445454ab90d6c4974a9e316">Dockerfile, compose and instructions for speedtest container</a>
<ul>
<li><a href="https://gist.github.com/foosel/70ecbeade55cc852dbc0a4f7c4040adc">Ookla speedtest based version</a></li>
<li><a href="https://gist.github.com/foosel/ef98a5774d1a495ab3781eba8a157fee">speedtest-rs based version</a></li>
</ul>
</li>
<li><a href="https://gist.github.com/foosel/46804306d510d79f14117f95ed64b877">Dockerfile, compose and instructions for infping container</a></li>
<li><a href="https://gist.github.com/foosel/ec0b6355d1d0c3ab65ee4df79d795a73">Panel JSON for the mentioned visualizations</a></li>
</ul>
]]></content:encoded></item></channel></rss>