<?xml version="1.0" encoding="utf-8" standalone="yes"?><?xml-stylesheet type="text/xsl" href="/index.xsl"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>./techtipsy</title><link>https://ounapuu.ee/tags/sbc/</link><description>Recent content on ./techtipsy, a blog written by Herman Õunapuu.</description><generator>Hugo -- gohugo.io</generator><language>en-GB</language><managingEditor>ihavesomethoughtsonyourblog@ounapuu.ee (Herman Õunapuu)</managingEditor><webMaster>ihavesomethoughtsonyourblog@ounapuu.ee (Herman Õunapuu)</webMaster><lastBuildDate>Sat, 04 Apr 2026 06:00:00 +0300</lastBuildDate><atom:link href="https://ounapuu.ee/tags/sbc/index.xml" rel="self" type="application/rss+xml"/><item><title>The most unstable computer in my fleet is now the most critical one</title><link>https://ounapuu.ee/posts/2026/04/04/lattepanda/</link><pubDate>Sat, 04 Apr 2026 06:00:00 +0300</pubDate><author>ihavesomethoughtsonyourblog@ounapuu.ee (Herman Õunapuu)</author><guid>https://ounapuu.ee/posts/2026/04/04/lattepanda/</guid><description>No way that this can go wrong. Not at all.</description><content:encoded><![CDATA[<img src="https://ounapuu.ee/posts/2026/04/04/lattepanda/media/cover_hu_73aa3329770b1e79.jpg" width="1200" height="630" alt="The most unstable computer in my fleet is now the most critical one" /><p>Remember <a href="/posts/2026/01/16/worst-media-server/">that failed experiment</a> where I ran Jellyfin off of a LattePanda V1?</p>
<p>Do you recall all the parts where I said what this single board computer <em><strong>cannot</strong></em> do?</p>
<p>Yeah, I remember.</p>
<p>Then I took it and put the two of the most critical services running on it: the blog you&rsquo;re reading right now, and my
Wireguard setup.</p>
<p>Trust me, it makes more sense with some context. The board is incapable of doing anything else other than serving
content from the eMMC module, and it has a functioning network port. It doesn&rsquo;t seem to crash in these scenarios.</p>
<p>When I try anything else with this board, especially things that include USB connectivity, things break. This makes the
board ideal for a light workload that needs to be up 24/7.</p>
<p>The biggest threat to my uptime is not internet connectivity or loss of power (although that did happen for the first
time in a year recently), it&rsquo;s me getting new ideas to try out on my setup, which results in downtime. This board is so
unreliable for trying those ideas out that it removes any and all temptation to <em>do</em> that, resulting in a computer that
has the highest chance of actually being up and running for a very long time.</p>
<p>To play things safe, I used an IKEA SJÖSS 20W USB-C power adapter that I got for 3 EUR, with a cheap USB-C to USB-A
adapter thrown into the mix. It looks janky, but the adapter outputs 5V 3A, which makes it the beefiest power adapter
that I have in my fleet for plain USB-A powered devices.</p>
<p>I then hit the board with some <code>stress</code> commands, including hitting the 2 GB of memory. It ran really well for days, no
issues at all.</p>









<figure class="center">
  <a href="/posts/2026/04/04/lattepanda/media/stressing-out.jpg">
    <img src="/posts/2026/04/04/lattepanda/media/stressing-out_hu_b4ea99889312878a.webp"
     width="1000"
     height="751"
     loading="lazy"
     decoding="async"
     alt="Less espresso, more Lattepanda, more stresso.">

  </a>
  <figcaption class="center">Less espresso, more Lattepanda, more stresso.</figcaption>
</figure>

<p>I also improved the cooling situation. I am now a proud owner of an assortment of M2, M2.5 and M3 screws and bits, and
equipped with a Makita cordless drill, I made some mounting holes into an old aluminium server heat sink. The drilling
was a complete hack job, everything was misaligned, but it was good enough. Certainly better than holding the board and
heat sink together with thin velcro strips. The cooling performance is completely adequate, the board hits a maximum of
65°C with the heat sink facing down. This is well below the point at which the board starts to throttle its CPU.</p>









<figure class="center">
  <a href="/posts/2026/04/04/lattepanda/media/side-view.jpg">
    <img src="/posts/2026/04/04/lattepanda/media/side-view_hu_62184c91343891eb.webp"
     width="1000"
     height="482"
     loading="lazy"
     decoding="async"
     alt="Two out of three chips have adequate cooling. Whoops.">

  </a>
  <figcaption class="center">Two out of three chips have adequate cooling. Whoops.</figcaption>
</figure>

<p>The theoretical maximum Wireguard throughput on this board is about 340 Mbps, measured using the
fantastic <a href="https://github.com/cyyself/wg-bench">wg-bench</a> solution.</p>
<p>Remember the part about the USB ports being flaky? Yeah. That didn&rsquo;t stop me from getting a USB Gigabit Ethernet
adapter to remove one of the main limitations of the LattePanda V1. Based off of vibe-recommendations by Claude, I got a
TP-Link UE300 for its alleged low power usage and its availability at a local computer store in Estonia. It seems to
work well enough, you can push gigabit speeds through it measured by <code>iperf3</code>, and the actual Wireguard performance that
I could push through it with an actual workload was at about 420 Mbit/s, higher than indicated by the benchmark, and
plenty fast for most workloads, especially in external networks that are usually slower than that.</p>









<figure class="center">
  <a href="/posts/2026/04/04/lattepanda/media/speed.png">
    <img src="/posts/2026/04/04/lattepanda/media/speed_hu_553c4ae4b61a3ad.webp"
     width="1000"
     height="439"
     loading="lazy"
     decoding="async"
     alt="iperf3 test results on LattePanda V1, with occasional CPU and memory stress tests thrown in.">

  </a>
  <figcaption class="center">iperf3 test results on LattePanda V1, with occasional CPU and memory stress tests thrown in.</figcaption>
</figure>










<figure class="center">
  <a href="/posts/2026/04/04/lattepanda/media/wireguard.png">
    <img src="/posts/2026/04/04/lattepanda/media/wireguard_hu_b67d71a1d5528ffb.webp"
     width="1000"
     height="439"
     loading="lazy"
     decoding="async"
     alt="Copying data from another Wireguard peer through the LattePanda V1.">

  </a>
  <figcaption class="center">Copying data from another Wireguard peer through the LattePanda V1.</figcaption>
</figure>










<figure class="center">
  <a href="/posts/2026/04/04/lattepanda/media/cables.jpg">
    <img src="/posts/2026/04/04/lattepanda/media/cables_hu_d0b5c96d42223007.webp"
     width="1000"
     height="751"
     loading="lazy"
     decoding="async"
     alt="Cable management is not my strength.">

  </a>
  <figcaption class="center">Cable management is not my strength.</figcaption>
</figure>

<p>A few hours after making that
change, <a href="https://news.ycombinator.com/item?id=47597159">a HN post put some mild load on the LattePanda V1,</a> what good
timing.</p>
<p>As of publishing this post, the blog has been running mostly off of the LattePanda V1 for over a month now, with that
gap in it being caused by contemplating getting that USB Ethernet adapter and temporarily running the blog and Wireguard
off of another mini PC during that time.</p>
<p>Did you notice?</p>
<h2 id="2026-july-update">
  <a class="heading-anchor" href="#2026-july-update">2026 July update<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>I was running out of room and network ports on my router, so I decided to stop this experiment. During all this time,
there were no issues with the LattePanda V1, except when I accidentally bumped into its power cable and made it go
offline. Oops.</p>
]]></content:encoded></item><item><title>I built the worst Jellyfin media server</title><link>https://ounapuu.ee/posts/2026/01/16/worst-media-server/</link><pubDate>Fri, 16 Jan 2026 06:00:00 +0200</pubDate><author>ihavesomethoughtsonyourblog@ounapuu.ee (Herman Õunapuu)</author><guid>https://ounapuu.ee/posts/2026/01/16/worst-media-server/</guid><description>This experiment is brought to you by absurd memory prices.</description><content:encoded><![CDATA[<img src="https://ounapuu.ee/posts/2026/01/16/worst-media-server/media/cover_hu_dd22e2bc1424d67c.jpg" width="1200" height="630" alt="I built the worst Jellyfin media server" /><p>LattePanda V1. <a href="/posts/2023/02/28/lattepanda-v1/">It&rsquo;s been a while, huh?</a></p>
<p>I had it as a backup server <a href="/posts/2023/06/10/how-i-blew-up-my-backup-server/">(which I blew up)</a>.</p>
<p>Then it got promoted to&hellip; <a href="/posts/2024/12/11/wireguard-backup-fleet/">a backup server.</a> But
then <a href="/posts/2024/12/11/wireguard-backup-fleet/media/lattepanda-psu-failure.png">its PSU blew up.</a></p>
<p>Then it was waiting for some cool ideas at <a href="https://kaurpalang.com/">a potato enthusiast.</a></p>
<p>Now it&rsquo;s back in my hands.</p>
<p><a href="/posts/2025/11/18/lattepanda-iota/">Unlike its modern counterpart,</a> the LattePanda V1 is a flawed single board
computer.</p>
<p>It&rsquo;s slow.</p>
<p>It&rsquo;s unstable if you connect power hungry USB devices to it.</p>
<p>It needs some cooling, but I&rsquo;m too cheap to buy a properly designed heat sink for it.</p>
<p>It has display quirks.</p>
<p>It only has a slow 100 Mbps Ethernet link.</p>
<p>It only seems to work reliably on one side. Not even joking, the &ldquo;heat sink down&rdquo; configuration is the only one that
works for me.</p>
<p><a href="https://libreelec.tv/">LibreELEC</a> failed to play back any videos on it properly. The videos would play for 10 seconds,
and then it would hang, no matter the encoding or hardware acceleration settings.</p>
<p>With hardware prices being wonky again, I decided to give this board a last chance of being useful. If new hardware is
absurdly expensive, then it makes perfect sense to use what you have, no matter how slow or crummy it might be. Reduce,
reuse, and only <em>then</em> recycle.</p>
<p>That&rsquo;s when I decided to run a Jellyfin server off of it. Transcoding is out of the question, but serving media files
over the network should still be quick enough, right?</p>
<p>For this experiment, I
used <a href="/posts/2025/10/06/datablocks-white-label-drives/">one of the 18 TB hard drives that I&rsquo;ve covered earlier.</a>
Just the single one, no redundancy here. This one drive is probably about 10x the cost of the LattePanda V1 itself,
making it a perfectly reasonable choice.</p>
<p>For ease of troubleshooting, debugging and guaranteed eventual reinstallation, I put Fedora Server on an 128 GB USB 3.0
flash drive by Samsung. <a href="/posts/2024/12/02/linux-on-usb/">Risky move, I know,</a> but as you might have noticed, this whole
build is everything <em>but</em> reasonable. That left the eMMC storage as the perfect candidate for storing cache and service
related files.</p>
<p>Cooling is solved by a random server heat sink slapped on the bottom of the LattePanda, with a few critical
components like the CPU making contact with thick and soft thermal pads. The whole thing is fastened using velcro strips
that I cut to a thin size in the middle so that I can route it between the components on the PCB and within the heat
sink fins. The edges of the heat sink are covered with some painters&rsquo; tape that I had around to avoid shorting anything
out on the board, because those parts on the board contain all sorts of metal bits and pins that have power going
through them. I&rsquo;m actually quite happy with that mount!</p>









<figure class="center">
  <a href="/posts/2026/01/16/worst-media-server/media/lattepanda-temps.png">
    <img src="/posts/2026/01/16/worst-media-server/media/lattepanda-temps_hu_84c5210842d31066.webp"
     width="1000"
     height="683"
     loading="lazy"
     decoding="async"
     alt="All things considered, the janky cooling setup is holding up very well. The 100 degree peaks are sensor/measurement
errors.">

  </a>
  <figcaption class="center">All things considered, the janky cooling setup is holding up very well. The 100 degree peaks are sensor/measurement
errors.</figcaption>
</figure>

<p>I&rsquo;ve been experimenting with Podman again after Docker kept doing weird things with the v29 release, and I&rsquo;ve been happy
with the results, so that&rsquo;s what I used on the LattePanda V1 as well. I slapped Jellyfin on it, threw in some test files
and gave it a go.</p>
<p>Navigating the UI feels a bit slow at times, but it&rsquo;s not really noticeable on an LG smart TV with a really laggy user
interface.</p>
<p>Actual video playback that requires no transcoding works quite well, at least for smaller media sizes.</p>
<p>Technically, you can do transcoding on this and even utilize the tiny little integrated GPU in it, but the results are
not usable. With smaller files it might be usable, but in one test I saw 7-8 FPS transcoding speeds and the server
struggling to keep up, with CPU usage locked at 100%.</p>
<p>If we ignore all the downsides, then the LattePanda V1 can actually be a usable media server. Serving files off of a big
drive does not require a lot of resources, and for that the LattePanda V1 is a solid choice. It also uses only a few
watts of power on its own, so you can keep it on 24/7 guilt-free. In this build, the hard drive itself is actually the
most power hungry component by a long shot (about 2/3 of the total power budget).</p>
<p>The 2 GB of memory is <em>juuuuuuuust</em> enough for this setup.</p>









<figure class="center">
  <a href="/posts/2026/01/16/worst-media-server/media/lattepanda-memory-usage.png">
    <img src="/posts/2026/01/16/worst-media-server/media/lattepanda-memory-usage_hu_ad0b4de22af0ece1.webp"
     width="1000"
     height="683"
     loading="lazy"
     decoding="async"
     alt="Totally usable.">

  </a>
  <figcaption class="center">Totally usable.</figcaption>
</figure>

<p>As of writing this post, it has been running for about a week, and it&rsquo;s been fine. I intend to keep it running in a
drawer for as long as possible just to see what will die first.</p>
<p>Will it be the eMMC storage?</p>
<p>The USB flash drive holding the operating system?</p>
<p>The expensive hard drive?</p>
<p>The power supply?</p>
<p>The thin velcro strips holding the cooling together?</p>
<p>My patience?</p>
<p>Don&rsquo;t worry, I have backups. <em>Well</em>, backups of the important bits. I&rsquo;m ready to lose
data <a href="/posts/2026/01/14/raid0/">again.</a></p>
<h2 id="2026-01-22-update">
  <a class="heading-anchor" href="#2026-01-22-update">2026-01-22 update<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>Okay, it was <em>too</em> bad of an idea.</p>
<p>The LattePanda V1 would occasionally just&hellip; stop.</p>









<figure class="center">
  <a href="/posts/2026/01/16/worst-media-server/media/lattepanda-is-kill.png">
    <img src="/posts/2026/01/16/worst-media-server/media/lattepanda-is-kill_hu_26193b745dd0bf59.webp"
     width="1000"
     height="507"
     loading="lazy"
     decoding="async"
     alt="Oops, it died.">

  </a>
  <figcaption class="center">Oops, it died.</figcaption>
</figure>

<p>From what I gathered by accident, it&rsquo;s likely that the USB port containing the operating system would flake out and
result in the system not being able to run any tools that are not in memory. I tried to move the installation to the
eMMC drive, but after failing multiple times due to the display not working, or the system deciding to shut down
randomly, I gave up on it. For now.</p>
<p>Guess I&rsquo;ll have to use it in a solar-powered website project. ¯\_(ツ)_/¯</p>
]]></content:encoded></item><item><title>LattePanda IOTA review: how does it perform as a home server?</title><link>https://ounapuu.ee/posts/2025/11/18/lattepanda-iota/</link><pubDate>Tue, 18 Nov 2025 06:00:00 +0200</pubDate><author>ihavesomethoughtsonyourblog@ounapuu.ee (Herman Õunapuu)</author><guid>https://ounapuu.ee/posts/2025/11/18/lattepanda-iota/</guid><description>I received a review sample of the LattePanda IOTA, here's what I did to it.</description><content:encoded><![CDATA[<img src="https://ounapuu.ee/posts/2025/11/18/lattepanda-iota/media/cover_hu_ee50a0b402f18b9b.jpg" width="1200" height="630" alt="LattePanda IOTA review: how does it perform as a home server?" /><p><em><strong>Disclosure:</strong></em> the review sample was provided by <a href="https://www.dfrobot.com/">DFRobot, the makers of LattePanda.</a> I am
allowed to keep the review sample indefinitely, no money exchanged hands, and as always, this post covers my own
thoughts and views on the product.<sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup></p>
<p><a href="/posts/2023/02/28/lattepanda-v1/">In 2023, I happened to find a LattePanda V1 for sale at a good price.</a> Given the
then-poor availability of affordable Raspberry Pi units, I got one for testing and finding potential use cases for it in
my setup. However, it was just a little bit too weak for any practical uses in 2023, with its CPU and USB connectivity
being just slow enough to be of less use, and the networking being capped at 100 Mbit/s.</p>
<p>In 2025, we have the spiritual successor to it: <a href="https://www.lattepanda.com/lattepanda-iota">the LattePanda IOTA.</a>
It keeps the same form factor, but the connectivity and raw power have all received a significant jump, with the CPU
performance rivalling my current home server, <a href="/posts/2024/10/16/third-times-the-charm/">the trusty ThinkPad T430.</a></p>
<p>The marketing materials list all sorts of sensible use cases for it. I&rsquo;m sure that it works fine for those, but I&rsquo;m only
interested in one thing: how close does this board get to
being <a href="/posts/2025/03/07/perfect-home-server/">the perfect home server?</a></p>
<blockquote>
<p>The perfect home server uses very little power, offers plenty of affordable storage and provides a lot of performance
when it’s actually being relied upon.</p>
</blockquote>
<blockquote>
<p>In my case, low power means less than 5 W while idling, 10+ TB of redundant storage for data resilience and integrity
concerns, and performance means about 4 modern CPU cores’ worth (low-to-midrange desktop CPU performance).</p>
</blockquote>
<h2 id="the-model-and-accessories">
  <a class="heading-anchor" href="#the-model-and-accessories">The model and accessories<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>The model I&rsquo;m reviewing is the 8GB RAM/64GB eMMC one, with a Windows 11 installation on it (not activated).</p>









<figure class="center">
  <a href="/posts/2025/11/18/lattepanda-iota/media/lattepanda-0.jpg">
    <img src="/posts/2025/11/18/lattepanda-iota/media/lattepanda-0_hu_c45484277466acf6.webp"
     width="1000"
     height="774"
     loading="lazy"
     decoding="async"
     alt="The LattePanda IOTA.">

  </a>
  <figcaption class="center">The LattePanda IOTA.</figcaption>
</figure>










<figure class="center">
  <a href="/posts/2025/11/18/lattepanda-iota/media/lattepanda-1.jpg">
    <img src="/posts/2025/11/18/lattepanda-iota/media/lattepanda-1_hu_d3a2ee51a8a3f4c3.webp"
     width="1000"
     height="686"
     loading="lazy"
     decoding="async"
     alt="My wife said that the logo for the LattePanda is cute. I agree.">

  </a>
  <figcaption class="center">My wife said that the logo for the LattePanda is cute. I agree.</figcaption>
</figure>










<figure class="center">
  <a href="/posts/2025/11/18/lattepanda-iota/media/lattepanda-2.jpg">
    <img src="/posts/2025/11/18/lattepanda-iota/media/lattepanda-2_hu_cae36972b32803a8.webp"
     width="1000"
     height="556"
     loading="lazy"
     decoding="async"
     alt="Side view, including the PCIe x1 connector.">

  </a>
  <figcaption class="center">Side view, including the PCIe x1 connector.</figcaption>
</figure>










<figure class="center">
  <a href="/posts/2025/11/18/lattepanda-iota/media/lattepanda-3.jpg">
    <img src="/posts/2025/11/18/lattepanda-iota/media/lattepanda-3_hu_4b383f3738800b2.webp"
     width="1000"
     height="540"
     loading="lazy"
     decoding="async"
     alt="Side view, with GPIO connections prominent.">

  </a>
  <figcaption class="center">Side view, with GPIO connections prominent.</figcaption>
</figure>










<figure class="center">
  <a href="/posts/2025/11/18/lattepanda-iota/media/lattepanda-4.jpg">
    <img src="/posts/2025/11/18/lattepanda-iota/media/lattepanda-4_hu_94feb7c0302ce393.webp"
     width="1000"
     height="626"
     loading="lazy"
     decoding="async"
     alt="Side view, including USB-C PD-compatible port, microSD card reader, a port forgotten by all smartphone makers, and
gigabit Ethernet.">

  </a>
  <figcaption class="center">Side view, including USB-C PD-compatible port, microSD card reader, a port forgotten by all smartphone makers, and
gigabit Ethernet.</figcaption>
</figure>










<figure class="center">
  <a href="/posts/2025/11/18/lattepanda-iota/media/lattepanda-5.jpg">
    <img src="/posts/2025/11/18/lattepanda-iota/media/lattepanda-5_hu_449bf0ed42b37f87.webp"
     width="1000"
     height="661"
     loading="lazy"
     decoding="async"
     alt="Side view, including three USB 3 10 Gbps ports, and a full-sized HDMI port.">

  </a>
  <figcaption class="center">Side view, including three USB 3 10 Gbps ports, and a full-sized HDMI port.</figcaption>
</figure>

<p>Along with the review unit itself, I got sent the following accessories:</p>
<ul>
<li><a href="https://www.dfrobot.com/product-2987.html">active cooler</a></li>
<li><a href="https://www.dfrobot.com/product-2985.html">M.2 M-key expansion board</a></li>
<li><a href="https://www.dfrobot.com/product-2984.html">51W PoE expansion board</a></li>
<li><a href="https://www.dfrobot.com/product-2982.html">M.2 4G LTE expansion board</a></li>
<li><a href="https://www.dfrobot.com/product-2983.html">UPS expansion board</a></li>
</ul>
<p>The board was tested with a Lenovo 65W USB-C power adapter, because that&rsquo;s what I had available. Given the specs of the
board and the accessories, that should be plenty. As far as I know, USB power delivery seems to work fine and it&rsquo;s not
just a weird USB-C connector that requires specific voltages to work.</p>
<p>The M.2 NVMe SSD used in this review is a 512 GB Samsung PM9A1. I got that one from another PC that really didn&rsquo;t need a
boot drive that large.</p>
<p>Most of the testing was done with a fresh Fedora Server 43 installation, kernel version 6.17.7.</p>
<h2 id="the-hardware">
  <a class="heading-anchor" href="#the-hardware">The hardware<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>I suggest looking at <a href="https://www.lattepanda.com/lattepanda-iota#spec">the spec sheet</a> if you&rsquo;re interested in all the
fine details and available configurations.</p>
<p>In short:</p>
<ul>
<li>CPU: Intel N150, 4 cores, 4 threads, up to 3.6 GHz</li>
<li>RAM: 8/16 GB (depending on model)</li>
<li>Onboard storage: 64/128GB eMMC (depending on model)</li>
<li>Networking: gigabit Ethernet port</li>
<li>Real-time clock: <em><strong>yes!</strong></em></li>
</ul>
<p>The overall connectivity has been improved with the new version of this board compared to the old board. The USB ports
are all fast 10 Gbit/s ones, and we have actual PCIe connectivity to play with, although the available bandwidth is
quite limited with a PCIe 3.0 x1 lane available on the port that both the M.2 M-key and PoE adapter connect to.</p>
<p>What caught my eye was the CPU performance I&rsquo;ve been proudly
running <a href="/posts/2024/10/16/third-times-the-charm/">an old ThinkPad T430</a> as a server for a while now, with some failed
attempts to find a more <a href="/posts/2023/10/09/zimaboard/">low-power</a>
and <a href="/posts/2025/06/06/thinkcentre-m900-tiny/">efficient</a>
solution.</p>
<p>The Intel N150 is now offering similar levels of performance, but in a much smaller power envelope.</p>
<p>When it comes to more specialized functionalities, such as GPIO and the RP2040 microcontroller, I don&rsquo;t currently have a
solid use case for them, so they won&rsquo;t be covered in this review. I might fancy giving them a go in the future though,
it would be nice to get some environmental sensors on it to monitor the temperature and humidity of the server room
(which is a closet).</p>
<p>Since I also don&rsquo;t have an 4G LTE modem available, I did not test the associated adapter.</p>
<h2 id="m2-m-key-adapter">
  <a class="heading-anchor" href="#m2-m-key-adapter">M.2 M-key adapter<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>The way you can add expansion boards to the LattePanda IOTA is quite similar to how Raspberry Pi 5 and other similar
single board computers do it: you simply run a flexible cable to an adapter board, and bam, you have extra
connectivity!</p>
<p>With the M.2 M-key adapter kit, you get the adapter itself, some mounting screws and brass stand-offs, and a tiny little
flexible cable for the PCIe signal.</p>









<figure class="center">
  <a href="/posts/2025/11/18/lattepanda-iota/media/m2-adapter-0.jpg">
    <img src="/posts/2025/11/18/lattepanda-iota/media/m2-adapter-0_hu_db0b0dd1c31ad3b0.webp"
     width="1000"
     height="632"
     loading="lazy"
     decoding="async"
     alt="Packaging of the M.2 M-key adapter.">

  </a>
  <figcaption class="center">Packaging of the M.2 M-key adapter.</figcaption>
</figure>










<figure class="center">
  <a href="/posts/2025/11/18/lattepanda-iota/media/m2-adapter-1.jpg">
    <img src="/posts/2025/11/18/lattepanda-iota/media/m2-adapter-1_hu_44b0dab8db46a0b8.webp"
     width="1000"
     height="556"
     loading="lazy"
     decoding="async"
     alt="The adapter itself.">

  </a>
  <figcaption class="center">The adapter itself.</figcaption>
</figure>










<figure class="center">
  <a href="/posts/2025/11/18/lattepanda-iota/media/m2-adapter-2.jpg">
    <img src="/posts/2025/11/18/lattepanda-iota/media/m2-adapter-2_hu_4a68666849c39eb2.webp"
     width="1000"
     height="450"
     loading="lazy"
     decoding="async"
     alt="Bottom of the adapter (or top, depending on how you mount it).">

  </a>
  <figcaption class="center">Bottom of the adapter (or top, depending on how you mount it).</figcaption>
</figure>










<figure class="center">
  <a href="/posts/2025/11/18/lattepanda-iota/media/m2-adapter-installed-0.jpg">
    <img src="/posts/2025/11/18/lattepanda-iota/media/m2-adapter-installed-0_hu_b7a06679bf9193a6.webp"
     width="1000"
     height="785"
     loading="lazy"
     decoding="async"
     alt="Adapter installed to the SBC.">

  </a>
  <figcaption class="center">Adapter installed to the SBC.</figcaption>
</figure>










<figure class="center">
  <a href="/posts/2025/11/18/lattepanda-iota/media/m2-adapter-installed-1.jpg">
    <img src="/posts/2025/11/18/lattepanda-iota/media/m2-adapter-installed-1_hu_37d9a777355bca8f.webp"
     width="1000"
     height="718"
     loading="lazy"
     decoding="async"
     alt="Adapter with an M.2 2280 NVMe SSD. This Western Digital SSD was used for some quick testing.">

  </a>
  <figcaption class="center">Adapter with an M.2 2280 NVMe SSD. This Western Digital SSD was used for some quick testing.</figcaption>
</figure>

<p>The link speed is PCIe 3.0, with one lane available. In theory, this means a maximum of 1 GB/s of throughput. In
practice and with this board and SSD combination, I got a maximum of ~810 MB/s. I expect some levels of losses with
these types of setups, so in my view this seems normal. For the test, I just did
a <code>dd if=/dev/nvme0n1 of=/dev/null bs=8M status=progress</code>. The SSD itself supports up to 4 lanes of PCIe connectivity so
that should not be a limiting factor here.</p>
<p>The lovely part about M.2 NVMe ports is that you can use it for a lot of off-label use cases.</p>
<p>Fancy some SATA ports? There&rsquo;s an <a href="https://www.dfrobot.com/product-2811.html">adapter</a> for that.<sup id="fnref:2"><a href="#fn:2" class="footnote-ref" role="doc-noteref">2</a></sup></p>
<p>Or a network card? Some fancy AI accelator thingy? Or a full-sized GPU? Anything will work (probably), as long as the
cables and adapters are high quality, and you provide extra power to the device through other means.</p>
<h2 id="poe-expansion-board">
  <a class="heading-anchor" href="#poe-expansion-board">PoE expansion board<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>The only device on my network that is connected over PoE is currently an Ubiquiti Wi-Fi access point, and that is
unlikely to change in the near future because that would require a full replacement of my networking gear.<sup id="fnref:3"><a href="#fn:3" class="footnote-ref" role="doc-noteref">3</a></sup></p>
<p>However, I still gave this board a quick go, and I&rsquo;m happy to report that it also works as an additional standalone
Ethernet port. The Ethernet controller seems to be similar or the same as on the main board, and it shows up as a
separate networking device. Both are Realtek
NIC-s (<code>Realtek Semiconductor Co., Ltd. RTL8111/8168/8211/8411 PCI Express Gigabit Ethernet Controller</code>), and they work
with the <code>r8169</code> driver. Realtek has a spotty compatibility story overall on Linux from what I&rsquo;ve read, but this one
seems to work fine on Fedora Server 43.</p>









<figure class="center">
  <a href="/posts/2025/11/18/lattepanda-iota/media/poe-0.jpg">
    <img src="/posts/2025/11/18/lattepanda-iota/media/poe-0_hu_228bfca3cc169a2d.webp"
     width="1000"
     height="746"
     loading="lazy"
     decoding="async"
     alt="PoE adapter.">

  </a>
  <figcaption class="center">PoE adapter.</figcaption>
</figure>










<figure class="center">
  <a href="/posts/2025/11/18/lattepanda-iota/media/poe-1.jpg">
    <img src="/posts/2025/11/18/lattepanda-iota/media/poe-1_hu_7365b2a8e90261be.webp"
     width="1000"
     height="780"
     loading="lazy"
     decoding="async"
     alt="PoE adapter, other side.">

  </a>
  <figcaption class="center">PoE adapter, other side.</figcaption>
</figure>










<figure class="center">
  <a href="/posts/2025/11/18/lattepanda-iota/media/poe-2.jpg">
    <img src="/posts/2025/11/18/lattepanda-iota/media/poe-2_hu_f73e8ff578bc9f0d.webp"
     width="1000"
     height="816"
     loading="lazy"
     decoding="async"
     alt="PoE adapter, installed.">

  </a>
  <figcaption class="center">PoE adapter, installed.</figcaption>
</figure>










<figure class="center">
  <a href="/posts/2025/11/18/lattepanda-iota/media/poe-3.png">
    <img src="/posts/2025/11/18/lattepanda-iota/media/poe-3_hu_7ab3c58ff5a4560.webp"
     width="1000"
     height="551"
     loading="lazy"
     decoding="async"
     alt="Detected network interfaces on Fedora Server 43. Both work!">

  </a>
  <figcaption class="center">Detected network interfaces on Fedora Server 43. Both work!</figcaption>
</figure>

<p>I was very close to pulling the trigger and turning it into a beefy router so that I can finally move my Wireguard
networks on the router as my current one cannot do more than 20 Mbit/s of Wireguard traffic, but I didn&rsquo;t end up going
through with that idea because of how well the SBC did in other areas.</p>
<h2 id="ups-expansion-board">
  <a class="heading-anchor" href="#ups-expansion-board">UPS expansion board<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>As some of you might know, I&rsquo;m a fan
of <a href="/posts/2025/08/18/cheap-power-banks-suck/">playing with fir-</a> 18650 Li-ion battery cells, and I&rsquo;m
hoping to one day build a <a href="https://solar.lowtechmagazine.com/">solar-powered server of my own</a> (of which there
are <a href="https://louwrentius.com/i-made-my-blog-solar-powered-then-things-escalated.html">many</a> <a href="https://dri.es/my-solar-powered-and-self-hosted-website">examples</a>).</p>
<p>I took some spare 18650 cells that came from an old ThinkPad battery, made sure that the voltages are more-or-less
the same, and threw them on the board.</p>









<figure class="center">
  <a href="/posts/2025/11/18/lattepanda-iota/media/ups-0.jpg">
    <img src="/posts/2025/11/18/lattepanda-iota/media/ups-0_hu_866496dcf875ef62.webp"
     width="1000"
     height="809"
     loading="lazy"
     decoding="async"
     alt="UPS adapter.">

  </a>
  <figcaption class="center">UPS adapter.</figcaption>
</figure>










<figure class="center">
  <a href="/posts/2025/11/18/lattepanda-iota/media/ups-1.jpg">
    <img src="/posts/2025/11/18/lattepanda-iota/media/ups-1_hu_7e7014640b9e0ab1.webp"
     width="1000"
     height="728"
     loading="lazy"
     decoding="async"
     alt="UPS adapter, other side.">

  </a>
  <figcaption class="center">UPS adapter, other side.</figcaption>
</figure>










<figure class="center">
  <a href="/posts/2025/11/18/lattepanda-iota/media/ups-2.jpg">
    <img src="/posts/2025/11/18/lattepanda-iota/media/ups-2_hu_fca2886a8254bb77.webp"
     width="1000"
     height="886"
     loading="lazy"
     decoding="async"
     alt="UPS adapter, installed on the board.">

  </a>
  <figcaption class="center">UPS adapter, installed on the board.</figcaption>
</figure>










<figure class="center">
  <a href="/posts/2025/11/18/lattepanda-iota/media/ups-3.jpg">
    <img src="/posts/2025/11/18/lattepanda-iota/media/ups-3_hu_5f85831f1acaa04.webp"
     width="1000"
     height="893"
     loading="lazy"
     decoding="async"
     alt="UPS adapter, running off of batteries.">

  </a>
  <figcaption class="center">UPS adapter, running off of batteries.</figcaption>
</figure>










<figure class="center">
  <a href="/posts/2025/11/18/lattepanda-iota/media/ups-4.jpg">
    <img src="/posts/2025/11/18/lattepanda-iota/media/ups-4_hu_7f9dc3c2894a962a.webp"
     width="1000"
     height="851"
     loading="lazy"
     decoding="async"
     alt="UPS adapter, charging.">

  </a>
  <figcaption class="center">UPS adapter, charging.</figcaption>
</figure>

<p>Connecting the UPS board with the standoffs was fine, but the cable connecting it
with the SBC was finicky. I triple-checked that the connector was the right way, but had to still use an uncomfortable
amount of force to connect it all up. The battery cells themselves sit snugly on the board, and unless you drop the
board, they should not fall out on their own. You&rsquo;d still want to build a case around it if you&rsquo;re going to actually put
it to use in rough environments.</p>
<p>The manual for the UPS board emphasizes that it only works on Windows 10/11, and sadly that seems to be the case, the
UPS does not seem to show up as an USB-listed device, and tools like <a href="https://networkupstools.org/">NUT</a> did not find
anything to monitor with a quick 5-minute investigation.</p>
<p>The UPS board also has an interesting selection of switches that you can use to adjust the behaviour of the board, like
automatically turning the board on when power comes back on, and setting an 80% battery charge limit. The first one was
not really necessary to use, the board would follow whatever setting you have enabled on the SBC itself. I configured
mine via UEFI settings to automatically turn on with a power adapter connected, and that worked here as well.</p>
<p>The run time of your LattePanda IOTA with the UPS expansion board will heavily depend on your workloads and quality of
your battery cells. Mine were used cells, and then I hit the board with <code>stress -c 4</code> to create some load on it. It ran
for over an hour like that, and then I got bored and wanted to proceed with testing other accessories. The marketing
materials mention up to 8 hours of runtime, and I suspect that with good Li-ion cells and workloads where you idle most
of the time, it will likely be achievable.</p>
<p>The board seems to trigger a hard shutdown on Linux because the host OS is not aware of a battery being connected. Not
that catastrophic for most modern filesystems and database engines, but something to consider in your own workloads in
case they are Linux-based.</p>
<p>The UPS board seems to handle power connection and disconnection events well enough, it did not do anything weird when
repeatedly plugging and unplugging the USB-C cable.<sup id="fnref:4"><a href="#fn:4" class="footnote-ref" role="doc-noteref">4</a></sup></p>
<p>Based on the readings from a wall outlet energy meter, the board uses up to 20W when charging the cells. It&rsquo;s possible
for the board to pull more than that with a maximum CPU load and connected peripherals, so I wonder if that may be an
issue with more intense usage scenarios.</p>
<p>During charging and discharging cycles, even under heavy loads, the battery cells did not get hot and were at best warm
to touch.</p>
<h2 id="ethernet">
  <a class="heading-anchor" href="#ethernet">Ethernet<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>It&rsquo;s gigabit.</p>
<p>Fine for my use case given that I still live in 2006 and only have devices that support gigabit Ethernet
speeds at best (excluding the Ubiquiti Wi-Fi AP), but certainly less
than <a href="https://www.zimaspace.com/products/single-board2-server#specs">some competing products.</a></p>
<h2 id="emmc-and-usb-storage">
  <a class="heading-anchor" href="#emmc-and-usb-storage">eMMC and USB storage<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>Compared to the LattePanda V1, the USB port performance is actually decent for my use case. I can connect up to three
USB-connected storage devices to the board, so that&rsquo;s exactly what I did.</p>
<p>I set up three different USB-connected devices:</p>
<ul>
<li>USB hard drive (Seagate Basic)</li>
<li>USB SATA SSD (Samsung QVO 4TB in ICY BOX USB-SATA adapter)</li>
<li>USB NVMe SSD (512 GB Samsung PM9A1 with some random cheap USB to M.2 NVMe adapter)</li>
</ul>
<p>For each device (including on-board eMMC device), I ran
a <code>while true; do dd if=/dev/X of=/dev/null bs=8M status=progress; sleep 5; done</code>, which puts a sequential
read workload on all the drives in an infinite loop.</p>
<p>After about 72 TB of data read in less than 24 hours, I checked the kernel logs and there were no stability issues
whatsoever. The NVMe SSD started throttling due to heat, which was expected with that cheap adapter.</p>









<figure class="center">
  <a href="/posts/2025/11/18/lattepanda-iota/media/storage-stress-test.png">
    <img src="/posts/2025/11/18/lattepanda-iota/media/storage-stress-test_hu_fe28dcd9ae42d4a9.webp"
     width="1000"
     height="437"
     loading="lazy"
     decoding="async"
     alt="Results of the storage stress test.">

  </a>
  <figcaption class="center">Results of the storage stress test.</figcaption>
</figure>

<p>Assuming no issues with any cables and adapters, the USB ports seem to be solid enough for running storage devices off
of. Yes, <a href="/posts/2025/06/06/thinkcentre-m900-tiny/#2025-06-08-update">it can be a horrible idea in some use cases,</a> but
at the same time my ThinkPad T430 has been excellent with USB-based storage, and that&rsquo;s with one of the USB ports being
coffee-stained!</p>
<p>The eMMC chip is also more performant compared to the previous iteration, with sequential read speeds averaging around
316 MB/s, writes around 175 MB/s, and average read latency being around 0.15 ms. Certainly good enough for a boot drive.</p>
<h2 id="display-connectivity">
  <a class="heading-anchor" href="#display-connectivity">Display connectivity<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>The LattePanda V1 struggled with larger displays, and when I gave it a go during this review, it would not properly
display an image on my 3440x1440p monitor.</p>
<p>The LattePanda IOTA just did it, at 60 Hz. On Fedora Workstation and GNOME, the experience was smooth. Once you start
doing things in the browser, like video playback, the situation is less optimal, but as a makeshift desktop PC it is
alright for most low/mid-range activities.</p>









<figure class="center">
  <a href="/posts/2025/11/18/lattepanda-iota/media/display-output.jpg">
    <img src="/posts/2025/11/18/lattepanda-iota/media/display-output_hu_b30923cd36a81fa0.webp"
     width="1000"
     height="712"
     loading="lazy"
     decoding="async"
     alt="The display output working as intended on Windows 11.">

  </a>
  <figcaption class="center">The display output working as intended on Windows 11.</figcaption>
</figure>

<h2 id="windows-compatibility">
  <a class="heading-anchor" href="#windows-compatibility">Windows compatibility<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>The board came with a Windows 11 installation (not activated). As is tradition with Windows, the initial impressions are
horrible, update processes running in the background made the active cooler go wild and the device felt sluggish.</p>
<p>But after that process is done, the experience is not bad at all if you look past the OS being Windows.</p>
<p>I did not do a thorough investigation and I suggest formatting the device boot drive either way when receiving it, but
the Windows 11 installation looked clean enough, with no obvious bloatware.</p>









<figure class="center">
  <a href="/posts/2025/11/18/lattepanda-iota/media/windows-experience.jpg">
    <img src="/posts/2025/11/18/lattepanda-iota/media/windows-experience_hu_bd5f1e67dc619872.webp"
     width="1000"
     height="760"
     loading="lazy"
     decoding="async"
     alt="The typical Windows experience.">

  </a>
  <figcaption class="center">The typical Windows experience.</figcaption>
</figure>

<h2 id="linux-compatibility">
  <a class="heading-anchor" href="#linux-compatibility">Linux compatibility<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>The LattePanda V1 had some quirks. The performance was iffy, and you had to specify a Linux kernel parameter on first
boot so that Fedora Linux does not confuse the optional display interface to be an always-connected primary display.</p>
<p>The previous version also didn&rsquo;t include a real-time clock (RTC) by default, which meant that it was impossible to
schedule some systemd timers as the time would always jump on boot years ahead on distros like Fedora Server. I got
stuck in a reboot loop with a scheduled reboot job that way, was not fun to recover from.</p>
<p>With the LattePanda IOTA, I have not observed any weird oddities and quirks with it. Even the kernel logs don&rsquo;t show
anything that&rsquo;s problematic, and the RTC is handy to have around as that helps avoid the issue mentioned above.</p>
<h2 id="active-cooler">
  <a class="heading-anchor" href="#active-cooler">Active cooler<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>With the LattePanda V1, the cooler was not strictly required, but strongly recommended if you were going to use the
board with moderate to high sustained loads. My solution was to slap an inappropriately sized heat sink to it with a
thermal pad and zip ties and/or velcro strips, which looked horrible, because it was.</p>
<p>With the LattePanda IOTA, the cooler is now a <em><strong>mandatory</strong></em> part of the assembly. It can be fitted with
either
a <a href="https://www.dfrobot.com/product-2988.html">passive cooler</a>, <a href="https://www.dfrobot.com/product-2992.html">a case with passive cooling</a>,
or an <a href="https://www.dfrobot.com/product-2987.html">active cooler</a>.</p>









<figure class="center">
  <a href="/posts/2025/11/18/lattepanda-iota/media/active-cooler-0.jpg">
    <img src="/posts/2025/11/18/lattepanda-iota/media/active-cooler-0_hu_c12676e55237e93e.webp"
     width="1000"
     height="537"
     loading="lazy"
     decoding="async"
     alt="LattePanda IOTA next to the active cooler.">

  </a>
  <figcaption class="center">LattePanda IOTA next to the active cooler.</figcaption>
</figure>










<figure class="center">
  <a href="/posts/2025/11/18/lattepanda-iota/media/active-cooler-1.jpg">
    <img src="/posts/2025/11/18/lattepanda-iota/media/active-cooler-1_hu_7ff1b540440bb8f8.webp"
     width="1000"
     height="703"
     loading="lazy"
     decoding="async"
     alt="The bottom of the active cooler.">

  </a>
  <figcaption class="center">The bottom of the active cooler.</figcaption>
</figure>

<p>The active cooler does a good job of keeping the board cool, but it does get super loud at higher loads. The default fan
curve is very primitive, with the fan changing it speeds in big and sudden increments. Bursty workloads certainly <em>feel</em>
bursty with this fan. You will not want to be in the same room with this active cooler.</p>
<p>The sound profile is very similar to a thin and light laptop, and the fan has a <em><strong>very</strong></em> strong high-pitched whine to
it.</p>
<p><a href="/posts/2025/11/18/lattepanda-iota/media/active-cooler.mp3">Here&rsquo;s an audio recording of the noise under heavy load if you&rsquo;re interested (MP3 file). Recorded using a Google Pixel 8a.</a></p>
<p>You can mitigate the active cooler noise issue by reducing the CPU clock speed by setting a lower power limit in UEFI
settings, or on Linux, setting a lower CPU performance ceiling using <code>intel_pstate</code> driver <code>max_perf_pct</code> option once on
boot. This comes at the obvious cost of some raw performance, but given that CPU power scales non-linearly, you may not
even notice it that much.</p>
<p>If you are sensitive to fan noise, then do get the passive cooler and slap a Noctua fan on it, it will likely be a much
better experience with both the cooling performance and noise levels.</p>
<p>Oh, and fun fact: I got so carried away with testing that <strong>I actually forgot to remove the plastic film on the larger
thermal pad</strong> that cools supporting components.</p>
<p><em><strong>And then I did about 24 hours of stress testing with that arrangement.</strong></em></p>
<p>I can confirm that the design of the board is idiot-proof, as I did not actually notice any severe throttling or thermal
issues with that mistake. You can actually see the plastic film being present in a few photos of the board in this
review. I still can&rsquo;t believe that after all these years I ended up making <em><strong>that one mistake</strong></em> that you usually see
online in tech support gore posts.</p>
<h2 id="power-consumption">
  <a class="heading-anchor" href="#power-consumption">Power consumption<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>The idle power consumption of the LattePanda IOTA seems to be around 4.0W, which is more than the Raspberry Pi 5 8GB
with its power
consumption <a href="https://www.jeffgeerling.com/blog/2024/new-2gb-pi-5-has-33-smaller-die-30-idle-power-savings">being around 3.2W.</a>
Slightly higher compared to that, but lower than most x86 mini PC-s with idle power consumption typically in the range
of 6-14W.</p>
<p>During the disk read speed stress test, I saw a maximum of 24.4W pulled from the wall.</p>
<p>With the disk read stress test and a full CPU stress test, I saw a peak of 36.3W, with it quickly dropping down as the
CPU settled down at a lower clock speed.</p>
<h2 id="home-server">
  <a class="heading-anchor" href="#home-server">Home server<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>This board came surprisingly close to my perfect home server criteria that I had outlined earlier this year.</p>
<p>Less than 5W when idling? Check.</p>
<p>10+ TB of redundant storage? <a href="/posts/2025/10/06/datablocks-white-label-drives/">Check.</a></p>
<p>4 modern cores&rsquo; worth of CPU performance? Check.</p>
<p>Enough performance during bursty workloads? So far, yes.</p>
<p>I then installed a fresh copy of Fedora Server 43 and moved all my home server workloads to it. The eMMC storage is used
as a boot drive, <code>journald</code> writes are disabled, workloads requiring good latency and speed are on the 512GB NVMe SSD,
and bulk storage is connected via two existing USB-SATA adapters taken from one of those WD Elements/MyBook external
hard drive enclosures.</p>
<p>Then it just worked. No issues.<sup id="fnref:5"><a href="#fn:5" class="footnote-ref" role="doc-noteref">5</a></sup></p>









<figure class="center">
  <a href="/posts/2025/11/18/lattepanda-iota/media/home-server.jpg">
    <img src="/posts/2025/11/18/lattepanda-iota/media/home-server_hu_5194e24434b1f066.webp"
     width="1000"
     height="749"
     loading="lazy"
     decoding="async"
     alt="The LattePanda IOTA next to two 18TB hard drives, running as a home server.">

  </a>
  <figcaption class="center">The LattePanda IOTA next to two 18TB hard drives, running as a home server.</figcaption>
</figure>

<p>The drop in the overall power consumption of my whole home server and networking stack was also immediately noticeable.</p>









<figure class="center">
  <a href="/posts/2025/11/18/lattepanda-iota/media/power-consumption.png">
    <img src="/posts/2025/11/18/lattepanda-iota/media/power-consumption_hu_6fcbbf1adf7484c5.webp"
     width="1000"
     height="656"
     loading="lazy"
     decoding="async"
     alt="Solid 10W drop in normal use.">

  </a>
  <figcaption class="center">Solid 10W drop in normal use.</figcaption>
</figure>










<figure class="center">
  <a href="/posts/2025/11/18/lattepanda-iota/media/cpu.png">
    <img src="/posts/2025/11/18/lattepanda-iota/media/cpu_hu_9717d24be3191575.webp"
     width="1000"
     height="657"
     loading="lazy"
     decoding="async"
     alt="CPU usage on the ThinkPad T430 vs the LattePanda IOTA (the gap is the server migration). Same workloads in both.">

  </a>
  <figcaption class="center">CPU usage on the ThinkPad T430 vs the LattePanda IOTA (the gap is the server migration). Same workloads in both.</figcaption>
</figure>










<figure class="center">
  <a href="/posts/2025/11/18/lattepanda-iota/media/memory.png">
    <img src="/posts/2025/11/18/lattepanda-iota/media/memory_hu_b7f4eeeb01b4598c.webp"
     width="1000"
     height="657"
     loading="lazy"
     decoding="async"
     alt="Memory consumption, ThinkPad T430 (16GB DDR3) vs LattePanda IOTA (8GB DDR5).">

  </a>
  <figcaption class="center">Memory consumption, ThinkPad T430 (16GB DDR3) vs LattePanda IOTA (8GB DDR5).</figcaption>
</figure>










<figure class="center">
  <a href="/posts/2025/11/18/lattepanda-iota/media/temps.png">
    <img src="/posts/2025/11/18/lattepanda-iota/media/temps_hu_a0a2f6525ea35be8.webp"
     width="1000"
     height="442"
     loading="lazy"
     decoding="async"
     alt="Temperature readings, ThinkPad T430 vs LattePanda IOTA with the active cooler.">

  </a>
  <figcaption class="center">Temperature readings, ThinkPad T430 vs LattePanda IOTA with the active cooler.</figcaption>
</figure>

<p>Here are my observations of the CPU performance and behaviour after hitting it with an all-core CPU load:</p>
<ul>
<li>2.9 GHz for a short time period (10-15 seconds), with CPU hovering around 80°C</li>
<li>2.2-2.3 GHz after that, with the CPU dropping to around 70°C</li>
</ul>
<p>I have seen the CPU hit around 3.6 GHz with a single core load while there is nothing running in the background, but
during my normal home server operations the cores are doing enough work across all 4 cores, so that doesn&rsquo;t happen all
that often, and 2.9 GHz is the ceiling for single core performance.</p>
<p>The only limiting factor so far has been the 8 GB of memory on my review unit, but on the bright side that limitation
forced me to review the memory usage of some of the jobs that I run on my home server, which ended up with me finding a
few resource hogs and then fixing them all up. Now I can run about 30 Docker containers of various resource consumption
on a single board computer, and with less than 4GB of RAM used. I set up an 8GB swap file on the SSD, just in case.</p>
<p>Thanks to the relatively small boot drive, I also learned that even if you move the Docker <code>data-root</code> folder to another
location, <code>containerd</code> will still clutter up your boot drive, so you&rsquo;ll have to change that path in
its <code>/etc/containerd/config.toml</code> file <code>root</code> setting.</p>
<p>I&rsquo;m genuinely impressed with how well the LattePanda IOTA runs as a home server. The board isn&rsquo;t really designed with
that use case in mind, and I suspect that the Intel N150 might be doing most of the heavy lifting here, but still, very
impressive!</p>
<p><strong>Is it the perfect home server?</strong> No, but it&rsquo;s pretty damn close to my definition of it.</p>
<h2 id="uefi-settings-tour">
  <a class="heading-anchor" href="#uefi-settings-tour">UEFI settings tour<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>For those interested in what options are available on the board via its UEFI settings, here are some screenshots of the
settings.<sup id="fnref:6"><a href="#fn:6" class="footnote-ref" role="doc-noteref">6</a></sup></p>
<ul>
<li><a href="/posts/2025/11/18/lattepanda-iota/media/uefi-0.jpg">Main view</a></li>
<li><a href="/posts/2025/11/18/lattepanda-iota/media/uefi-1.jpg">Advanced</a></li>
<li><a href="/posts/2025/11/18/lattepanda-iota/media/uefi-2.jpg">Advanced -&gt; ACPI</a></li>
<li><a href="/posts/2025/11/18/lattepanda-iota/media/uefi-3.jpg">Advanced -&gt; CPU configuration</a></li>
<li><a href="/posts/2025/11/18/lattepanda-iota/media/uefi-4.jpg">Advanced -&gt; Super IO configuration</a></li>
<li><a href="/posts/2025/11/18/lattepanda-iota/media/uefi-5.jpg">Advanced -&gt; Serial port 1 configuration</a></li>
<li><a href="/posts/2025/11/18/lattepanda-iota/media/uefi-6.jpg">Advanced -&gt; SMART Fan Control</a></li>
<li><a href="/posts/2025/11/18/lattepanda-iota/media/uefi-7.jpg">Advanced -&gt; Trusted Computing</a></li>
<li><a href="/posts/2025/11/18/lattepanda-iota/media/uefi-8.jpg">Advanced -&gt; NVMe configuration</a> (no device connected at time of screenshot, oops)</li>
<li><a href="/posts/2025/11/18/lattepanda-iota/media/uefi-9.jpg">Advanced -&gt; Power configuration</a></li>
<li><a href="/posts/2025/11/18/lattepanda-iota/media/uefi-10.jpg">Advanced -&gt; USB configuration</a></li>
<li><a href="/posts/2025/11/18/lattepanda-iota/media/uefi-11.jpg">Advanced -&gt; Serial Port console redirection</a></li>
<li><a href="/posts/2025/11/18/lattepanda-iota/media/uefi-12.jpg">Advanced -&gt; SDIO configuration</a></li>
<li><a href="/posts/2025/11/18/lattepanda-iota/media/uefi-13.jpg">Advanced -&gt; Realtek PCIe Ethernet controller</a></li>
<li><a href="/posts/2025/11/18/lattepanda-iota/media/uefi-14.jpg">Chipset</a></li>
<li><a href="/posts/2025/11/18/lattepanda-iota/media/uefi-15.jpg">Chipset -&gt; System Agent (SA) configuration</a></li>
<li><a href="/posts/2025/11/18/lattepanda-iota/media/uefi-16.jpg">Chipset -&gt; Device configuration</a></li>
<li><a href="/posts/2025/11/18/lattepanda-iota/media/uefi-17.jpg">Security</a></li>
<li><a href="/posts/2025/11/18/lattepanda-iota/media/uefi-18.jpg">Security -&gt; Secure Boot</a></li>
<li><a href="/posts/2025/11/18/lattepanda-iota/media/uefi-19.jpg">Boot</a></li>
<li><a href="/posts/2025/11/18/lattepanda-iota/media/uefi-20.jpg">Save &amp; Exit</a></li>
</ul>
<h2 id="conclusion">
  <a class="heading-anchor" href="#conclusion">Conclusion<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>If the LattePanda IOTA with its adapters fits your project requirements, you&rsquo;re aware of its limitations, and the
price is right, then I believe it&rsquo;s a solid choice for your next project. My testing didn&rsquo;t immediately break it, even
when I forgot to remove the plastic film on one of the thermal pads.</p>
<p>The current pricing of it and its accessories seem to be roughly in the ballpark of the Raspberry Pi 5 8GB (based on
prices in Estonia). Boards like <a href="https://shop.zimaspace.com/products/zimaboard2-single-board-server">the Zimaboard 2</a>
<strong><em>(have not tested it myself)</em></strong> are more expensive, but they&rsquo;re also catering to a slightly different audience and
have better specs, like 2.5G Ethernet ports and SATA ports with power delivery suitable for running two 3.5&quot; hard drives
straight from the board.</p>
<p>It&rsquo;s hard to beat the bargain that you can get from a used mini PC or NAS, but it won&rsquo;t come with the charm, low power
consumption and bragging rights that a single board computer gets you, especially if you&rsquo;re using it for an off-label
use case like I am.<sup id="fnref:7"><a href="#fn:7" class="footnote-ref" role="doc-noteref">7</a></sup></p>
<p>In the meantime, I&rsquo;ll keep rocking it as a home server. In case something noteworthy happens, I&rsquo;ll update this post,
which is brought to you by the very same LattePanda IOTA at the time of publishing.</p>
<h2 id="2025-12-12-update">
  <a class="heading-anchor" href="#2025-12-12-update">2025-12-12 update<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>About a month after switching my home server workloads to it, the LattePanda IOTA is still rock solid. No issues with
USB HDD stability as well.</p>
<p>The only complaint that carries over from the review is the fact that the active cooler is still way too loud. I&rsquo;m
seriously considering getting the passive cooler for it to shut it up. I can hear it from the bedroom while the IOTA is
in a closet on the other side of the apartment!</p>
<p>I also played around with Intel RAPL settings, which allow you to control the power budget of the CPU on the fly.</p>
<p>The power limit is 10W by default, and short term power limit is 20W. You can control it via these toggles:</p>
<pre tabindex="0"><code>/sys/class/powercap/intel-rapl/intel-rapl:0/constraint_0_power_limit_uw
/sys/class/powercap/intel-rapl/intel-rapl:0/constraint_1_power_limit_uw
</code></pre><p>Get current values:</p>
<pre tabindex="0"><code>cat /sys/class/powercap/intel-rapl/intel-rapl:0/constraint_0_power_limit_uw
cat /sys/class/powercap/intel-rapl/intel-rapl:0/constraint_1_power_limit_uw
</code></pre><p>Set a new limit of 8W to both:</p>
<pre tabindex="0"><code>echo 8000000 &gt; /sys/class/powercap/intel-rapl/intel-rapl:0/constraint_0_power_limit_uw
echo 8000000 &gt; /sys/class/powercap/intel-rapl/intel-rapl:0/constraint_1_power_limit_uw
</code></pre><p>These reset every boot, so you should probably set a one-shot systemd unit to call these early in the boot cycle.</p>
<p>The LattePanda IOTA is the most exciting yet boring addition to my setup. It just works.</p>
<div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p>this also marks the first time that I&rsquo;ve been sent a review sample throughout the course of running this blog!&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:2">
<p>do note that with most M.2 PCIe-&gt;SATA adapters, the controller of the adapter determines how good of an experience
you will have. With some, I&rsquo;ve read that the controllers may not handle some failure scenarios well, one device having
issues may throw off the whole controller, and now you have a bigger mess.&#160;<a href="#fnref:2" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:3">
<p>the earliest PC motherboard with a gigabit Ethernet connection that I&rsquo;ve personally used was manufactured in 2006.
That&rsquo;s how long gigabit Ethernet has been around for in the consumer space.&#160;<a href="#fnref:3" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:4">
<p>say that 10 times in a row!&#160;<a href="#fnref:4" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:5">
<p>I know, that usually does not happen on this blog.&#160;<a href="#fnref:5" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:6">
<p>being <a href="/posts/2025/02/17/influencer/">a prolific open source influencer</a> does not bring in as much money as you&rsquo;d
think, so I haven&rsquo;t bought a proper capture device yet.&#160;<a href="#fnref:6" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:7">
<p>no, but seriously, I cannot be the only one who has a strange affection towards SBC-s with their bare PCB-s.
I can&rsquo;t tell a capacitor from a resistor, but the boards are just so damn cool, right?&#160;<a href="#fnref:7" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</div>
]]></content:encoded></item><item><title>./project2038: can I keep the Orange Pi Zero running until 2038 and beyond?</title><link>https://ounapuu.ee/posts/2025/10/20/project2038/</link><pubDate>Mon, 20 Oct 2025 06:00:00 +0300</pubDate><author>ihavesomethoughtsonyourblog@ounapuu.ee (Herman Õunapuu)</author><guid>https://ounapuu.ee/posts/2025/10/20/project2038/</guid><description>Only one way to find out!</description><content:encoded><![CDATA[<img src="https://ounapuu.ee/posts/2025/10/20/project2038/media/cover_hu_b330c3c2c479a395.jpg" width="1200" height="630" alt="./project2038: can I keep the Orange Pi Zero running until 2038 and beyond?" /><p><em>Start of experiment: September 2025</em></p>
<p><em>Post last updated: October 2025</em></p>
<p><a href="https://project2038.ounapuu.ee/">Check the live status of my Orange Pi Zero here!</a></p>
<p>I love the <a href="https://www.armbian.com/orange-pi-zero/">Orange Pi Zero.</a> It&rsquo;s tiny, uses very little power and it&rsquo;s just
neat! It&rsquo;s also the subject of <a href="/posts/2020/07/23/the-little-wifi-ap-that-could/">the very first post on my blog,</a> which
makes it a bit special.</p>
<p>Unfortunately I haven&rsquo;t really found a good use case for it, given that its performance is quite limited and the CPU is
a 32-bit ARM CPU with 4 relatively weak cores, which rules out using it as a Docker container host due to the
architectural limitations.</p>
<p>The board is currently not doing much, but I&rsquo;ll figure out a use case for it.</p>
<p>The board also has a few quirks at the moment that I&rsquo;ve worked around. For example, rebooting seems to be broken, and
it&rsquo;s unlikely to get fixed any time soon. I resolved it by simply not rebooting it<sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup>, at least not on a regular
schedule, anyway. I&rsquo;m hoping that any short-term power outages at home will take care of the need to reboot it.</p>
<p>It also runs quite hot in its stock Armbian configuration, which I worked around by running <code>powertop --auto-tune</code> on
startup as that forces the CPU to always run at its slowest clock speed (480 MHz). Without it, I found that this board
can run its CPU at 105°C, and it does have a thermal shutdown feature.</p>
<p>This board has been featured in a few previous posts as well, and even then it was quite underpowered:</p>
<ul>
<li><a href="/posts/2020/07/23/the-little-wifi-ap-that-could/">the little Wi-Fi AP that could</a></li>
<li><a href="/posts/2021/03/20/whacky-setups-1/">seedbox on a wall</a></li>
<li><a href="/posts/2021/02/27/database-optimization-adventures-on-low-end-hardware/">database optimization adventures on low-end hardware</a></li>
</ul>
<p>Now that I have it set up, will it be able to survive
to <a href="https://en.wikipedia.org/wiki/Year_2038_problem">year 2038 and beyond?</a> Only time will tell.</p>
<p>Which issue will we run into first? Plausible options based on my previous experience:</p>
<ul>
<li>the cheap 8GB SD card craps out</li>
<li>component on the board dies from heat-related issues</li>
<li>the USB power supply dies
<ul>
<li>it&rsquo;s currently running off of an IKEA extension cord that has two USB-A ports, so hopefully not</li>
</ul>
</li>
<li>board loses Armbian support completely (currently under community maintenance status)</li>
</ul>
<p>The board is currently running the latest version of Armbian, and I might occasionally refresh its version from time to
time.</p>
<p><a href="https://www.armbian.com/donate/">If you like Armbian, then please support them!</a> They&rsquo;re doing great work with keeping
all sorts of SBC-s up and running with usable versions of Debian and Ubuntu Linux.</p>
<h2 id="2025-10-20-update">
  <a class="heading-anchor" href="#2025-10-20-update">2025-10-20 update<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>What are the chances that the day I make this project
public, <a href="https://aws.amazon.com/message/101925/">AWS suffers a massive outage?</a>
Poetic in a way. And yes, my website and the Orange Pi Zero were fully operational.</p>
<div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p>the first time in my career that the solution ended up being &ldquo;have you tried <em><strong>not</strong></em> turning it off and on
again?&rdquo;&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</div>
]]></content:encoded></item><item><title>How to build a fleet of networked offsite backups using Linux, WireGuard and rsync</title><link>https://ounapuu.ee/posts/2024/12/11/wireguard-backup-fleet/</link><pubDate>Wed, 11 Dec 2024 06:00:00 +0200</pubDate><author>ihavesomethoughtsonyourblog@ounapuu.ee (Herman Õunapuu)</author><guid>https://ounapuu.ee/posts/2024/12/11/wireguard-backup-fleet/</guid><description>You have offsite backups of your most important data, right? Right???</description><content:encoded><![CDATA[<img src="https://ounapuu.ee/posts/2024/12/11/wireguard-backup-fleet/media/cover_hu_79c3c1903608e4ea.jpg" width="1200" height="630" alt="How to build a fleet of networked offsite backups using Linux, WireGuard and rsync" /><p>Just like most people out there, I have some files that are irreplaceable, such as cat pictures.</p>
<p>At one point I had a few single-board computers sitting idle, namely
the <a href="http://www.orangepi.org/html/hardWare/computerAndMicrocontrollers/details/Orange-Pi-Zero.html">Orange Pi Zero</a> and
the <a href="https://www.lattepanda.com/lattepanda-v1">LattePanda V1</a>, and a few
1TB SSD-s.</p>
<p>I hate idle hardware, so I did the most sensible thing and assembled a fleet of networked offsite backups for
backing up the most important data.</p>
<p>My setup is based on various flavors of Linux, but the ideas will likely translate well onto other operating systems
and solutions.</p>
<h2 id="networking">
  <a class="heading-anchor" href="#networking">Networking<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>The most important part is the networking. The offsite backup endpoints connect together to my home server over a
WireGuard network. The home server is, well, <em>the server</em>, and backup endpoints are clients.</p>
<p>I like <a href="https://github.com/linuxserver/docker-WireGuard">this WireGuard Docker image</a> a lot because it generates
the server and client configurations automatically, but you can use plain WireGuard or a completely different networking
solution to connect all the devices together. Some use Tailscale to make the setup process easier, but I like to keep
things as self-hosted as possible.</p>
<p>I&rsquo;m not a networking expert, but here&rsquo;s how I&rsquo;ve set up my network. For this example, the WireGuard network operates in
the <code>10.13.69.0/24</code> range.<sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup></p>
<p>To only allow traffic between the devices and avoid tunneling everything through the home server, set the <code>AllowedIPs</code>
setting to <code>AllowedIPs = 10.13.69.0/24,10.13.69.1</code>. We want to be able to access the backup endpoints, and nothing more.</p>
<p>All the devices have a static IP address in that network, such as <code>10.13.69.1</code> for the home server, <code>10.13.69.2</code> for a
backup endpoint and so on.</p>
<p>The <code>PersistentKeepalive = 25</code> option is present in the client configurations so that I don&rsquo;t lose the ability to access
the backup endpoints. With it, all the backup endpoints call back to the home server from time to time. The
aforementioned Docker image automatically adds it to the generated configuration using
the <code>PERSISTENTKEEPALIVE_PEERS=all</code> option.
This setting is <em><strong>crucial.</strong></em> Without it, I sometimes ran into problems trying to connect from my home server to the
backup endpoint, and that&rsquo;s something you can&rsquo;t easily alleviate without having physical access to the backup endpoints,
which are offsite.</p>
<p>Remove the DNS configuration from generated WireGuard client configurations, as you don&rsquo;t need it for this purpose.</p>
<p>Optionally, edit the <code>/etc/hosts</code> file for the home server and backup endpoints so that you can access your backup
endpoints using simple hostnames, like <code>orangepizero</code>. Example row can look like this: <code>10.13.69.6 orangepizero</code>.</p>
<p>if your WireGuard server operates in a network with a dynamic external IP address, as is common with many home internet
connections, I recommend getting yourself a domain name that you can update whenever your IP address changes and using
that in your WireGuard client configurations. Without this, an IP address change will result in your backup endpoints
being inaccessible.</p>
<p>You&rsquo;ll also likely need to set up port forwarding and/or traffic rules for your backup endpoints to be able to connect
back to your WireGuard server.</p>
<p>Once you have the WireGuard connection set up and SSH running on the backup endpoints, you should be able to drop the
backup endpoints into any network that you have permission for. Ask your friends and family, and sweeten the deal by
offering free technical support or help in some other area in return. The cost of running a single-board computer 24/7
is minuscule with the typical power consumption being 1-3W, so that won&rsquo;t be much of a concern.</p>
<h2 id="making-backups">
  <a class="heading-anchor" href="#making-backups">Making backups<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>For making the actual backups themselves, you have all sorts of options.</p>
<p>I rely on <code>rsync</code> to copy the data over. It&rsquo;s simple and it works, that&rsquo;s all I expect from it.
Example command: <code>rsync -aAXvz /folder/to/back/up/ backupuser@backupendpoint:/backup/ --delete</code>.
The files will be compressed during transit with the <code>-z</code> option, and with <code>--delete</code> you&rsquo;ll ensure that the target
folder has all the files from the source, and nothing else.</p>
<p>The backup storage is specified in <code>/etc/fstab</code> with the <code>nofail</code> option present. This ensures that in case the disk
dies, the backup endpoint will still boot properly, allowing me to access the machine to troubleshoot the issue and/or
force a desperate reboot to try to fix things. A good alternative approach is to mount/unmount the remote disk manually
as part
of the backup script.</p>
<p>The backup storage uses the <code>btrfs</code> filesystem, and I use <code>btrbk</code> to take snapshots of the contents. If I accidentally
delete all the files on the backup endpoint, then I can still recover from that situation because the data is still
present in snapshots. 30 days is a good retention period: enough time to save the data in case of an accidental
deletion, but short
enough to avoid the backup disk getting full.</p>
<p>If you don&rsquo;t want to use filesystem-level snapshots, then tools like <code>restic</code> are a good alternative. It can also
operate
over SSH and you can configure snapshot retention policies in your backup script. Just make sure to not lose the
encryption password, and
verify the backups once in a while.</p>
<h2 id="deployment">
  <a class="heading-anchor" href="#deployment">Deployment<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>I manage my backup endpoints using some cobbled-together Ansible roles. I&rsquo;ve perfected it to the point where the only
manual
steps are flashing the OS and setting up the storage, the rest is handled via Ansible.</p>
<p>I&rsquo;d like to share my work here, but it will make Jeff Geerling cry. Maybe one day I&rsquo;ll take the time to improve
things&hellip;</p>
<h2 id="maintenance">
  <a class="heading-anchor" href="#maintenance">Maintenance<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>All the backup endpoints update and reboot themselves regularly. It&rsquo;s just the sensible thing to do.</p>
<p>Every 6-12 months I also do major OS version updates. It&rsquo;s risky because of the whole offsite aspect of the solution,
but so far I haven&rsquo;t been burned yet.</p>
<h2 id="monitoring">
  <a class="heading-anchor" href="#monitoring">Monitoring<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>Monitoring is an area where I have some room for improvement. So far, I&rsquo;ve set up Prometheus node-exporter to all of
the backup endpoints, and my home server keeps track of how the backup endpoints are doing.</p>
<p>This allows me to check once in a while if any of the backup endpoints has fallen off the network, or if the backup disk
is getting full.</p>
<h2 id="issues-ive-faced">
  <a class="heading-anchor" href="#issues-ive-faced">Issues I&rsquo;ve faced<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>I&rsquo;ve had this system running for a few years now, and it&rsquo;s mostly stable! There have been some issues I&rsquo;ve faced as
well,
though. Some are very specific to certain hardware, but I think there&rsquo;s value in mentioning them.</p>
<p><a href="/posts/2023/06/10/how-i-blew-up-my-backup-server/">I once blew up a backup server because of an Ansible configuration issue.</a>
That meant that I had to physically go pick up the server to re-image it.</p>
<p>The Orange Pi Zero was running quite hot, resulting in stability issues, so I put together a really janky cooling
solution.</p>









<figure class="center">
  <a href="/posts/2024/12/11/wireguard-backup-fleet/media/orangepizero.jpg">
    <img src="/posts/2024/12/11/wireguard-backup-fleet/media/orangepizero_hu_689cb39c9001c4e2.webp"
     width="750"
     height="1000"
     loading="lazy"
     decoding="async"
     alt="Cooling. It works.">

  </a>
  <figcaption class="center">Cooling. It works.</figcaption>
</figure>

<p>Hell, I did the same for the LattePanda as well.</p>









<figure class="center">
  <a href="/posts/2024/12/11/wireguard-backup-fleet/media/lattepanduh.jpg">
    <img src="/posts/2024/12/11/wireguard-backup-fleet/media/lattepanduh_hu_b5634f62aec46ed4.webp"
     width="1000"
     height="750"
     loading="lazy"
     decoding="async"
     alt="First version of the cooling upgrade on the LattePanda.">

  </a>
  <figcaption class="center">First version of the cooling upgrade on the LattePanda.</figcaption>
</figure>

<p>It might look horrific but the extra cooling has fixed all the stability problems on both boards.</p>
<p>The lack of a real-time clock on the LattePanda has required me to make its backup script a bit special. I can&rsquo;t rely on
a systemd timer that automatically reboots the machine once in a while, so instead that part is present in the backup
script. The issue is that the LattePanda boots up with the time being set in the past, and once it gets the actual time
from the
network, it will run all sorts of tasks because enough time has passed!
This included the reboot timer as well.</p>
<p>At one point, the power supply on the LattePanda just died, and it was very visible on my graphs. That required a
replacement.</p>









<figure class="center">
  <a href="/posts/2024/12/11/wireguard-backup-fleet/media/lattepanda-psu-failure.png">
    <img src="/posts/2024/12/11/wireguard-backup-fleet/media/lattepanda-psu-failure_hu_83ab55cb07768116.webp"
     width="1000"
     height="725"
     loading="lazy"
     decoding="async"
     alt="Signs that you might have a failing power supply.">

  </a>
  <figcaption class="center">Signs that you might have a failing power supply.</figcaption>
</figure>

<h2 id="conclusion">
  <a class="heading-anchor" href="#conclusion">Conclusion<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>That&rsquo;s how I back up the most important data. I hope that this has given you inspiration to take your own backup
approach to the next level!</p>
<div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p>yes, I do plan to move this setup to IPv6 eventually.&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</div>
]]></content:encoded></item><item><title>How to save an old printer from the e-waste pile with a Raspberry Pi</title><link>https://ounapuu.ee/posts/2024/06/12/save-old-printer/</link><pubDate>Wed, 12 Jun 2024 06:00:00 +0300</pubDate><author>ihavesomethoughtsonyourblog@ounapuu.ee (Herman Õunapuu)</author><guid>https://ounapuu.ee/posts/2024/06/12/save-old-printer/</guid><description>Turning a 15-year-old Canon PIXMA MP250 printer into a network printer was much easier than I initially thought.</description><content:encoded><![CDATA[<img src="https://ounapuu.ee/posts/2024/06/12/save-old-printer/media/cover_hu_8b18de1695374b7c.jpg" width="1200" height="630" alt="How to save an old printer from the e-waste pile with a Raspberry Pi" /><p>A family member has a Canon PIXMA MP250 printer, originally released in 2009.
It has been a very reliable piece of hardware, especially for a printer.</p>
<p>Then came Windows 10. The printer would not work out of the box with it and
the official drivers got stuck during installation. Fiddling with the printer
in device manager, trying to install drivers via Windows Update and stars
aligning
got the printer to work again.</p>
<p>Then came Windows 11. Nothing I did could get it working now, and the printer
is not even officially supported by Canon on this version of Windows.</p>
<p>This printer works out of the box on any mainstream Linux distribution, and
the family member had been using the printer with Ubuntu for years,
but <a href="https://www.id.ee/en/article/install-id-software/">a certain piece
of important software in Estonia</a>
was not working properly a lot of the time, which triggered a switch to Windows.<sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup></p>
<p>Quick searches online suggested that I could turn this printer into a network
printer, as long as I had some patience and a spare computer.</p>
<p>The idea is simple: take a spare computer, hook it up to the printer, install
CUPS on it, configure it and you&rsquo;re good to go!</p>
<p>I initially tested this setup with a Zimaboard running Fedora Server, but the
final solution used an old Raspberry Pi B+ running the latest version of
Raspberry Pi OS.</p>
<h2 id="how-to-set-it-up">
  <a class="heading-anchor" href="#how-to-set-it-up">How to set it up<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>The steps will be similar with other pieces of hardware and Linux distributions,
you may just need to adjust a few commands and package names.</p>
<p>The steps are roughly based on these two guides:</p>
<ul>
<li><a href="https://m-hussainul-islam.medium.com/setting-up-network-printer-with-raspberry-pi-and-cups-d5a18e91b1f3">Setting up Network Printer with Raspberry Pi and CUPS</a></li>
<li><a href="https://pimylifeup.com/raspberry-pi-print-server/">Raspberry Pi Print Server: Setup a Network Printer</a></li>
</ul>
<p>If you&rsquo;re following along with a Raspberry Pi, set up your OS first. A minimal
installation with no graphical interface will be just fine.</p>
<p>Next, install <a href="https://www.cups.org/">CUPS</a> and optionally the right printer
drivers for your printer. The Canon PIXMA MP250 requires the
package <code>printer-driver-gutenprint</code>.</p>
<pre tabindex="0"><code>sudo apt install -y cups printer-driver-gutenprint
</code></pre><p>Make sure that CUPS is running.</p>
<pre tabindex="0"><code>sudo systemctl enable --now cups.service
</code></pre><p>Next, allow your user to manage printing. In this example, the username is <code>pi</code>.</p>
<pre tabindex="0"><code>sudo usermod -a -G lpadmin pi
</code></pre><p>Next, make sure that CUPS allows connections from other machines in your
network, and then restart it.</p>
<pre tabindex="0"><code>sudo cupsctl --remote-any
sudo systemctl restart cups
</code></pre><p>Find out the IP address of the Pi and navigate to it in your browser.
It will look something like <code>https://192.168.0.49:631</code>. The browser will likely
warn you about a self-signed certificate. It&rsquo;s safe to proceed.</p>
<p>If you haven&rsquo;t already connected your printer to the Raspberry Pi via USB, then
do so now.</p>
<p>Use the graphical interface to add a new printer under the <code>Administration</code>
section.
You&rsquo;ll need to enter the username and password for your user here. It&rsquo;s the same
user we used earlier, so in this example it&rsquo;s <code>pi</code>.</p>
<p>If you can&rsquo;t find your printer model listed in the <code>Add printer</code> view, then you
are probably missing the proper driver package, or your printer simply isn&rsquo;t
supported.</p>









<figure class="center">
  <a href="/posts/2024/06/12/save-old-printer/media/add-printer.png">
    <img src="/posts/2024/06/12/save-old-printer/media/add-printer_hu_6f3d551a1ca09828.webp"
     width="800"
     height="780"
     loading="lazy"
     decoding="async"
     alt="You should be able to find your printer in this view.">

  </a>
  <figcaption class="center">You should be able to find your printer in this view.</figcaption>
</figure>

<p>After adding your printer, you can use the CUPS web interface to print a test
page.</p>
<p>If that worked, then you should now be able to use any other device on the
network
to print!</p>
<p>On Linux and Windows, open the settings section that handles printing, and add a
new printer.
This networked printer should appear automagically, no additional configuration
required.</p>
<p>I also did testing using a Fairphone 5 running Android 13, and an iPhone X
running iOS 16. In both
cases the printing just worked.</p>









<figure class="center">
  <a href="/posts/2024/06/12/save-old-printer/media/test-page-windows.jpg">
    <img src="/posts/2024/06/12/save-old-printer/media/test-page-windows_hu_1a44a0e7cfd60776.webp"
     width="600"
     height="800"
     loading="lazy"
     decoding="async"
     alt="Test page printed using Windows 11.">

  </a>
  <figcaption class="center">Test page printed using Windows 11.</figcaption>
</figure>










<figure class="center">
  <a href="/posts/2024/06/12/save-old-printer/media/test-page-fedora.jpg">
    <img src="/posts/2024/06/12/save-old-printer/media/test-page-fedora_hu_686fc992f2a4cbdf.webp"
     width="600"
     height="800"
     loading="lazy"
     decoding="async"
     alt="Test page printed using Fedora. Yes, most of the colors in the colored ink
cassette have run out.">

  </a>
  <figcaption class="center">Test page printed using Fedora. Yes, most of the colors in the colored ink
cassette have run out.</figcaption>
</figure>

<p>I&rsquo;ve used the scanning functionality of this particular printer on Linux and it
has worked, however I forgot to test this out using this setup. I&rsquo;ll try to
test that out once I get the chance to try the printer out again.</p>
<h2 id="hardware-tech-tips">
  <a class="heading-anchor" href="#hardware-tech-tips">Hardware tech tips<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>I first ran this setup with a Zimaboard to test the idea out. It worked very
well,
but as a simple print server it is a bit overkill.</p>
<p>I then replaced it with a Raspberry Pi B+, and while the printing works, I
discovered that a single ARM CPU core is apparently a limiting factor during
printing. A simple test page print pegged the CPU at 100%, and that&rsquo;s with the
700-&gt;1000 MHz overclock applied.</p>









<figure class="center">
  <a href="/posts/2024/06/12/save-old-printer/media/cups-high-cpu.png">
    <img src="/posts/2024/06/12/save-old-printer/media/cups-high-cpu_hu_dd8b775751f19ff5.webp"
     width="800"
     height="435"
     loading="lazy"
     decoding="async"
     alt="Raspberry Pi B&#43; struggling during printing.">

  </a>
  <figcaption class="center">Raspberry Pi B&#43; struggling during printing.</figcaption>
</figure>

<p>If you don&rsquo;t mind a slower printing speed, then any Raspberry Pi will be
absolutely OK.
More performant versions of Raspberry Pi will likely fare even better.</p>
<p>If you already have a small home server running, then you may want to hook the
printer up to that and set up the printer there. It&rsquo;s already running 24/7, so
it would be a perfect match.</p>
<p>One useful aspect of this setup is that you can queue up print jobs even when
the printer itself is powered off. Once you turn it on, the print jobs will
start, assuming that you have enough paper and ink.</p>
<p>Free open source software prolongs the useful life of hardware once again.
<a href="https://www.canalys.com/insights/end-of-windows-10-support-could-turn-240-million-pcs-into-e-waste">See y&rsquo;all in October 2025!</a></p>
<h2 id="2024-06-15-update">
  <a class="heading-anchor" href="#2024-06-15-update">2024-06-15 update<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>This post got featured on:</p>
<ul>
<li><a href="https://www.xda-developers.com/raspberry-pi-unsupported-printer-on-windows/">XDA Developers</a></li>
<li><a href="https://www.hackster.io/news/herman-ounapuu-brings-an-abandoned-printer-back-from-the-brink-with-a-raspberry-pi-90701ccb1ab9">hackster.io</a></li>
<li><a href="https://hackaday.com/2024/06/13/raspberry-pi-saves-printer-from-junk-pile/">Hackaday</a></li>
<li><a href="https://news.ycombinator.com/item?id=40657753">Hacker News</a></li>
</ul>
<p><a href="https://ubuntu.social/@till/112616367405119050">And even the leader of OpenPrinting, Till Kamppeter, chimed in!</a>
They also held a talk about <a href="https://fosdem.org/2024/schedule/event/fosdem-2024-1930-openprinting-we-make-printing-just-work-/">OpenPrinting at FOSDEM 2024.</a></p>
<p>Regarding scanning, seems like there&rsquo;s a separate project for that called <a href="http://www.sane-project.org/">SANE - Scanner Access Now Easy.</a></p>
<p><a href="https://openprinting.github.io/">Find out more about OpenPrinting here.</a></p>
<h2 id="2024-11-14-update">
  <a class="heading-anchor" href="#2024-11-14-update">2024-11-14 update<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>A reader shared with me the <a href="https://github.com/kenyapcomau/p910nd">p910nd</a> project that can be used for a similar
purpose. I have not yet tried this myself.</p>
<p>There&rsquo;s even
an <a href="https://openwrt.org/docs/guide-user/services/print_server/p910ndprinterserver">OpenWRT page that describes its use on a router!</a></p>
<div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p>that might be about to change as there is an <a href="https://flathub.org/apps/ee.ria.qdigidoc4">unofficial Flatpak version</a> out there.&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</div>
]]></content:encoded></item><item><title>Zimaboard: the closest thing to my dream home server setup</title><link>https://ounapuu.ee/posts/2023/10/09/zimaboard/</link><pubDate>Mon, 09 Oct 2023 14:00:00 +0300</pubDate><author>ihavesomethoughtsonyourblog@ounapuu.ee (Herman Õunapuu)</author><guid>https://ounapuu.ee/posts/2023/10/09/zimaboard/</guid><description>I gave in to my impulses and bought myself a small single board computer to be my power-efficient home server, here's how it went.</description><content:encoded><![CDATA[<img src="https://ounapuu.ee/posts/2023/10/09/zimaboard/media/cover_hu_1511165ed98ee92c.jpg" width="1200" height="630" alt="Zimaboard: the closest thing to my dream home server setup" /><p>I stumbled upon <a href="https://youtu.be/V_ZdvrIMKEQ">this Hardware Haven video about the Zimaboard recently.</a></p>
<p>I liked it a lot.</p>
<p>I finally bought one.</p>
<p>In short, <a href="https://www.zimaboard.com/zimaboard/product">Zimaboard</a> is a small single-board computer that is relatively affordable and comes
with an interesting selection of ports, which includes an exposed PCI Express port.</p>
<p>Before we get down to the build, here&rsquo;s a list of aspects that I want to see in my dream home server:</p>
<ul>
<li>low power usage (2-15W typical power usage)</li>
<li>8GB of RAM or better</li>
<li>enough performance to run my workloads, most of which are containerized</li>
<li>2x SATA or NVMe SSD slots, plus option for a third drive for the OS</li>
<li>passively cooled and completely silent</li>
<li>compact size</li>
<li>gigabit Ethernet or better</li>
</ul>
<p>You might be thinking, &ldquo;<em>Wait, that&rsquo;s your <strong>dream setup</strong>? No clusters of machines, Threadrippers, 10 Gigabit networking, crazy number of disks?</em>&rdquo;.
Well, yes. After years of trying all sorts of setups and learning about my home server usage patterns, this is the set of requirements that finds a balance between performance, efficiency
and silence.</p>
<h2 id="basics">
  <a class="heading-anchor" href="#basics">Basics<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>I recommend checking <a href="https://www.zimaboard.com/zimaboard/product">the product page</a> to see the exact specifications.
The configuration I bought was the 832 model: 8GB of RAM, 32GB of eMMC storage and a quad-core Intel Celeron N3450 CPU.
It&rsquo;s not the most powerful setup or even a recent one with the CPU being from 2016, but it&rsquo;s just powerful enough to fit
my needs.</p>
<p>This variant of the board costs 200 USD, but other configurations cost much less
than that, I just needed the extra memory to be on the safe side. If you don&rsquo;t
care about the noise and size aspect of home servers, then you can get a better
deal on the used market (<a href="https://www.servethehome.com/introducing-project-tinyminimicro-home-lab-revolution/">see the TinyMiniMicro project for inspiration)</a>,
but as you know by this point, I care about those aspects a lot.</p>
<h2 id="the-package">
  <a class="heading-anchor" href="#the-package">The package<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>What sets the Zimaboard apart from other single board computers is how polished the product feels.
Unlike a board like the Raspberry Pi, this one comes with a case and a cooling setup
already attached to it. I suspect that a similarily configured Raspberry Pi 4/5
with all the accessories added on top would result in a price that&rsquo;s quite
similar to the cost of a top-of-the-line Zimaboard.</p>
<p>The heatsink looks great and is practical at the same time.
Under the most torturous loads I could only see the CPU being around 72°C and due
to it being passively cooled it made absolutely no noise. With the case being
present, I do not have to worry about placing the board on my desk and scratching
the table or shorting something out.</p>









<figure class="center">
  <a href="/posts/2023/10/09/zimaboard/media/theboard.jpg">
    <img src="/posts/2023/10/09/zimaboard/media/theboard_hu_2cd89bb8686bd5dc.webp"
     width="600"
     height="800"
     loading="lazy"
     decoding="async"
     alt="Just plop it wherever.">

  </a>
  <figcaption class="center">Just plop it wherever.</figcaption>
</figure>

<p>The board does not seem to have a power button, but by default it&rsquo;s configured
to power on as soon as you connect the power supply, which is great if you&rsquo;re
going to use this as a home server.</p>
<p>The box that the board was shipped survived and overall I&rsquo;d say that the packaging
is good. The board comes with some stickers and a single SATA data+power cable.
The included power adapter comes with EU, US and UK plugs all included.</p>
<p>Shipping to Estonia was quite fast, taking just 10 days. The shipping costs were
18 USD.</p>









<figure class="center">
  <a href="/posts/2023/10/09/zimaboard/media/box.jpg">
    <img src="/posts/2023/10/09/zimaboard/media/box_hu_eb50fa4af959b977.webp"
     width="1067"
     height="800"
     loading="lazy"
     decoding="async"
     alt="The box did its job.">

  </a>
  <figcaption class="center">The box did its job.</figcaption>
</figure>

<h2 id="storage">
  <a class="heading-anchor" href="#storage">Storage<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>The included 32GB eMMC storage is fine for hosting your operating system. The
read speeds cap out at around 175 MB/s and the typical write speeds I observed
were around 50-100 MB/s. The storage is identified as <code>mmc-BJTD4R_0xc7d04e40</code> under
<code>/dev/disk/by-id/</code>, and searching online suggests that it&rsquo;s a Samsung chip.</p>
<p>Because this board offers two SATA ports, I also added a SATA Y-cable to my order
(4 USD) so that I can take my existing Samsung 870 QVO 4TB SATA drives and move
my home server setup to this board.</p>









<figure class="center">
  <a href="/posts/2023/10/09/zimaboard/media/ycable.jpg">
    <img src="/posts/2023/10/09/zimaboard/media/ycable_hu_1b434f16b568b5da.webp"
     width="600"
     height="800"
     loading="lazy"
     decoding="async"
     alt="SATA Y-cable in action.">

  </a>
  <figcaption class="center">SATA Y-cable in action.</figcaption>
</figure>

<p>Allegedly this cable can also be used to drive
two 3.5&quot; hard drives powered by the board itself according to <a href="https://shop.zimaboard.com/products/sata-y-cable-for-zimaboard-2-5-inch-hdd-3-5-inch-hdd-raid-free-nas-unraid">the shop page
for the Y-cable</a>, but I suspect that at that point you&rsquo;ll be pushing the limits of
the 12V/3A power adapter.</p>
<p>There is also a white drive activity LED
placed near the SATA power connector on the board. Perhaps not for everyone, but I
like the aesthetic and the sight of the server doing server things.</p>
<p>The performance of the SATA ports is what you would expect. When performing
read operations on both SSD-s I saw the maximum total transfer rates hover around
900-950MB/s, which is pretty close to the SATA III transfer speed limit.</p>
<p>There is no native way to mount the two SATA drives to the Zimaboard. The creators
of the board do sell a metal bracket, but it doesn&rsquo;t seem to integrate that well
to the board. However, <a href="https://www.printables.com/model/224057-zimaboard-dual-hdd-stand">there exists a 3D printable design that houses two
2.5&quot; drives, even 15mm ones</a>, and
that&rsquo;s how I ended up using a 3D printer for the first time in my life.
The print was done using a <a href="https://wiki.k-space.ee/en/utilities/3D-Printer">Voron v2 Afterburner printer hosted at k-space</a>
and it came out pretty well.</p>









<figure class="center">
  <a href="/posts/2023/10/09/zimaboard/media/3dprint-1.jpg">
    <img src="/posts/2023/10/09/zimaboard/media/3dprint-1_hu_1063ec1f0205a475.webp"
     width="600"
     height="800"
     loading="lazy"
     decoding="async"
     alt="Print in progress.">

  </a>
  <figcaption class="center">Print in progress.</figcaption>
</figure>










<figure class="center">
  <a href="/posts/2023/10/09/zimaboard/media/3dprint-2.jpg">
    <img src="/posts/2023/10/09/zimaboard/media/3dprint-2_hu_d701924b7455a796.webp"
     width="600"
     height="800"
     loading="lazy"
     decoding="async"
     alt="The final product">

  </a>
  <figcaption class="center">The final product</figcaption>
</figure>










<figure class="center">
  <a href="/posts/2023/10/09/zimaboard/media/3dprint-3.jpg">
    <img src="/posts/2023/10/09/zimaboard/media/3dprint-3_hu_824404626ee747d8.webp"
     width="600"
     height="800"
     loading="lazy"
     decoding="async"
     alt="Another angle.">

  </a>
  <figcaption class="center">Another angle.</figcaption>
</figure>










<figure class="center">
  <a href="/posts/2023/10/09/zimaboard/media/3dprint-4.jpg">
    <img src="/posts/2023/10/09/zimaboard/media/3dprint-4_hu_734e2439b5176454.webp"
     width="600"
     height="800"
     loading="lazy"
     decoding="async"
     alt="Some 3D printing related inconsistencies, but nothing serious.">

  </a>
  <figcaption class="center">Some 3D printing related inconsistencies, but nothing serious.</figcaption>
</figure>

<p>The SSD mounting holes were a bit finicky due
to slight printing errors, and during my first installation attempt I forgot to
put in the plastic middle layer of the case that&rsquo;s between the PCB and the stock
bottom cover, but other than that the installation was a breeze.</p>









<figure class="center">
  <a href="/posts/2023/10/09/zimaboard/media/board-backside.jpg">
    <img src="/posts/2023/10/09/zimaboard/media/board-backside_hu_df793b4541493c33.webp"
     width="600"
     height="800"
     loading="lazy"
     decoding="async"
     alt="Installation of the caddy requires removing the stock backplate and splitting it.">

  </a>
  <figcaption class="center">Installation of the caddy requires removing the stock backplate and splitting it.</figcaption>
</figure>










<figure class="center">
  <a href="/posts/2023/10/09/zimaboard/media/caddy-1.jpg">
    <img src="/posts/2023/10/09/zimaboard/media/caddy-1_hu_78d2b684b7f1572c.webp"
     width="1067"
     height="800"
     loading="lazy"
     decoding="async"
     alt="The finished result.">

  </a>
  <figcaption class="center">The finished result.</figcaption>
</figure>

<p>








<figure class="center">
  <a href="/posts/2023/10/09/zimaboard/media/caddy-2.jpg" aria-label="View full-size image">
    <img src="/posts/2023/10/09/zimaboard/media/caddy-2_hu_bb144d2c394a571f.webp"
     width="1067"
     height="800"
     loading="lazy"
     decoding="async"
     alt="">

  </a>
  
</figure>










<figure class="center">
  <a href="/posts/2023/10/09/zimaboard/media/caddy-3.jpg" aria-label="View full-size image">
    <img src="/posts/2023/10/09/zimaboard/media/caddy-3_hu_835bdd7977c2313d.webp"
     width="1067"
     height="800"
     loading="lazy"
     decoding="async"
     alt="">

  </a>
  
</figure>










<figure class="center">
  <a href="/posts/2023/10/09/zimaboard/media/caddy-4.jpg" aria-label="View full-size image">
    <img src="/posts/2023/10/09/zimaboard/media/caddy-4_hu_bcbdbc57030a3901.webp"
     width="600"
     height="800"
     loading="lazy"
     decoding="async"
     alt="">

  </a>
  
</figure>










<figure class="center">
  <a href="/posts/2023/10/09/zimaboard/media/caddy-5.jpg" aria-label="View full-size image">
    <img src="/posts/2023/10/09/zimaboard/media/caddy-5_hu_7ba9351ed37ad4e3.webp"
     width="600"
     height="800"
     loading="lazy"
     decoding="async"
     alt="">

  </a>
  
</figure>










<figure class="center">
  <a href="/posts/2023/10/09/zimaboard/media/caddy-6.jpg" aria-label="View full-size image">
    <img src="/posts/2023/10/09/zimaboard/media/caddy-6_hu_5a82ffd61f02dfe2.webp"
     width="600"
     height="800"
     loading="lazy"
     decoding="async"
     alt="">

  </a>
  
</figure>










<figure class="center">
  <a href="/posts/2023/10/09/zimaboard/media/caddy-7.jpg" aria-label="View full-size image">
    <img src="/posts/2023/10/09/zimaboard/media/caddy-7_hu_4e393891551319ac.webp"
     width="600"
     height="800"
     loading="lazy"
     decoding="async"
     alt="">

  </a>
  
</figure>
</p>
<p>The drives never hit above 64°C, which is absolutely okay for these SSD-s. I&rsquo;m not
sure how actual spinning hard drives might fare in this environment, but I don&rsquo;t
think that it&rsquo;s going to be that serious because 2.5&quot; hard drives should not
generate as much heat in the first place.</p>
<h2 id="power-consumption">
  <a class="heading-anchor" href="#power-consumption">Power consumption<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>What I love about this board is the power usage. At this point my home server
is not even the most power hungry component of my setup, that honor now goes
to the ISP-provided router/modem combo box that always draws at least 12W, even
when it&rsquo;s in bridge mode.</p>
<p>Here are my power usage measurements (measured with a simple power meter):</p>
<ul>
<li>idle: 2.5W</li>
<li>no drives attached, CPU stress test (<code>stress -c 4</code>): 9.0W</li>
<li>one Samsung 870 QVO 4TB SSD attached, CPU stress test: 13.2W</li>
<li>2 SSD-s attached, typical power draw in my setup (~10-40% CPU usage): ~8-9W</li>
<li>2 SSD-s attached, max load on SSD-s and CPU: ~14W</li>
</ul>
<p>The Zimaboard, ISP modem/router box, my TP-Link router/Wi-Fi AP and my CyberPower
UPS all together use at most around 34W, all combined. That&rsquo;s even less than
what my Dell monitor uses at reasonably low brightness levels!</p>
<p>These tests are not scientifically accurate, but they should give you an idea on what
power consumption numbers to expect when running this setup.</p>
<h2 id="performance">
  <a class="heading-anchor" href="#performance">Performance<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>I use a simple Prometheus Node Exporter + Grafana setup to view how much resources
my various servers use. My home server has lately either been an <a href="/posts/2022/01/17/asrock-x300-future-of-desktops/">ASRock Deskmini X300 based setup</a> or
an <a href="/posts/2022/05/10/thinkpad-as-a-home-server/">old ThinkPad T430</a>, and something that both had in common was that the CPU usage was
generally very low, mostly at or below the 10% mark. There would be bursty loads
from time to time and backup processes running that bump that up, but not significantly.</p>









<figure class="center">
  <a href="/posts/2023/10/09/zimaboard/media/prom-old.png">
    <img src="/posts/2023/10/09/zimaboard/media/prom-old_hu_708f14b1eed98d02.webp"
     width="1280"
     height="674"
     loading="lazy"
     decoding="async"
     alt="Typical CPU performance on a ThinkPad T430 acting as a home server.">

  </a>
  <figcaption class="center">Typical CPU performance on a ThinkPad T430 acting as a home server.</figcaption>
</figure>

<p>Memory usage of my setup was also quite low, with all my services and containers
fitting into 2GB during typical usage. With this information and some CPU performance
comparisons done, I knew that the Zimaboard will likely be able to handle my home
server tasks.</p>
<p>This board is not very powerful, but if you mainly rely on containerized workloads
and can rely on Intel QuickSync to accelerate media transcodes, then you&rsquo;ll be
just fine.</p>









<figure class="center">
  <a href="/posts/2023/10/09/zimaboard/media/prom-new.png">
    <img src="/posts/2023/10/09/zimaboard/media/prom-new_hu_85b12aa5a7e8f9b7.webp"
     width="1280"
     height="674"
     loading="lazy"
     decoding="async"
     alt="Zimaboard CPU usage, which includes migrating filesystems, creating new multi-TB
backups from scratch and a lot of Jellyfin playback and GPU-accelerated transcoding.
Pretty much the worst case scenario for this board.">

  </a>
  <figcaption class="center">Zimaboard CPU usage, which includes migrating filesystems, creating new multi-TB
backups from scratch and a lot of Jellyfin playback and GPU-accelerated transcoding.
Pretty much the worst case scenario for this board.</figcaption>
</figure>

<p>I was actually impressed with how well the GPU-accelerated transcode
worked on this machine once you set everything up properly.
If you&rsquo;re running Linux and Jellyfin,
run <code>vainfo</code> to get a list of supported codecs and make sure that you have hardware
decoding selected for those in Jellyfin settings. Also enable hardware encoding.
I checked with <code>intel_gpu_top</code> to see if work was offloaded to the GPU and saw
activity there, which means that hardware acceleration for Jellyfin worked out great!
<a href="https://jellyfin.org/docs/general/administration/hardware-acceleration/">Check the Jellyfin hardware acceleration for more details on other requirements
that have to be met for all of this to work.</a></p>









<figure class="center">
  <a href="/posts/2023/10/09/zimaboard/media/jellyfin-qs-conf.png">
    <img src="/posts/2023/10/09/zimaboard/media/jellyfin-qs-conf_hu_6c1ba97b1f638294.webp"
     width="715"
     height="800"
     loading="lazy"
     decoding="async"
     alt="The Jellyfin QuickSync hardware acceleration config that works on my Zimaboard.
May not be 100% correct but so far have not encountered issues.">

  </a>
  <figcaption class="center">The Jellyfin QuickSync hardware acceleration config that works on my Zimaboard.
May not be 100% correct but so far have not encountered issues.</figcaption>
</figure>










<figure class="center">
  <a href="/posts/2023/10/09/zimaboard/media/intel-gpu-top.png">
    <img src="/posts/2023/10/09/zimaboard/media/intel-gpu-top_hu_c612456e5219acc0.webp"
     width="1280"
     height="204"
     loading="lazy"
     decoding="async"
     alt="intel_gpu_top during Jellyfin transcoded media playback. ">

  </a>
  <figcaption class="center">intel_gpu_top during Jellyfin transcoded media playback. </figcaption>
</figure>

<h2 id="caveats">
  <a class="heading-anchor" href="#caveats">Caveats<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>The Zimaboard does ship with a Linux-based OS called CasaOS. However, I had no
intention of using it as I know what my requirements are and my infrastructure
is already decently documented and set up via Ansible, which is why I can&rsquo;t say
how good that experience is. I also did not test Windows 10 or 11.</p>
<p>During testing, I noticed that the USB 3 ports can act a bit weird. The Fedora
Server USB stick would not boot properly if connected to one of the USB ports,
and when doing other tests with external USB storage I noticed hiccups from time to time.
Not sure what might be the cause, but I&rsquo;m writing it down nevertheless. It&rsquo;s not
a dealbreaker for me luckily since I don&rsquo;t rely much on the USB ports in typical use anyway.</p>
<p>I did not test the PCI Express port, simply because I don&rsquo;t need it, yet. It&rsquo;s
a great addition, though, and opens up plenty of modding capabilities in the
future.</p>
<h2 id="fedora-server-and-btrfs">
  <a class="heading-anchor" href="#fedora-server-and-btrfs">Fedora Server and btrfs<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>The Zimaboard gave me an opportunity to start fresh with my home server.</p>
<p>I made a leap: I&rsquo;ve ditched ZFS and am now running
Fedora Server with my storage being on a btrfs RAID1 setup, snapshotted
and backed up using <a href="/posts/2022/07/09/btrbk-is-awesome/">btrbk</a>.
It was a bit tricky to migrate and set everything
up regarding backups and snapshotting, but I got it working.</p>
<p>ZFS is great, but it has always felt like an unwanted guest in the Linux ecosystem.
The kernel developers don&rsquo;t care much for maintaining compatibility with ZFS since
it&rsquo;s not in the kernel due to licensing issues, and Ubuntu has been one of the few
distros that actually ships a kernel that includes ZFS built in. I didn&rsquo;t want
to be tied to Ubuntu forever, especially because of how they try to make <code>snap</code>
a thing. ZFS DKMS builds are generally okay on distros like Debian, but on
others you might find yourself not being able to access your data after a reboot
because of a kernel update.</p>
<p>btrfs has had some issues in the past, especially with the RAID5/6 setup, but
in my single and dual disk setups it has been solid for years, except for that one time around
2018-2019 when I ran btrfs RAID1 over USB storage. To be fair to btrfs, that
was a pretty stupid setup.</p>
<p>Before committing
to btrfs, I used two USB sticks to create a RAID1 setup and created real torture test scenarios.
Tests looked something like this:</p>
<ul>
<li>write a file to the filesystem</li>
<li>use <code>md5sum</code> to calculate a hash of it for verification purposes</li>
<li>completely wipe one USB drive with <code>dd</code></li>
<li>run <code>md5sum</code> to calculate the hash again (it matched every time)</li>
<li>run <code>btrfs scrub</code> on the filesystem to fix all errors</li>
<li>rinse and repeat with variations to this setup</li>
</ul>
<p>After doing all that, I was quite confident that this was going to work.</p>
<p>One thing to note with <code>btrfs</code>: if you&rsquo;re running any type of multi-disk and
redundant setup like RAID1 or RAID10, then make sure to include the mount option
<code>degraded</code> in <code>/etc/fstab</code> so that you can still mount your filesystem if one or
more of your drives fail. If you lose too many drives then it&rsquo;s still probably going to fail to boot.</p>
<p>Here&rsquo;s my <code>/etc/fstab</code> setup to serve as an example:</p>
<pre tabindex="0"><code>LABEL=turbo /turbo      btrfs subvol=turbo,compress-force=zstd:1,ssd,degraded,nofail            0 0
</code></pre><p>When doing the migration I kept all the paths the same, and each ZFS dataset
was recreated using <code>btrfs</code> subvolumes, which is why this filesystem is mounted on a top-level folder.</p>
<h2 id="alternatives">
  <a class="heading-anchor" href="#alternatives">Alternatives<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>My notes for the next dream home server setup included a few candidates:</p>
<ul>
<li>
<p>the Zimaboard</p>
</li>
<li>
<p><a href="https://www.asustor.com/en/product?p_id=79">Asustor Flashstor 6</a> or <a href="https://www.asustor.com/en/product?p_id=80">Flashstor 12</a></p>
</li>
<li>
<p>a TinyMiniMicro style machine with at least two NVMe SSD slots</p>
</li>
</ul>
<p>The first two fall nicely into my requirements for the dream home server. I picked
the Zimaboard mainly because it&rsquo;s much cheaper and I was already running two SATA SSD-s
for my home server storage, so migrating would be really easy and I would not
have to buy any new drives.</p>
<p>If large capacity SATA SSD-s start becoming less common and NVMe SSD-s become
even cheaper than they already are, then I&rsquo;ll have to look into something like a Flashstor.</p>
<h2 id="conclusion">
  <a class="heading-anchor" href="#conclusion">Conclusion<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>Overall, I&rsquo;m very happy with this purchase. The performance is just enough for
my services to work reasonably fast, the board uses very little power and it&rsquo;s
silent, and it looks good on my wall.</p>









<figure class="center">
  <a href="/posts/2023/10/09/zimaboard/media/wallsetup.jpg">
    <img src="/posts/2023/10/09/zimaboard/media/wallsetup_hu_263feac6bc54aaa1.webp"
     width="600"
     height="800"
     loading="lazy"
     decoding="async"
     alt="Oh it&#39;s a setup it&#39;s a setup it&#39;s a setup 🎶">

  </a>
  <figcaption class="center">Oh it&#39;s a setup it&#39;s a setup it&#39;s a setup 🎶</figcaption>
</figure>










<figure class="center">
  <a href="/posts/2023/10/09/zimaboard/media/cablegore.jpg">
    <img src="/posts/2023/10/09/zimaboard/media/cablegore_hu_75af033ad64d88f6.webp"
     width="1067"
     height="800"
     loading="lazy"
     decoding="async"
     alt="Managing the coax cable like this feels so wrong, and yet it works fine.">

  </a>
  <figcaption class="center">Managing the coax cable like this feels so wrong, and yet it works fine.</figcaption>
</figure>

<p>My setup is also quite flexible, so in case I need more resources, I can get
more Zimaboards and make them serve different purposes. However, it&rsquo;s more likely
that I&rsquo;m going to discover a new toy to experiment and play with by the time
I run out of resources on this one.</p>
<h2 id="2024-08-20-update">
  <a class="heading-anchor" href="#2024-08-20-update">2024-08-20 update<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>I ran the Zimaboard for over half a year, but decided to switch back to
the <a href="/posts/2022/01/17/asrock-x300-future-of-desktops/">ASRock Deskmini X300.</a></p>
<p>I still love the low power consumption and the expandability, but I ended up putting more load on the system than I
initially anticipated CPU-wise (running over 20 different Docker containers, some heavy). Should&rsquo;ve guessed that it would happen eventually.</p>
<p>If it came with an embedded AMD Ryzen APU, then that would probably change things up quite a bit.</p>
<p>Zimaboard: still the closest thing to my dream home server, but it&rsquo;s that last little bit of performance being missing
that gets me. If your needs are moderate or low, then it&rsquo;s still a fantastic option, if the price is right.</p>
<p>My eyes are now on
the <a href="https://nascompares.com/2024/06/10/the-asustor-flashstor-gen2-performance-and-pci-lanes/">Asustor Flashstor Gen 2</a>
machines.
Up to 12 NVMe SSD-s plus 4 cores of AMD Ryzen goodness sounds too good to be true. Let&rsquo;s see what the reviews will say
once it&rsquo;s out.</p>
]]></content:encoded></item><item><title>My experience at the k-space hackerspace hackathon</title><link>https://ounapuu.ee/posts/2023/08/03/k-space-hackathon/</link><pubDate>Thu, 03 Aug 2023 06:00:00 +0300</pubDate><author>ihavesomethoughtsonyourblog@ounapuu.ee (Herman Õunapuu)</author><guid>https://ounapuu.ee/posts/2023/08/03/k-space-hackathon/</guid><description>I went to the hackathon, built some useful stuff and only did stupid things about 4 times!</description><content:encoded><![CDATA[<img src="https://ounapuu.ee/posts/2023/08/03/k-space-hackathon/media/cover_hu_417372bb9bfe3c4.jpg" width="1200" height="630" alt="My experience at the k-space hackerspace hackathon" /><p><a href="https://www.k-space.ee/">k-space</a> is a hackerspace in Tallinn, Estonia, and they organized
a hackathon recently. Unlike in most hackathons, in this one you could whatever you like with no
expectations about building a business or coming up with an MVP, just come on down to the space and
start working on your passion projects!</p>
<p>I had some ideas on what I could do, but a few of them would have required access to workshop tools,
for which I did not have a key. I could always get one, but was too lazy to bother with it. I looked at
<a href="https://wiki.k-space.ee/en/hackathon/2023">the list of ideas that had been written down by other hackerspace members</a> and picked
the one marked as <code>[easy]</code>:  <em>Wire up electronic lock for workshop</em>.</p>
<p>If I achieve that goal, then I don&rsquo;t have to worry about getting another key, and I could also get access to all
the workshop tooling! And since it was marked as easy, I figured that I could do it and have some time
left over for playing around with things like the laser cutter.</p>
<h2 id="impressions">
  <a class="heading-anchor" href="#impressions">Impressions<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>Before I get to the technical part, I&rsquo;d like to say a few words about the hackathon and the organization itself.</p>
<p>The highlight of the hackathon was the immense sense of accomplishment that I felt. I work as a software
developer at my day job, which often involves dealing with incidents, migrating services from virtual machines
to Kubernetes, and sometimes from Kubernetes to Kubernetes, and anything else that comes my way.
The issue with most software teams is that the products that you build and maintain are often disconnected
from the real world. You don&rsquo;t see the physical impact of the work that you do, and that can leave you
feeling empty. Sure, you spent days switching a service to Kubernetes, but you don&rsquo;t feel like you did anything at all.</p>
<p>During this hackathon I had the opportunity to build things with my own hands, and the door controller software doing
its thing resulted in real-life actions. You swipe the card, it beeps, and you can hear the electronic lock being
opened. That, and the opportunity to work on a project involving a Raspberry Pi and mounting it so neatly was very
satisfying.</p>









<figure class="center">
  <a href="/posts/2023/08/03/k-space-hackathon/media/image0.jpg">
    <img src="/posts/2023/08/03/k-space-hackathon/media/image0_hu_61bd02bbbae6985d.webp"
     width="1200"
     height="800"
     loading="lazy"
     decoding="async"
     alt="Software developer at work. Photo by Arti Zirk.">

  </a>
  <figcaption class="center">Software developer at work. Photo by Arti Zirk.</figcaption>
</figure>

<p>The hackathon crowd itself was not that big, hovering around 15 or so people. We even had guests from Germany who were
really helpful, great to talk with and they provided their expertise to help out wherever possible. I loved how the
collaboration worked for the rewrite of the door controller software to the Go programming language. One guy knew all about
the original software and how it works but was just learning Go, and the other guy was just visiting the space and had
extensive Go experience.</p>
<p>Although this post is mainly about my own experience and the stuff that I worked on, there were plenty of other
cool projects going on during the hackathon as well. One that I really liked due to how practical it was is <a href="https://wiki.k-space.ee/en/utilities/kegerator">&ldquo;the kegerator&rdquo;</a>
that provided cold carbonated mate tea throughout the hackathon. It lives in an old fridge and I think the execution
of it was really neat! <a href="https://youtu.be/x4Qh9MTCzQo">Here&rsquo;s the livestream recording where other projects are also covered.</a></p>
<p>There were plenty of refreshments available and I took full advantage of that because if there&rsquo;s one thing that can get
my brain working on overdrive, it&rsquo;s copious amounts of sugar and caffeinated beverages. Oh, and we got pancakes as well!
Peetri Pizza really blew it with the pizzas though, never seen pizzas that are this sad.</p>









<figure class="center">
  <a href="/posts/2023/08/03/k-space-hackathon/media/image1.jpg">
    <img src="/posts/2023/08/03/k-space-hackathon/media/image1_hu_d56a9b50ed3dd9d7.webp"
     width="601"
     height="800"
     loading="lazy"
     decoding="async"
     alt="Vibes on day 0.">

  </a>
  <figcaption class="center">Vibes on day 0.</figcaption>
</figure>

<p>There were some small issues, such as the streaming setup crapping out at the last day during the part where we presented
our work, but overall I was happy with how the hackathon turned out.</p>
<p>For future hackathons we probably need to do a bit more marketing and think about the dates more so that we can get
more enthusiasts on board. Having our German friends around really added a lot to the event and I would like to see
more knowledge-sharing between communities in the future.</p>
<h2 id="build-log">
  <a class="heading-anchor" href="#build-log">Build log<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>Here&rsquo;s a rundown of what I did during the hackathon.</p>
<p><a href="https://youtu.be/x4Qh9MTCzQo?t=985">There&rsquo;s also a video where I talk about my hackathon work!</a></p>
<p>Whenever you see the name <a href="https://zirk.me">Arti</a>, then that refers to my good friend who helped out a lot during the hackathon.</p>
<h3 id="day-0">
  <a class="heading-anchor" href="#day-0">Day 0<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h3>
<p>The hackathon began on 27th of July at 18:00.</p>
<p><a href="https://www.youtube.com/watch?v=eZLQK60Cj3c">Everyone presented their plans</a> and then the work begun.</p>
<p>I used the first evening to put together a rough plan and figure out what needs to be done. In short, the
plan was like this:</p>
<ul>
<li>buy some quick splice terminals</li>
<li>assemble the Raspberry Pi with the custom HAT that is used to interact with the card reader and electronic door lock</li>
<li>install the card reader on the door</li>
<li>run the networking and power cables</li>
<li>connect all the cables to the Pi</li>
<li>set up the card reader software</li>
<li>test in production</li>
</ul>
<p>After taking some pictures of the door lock test setup that another participant assembled, I decided to go and rest for what&rsquo;s
to come.</p>









<figure class="center">
  <a href="/posts/2023/08/03/k-space-hackathon/media/image3.jpg">
    <img src="/posts/2023/08/03/k-space-hackathon/media/image3_hu_e04dcad5c3a93216.webp"
     width="1200"
     height="800"
     loading="lazy"
     decoding="async"
     alt="Door controller test setup. Photo by Arti Zirk.">

  </a>
  <figcaption class="center">Door controller test setup. Photo by Arti Zirk.</figcaption>
</figure>

<h3 id="day-1">
  <a class="heading-anchor" href="#day-1">Day 1<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h3>
<p>This is the part where all the action started.</p>
<p>I began by taking stuff apart.</p>









<figure class="center">
  <a href="/posts/2023/08/03/k-space-hackathon/media/image4.jpg" aria-label="View full-size image">
    <img src="/posts/2023/08/03/k-space-hackathon/media/image4_hu_1a64de43f3ae9edb.webp"
     width="600"
     height="800"
     loading="lazy"
     decoding="async"
     alt="">

  </a>
  
</figure>

<p>After making some additional holes I ran the cable that connects to the electronic door switch. That was easy enough.</p>
<p>Then I began thinking about where the Raspberry Pi door controller setup would go. The workshop is a very
dusty place and it would probably need some kind of protection from it. The first idea was to custom design
a 3D printed case or customise an existing design, but after a short discussion and brainstorming we realized
that getting a plastic box big enough to house the Pi and all the wiring makes more sense.</p>
<p>Me and Arti set off to find something like that in the hackerspace. After going through lots of boxes and shelves,
we stumbled upon two metal boxes. Those boxes used to house some kind of security equipment and had inside
circuitry that converts 220V AC to 13.6V DC, which was ideal for our use case. It also had leads to connect
an UPS battery, which was even better!</p>









<figure class="center">
  <a href="/posts/2023/08/03/k-space-hackathon/media/image5.jpg" aria-label="View full-size image">
    <img src="/posts/2023/08/03/k-space-hackathon/media/image5_hu_945147e72f8db4e3.webp"
     width="600"
     height="800"
     loading="lazy"
     decoding="async"
     alt="">

  </a>
  
</figure>

<p>Oh, and we also found this fun little thing.</p>









<figure class="center">
  <a href="/posts/2023/08/03/k-space-hackathon/media/image6.jpg" aria-label="View full-size image">
    <img src="/posts/2023/08/03/k-space-hackathon/media/image6_hu_9bd0f755b43c90a5.webp"
     width="600"
     height="800"
     loading="lazy"
     decoding="async"
     alt="">

  </a>
  
</figure>

<p>Anyway, I went ahead and drilled some mounting holes for the Pi. We had M2.5 nylon screws and standoffs available
at the space, and with some assistance from Arti I learned about the wonders of countersink drill bits.</p>
<p>I really liked how the mounted Pi looked. I&rsquo;ve seen a ton of projects on YouTube and elsewhere with Raspberry Pi-s
being modded and mounted in all sorts of ways, but doing it myself felt really good, especially since I
was reusing an old metal box that had no other purpose.</p>









<figure class="center">
  <a href="/posts/2023/08/03/k-space-hackathon/media/image7.jpg" aria-label="View full-size image">
    <img src="/posts/2023/08/03/k-space-hackathon/media/image7_hu_bcd67fde930b4011.webp"
     width="1067"
     height="800"
     loading="lazy"
     decoding="async"
     alt="">

  </a>
  
</figure>

<p>I set up the microSD card with Raspberry Pi OS and figured that I could find it on the k-space network. However,
I then remembered that the internal network was <code>/16</code>, which made the process much longer. I did not have access
to the network switch, but I did end up getting acces to <em>a</em> Pi, it just wasn&rsquo;t the one I just set up. That was a
fun discovery.</p>
<p>I decided to go with the easy route and connect the Pi to an actual monitor and keyboard. That process ended
up being faster than scanning the network for Pi-s.</p>









<figure class="center">
  <a href="/posts/2023/08/03/k-space-hackathon/media/image8.jpg" aria-label="View full-size image">
    <img src="/posts/2023/08/03/k-space-hackathon/media/image8_hu_e71431422df0ef61.webp"
     width="1067"
     height="800"
     loading="lazy"
     decoding="async"
     alt="">

  </a>
  
</figure>

<p>I also added an UPS battery to the setup. It barely fit the enclosure and it had to be raised a bit so that
the lid on the box would close properly. But it worked out really well!</p>









<figure class="center">
  <a href="/posts/2023/08/03/k-space-hackathon/media/image9.jpg" aria-label="View full-size image">
    <img src="/posts/2023/08/03/k-space-hackathon/media/image9_hu_abe30aa12543d233.webp"
     width="600"
     height="800"
     loading="lazy"
     decoding="async"
     alt="">

  </a>
  
</figure>

<p>By the end of the day we also had the card reader installed on the door. We contemplated putting the reader on the other
side of the glass because the reader can read cards up to 9cm away, and quick tests showed that it would actually work,
however we had concerns about mounting it that way, and it would look a bit too janky even by k-space standards.</p>









<figure class="center">
  <a href="/posts/2023/08/03/k-space-hackathon/media/image10.jpg" aria-label="View full-size image">
    <img src="/posts/2023/08/03/k-space-hackathon/media/image10_hu_932489d20a35046e.webp"
     width="600"
     height="800"
     loading="lazy"
     decoding="async"
     alt="">

  </a>
  
</figure>

<h3 id="day-2">
  <a class="heading-anchor" href="#day-2">Day 2<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h3>
<p>Day 2 started with me trying to figure out how to run the cables. Making a suitably sized CAT5e cable was easy and
it worked on the first try and drilling a hole through plywood was also simple, but when trying to figure out how to
run the power I ran into a bit of trouble. There was very little room in the junction point that I intended to use, and
when my brain shorted out I asked Arti for some help (again). He figured out a way to run the additional cable while not
interfering with the power cables that ran to the light fixtures.</p>









<figure class="center">
  <a href="/posts/2023/08/03/k-space-hackathon/media/image11.jpg">
    <img src="/posts/2023/08/03/k-space-hackathon/media/image11_hu_54326914815c4fce.webp"
     width="600"
     height="800"
     loading="lazy"
     decoding="async"
     alt="In hindsight, that first aid kit didn&#39;t really have anything that would help with an electricity-related accident.">

  </a>
  <figcaption class="center">In hindsight, that first aid kit didn&#39;t really have anything that would help with an electricity-related accident.</figcaption>
</figure>

<p>Due to the way we decided to run the card reader cables, we had to extend the cable that comes from the card reader.
For that I used a CAT5e cable and some quick splices. I later learned that using your thumb power alone is not enough to
splice cables, you actually need to push them all the way in with plyers. Once that was figured out, me and Arti
installed a very professional looking cable cover involving a random piece of plastic tube, zipties and screws.
Not that I needed the help, Arti was just working on porting some Python code to Golang and wanted a break. He ended
up making a lot of breaks, not sure what that says about the learning curve of Golang.</p>









<figure class="center">
  <a href="/posts/2023/08/03/k-space-hackathon/media/image12.jpg" aria-label="View full-size image">
    <img src="/posts/2023/08/03/k-space-hackathon/media/image12_hu_f41214ba834d1d6e.webp"
     width="600"
     height="800"
     loading="lazy"
     decoding="async"
     alt="">

  </a>
  
</figure>

<p>Now came the difficult part. I had to wire up everything to the Raspberry Pi without breaking anything. I had the photos
I took on day 0, but in hindsight they were not that great since I had trouble figuring out what went where. Luckily
another door controller in the space had a similar setup and I could use that as a reference point.</p>









<figure class="center">
  <a href="/posts/2023/08/03/k-space-hackathon/media/image13.jpg" aria-label="View full-size image">
    <img src="/posts/2023/08/03/k-space-hackathon/media/image13_hu_d3ba65c2fc38a4d6.webp"
     width="600"
     height="800"
     loading="lazy"
     decoding="async"
     alt="">

  </a>
  
</figure>

<p>The Raspberry Pi HAT gets 12V input power, some of that is passed to the door controller, and then we have two leads
that are connected to both the door controller and the electronic lock. If someone swipes their card and they have access to
that particular door, the card reader light
goes green and 12V is applied to the electronic door lock, making it open it. There&rsquo;s software that controls it, but
I did not have to worry about that too much because two other hackathon participants were working on that.</p>
<p>I had Arti check the cabling before the initial test and after a hesitant go-ahead from him we powered it on. The Pi
powered on, but the card reader was not doing anything. It was supposed to do a few beeps and show a red light. Uh-oh.
That&rsquo;s when Arti reviewed the quick splices that I used and pointed out that they were not pushed all the way in. After
using brute force (pliers), we powered it on again and it worked!</p>
<p>The rest of the evening was spent testing out the card reader software that was being ported. That revealed a few issues,
but <a href="/posts/2023/08/03/k-space-hackathon/media/dooropen.mov">we did get a successful door opening!</a></p>
<p>At this point I was very happy and I think half the hackerspace heard that.</p>
<h3 id="day-3">
  <a class="heading-anchor" href="#day-3">Day 3<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h3>
<p>At this point I was quite tired, but I felt really accomplished. I assembled the setup without burning everything down,
and I only shorted out the UPS battery once after absent-mindedly connecting the same alligator clip to both power
leads. Whoops.</p>
<p>I spent that half-day cleaning everything up and mounting the power and networking cables to the wall. I also labeled
the box so that we know what that mysterious white box is and where it gets its power.</p>
<p>At 14:00 the hackathon timer ran to zero and we were wondering what would happen with the countdown. Well&hellip;</p>









<figure class="center">
  <a href="/posts/2023/08/03/k-space-hackathon/media/image14.jpg" aria-label="View full-size image">
    <img src="/posts/2023/08/03/k-space-hackathon/media/image14_hu_a2d06791217a9388.webp"
     width="1067"
     height="800"
     loading="lazy"
     decoding="async"
     alt="">

  </a>
  
</figure>

<p>I presented my work, listened to what others were up to, and then we got some creative awards. Arti, the guy working
on the Golang port of the door controller software, got &ldquo;K-SPACE Certified Go Developer&rdquo;, and I am now a &ldquo;K-SPACE
Certified Licensed Electrician&rdquo;. Whoo!</p>









<figure class="center">
  <a href="/posts/2023/08/03/k-space-hackathon/media/image15.jpg" aria-label="View full-size image">
    <img src="/posts/2023/08/03/k-space-hackathon/media/image15_hu_d3effbeb939ea057.webp"
     width="600"
     height="800"
     loading="lazy"
     decoding="async"
     alt="">

  </a>
  
</figure>

<p>I&rsquo;d like to thank everyone who organized the event, and Arti Zirk for helping out with the project on many occasions!</p>
<p>That was pretty much it!</p>









<figure class="center">
  <a href="/posts/2023/08/03/k-space-hackathon/media/image16.jpg">
    <img src="/posts/2023/08/03/k-space-hackathon/media/image16_hu_ff471a16a5d6d66f.webp"
     width="1200"
     height="800"
     loading="lazy"
     decoding="async"
     alt="Left: happy hackathon participant. Right: the guy responsible for organizing it. Photo by Arti Zirk.">

  </a>
  <figcaption class="center">Left: happy hackathon participant. Right: the guy responsible for organizing it. Photo by Arti Zirk.</figcaption>
</figure>

]]></content:encoded></item><item><title>LattePanda V1 - my experience with a Raspberry Pi alternative</title><link>https://ounapuu.ee/posts/2023/02/28/lattepanda-v1/</link><pubDate>Tue, 28 Feb 2023 09:00:00 +0200</pubDate><author>ihavesomethoughtsonyourblog@ounapuu.ee (Herman Õunapuu)</author><guid>https://ounapuu.ee/posts/2023/02/28/lattepanda-v1/</guid><description>I got a LattePanda V1 and gave it a go as a Raspberry Pi replacement for my self-hosting setup. Here's how it went.</description><content:encoded><![CDATA[<img src="https://ounapuu.ee/posts/2023/02/28/lattepanda-v1/media/cover_hu_d0bf1305a5f9620b.jpg" width="1200" height="630" alt="LattePanda V1 - my experience with a Raspberry Pi alternative" /><p>As with many homelab experiments around 2022/2023, it all started with Raspberry Pi-s
being either out of stock or absurdly overpriced.</p>
<p>I once noticed a listing for a <a href="https://www.lattepanda.com/lattepanda-v1">LattePanda V1</a> on a local auction site.
The price was reasonable at 45 EUR, and after I looked at the specifications, I
had to get one to play around with.</p>
<p>The auction site usually sells used items, but this LattePanda V1 was brand new
in box, which surprised me. I got the 2GB RAM/32GB eMMC option.</p>
<p>I put the LattePanda through its paces, and here&rsquo;s what I learned.</p>
<p>Please note that my use cases are more on the software side, I did not try out
the hardware capabilities that SBC-s are also associated with (GPIO, camera/display
ports etc).</p>
<h2 id="the-hardware">
  <a class="heading-anchor" href="#the-hardware">The hardware<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>What makes the LattePanda V1 special is that it&rsquo;s based off of an x86 CPU.
Mine came with an <a href="https://ark.intel.com/content/www/us/en/ark/products/93361/intel-atom-x5z8350-processor-2m-cache-up-to-1-92-ghz.html">Intel Atom x5-Z8350</a>.
4 cores, not very fast ones, but similar or better to what you&rsquo;d find in a
Raspberry Pi 4. Most single-board computers usually come with an ARM-based CPU.</p>
<p>The board behaves like any normal PC. You power it on, you see the LattePanda
logo, and the OS just starts up. Smashing the &ldquo;Delete&rdquo; key during the boot
will direct you to the UEFI settings. Since this board is marketed towards
the technical crowd, it has so many settings that you can play with.
Definitely more than what I&rsquo;d know to do with.</p>
<p>The board comes with Windows 10 preinstalled. I booted it up and gave it a go,
and it was slow as molasses while it downloaded the latest updates. At one
point I reinstalled Windows 10 and ran into issues. It &ldquo;works&rdquo;, but I had trouble
getting any Intel GPU drivers installed on it, which rendered it almost useless
for any media playback use case that I could have used it for.</p>
<p>The port selection is okay. It comes with 100 Mbit/s Ethernet, one USB 3.0 port
and two USB 2.0 ports. I could get around 350 MB/s out of the USB 3 port with
an external SSD, and the USB 2 ports pulled anywhere between 15-40 MB/s,
depending on my luck. If you fancy a gigabit connection, then an USB-to-Ethernet
adapter might do the trick.</p>
<p>Adding one external HDD or SSD over USB is okay and works well, but after
adding a second one I noticed issues with either one of the disks not receiving
enough power. If you intend to use the LattePanda V1 as the brains for a cheap
NAS, then use drives that are powered externally.</p>
<p>The eMMC storage on the board is decent. Regarding performance it&rsquo;s somewhere
between a hard drive and a proper SSD, and the sequential read speeds max out
around 150 MB/s. My main concern with it is the durability. The eMMC chip is probably hidden
behind the metal shielding on the board and replacing it (if that is even
possible) might turn out to be tricky. <code>ls -lah /dev/disk/by-id/</code> lists the
eMMC chip as <code>mmc-DA4032</code>, which a little bit of Googling refers to it being a
SanDisk chip.</p>
<p>The microSD card port works, but either booting from the microSD card is not
possible or the board was a bit temperamental when I gave it a go with Ubuntu Server 22.04.</p>
<p>The board runs hot in its barebones configuration, any decent load over a longer time period
will result in the CPU throttling itself. I recommend rigging up a metal
heat sink to the bottom of the board to avoid throttling and stability issues
under very high load. A thermal pad, a piece of metal, and a bunch of zip ties
will do wonders.</p>









<figure class="center">
  <a href="/posts/2023/02/28/lattepanda-v1/media/image-1.jpg">
    <img src="/posts/2023/02/28/lattepanda-v1/media/image-1_hu_e1f7f36d88fce326.webp"
     width="1067"
     height="800"
     loading="lazy"
     decoding="async"
     alt="Do not look at the bend.">

  </a>
  <figcaption class="center">Do not look at the bend.</figcaption>
</figure>

<h2 id="the-linux-experience">
  <a class="heading-anchor" href="#the-linux-experience">The Linux experience<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>When experimenting with Linux, I found a couple of annoyances. The LattePanda V1
seems to have a display connector on board. However, in Linux it turned out to
be an annoyance as the system always presented a 1024x768 display being
connected to the system. Booting into a Fedora Linux liveUSB environment will
lead you to staring a blank view with only the wallpaper present.
Playing with settings in UEFI did not lead to any improvements. What works is
<a href="https://unix.stackexchange.com/a/526619">adding a kernel parameter</a>:
<code>video=DSI-1:d</code>. With Fedora Linux, if you apply this fix in GRUB when first
booting into the liveUSB environment, it will persist after the installation
is done.</p>
<p>Once I had Fedora Linux booted up, I did not have a good time. The display
flickered when I dragged the mouse near the edges and the performance was awful.
It didn&rsquo;t take long for the desktop session to crash.</p>
<p>One of the main reasons I wanted to experiment with this setup was the low power
usage of this board. The LattePanda V1 idles at around 3 watts, and under a high
CPU load generated with <code>stress -c 4</code> I could get it to 5-6 watts. This made it
a great candidate for running this website and Wireguard VPN 24/7 at home.
I ended up installing Ubuntu Server 22.04 on it and actually ran this website
off of it for about a week or so.</p>
<p>The reason I stopped using the LattePanda V1 for that purpose was the
performance. The 100 Mbit/s Ethernet wasn&rsquo;t a disaster, but it did set limits
to how much traffic I could push through the board. What made me reconsider was
the CPU performance. Simply put: SSL encryption speeds were about 5-10x slower
than on my ThinkPad T430 that ran as a server before.</p>
<p>My performance testing wasn&rsquo;t scientific or anything, but I did run simple tests.
One of the involved running <code>curl</code> against resources, such as an image on my
blog, in an infinite loop and over multiple threads. The ThinkPad T430 peaked at
around 650 Mbit/s of network bandwidth while the LattePanda V1 struggled at
around 60 Mbit/s.</p>
<p>After looking for some other benchmarking options that I could set up really
quickly, I also gave <a href="https://serverfault.com/a/160807">ApacheBenchmark a go</a>.
This more-or-less confirmed my findings and the requests per second results
are the following:</p>
<ul>
<li>ThinkPad T430: 301.72</li>
<li>LattePanda V1: 55.86</li>
</ul>









<figure class="center">
  <a href="/posts/2023/02/28/lattepanda-v1/media/bench-T430.png">
    <img src="/posts/2023/02/28/lattepanda-v1/media/bench-T430_hu_558c4a4c431b3448.webp"
     width="626"
     height="733"
     loading="lazy"
     decoding="async"
     alt="ApacheBenchmark results for the ThinkPad T430.">

  </a>
  <figcaption class="center">ApacheBenchmark results for the ThinkPad T430.</figcaption>
</figure>










<figure class="center">
  <a href="/posts/2023/02/28/lattepanda-v1/media/bench-lattepanda.png">
    <img src="/posts/2023/02/28/lattepanda-v1/media/bench-lattepanda_hu_84fa5fa602aa54cc.webp"
     width="626"
     height="708"
     loading="lazy"
     decoding="async"
     alt="ApacheBenchmark results for the LattePanda V1.">

  </a>
  <figcaption class="center">ApacheBenchmark results for the LattePanda V1.</figcaption>
</figure>

<p>The LattePanda V1 was over 5 times slower in that test. With a slow internet
uplink this might not matter much, though.</p>
<p>I ended up putting the T430 back in service after doing more calculations.
One idea I had with the LattePanda V1 was to have that run 24/7 due to its
low idle power usage and have another beefy server run during certain hours.
I liked that idea until I calculated the difference in power savings. Having
the main server with around 12 W of idle power turn off for 6 hours and the
LattePanda running at the same time would have actually increased the total
power consumption of the setup compared to having the main server running 24/7.</p>
<p>The math will make sense if your main server uses much more power. Most desktop
PC-s that I have seen idle around 35-50 W and rack-mounted servers use even
more than that, so in those situations this might make more sense. <a href="https://maximiliangolla.com/blog/2022-10-wol-plex-server/">Or you can
whip up a solution that starts and stops machines in your homelab on-demand.</a></p>
<p>Oh, and don&rsquo;t expect to run CPU or GPU based transcoding off of this thing with
Jellyfin. It works okay for certain video formats and resolutions, but a 1080p
H.265 video transcoded to H.264 is just not fast enough on this machine.</p>
<h2 id="a-suitable-use-case">
  <a class="heading-anchor" href="#a-suitable-use-case">A suitable use case<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>I might change my mind at one point and give the LattePanda a go again as a
low power web server. <a href="/posts/2022/11/01/finding-use-case-for-raspberry-pi/">I hate unused hardware</a>,
which is why this LattePanda V1 is now serving as an offsite backup. The USB 3
port makes sense for attaching a bigger storage device and if you run ZFS, you
can also send your whole filesystem to it with <code>zfs send/receive</code> or <code>syncoid</code>.
I haven&rsquo;t had much luck with ARM and ZFS, but with the LattePanda and its
x86-based CPU I have not had issues.</p>









<figure class="center">
  <a href="/posts/2023/02/28/lattepanda-v1/media/image-2.jpg">
    <img src="/posts/2023/02/28/lattepanda-v1/media/image-2_hu_6b11150490335f68.webp"
     width="600"
     height="800"
     loading="lazy"
     decoding="async"
     alt="LattePanda V1 in its final form: a backup endpoint.">

  </a>
  <figcaption class="center">LattePanda V1 in its final form: a backup endpoint.</figcaption>
</figure>

<h2 id="conclusion">
  <a class="heading-anchor" href="#conclusion">Conclusion<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>All-in-all, it&rsquo;s a neat little board that shows signs of instability from time to time.
If you intend to just run Ubuntu Server on it and your workloads are not
very performance critical, then it might work out well for you. Think of it
like a juiced-up Raspberry Pi 4 to get an idea of what it might be suitable for
regarding performance.</p>
<p>It did not fit the use case I intended to use it for, but I&rsquo;m still happy that
I could play around with this board. It was fun!</p>
]]></content:encoded></item><item><title>I finally found an use case for my Raspberry Pi Model B+</title><link>https://ounapuu.ee/posts/2022/11/01/finding-use-case-for-raspberry-pi/</link><pubDate>Tue, 01 Nov 2022 06:00:00 +0200</pubDate><author>ihavesomethoughtsonyourblog@ounapuu.ee (Herman Õunapuu)</author><guid>https://ounapuu.ee/posts/2022/11/01/finding-use-case-for-raspberry-pi/</guid><description>I take a severely underpowered computer and make it do something useful.</description><content:encoded><![CDATA[<img src="https://ounapuu.ee/media/cover_hu_4fe4cf2661554252.jpg" width="1200" height="630" alt="I finally found an use case for my Raspberry Pi Model B+" /><p>You have probably heard about the Raspberry Pi. It&rsquo;s a nice little affordable
single-board computer with a huge community using it for all sorts of projects.</p>
<p>I got my first Raspberry Pi, <a href="https://www.raspberrypi.com/products/raspberry-pi-1-model-b-plus/">the Model B+</a>,
during my first year at university, which was around the winter of 2014/2015.
The idea of a super tiny PC that could actually do useful things was just very
fascinating to me, and I loved the way that green PCB looked.</p>
<p>Over the years, I&rsquo;ve used that Pi and newer revisions of them in all sorts of
use cases: a simple Kodi media box, a Minecraft server, a web server, retro game
emulation box, and much more.</p>
<p>Because the goal of the Raspberry Pi was to be an affordable platform for
experimentation and learning for everyone, they had to keep the costs down. This
meant that the computing power that the Raspberry Pi 1 packed wasn&rsquo;t much.
With the Model B+, you get one ARM CPU core that you can overclock to 1 GHz,
and 512MB of RAM. It wasn&rsquo;t much even at the time of release, and it definitely
isn&rsquo;t great in 2022.</p>
<p>Due to the very limited performance, the use cases for a Raspberry Pi 1 are
quite limited in 2022. Use cases that don&rsquo;t require much computational power
are often better solved by other platforms. Use cases that are actually useful
to me and solve a problem I have are too much for the Pi 1. At the same time,
I absolutely hate it when I have computing equipment sitting around on a shelf
doing nothing. I can&rsquo;t even sell this Pi, because it is not worth much any more
and it has some sentimental value for me.</p>
<p>Taking all that into account, and looking at my parts box, I decided to give one
idea a go: let&rsquo;s build the slowest damn Syncthing backup endpoint imaginable.</p>









<figure class="center">
  <a href="/posts/2022/11/01/finding-use-case-for-raspberry-pi/media/0-setup.jpg" aria-label="View full-size image">
    <img src="/posts/2022/11/01/finding-use-case-for-raspberry-pi/media/0-setup_hu_1440ba594030c917.webp"
     width="1067"
     height="800"
     loading="lazy"
     decoding="async"
     alt="">

  </a>
  
</figure>

<h2 id="the-build">
  <a class="heading-anchor" href="#the-build">The build<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>Here&rsquo;s a quick rundown of the parts:</p>
<ul>
<li>SBC: Raspberry Pi 1 Model B+</li>
<li>Storage (microSD): SanDisk 8GB that I had lying around</li>
<li>Storage (USB): Crucial BX500 1TB SATA 2.5&quot; SSD, in an IcyBox USB-SATA enclosure</li>
<li>Power: official Raspberry Pi microUSB power adapter</li>
<li>Networking: TP-Link TL-WN722N USB WiFI adapter</li>
<li>OS: Raspberry Pi OS 32-bit (lite)</li>
<li>Acoustic foam: yes.</li>
</ul>









<figure class="center">
  <a href="/posts/2022/11/01/finding-use-case-for-raspberry-pi/media/1-setup.jpg">
    <img src="/posts/2022/11/01/finding-use-case-for-raspberry-pi/media/1-setup_hu_525023390c5fe338.webp"
     width="1067"
     height="800"
     loading="lazy"
     decoding="async"
     alt="Alternate angle of the setup.">

  </a>
  <figcaption class="center">Alternate angle of the setup.</figcaption>
</figure>

<p>Use case: networked offsite backup of files that I cannot afford
to lose, powered by <a href="https://syncthing.net/">Syncthing</a>, <code>btrfs</code> as the
filesystem, and <a href="https://digint.ch/btrbk/">btrbk</a> as the snapshotting solution.</p>
<p>I set the OS up using the Raspberry Pi imager due to the useful options it
offered, such as automatically setting my SSH public key authentication up.
Once booted, I logged in and ran <code>sudo apt update -y</code>. I knew what to expect
regarding performance, and was still surprised at how slow things have become.
Updating the system and deploying the configuration using Ansible took hours.</p>
<p>The 1TB SSD is formatted as a <code>btrfs</code> file system and mounted to <code>/storage</code>.
For the Syncthing service, I created a separate user <code>syncthing</code> with the home
folder on <code>/storage/home/syncthing</code>. The synced data will live on <code>/storage/syncthing</code>.
Keeping the home folder on the SSD is intentional: Syncthing keeps track of
application state in a database and storing it on the microSD card will wear it
out much faster. The database can also be quite big if you have a lot of
files to sync.</p>
<p>I&rsquo;m not going to go into the <code>btrbk</code> setup in much detail, but if you&rsquo;re
interested in that, then <a href="/posts/2022/07/09/btrbk-is-awesome/">I do have a write-up about btrbk</a>.
Long story short: snapshots are cool, and they help prevent data loss in case
of accidental deletions.</p>
<p>I set up Syncthing to allow access to the GUI from over the network by changing
the <code>~/.config/syncthing/config.xml</code> file while the service was stopped. Just
change the GUI listen address to <code>0.0.0.0:8384</code>, that will make the GUI accept
connections not only from localhost, but from all machines on the same network.
The next step was to set a password to the GUI and check the &ldquo;Use HTTPS for GUI&rdquo;
box, because you probably don&rsquo;t want any rando messing your machine up.</p>
<p>The choice to go with the WiFi for networking is related to the environment
this system will eventually be deployed to. Ethernet isn&rsquo;t an option there.</p>
<p>Once the system was all set up and files were syncing extremely slowly, I kept
an eye on the Pi, especially the red power LED. I had set the CPU to run at 1 GHz
using <code>raspi-config</code>, and with both the WiFi adapter and SSD connected, I had
concerns that the Pi could not supply enough power. The power limitations of the
Pi are a common source for issues and that has come up in the past as well,
especially with external storage connected to the Pi. However, with this
particular setup this has not been an issue so far. The fact that Pi is so
underpowered that it cannot even make full use of the SSD is probably a
contributing factor to the overall stability.</p>
<p>The file sync was very slow, but at least it was working. The typical transfer
speeds hovered around 1.5 MB/s. Not great, but given the fact that this setup
will operate in an environment where the download speeds are typically capped
around 15-20 Mbit/s, this will be more than enough.</p>









<figure class="center">
  <a href="/posts/2022/11/01/finding-use-case-for-raspberry-pi/media/2-htop.png">
    <img src="/posts/2022/11/01/finding-use-case-for-raspberry-pi/media/2-htop_hu_5e9fa9e6be7ff6de.webp"
     width="956"
     height="295"
     loading="lazy"
     decoding="async"
     alt="`htop` showing how much the Pi is struggling under operation.">

  </a>
  <figcaption class="center">`htop` showing how much the Pi is struggling under operation.</figcaption>
</figure>










<figure class="center">
  <a href="/posts/2022/11/01/finding-use-case-for-raspberry-pi/media/3-syncthing.png">
    <img src="/posts/2022/11/01/finding-use-case-for-raspberry-pi/media/3-syncthing_hu_21fd106fb915d1da.webp"
     width="735"
     height="205"
     loading="lazy"
     decoding="async"
     alt="Typical transfer speed that I observed with the setup.">

  </a>
  <figcaption class="center">Typical transfer speed that I observed with the setup.</figcaption>
</figure>

<p>How well will this setup work over a longer time period? Only time will tell.
Just like with <a href="/posts/2021/03/20/whacky-setups-1/">other disastrous tests that I have done</a>,
I&rsquo;ll try to update this post whenever anything noteworthy happens.</p>
<p>Does this setup make any sense if you need a performant Syncthing endpoint?
Hell no. However, I&rsquo;m very happy that this little Pi finally has a purpose.</p>
<h2 id="alternatives">
  <a class="heading-anchor" href="#alternatives">Alternatives<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>This project was about finding a purpose for an SBC I already had lying around.</p>
<p><a href="https://www.jeffgeerling.com/blog/2022/you-cant-buy-raspberry-pi-right-now">If the price and availability of Raspberry Pi-s wasn&rsquo;t a complete shitshow in
2022</a>,
I would go for a Raspberry Pi 4 in a heartbeat. I can&rsquo;t, and that makes me
and most of the Raspberry Pi community very sad. The more performant Pi-s open
up so many possibilities.</p>
<p>An <a href="https://orangepi.com/index.php?route=product/product&amp;product_id=846">Orange Pi Zero</a>
running <a href="https://www.armbian.com/orange-pi-zero/">Armbian</a> was something I also
considered, since I had one lying around, but it was a bit too competent for
the job, and I might find a better use for it eventually.</p>
<p>If you wanted performance, then any x86-based PC will do just fine. My
recommendation is to go for an used PC, be it <a href="/posts/2022/05/10/thinkpad-as-a-home-server/">a laptop</a>
or <a href="https://www.servethehome.com/introducing-project-tinyminimicro-home-lab-revolution/">a very small and efficient PC</a>.
Just keep in mind that the power usage is typically higher on these setups
compared to a small ARM-based single-board computer. If a machine runs 24/7, then
the difference between 2-3 W and 10-20 W will start to matter, especially when
energy prices are quite high in your region.</p>
]]></content:encoded></item><item><title>Whacky setups: seedbox on a wall</title><link>https://ounapuu.ee/posts/2021/03/20/whacky-setups-1/</link><pubDate>Sat, 20 Mar 2021 12:00:00 +0200</pubDate><author>ihavesomethoughtsonyourblog@ounapuu.ee (Herman Õunapuu)</author><guid>https://ounapuu.ee/posts/2021/03/20/whacky-setups-1/</guid><description>This is what happens when someone takes the meaning of 'brute force' too literally.</description><content:encoded><![CDATA[<img src="https://ounapuu.ee/media/cover_hu_4fe4cf2661554252.jpg" width="1200" height="630" alt="Whacky setups: seedbox on a wall" /><p>The Orange Pi Zero is one hell of an SBC. It has served as
a <a href="/posts/2020/07/23/the-little-wifi-ap-that-could/">Wi-Fi access point for months without issues</a>
and as <a href="/posts/2021/02/27/database-optimization-adventures-on-low-end-hardware/">a testbed for playing around with MySQL</a>.</p>
<p>I wanted it to be a useful device again, but had trouble finding an use case for it due to its hardware limitations.
After messing around with my amateur archival work, I had accumulated some data that might be worth keeping around. Due
to my network being quite unreliable and slow, I decided to go with torrents as the main distribution method. I could
have just hosted the torrents on my main server box, which is what I later did anyway, but then I realized that hosting
torrents is a workload that a weak machine could handle just as well.</p>
<p>I took a board that was left over from a shelf, grabbed some twine and nails and banged together this monstrosity:</p>









<figure class="center">
  <a href="/posts/2021/03/20/whacky-setups-1/media/image1.jpg">
    <img src="/posts/2021/03/20/whacky-setups-1/media/image1_hu_16c4fe809499083c.webp"
     width="1067"
     height="800"
     loading="lazy"
     decoding="async"
     alt="The setup in all its glory.">

  </a>
  <figcaption class="center">The setup in all its glory.</figcaption>
</figure>










<figure class="center">
  <a href="/posts/2021/03/20/whacky-setups-1/media/image2.jpg">
    <img src="/posts/2021/03/20/whacky-setups-1/media/image2_hu_8a7fb99c0fa20331.webp"
     width="1067"
     height="800"
     loading="lazy"
     decoding="async"
     alt="This setup originally had two 4TB hard drives. Unfortunately one of them was too faulty for even BTRFS to handle.">

  </a>
  <figcaption class="center">This setup originally had two 4TB hard drives. Unfortunately one of them was too faulty for even BTRFS to handle.</figcaption>
</figure>

<p>This brave little machine runs on <a href="https://www.armbian.com/">Armbian</a> and hosts one Transmission instance. This instance
is a mirror for some of the data that I collect as part of my archival effort. The OS
lives on a 120GB Crucial SSD with the help of the <code>nand-sata-install</code> script that Armbian provides, and the data lives
on one 4TB Seagate hard drive that is somehow still working.</p>
<p>The board is pressed against the metal part of an AMD AM4 socket stock cooler with the help of a thick 5mm thermal pad
and solid copper wires taken from an electrical cable. This looks very janky, but the cooling performance is absolutely
fantastic: 30C when idling and not more than 50-60C under the heaviest workloads.</p>
<p>The total power consumption of this setup is typically between the 5-10W range, which isn&rsquo;t the lowest, but still
acceptable. The CPU is a 32-bit one, so let&rsquo;s see if this board can make it to 2038.</p>









<figure class="center">
  <a href="/posts/2021/03/20/whacky-setups-1/media/image3.jpg">
    <img src="/posts/2021/03/20/whacky-setups-1/media/image3_hu_188439b7a186b652.webp"
     width="1067"
     height="800"
     loading="lazy"
     decoding="async"
     alt="All in all, it was just another server on the wall.">

  </a>
  <figcaption class="center">All in all, it was just another server on the wall.</figcaption>
</figure>

<h2 id="2021-04-02-update">
  <a class="heading-anchor" href="#2021-04-02-update">2021-04-02 update<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>The 4TB Seagate HDD decided to start a career in experimental music production and started clicking and not showing up
when connected to a PC. And thus, the seedbox on a wall has been put on pause for now.</p>
]]></content:encoded></item><item><title>Database optimization adventures on low-end hardware</title><link>https://ounapuu.ee/posts/2021/02/27/database-optimization-adventures-on-low-end-hardware/</link><pubDate>Sat, 27 Feb 2021 15:00:00 +0200</pubDate><author>ihavesomethoughtsonyourblog@ounapuu.ee (Herman Õunapuu)</author><guid>https://ounapuu.ee/posts/2021/02/27/database-optimization-adventures-on-low-end-hardware/</guid><description>Who would have thought that performing basic database optimizations could be fun?</description><content:encoded><![CDATA[<img src="https://ounapuu.ee/media/cover_hu_4fe4cf2661554252.jpg" width="1200" height="630" alt="Database optimization adventures on low-end hardware" /><p>I used to work on a short-term project a while ago where the goal was to visualize some metrics that were collected from
a pretty fancy smart home setup. This data included power usage of various sections of the building, temperature
sensors, water usage levels and more. The data itself was collected by a proprietary piece of software that sent this
data to a MySQL database. My job was to understand the data, get useful values from the binary data and visualize it.</p>
<h2 id="the-hardware">
  <a class="heading-anchor" href="#the-hardware">The hardware<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>While testing out this solution, I started with an <a href="http://www.orangepi.org/orangepizero/">Orange Pi Zero</a> that a good
friend had given to me. You might remember this board
from <a href="/posts/2020/07/23/the-little-wifi-ap-that-could/">a previous adventure</a>. This board boasts a whopping 4 ARM 32-bit
CPU cores running at 1000MHz, 100 Mbps networking and one USB 2.0 port. The slow USB port means that the read speeds
for any storage you attach to it will be capped out at 40 MB/s.</p>
<p>With all of this in mind, I still went ahead and built this monstrosity. I took a 480 GB Kingston SSD that was lying in
a box and connected it to the board.</p>









<figure class="center">
  <a href="/posts/2021/02/27/database-optimization-adventures-on-low-end-hardware/media/image1.jpg">
    <img src="/posts/2021/02/27/database-optimization-adventures-on-low-end-hardware/media/image1_hu_8aa59cf979c030fe.webp"
     width="600"
     height="800"
     loading="lazy"
     decoding="async"
     alt="I&#39;m pretty sure that the PCB of the SSD itself is larger than the SBC itself.">

  </a>
  <figcaption class="center">I&#39;m pretty sure that the PCB of the SSD itself is larger than the SBC itself.</figcaption>
</figure>

<h2 id="the-workload">
  <a class="heading-anchor" href="#the-workload">The workload<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>This server had two jobs: collect the incoming data from sensors to a MariaDB instance and visualize it using a tool
like Grafana. The first part was OK, since the amount of incoming data was not that high and the SBC could handle it.
However, I hit some roadblocks when trying to visualize it.</p>
<p>The first hurdle was to convert the binary values into something usable. Going by the documentation, I could figure out
how to show signed and unsigned integer values correctly by utilizing some SQL magic that did the conversions
more-or-less correctly. However, with other data types, such as floating-point values of varying precision and other fun
formats, I could not use the same methods to perform the conversion.</p>
<p>The second hurdle was performance. The incoming data was put into one table, which would periodically get split up on a
month-by-month basis to avoid the table getting too big. Not a bad solution, but since I was planning on using Grafana,
having all the data in one table was the only sensible solution if I wanted to show data for previous months as well.
This meant that I had one big table with all the important data, plus some adjacent ones that provided details for the
sensor/meter type, its value type (integer, floating point, etc.) and more. Performing <code>SELECT</code> statements with a couple
of joins proved to be a headache: the queries would trigger a full table search, which was very painful on a system
where the maximum read speed of the SSD is 40 MB/s. Understandably, lookups on a database that was already at a couple
of gigabytes in size and growing would be slow even for shorter time spans (30 days).</p>
<p>These limitations meant that in its current state, the solution was pretty limited in functionality and very slow to use
as well.</p>
<h2 id="the-solution">
  <a class="heading-anchor" href="#the-solution">The solution<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>I soon learned that the company behind the hardware and software of this system provides a tool which can be used
to connect to the database and read the collected data, with values converted properly and sensor/meter names provided
as well. And to top it all off, this thing was written in Java!</p>
<p>I decided to dig around in the provided <code>.jar</code> file using IntelliJ IDEA and stumbled upon some interesting files. These files
corresponded to different data types, and also contained the logic that was used to convert the binary data to usable
values. I can only guess that this conversion was made with the goal of keeping the database size as small as possible,
or to just avoid users from using this data for other purposes using tools made by other companies.</p>
<p>There were still the performance issues to resolve. I looked into optimizing MySQL/MariaDB tables and queries and
stumbled upon some useful tips and tricks. While I cannot remember the exact details, I did end up testing the different
DB engines (InnoDB vs whatever they had previously), configuring various cache sizes and limits, indexes on various
column types, investigating query plans and the performance benefits of <a href="https://en.wikipedia.org/wiki/Denormalization">denormalization</a>.</p>
<p>And then it clicked.</p>
<p>What if I wrote a small Java service that would handle the data conversion <em>and</em> put all the data into one table that
holds only the relevant data and has the correct set of indexes set up? The service would periodically check the main table that
collected all the data, select the results, convert the value into something that a human can understand, and then
insert it into a new table that is optimized for read performance.</p>
<p>After hours of work, I had this Java service up and running on the underpowered server and started testing this
solution. Queries that would previously take minutes to run, would now finish within seconds. Even queries with a time
window of 90+ days would still finish within 5 seconds. This improvement in performance is further amplified by the fact
that Grafana is able to show multiple graphs at the same time, resulting in multiple queries running at the same time.</p>
<h2 id="deployment">
  <a class="heading-anchor" href="#deployment">Deployment<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>The hardware that I tested this solution on was pretty neat and used up very little power. The total cost with the SSD
included was roughly in the 100-150 euro range. However, it was decided that the deployment would be done on a more
conventional machine.</p>
<p>I went ahead and built a tiny PC based on
the <a href="https://www.asrock.com/nettop/amd/deskmini%20a300%20series/index.asp">AsRock Deskmini A300</a>. The build included a
dual-core AMD Athlon APU (cut-down version of a Ryzen APU), 16 GB of DDR4 RAM because it
cost just as much as an 8 GB DDR4 kit did at the time, one 120 GB SATA SSD for the OS, two 512GB Kingston A1000 NVMe SSD-s for the main storage (ZFS
mirror) and a cheap 480 GB Kingston A400 SATA SSD for local backups. This whole build fit in a 500 euro budget and was a
bit overkill for the purpose, but the performance that you could get out of this build was <em>insane</em>. And to top it all
off, the server itself is very tiny and energy efficient, meaning that you could stick it pretty much anywhere, and it would
still run happily while consuming less than 50 watts even under the most intense workloads.</p>









<figure class="center">
  <a href="/posts/2021/02/27/database-optimization-adventures-on-low-end-hardware/media/image2.jpg">
    <img src="/posts/2021/02/27/database-optimization-adventures-on-low-end-hardware/media/image2_hu_c3c5e0cac5b66930.webp"
     width="1067"
     height="800"
     loading="lazy"
     decoding="async"
     alt="Yup, that&#39;s the whole motherboard. Very small, but it can pack quite a punch.">

  </a>
  <figcaption class="center">Yup, that&#39;s the whole motherboard. Very small, but it can pack quite a punch.</figcaption>
</figure>

<p>The performance optimizations that I did were a must-have on the SBC that I did most of my testing on. On this new
build, however, all the bottlenecks were lifted. The CPU probably had more processing power than 20 of the Orange Pi
Zero boards combined, and the maximum read speeds on the crazy fast ZFS mirror were measured in <em>gigabytes per second</em>.
Queries that took a second to run on the old setup were now done in the blink of an eye (or in other words, measured in
milliseconds).</p>
<p>This deployment would probably last years without any intervention from anyone, assuming that the incoming data would
not grow too fast. Unfortunately the solution itself did not find much use, so I could not test this theory out. The box
itself is still happily running at the time of writing.</p>
<h2 id="lessons-learned">
  <a class="heading-anchor" href="#lessons-learned">Lessons learned<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>The main reason that I am writing about this experience is the simple fact that it was a fantastic challenge to try to
extract as much performance out of the Orange Pi Zero based server. Getting your queries from 30 seconds down to 0.3
seconds felt like a great achievement, plus I got to revisit some database related topics that I first learned about during
my university days.</p>
<p>This experience also shows that even low-end hardware can achieve a lot if you are aware of its limitations and can
work around them with a little bit of effort. After this project, I have played around with my homelab setup a lot and
have finally settled on a solution that does not consume a lot of power, but can still run all the workloads that I want
to run.</p>
]]></content:encoded></item><item><title>The little Wi-Fi AP that could</title><link>https://ounapuu.ee/posts/2020/07/23/the-little-wifi-ap-that-could/</link><pubDate>Thu, 23 Jul 2020 01:17:30 +0300</pubDate><author>ihavesomethoughtsonyourblog@ounapuu.ee (Herman Õunapuu)</author><guid>https://ounapuu.ee/posts/2020/07/23/the-little-wifi-ap-that-could/</guid><description>Depends on your definition of _could_.</description><content:encoded><![CDATA[<img src="https://ounapuu.ee/media/cover_hu_4fe4cf2661554252.jpg" width="1200" height="630" alt="The little Wi-Fi AP that could" /><p>I have a bad habit of testing things whenever a &ldquo;good&rdquo; idea pops into my head. This is a short overview of one of them.</p>
<p>The <a href="http://linux-sunxi.org/Xunlong_Orange_Pi_Zero">Orange Pi Zero</a> is a SBC (single board computer) that has a slow 32-bit ARM 4 core CPU, 512MB of RAM and no display output.
It&rsquo;s actually quite OK for many tasks, such as reverse proxy (assuming 100Mbit/s is enough for you), low-performance
NAS (assuming you are fine with 10-12MB/s file transfer speeds) or a Syncthing relay. Oh, and you can also turn it into
a Wi-Fi access point.</p>









<figure class="center">
  <a href="/posts/2020/07/23/the-little-wifi-ap-that-could/media/wifi-ap.jpg">
    <img src="/posts/2020/07/23/the-little-wifi-ap-that-could/media/wifi-ap_hu_b66fbeeb649becd7.webp"
     width="1067"
     height="800"
     loading="lazy"
     decoding="async"
     alt="The Wi-Fi access point in its natural habitat.">

  </a>
  <figcaption class="center">The Wi-Fi access point in its natural habitat.</figcaption>
</figure>

<h2 id="why">
  <a class="heading-anchor" href="#why">Why?<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>Because <a href="https://www.armbian.com/">Armbian</a> made it really easy to test out and I was interested in seeing what kind of
performance an old USB Wi-Fi dongle could offer. This cheap AP could also come into handy in situations where my main
access point dies for some reason.</p>
<h2 id="how">
  <a class="heading-anchor" href="#how">How?<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>Go to the <a href="https://www.armbian.com/orange-pi-zero/">Armbian device page for your SBC</a> and download the latest image, then
write it to your microSD card using the tool of your choice, start your SBC and finish the initial setup.</p>
<p>After all that is done, start <code>armbian-config</code> as root. This tool allows you to do many things over a terminal UI, including
a no-hassle method of setting up an Wi-Fi AP.</p>
<p>The option you are looking for is under <code>Network -&gt; Hotspot</code>.</p>









<figure class="center">
  <a href="/posts/2020/07/23/the-little-wifi-ap-that-could/media/armbian-config-1.png">
    <img src="/posts/2020/07/23/the-little-wifi-ap-that-could/media/armbian-config-1_hu_86a28d26c03eeca9.webp"
     width="710"
     height="403"
     loading="lazy"
     decoding="async"
     alt="This image will likely be way out of date in a couple of years.">

  </a>
  <figcaption class="center">This image will likely be way out of date in a couple of years.</figcaption>
</figure>

<p>Follow the on-screen instructions to set everything up. After the initial setup is done, make sure to navigate to the same
menu again to change the SSID and the Wi-Fi password because the defaults are horribly insecure.</p>
<p>After all this you should be good to go!</p>
<h2 id="issues-and-troubleshooting-tips">
  <a class="heading-anchor" href="#issues-and-troubleshooting-tips">Issues and troubleshooting tips<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>It would not be a proper project if something didn&rsquo;t go wrong in the process.</p>
<p>Before starting this configuration, run <code>ip a</code> to see if your Wi-Fi device is present. In my case the Orange Pi Zero also
has onboard Wi-Fi, but that particular one has poor support, so I use an USB Wi-Fi dongle instead.</p>
<p>If your Wi-Fi device is not showing up, make sure that the correct firmware is present. In my case I had to install
<code>firmware-atheros</code> package so that my <code>ath9k_htc</code> based Wi-Fi adapter would start working. <code>dmesg</code> and <code>lsusb -v</code> can help determine
what chip your Wi-Fi adapter is using and what driver it needs.</p>
<p>The Orange Pi Zero that I have could set everything up, but it would crash hard with the logs not really showing much.
After testing the USB Wi-Fi adapter in all the different USB ports with no success, I opted to use <code>armbian-config</code> menu <code>System -&gt; CPU</code>
to limit the CPU clock speed to 480MHz and set the CPU governor to <code>performance</code> to rule out power delivery issues that might be caused by
variations in CPU power usage. That seems to have done the trick, because after that change the Wi-Fi AP has been rock solid.</p>
<h2 id="testing-and-conclusions">
  <a class="heading-anchor" href="#testing-and-conclusions">Testing and conclusions<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>After setting it up and tweaking it a bit I started testing this thing out. The AP had no major issues
throughout the day and did not crash.</p>
<p>The performance, however, isn&rsquo;t anything to write home about. Speed maxes out at 30Mbit/s and is generally lower than that,
especially when more than one client is connected. You can do things like Steam Remote Play (stream your game over your home network),
but the quality will suffer. It was still quite fun to mess around in GTA V regardless of the image quality and during ~1h
of play time there were only 4-5 stutters that were caused by the network.</p>









<figure class="center">
  <a href="/posts/2020/07/23/the-little-wifi-ap-that-could/media/i-am-speed.png">
    <img src="/posts/2020/07/23/the-little-wifi-ap-that-could/media/i-am-speed_hu_a2e4f1e9419a97f.webp"
     width="223"
     height="185"
     loading="lazy"
     decoding="async"
     alt="I am speed.">

  </a>
  <figcaption class="center">I am speed.</figcaption>
</figure>

<p><strong>Would I use this as my main Wi-Fi access point?</strong></p>
<p>Definitely not. Any half-decent router will out-perform this setup.</p>
<p><strong>Can it still be useful?</strong></p>
<p>Definitely. A crappy Wi-Fi AP is better than no AP.</p>
<h2 id="parts-list">
  <a class="heading-anchor" href="#parts-list">Parts list<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<ul>
<li>Orange Pi Zero SBC (512MB RAM)</li>
<li>Orange Pi Zero expansion board (adds two USB 2.0 ports)</li>
<li>Cheap case for the Orange Pi Zero</li>
<li>32GB Sandisk microSD card</li>
<li>TP-Link WN-722N USB Wi-Fi adapter</li>
<li>Official Raspberry Pi microUSB power adapter</li>
</ul>
<h2 id="update-2020-08-22">
  <a class="heading-anchor" href="#update-2020-08-22">Update (2020-08-22)<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>It&rsquo;s still working and is happily serving as a <em>temporary</em> Wi-Fi access point.</p>
<p>During additional testing I could also hit 40 Mbps speeds when testing in an environment with
far fewer competing Wi-Fi access points nearby.</p>
<h2 id="update-2020-08-30">
  <a class="heading-anchor" href="#update-2020-08-30">Update (2020-08-30)<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>It&rsquo;s still running well and it seems that it won&rsquo;t be a simple temporary
solution after all.</p>
<h2 id="update-2020-11-30-approximately">
  <a class="heading-anchor" href="#update-2020-11-30-approximately">Update (2020-11-30, approximately)<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>This setup has now been retired. It had 0 issues throughout its lifespan as a Wi-Fi access point, but I replaced
it with a more standard Wi-Fi access point so that this board can be used somewhere else.</p>
<p>The setup did surprisingly well and even survived nightly automated updates and restarts, which can be attributed to the good
work that <a href="https://www.armbian.com/">the Armbian project</a> has done.</p>
]]></content:encoded></item></channel></rss>