<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>th.adde.us</title>
  
  
  <link href="https://th.adde.us/feed/atom.xml" rel="self"/>
  
  <link href="https://th.adde.us/"/>
  <updated>2025-12-14T14:10:00.000Z</updated>
  <id>https://th.adde.us/</id>
  
  <author>
    <name>Thaddeus Ternes</name>
    
  </author>
  
  <generator uri="https://hexo.io/">Hexo</generator>
  
  <entry>
    <title>Rust In Linux</title>
    <link href="https://th.adde.us/2025/12/14/rust-in-linux/"/>
    <id>https://th.adde.us/2025/12/14/rust-in-linux/</id>
    <author>
      <name>Thaddeus Ternes</name>
    </author>
    <published>2025-12-14T14:10:00.000Z</published>
    <updated>2025-12-14T14:10:00.000Z</updated>
    
    <content type="html"><![CDATA[<p>Congratulations to the Linux kernel contributors who advocated for and proved Rust’s worthiness in the mainline kernel. Seeing <a href="https://lwn.net/Articles/1049831/">the experimental tag coming off</a> is an incredible milestone for the project and those developers. Millions of users will benefit from this hard-earned accomplishment for decades.</p><p>Over the past year, I’ve been on my own Rust journey. I started with a couple of small prototypes and worked through parts of <em><a href="https://doc.rust-lang.org/book/">The Rust Book</a></em>. That led to experimental features in projects at work, which have now evolved into foundational libraries written in the language. I hope to eventually write a lot more about that.</p><p>In addition to the technical benefits of the language, Rust has been <em>fun</em>, and it has made me a much better software developer and systems designer. That’s probably worth another post as well. Someday. Maybe.<sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup></p><hr class="footnotes-sep"><section class="footnotes"><ol class="footnotes-list"><li id="fn1" class="footnote-item"><p>After all, it has been a year since I last wrote here. <a href="#fnref1" class="footnote-backref">↩︎</a></p></li></ol></section>]]></content>
    
    
    <summary type="html">&lt;p&gt;Congratulations to the Linux kernel contributors who advocated for and proved Rust’s worthiness in the mainline kernel. Seeing &lt;a href=&quot;https://lwn.net/Articles/1049831/&quot;&gt;the experimental tag coming off&lt;/a&gt; is an incredible milestone for the project and those developers. Millions of users will benefit from this hard-earned accomplishment for decades.&lt;/p&gt;</summary>
    
    
    
    
    <category term="linux" scheme="https://th.adde.us/tags/linux/"/>
    
    <category term="rust" scheme="https://th.adde.us/tags/rust/"/>
    
  </entry>
  
  <entry>
    <title>Cut-out CDs</title>
    <link href="https://th.adde.us/2024/12/31/cut-out-cds/"/>
    <id>https://th.adde.us/2024/12/31/cut-out-cds/</id>
    <author>
      <name>Thaddeus Ternes</name>
    </author>
    <published>2024-12-31T02:45:00.000Z</published>
    <updated>2024-12-31T02:45:00.000Z</updated>
    
    <content type="html"><![CDATA[<p>I started building up my CD collection this year. I never really got rid of any CDs acquired earlier in life, but my purchases have picked up quite a bit - about 20 CDs in the past couple months.</p><p>One of the biggest reasons is the satisfaction of owning and holding a physical thing. Even though I’m not currently listening directly to the discs,<sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup> I do enjoy the tactical part of the experience. Scavenging at second-hand book and record stores can be pretty exciting - you never know what you might or what might catch your eye. We’ve found some gems in the local bins.</p><p>I’ve also had great luck on eBay. Since I’m primarily collecting for ownership, I can concede on the condition of the case, inserts, etc. as long as the disc is intact. That’s yielded some great deals.</p><p>I purchased a three-disc lot of <a href="https://www.liquidsoul.com">Liquid Soul</a> albums on eBay last week and they showed up today. I already owned one of the albums, but the price for the set of three was too good to pass up.</p><p>When I unpacked the discs, I noticed a notch in the spine of one of the cases.</p><img src="/2024/12/31/cut-out-cds/IMG_5673.jpeg" title="What's the deal with my copy of Here's The Deal?" loading="lazy"><span class="image-caption">What's the deal with my copy of Here's The Deal?</span><p>I inspected everything closely, and all the discs looked like they were in good shape. In fact, the cases were all much better than I was expecting… except for that notch.</p><p>Out of curiousity, I went back and looked at the original listing, and the photo clearly shows the notch.</p><img src="/2024/12/31/cut-out-cds/s-l1600.jpg" title="Photo from auction listening" loading="lazy"><span class="image-caption">Photo from auction listening</span><p>Since I’m primarily collecting for ownership, the notch didn’t really bother me, but I was still curious, so I started Googling.</p><p>Fortunately, someone on <a href="https://www.reddit.com/r/whatisthisthing/comments/ljfoyc/this_wierd_notch_in_this_cd/?rdt=54030">r/whatisthisthing</a> asked the same question a few years ago, and the answer is: it’s a <a href="https://en.m.wikipedia.org/wiki/Cut-out_(recording_industry)">cut-out</a></p><blockquote><p>Cut-outs are typically wholesaled to retailers as non-returnable items, meaning that the store cannot send them back to the distributor for a refund. The marking also serves to prevent the retailer from attempting to sell the discounted item at the original full price.<br>…<br>Except for the physical damage to the liner notes and/or outer case, the actual disc (LP or CD) is generally unharmed by the cut-out process, and sounds exactly the same as the originally sold recording.</p></blockquote><p>Huh. Well… today I learned!</p><div class="gallery"><div class="gcell"><a href="IMG_5674.jpeg" data-fancybox="8f434346648f6b96df89dda901c5176b10a6d83961dd3c1ac88b59b2dc327aa4" data-caption="Back Side"><img class="gimage" src="IMG_5674.jpeg"></a><p class="gcaption">Back Side</p></div><div class="gcell"><a href="IMG_5675.jpeg" data-fancybox="8f434346648f6b96df89dda901c5176b10a6d83961dd3c1ac88b59b2dc327aa4" data-caption="Spine"><img class="gimage" src="IMG_5675.jpeg"></a><p class="gcaption">Spine</p></div><div class="gcell"><a href="IMG_5676.jpeg" data-fancybox="8f434346648f6b96df89dda901c5176b10a6d83961dd3c1ac88b59b2dc327aa4" data-caption="Front"><img class="gimage" src="IMG_5676.jpeg"></a><p class="gcaption">Front</p></div></div><p>Don’t let my cut-out copy lead you to believe these albums aren’t great - they’re <em>fantastic</em>. Stream them on your platform of choice and hear for yourself.</p><ul><li><a href="https://album.link/s/25r8YzrR6BJ2HsiBl4INT7">Liquid Soul - Here’s the Deal</a></li><li><a href="https://album.link/s/2Vjl8W32UJFgfGJKGKzZsi">Liquid Soul - Self Titled</a></li><li><em>Make Some Noise</em> isn’t available on streaming platforms,<sup class="footnote-ref"><a href="#fn2" id="fnref2">[2]</a></sup> so check out their take on <a href="https://www.youtube.com/watch?v=LTbNkxbVMiw">Salt Peanuts/Chocolate Covered Nut</a></li></ul><hr class="footnotes-sep"><section class="footnotes"><ol class="footnotes-list"><li id="fn1" class="footnote-item"><p>Sneak previous of the post I <a href="/2024/12/26/spotify-connect-family/" title="Our Living Room Music Setup">previously</a> promised… I’m ripping CDs and loading them in to Jellyfin. <a href="#fnref1" class="footnote-backref">↩︎</a></p></li><li id="fn2" class="footnote-item"><p>The other reason for owning the physical media… and now I have two copies 😁 <a href="#fnref2" class="footnote-backref">↩︎</a></p></li></ol></section>]]></content>
    
    
    <summary type="html">&lt;p&gt;I started building up my CD collection this year. I never really got rid of any CDs acquired earlier in life, but my purchases have picked up quite a bit - about 20 CDs in the past couple months.&lt;/p&gt;</summary>
    
    
    
    
  </entry>
  
  <entry>
    <title>Our Living Room Music Setup</title>
    <link href="https://th.adde.us/2024/12/26/spotify-connect-family/"/>
    <id>https://th.adde.us/2024/12/26/spotify-connect-family/</id>
    <author>
      <name>Thaddeus Ternes</name>
    </author>
    <published>2024-12-26T04:45:00.000Z</published>
    <updated>2024-12-26T04:45:00.000Z</updated>
    
    <content type="html"><![CDATA[<p>Merry Christmas! 🎄</p><p>This year, Santa brought me a set of big speakers and a receiver for our living room. It’s the setup I’ve wanted for years - primarily to be used for listening to music. Since our living room is open to other parts of the house, music played there easily fills our primary living spaces.</p><p>We have a couple of kids who are starting to get in to music - as avid performers and listeners. They’re individually exploring their own musical tastes, while also sharing in some of our family favorites. For a while, we’ve been trying to enjoy communal listening experiences, especially as the kids discover new sub-genres and artists and want to share. Before the new living room system, these (brief) sessions were usually AirPlayed through a HomePod Mini in our kitchen… not exactly a stellar experience.</p><p>Our music primarily comes from Spotify, and we’ve recently <a href="https://mastodon.social/@thaddeus/113386725224096425#.">settled in to a family plan</a>. Everyone has their own profile, allowing them to build their own libraries and feed the AI recommendation beast separately. I also have a collection of digital purchases and ripped media I enjoy with <a href="https://jellyfin.org">Jellyfin</a>, but that’s a different blog post.</p><p>Spotify is mired in controversy, but the alternative was <a href="https://mastodon.social/@thaddeus/113386734034146186">very disappointing</a>, so it’s what we use.</p><h1>Listening Together</h1><p><a href="https://www.spotify.com/connect/">Spotify Connect</a> is what drives the integration in many smart devices. TVs, speakers, and other Spotify-enabled gadgets (like my Onkyo receiver) have a built-in Spotify client that streams audio directly from their servers.</p><p>Unlike AirPlay, where data passes through another device (either an iPhone or Macintosh), data is delivered directly from Spotify’s servers to the playback device. The Spotify apps shift into a remote-control mode transparently, as if it was playing audio locally. That makes it easy to use either the phone or desktop apps to control music on the stereo.<sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup></p><img src="/2024/12/26/spotify-connect-family/spotify-connect-desktop-jam.png" title="A Spotify Jam playing through our Living Room receiver" loading="lazy"><span class="image-caption">A Spotify Jam playing through our Living Room receiver</span><p>With Spotify’s <a href="https://support.spotify.com/uk/article/jam/">Jam</a> feature, it’s also possible to share the queue of these playback sessions, allowing anyone who is participating to add, skip, or control tracking on songs in the queue. Participants can use their own device, so their libraries (including favorite albums, songs, and playlists) are readily available and can easily be referenced when adding music to the shared playback queue.</p><p>This really comes to life when you have multiple people sitting down and enjoying music together. They’re able to use their own phones to choose what’s next, and be inspired by what’s playing right now.</p><p>It’s pretty cool, and it Just Works.</p><h1>The Internet of (Dumb) Things</h1><p>Folks who have known me a while might be surprised that I connected my receiver to the internet. I’m not a fan of services and devices that unnecessarily <a href="https://en.wikipedia.org/wiki/Enshittification">decay</a> over time because of the diverging needs of users and businesses. As more manufacturers subsidize low-cost electronics with on-device advertising and analytics, I try to avoid purchasing those devices. When I can’t avoid it (like TVs), I simply don’t connect them to a network.</p><p>I just don’t think everything needs an IP address. I’ve come to really prefer what have become colloquially known as “dumb” devices - those without network capabilities that retain their original design, function, and performance.</p><p>I’ve opted to <em>not</em> connect my Onkyo receiver to the internet. Like I’ve done with my TVs in the past, I’m leaving it off my home network, and instead connecting devices to it I have more trust and confidence in (and that I can easily remove or replace).</p><p>For Spotify Connect, the device I’m using is a Raspberry Pi 3B.</p><p>Wait… what? 👀</p><h1>Raspotify To The Rescue</h1><p>It probably deserves its own post, but the <a href="https://en.wikipedia.org/wiki/TL;DR">TL;DR</a> version of my solution is that I installed <a href="https://github.com/dtcooper/raspotify">Raspotify</a> on a Raspberry Pi connected to my receiver.</p><p>Raspotify is powered by <a href="https://github.com/librespot-org/librespot">librespot</a>, an open source implementation of the Spotify Connect receiver. Installation is fairly straight-forward for those who are comfortable in a Linux/Unix command line environment, and things work pretty well out of the box.</p><p>When it’s up and running, it behaves just like a device with Spotify built-in. It shows up in the Spotify apps, and can be accessed by any Spotify Premium user on the same local network.<sup class="footnote-ref"><a href="#fn2" id="fnref2">[2]</a></sup></p><p>I’ve opted to do some customization to the service. The audio level that comes out of the 3.5mm audio jack on my Raspberry Pi was much weaker than other devices I tested.<sup class="footnote-ref"><a href="#fn3" id="fnref3">[3]</a></sup> After confirming the output levels were properly maxed out in <code>alsamixer</code>, I switched to the HDMI port on the Raspberry Pi, which required a simple update to the <code>/etc/raspotify/conf</code> file:</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">LIBRESPOT_DEVICE=&quot;hdmi:CARD=vc4hdmi,DEV=0&quot;</span><br></pre></td></tr></table></figure><p>I used the following command to figure out which devices librespot was able to detect, then dropped the identifier into the config above:</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ librespot -d ?</span><br></pre></td></tr></table></figure><p>After that change (and tracking down a suitable HDMI cable), things worked great.</p><h1>Nerding Out</h1><p>Of course, I had to nerd out a bit. librespot supports <a href="https://github.com/librespot-org/librespot/wiki/Events">event notifications</a> by calling a provided executable whenever when events fire in the service. There are quite a few different types of events produced, so I started experimenting.</p><p>I created a script at <code>/usr/local/bin/librespot-event.sh</code>, made it executable, and updated <code>/etc/raspotify/conf</code> with the following:</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">LIBRESPOT_ONEVENT=/usr/local/bin/librespot-event.sh</span><br></pre></td></tr></table></figure><p>After some initial experimentation with simple things like piping <code>env</code> to <code>logger</code> and peeking at the values, I realized there were <em>a lot</em> of possibilities (and quite a bit of potential complexity). After some Googling, I stumbled on <a href="https://github.com/librespot-org/librespot/blob/dev/contrib/event_handler_example.py">this Python script</a> with some thorough logic around event types that produced JSON accordingly.</p><p>Then it clicked! I could publish that JSON on my local MQTT broker, making the data accessible to other integrations in my home. However, I wasn’t excited about futzing with python, and liked the idea of keeping things in a shell script.</p><p>Soooo… I asked ChatGPT to convert the python to bash and use <code>jq</code> for the JSON parts. It did it almost perfectly, and I asked for a simple correction, which it was successful in making.</p><p>After that, I added some environment variables for MQTT and watched the events start flowing through my network.</p><p>Here’s my <a href="https://gist.github.com/tternes/fe1cfb354c89e1efe00c026fb1c81ce3">librespot-event.sh</a> script if you’re interested in taking a look.</p><p>And here’s what some of the events look like when I subscribe with <code>mosquitto_sub</code></p><figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><span class="line"><span class="punctuation">&#123;</span></span><br><span class="line">  <span class="attr">&quot;event_time&quot;</span><span class="punctuation">:</span> <span class="string">&quot;2024-12-24 23:05:30&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;event&quot;</span><span class="punctuation">:</span> <span class="string">&quot;track_changed&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;common_metadata_fields&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;item_type&quot;</span><span class="punctuation">:</span> <span class="string">&quot;Track&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;track_id&quot;</span><span class="punctuation">:</span> <span class="string">&quot;06jYhkarVbcRsKcQaTZXJz&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;uri&quot;</span><span class="punctuation">:</span> <span class="string">&quot;spotify:track:06jYhkarVbcRsKcQaTZXJz&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;name&quot;</span><span class="punctuation">:</span> <span class="string">&quot;Winter Blessings&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;duration_ms&quot;</span><span class="punctuation">:</span> <span class="string">&quot;250713&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;is_explicit&quot;</span><span class="punctuation">:</span> <span class="string">&quot;false&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;language&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span></span><br><span class="line">      <span class="string">&quot;zxx&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="punctuation">]</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;covers&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span></span><br><span class="line">      <span class="string">&quot;https://i.scdn.co/image/ab67616d0000b27306afd8641a8e72354c5b01eb&quot;</span><span class="punctuation">,</span></span><br><span class="line">      <span class="string">&quot;https://i.scdn.co/image/ab67616d00001e0206afd8641a8e72354c5b01eb&quot;</span><span class="punctuation">,</span></span><br><span class="line">      <span class="string">&quot;https://i.scdn.co/image/ab67616d0000485106afd8641a8e72354c5b01eb&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="punctuation">]</span></span><br><span class="line">  <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;track_metadata_fields&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;number&quot;</span><span class="punctuation">:</span> <span class="string">&quot;1&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;disc_number&quot;</span><span class="punctuation">:</span> <span class="string">&quot;1&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;popularity&quot;</span><span class="punctuation">:</span> <span class="string">&quot;63&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;album&quot;</span><span class="punctuation">:</span> <span class="string">&quot;Winter Blessings&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;artists&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span></span><br><span class="line">      <span class="string">&quot;The Three Queens&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="punctuation">]</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;album_artists&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span></span><br><span class="line">      <span class="string">&quot;The Three Queens&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="punctuation">]</span></span><br><span class="line">  <span class="punctuation">&#125;</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure><p>I’m not doing anything with the events right now, but I can envision a bunch of different things for the future.</p><h1>Wrapping Up</h1><p>So there you have it - our roundabout way of getting Spotify Connect on a receiver that has the capability natively. 🙃</p><p>If you have any questions or ideas, I’m always happy to chat. You can find me at <a href="http://mastodon.social/@thaddeus">@thaddeus@mastodon.social</a> or <a href="/links">other places</a> online.</p><hr class="footnotes-sep"><section class="footnotes"><ol class="footnotes-list"><li id="fn1" class="footnote-item"><p>You can also use <em>both</em> simultaneously, which is pretty rad. <a href="#fnref1" class="footnote-backref">↩︎</a></p></li><li id="fn2" class="footnote-item"><p>The Spotify apps have to be granted Local Network permissions on recent versions of iOS and macOS, which is a tradeoff I’m willing to make for the convenience. I wish companies weren’t abusing mDNS, but alas… <a href="#fnref2" class="footnote-backref">↩︎</a></p></li><li id="fn3" class="footnote-item"><p>I initially tried using AirPlay with my <a href="https://en.wikipedia.org/wiki/AirPort_Express#2012_model">2012 AirPort Express</a>, but the overall experience was pretty poor for our family needs. However, the audio quality and levels were great. I still love the hardware so much. <a href="#fnref3" class="footnote-backref">↩︎</a></p></li></ol></section>]]></content>
    
    
    <summary type="html">&lt;p&gt;Merry Christmas! 🎄&lt;/p&gt;</summary>
    
    
    
    
  </entry>
  
  <entry>
    <title>BMBX 1.0</title>
    <link href="https://th.adde.us/2024/06/01/bmbx-1-0/"/>
    <id>https://th.adde.us/2024/06/01/bmbx-1-0/</id>
    <author>
      <name>Thaddeus Ternes</name>
    </author>
    <published>2024-06-01T20:00:00.000Z</published>
    <updated>2024-06-01T20:00:00.000Z</updated>
    
    <content type="html"><![CDATA[<p>Earlier this week, I released BMBX<sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup> <a href="https://apps.apple.com/us/app/bmbx/id1567758542">on the App Store</a>. 🎉</p><img src="/2024/06/01/bmbx-1-0/bmbx-1.0-social-launch-three-up.png" title="Screenshots of the main player, station library, and song history" loading="lazy"><span class="image-caption">Screenshots of the main player, station library, and song history</span><h1>Features</h1><p>The app is deceptively simple, with just a handful of launch features:</p><ul><li>Live streaming for tens-of-thousands of stations around the world</li><li>Automatic song identification: artist, track, and artwork display</li><li>Song playback history, with links to view in Apple Music</li><li>Personalized station catalog, with a global, searchable database of stations, as well as the ability to add custom URLs, artwork, and station information</li><li>Station sync across devices through iCloud</li><li>System integration with Siri and Now Playing controls</li></ul><p>In some ways, it’s a little embarrassing to talk about how long it took to go from the idea to this week’s launch. I’ve <a href="/2022/01/28/the-story-of-bmbx/" title="The Story of BMBX">previously written</a> about the story behind BMBX. If you read that post, it becomes clear pretty quickly that it definitely isn’t a <a href="https://medium.com/carpe-aqua/ninety-days-d0974b5c6311">Ninety Days</a> app.</p><p>When I step back and think about the journey, however, it’s a good example of how difficult it is to create minimal, simple products. There are dozens of subtle decisions that contributed to the minimalistic experience that BMBX presents, as well as a lot of behind-the-scenes details that make things look simple, when they’re really not.</p><p>That work took time: hundreds of test builds, lots of feedback from friends and TestFlight users, and dozens of sketches, stickies, and shower thoughts to land on the simple experince that BMBX 1.0 is.</p><p>Also… life gets in the way of hobbies. 🤷🏻‍♂️</p><h1>Price</h1><p>The hardest part of getting the app released was non-technical: it was pricing.<sup class="footnote-ref"><a href="#fn2" id="fnref2">[2]</a></sup></p><p><s>I believe</s> software is valuable. Digital experiences have been devastatingly commoditized by venture capital, advertisers, and mega corporations that use loss-leaders to build their enterprises. These behaviors distort user expectations of software and the value users place on it.</p><p>I knew BMBX wasn’t going to be a source of meaningful revenue for me. I’ve had apps that made <em>interesting</em> money, but even those weren’t “quit your day job” money, and radio streaming is already a commoditized space. I also really didn’t want BMBX to be motivated by money. I built it because I wanted it to exist, and believed others would enjoy and appreciate it as well.</p><p>So that’s why BMBX is free.</p><p>In some ways, this feels really fair. The content the app delivers doesn’t cost me anything personally. Everything is publicly available online, and the <a href="https://www.radio-browser.info">database powering the station discovery</a> is a community-supported effort. Syncing and initial station catalog features are driven by iCloud, so I don’t have any server costs associated with running the app.</p><p>The app is definitely <a href="https://en.wikipedia.org/wiki/Standing_on_the_shoulders_of_giants">standing on a lot of shoulders</a>.</p><p>But I also believe there’s value in what I’ve created: a simple, elegant streaming app for music that integrates with my phone’s features, and brings some unique features to the table. And it’s a strong foundation to build out other features.</p><p>Some of those features will require <em>some</em> kind of purchase. More on that another day.</p><h1>What’s Next</h1><p>For now, I’m enjoying having released a new app after taking a break for a couple years. I’ve started working on a couple of bug fixes based on user feedback, and have started sketching out more concrete ideas for features I kept in the backlog for 1.0.</p><p>The backlog also includes quite a few ideas about some blog posts I want to share. I learned quite a bit during the development of the app, and built some ideas in the project code I think others might find interesting.</p><p>Thanks to everyone who has tested the app, and shared feedback and ideas along the way. It’s been a blast to build, and I’m looking forward to continuing to work on it. It’s an app I use every day, which makes it easy to stay enthusiastic about it’s improvement.</p><hr class="footnotes-sep"><section class="footnotes"><ol class="footnotes-list"><li id="fn1" class="footnote-item"><p>The letters B-M-B-X are a nod to <a href="https://en.wikipedia.org/wiki/Call_signs_in_the_United_States">callsigns</a> of broadcast radio. They are also an abbreviation for “boombox,” which is what I usually call the app. <a href="#fnref1" class="footnote-backref">↩︎</a></p></li><li id="fn2" class="footnote-item"><p>My pal <a href="https://mastodon.social/@marioguzman">Mario</a> can attest to the dozens of texts where I <a href="https://en.wikipedia.org/wiki/Rubber_duck_debugging">rubber ducked</a> pricing with him. <a href="#fnref2" class="footnote-backref">↩︎</a></p></li></ol></section>]]></content>
    
    
    <summary type="html">&lt;p&gt;Earlier this week, I released BMBX&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn1&quot; id=&quot;fnref1&quot;&gt;[1]&lt;/a&gt;&lt;/sup&gt; &lt;a href=&quot;https://apps.apple.com/us/app/bmbx/id1567758542&quot;&gt;on the App Store&lt;/a&gt;. 🎉&lt;/p&gt;</summary>
    
    
    
    
    <category term="bmbx,app store,development" scheme="https://th.adde.us/tags/bmbx-app-store-development/"/>
    
  </entry>
  
  <entry>
    <title>You Won&#39;t Get Left Behind</title>
    <link href="https://th.adde.us/2024/02/05/you-won-t-get-left-behind/"/>
    <id>https://th.adde.us/2024/02/05/you-won-t-get-left-behind/</id>
    <author>
      <name>Thaddeus Ternes</name>
    </author>
    <published>2024-02-05T03:30:00.000Z</published>
    <updated>2024-02-05T03:30:00.000Z</updated>
    
    <content type="html"><![CDATA[<p>Almost a year ago, I wrote a short quip that is turning out to be an evergreen reminder:</p><div class="oembed-error" style="color: red;"><span>failed getting oembed item.(url=https://mastodon.social/@thaddeus/110200961569922277)</span></div><blockquote><p>… thought leaders are in full force with quips like, &quot;it will be really easy to be left behind.</p><p>That’s gatekeeping, and it’s a lie.</p></blockquote><p>I was thinking specifically about the growing hype around AI when I wrote that. While the hype hasn’t subsided, it has become clear to most people that the large language and diffusion models that constitute the “artificial intelligence” space right now are increasingly approachable. The notion of “prompt engineering” as a required skill will soon vanish.<sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup></p><h1>This week’s future of computing</h1><p>That post came to mind this week when tech attention shifted to Apple’s Vision Pro, which customers began receiving a couple days ago.</p><p>There’s some <a href="https://en.wikipedia.org/wiki/Reality_distortion_field">reality distortion</a> happening; others have been in the mixed-reality space for a long time, but Apple is receiving a substantial amount of credit for creating something very different. Admittedly, their first efforts are impressive, and offer a glimpse of new computing paradigms. However, they’re hardly the first in this space, and the barrier to entry is staggeringly high for most people.</p><p><a href="https://9to5mac.com/2024/02/02/tim-cook-vision-pro-interview/">Tim Cook says it’s tomorrow’s technology today</a>.</p><p>The problem I have with Tim’s assertion is that it implies it is the only technology - that spatial computing is <em>the</em> future. It’s absolutely going to be an interesting part of the future, but spatial computing will not be the singular experience for computing.</p><p>Ask ambient computing how that worked out.</p><h1>Not left behind</h1><p>The second, larger issue, I have with the topic is that there’s a push (even within indie developer circles) to make sure your app experiences are customized for this new platform. The prompt being, you don’t want your users to <em>not</em> be able to experience your app in a spatial environment.</p><p>Here, the implication is that you’ll either miss out on critical sales, or that other experiences will steal the attention of current or prospective users and you’ll never have a chance to win their usage or business.</p><p>In that post I go on to say:</p><blockquote><p>“Imagine being 10 years old right now, and having some old dude say, you need to learn [tech of the day] or you’ll be left behind.”</p><p>That’s not how technology works. You can join at any time, with any past experience, and start learning something new. There’s a place for you.</p></blockquote><p>There’s still going to be a place for you. It’s okay to sit on the sidelines for the first round and be a spectator.<sup class="footnote-ref"><a href="#fn2" id="fnref2">[2]</a></sup></p><p>The Macintosh was 28 years old when I started my first professional job targeting the platform. Against all odds, I managed to learn enough to be paid a healthy salary doing that work, in spite of being born just months before the Macintosh was released.</p><p>Don’t sweat it. You won’t be left behind when <em>the</em> future of computing arrives.</p><hr class="footnotes-sep"><section class="footnotes"><ol class="footnotes-list"><li id="fn1" class="footnote-item"><p>The idea that <em>special intelligence</em> is required to use artificial intelligence is pretty rich <a href="#fnref1" class="footnote-backref">↩︎</a></p></li><li id="fn2" class="footnote-item"><p>If you were excited about getting a Vision Pro, but couldn’t because of the cost, compatibility with your eye prescription, or because of where you live… I hope that Apple will address those issues in the next revision. I’m very interested in the platform, and have felt some FOMO too. But it’s simply not in a place that makes sense for me today. <a href="#fnref2" class="footnote-backref">↩︎</a></p></li></ol></section>]]></content>
    
    
    <summary type="html">&lt;p&gt;Almost a year ago, I wrote a short quip that is turning out to be an evergreen reminder:&lt;/p&gt;</summary>
    
    
    
    
    <category term="tech,vision-pro" scheme="https://th.adde.us/tags/tech-vision-pro/"/>
    
  </entry>
  
  <entry>
    <title>HTTPS Proxy for the G4 iMac</title>
    <link href="https://th.adde.us/2024/01/08/https-proxy-g4-imac/"/>
    <id>https://th.adde.us/2024/01/08/https-proxy-g4-imac/</id>
    <author>
      <name>Thaddeus Ternes</name>
    </author>
    <published>2024-01-08T01:50:00.000Z</published>
    <updated>2024-01-08T01:50:00.000Z</updated>
    
    <content type="html"><![CDATA[<p>In my <a href="/2024/01/02/my-new-g4-imac/" title="My New G4 iMac">previous post</a>, the footnotes mentioned one of the biggest challenges when using old systems online today: their outdated versions of security protocols like SSL are usually unsupported by modern services.</p><p>For example, may websites today (including my own blog), require the use of HTTPS connections. This is a fairly standard practice across the internet today, but for older browsers like Safari on OS X Tiger, this is a problem. The SSL protocols supported in that browser are no longer used by most modern webservers due to vulnerabilities that are mitigated in newer versions.</p><img src="/2024/01/08/https-proxy-g4-imac/g4-safari-https-unsupported.png" title="Safari is unable to establish a secure connection to my website, which requires HTTPS connections." loading="lazy"><span class="image-caption">Safari is unable to establish a secure connection to my website, which requires HTTPS connections.</span><p>When you try and load a modern website over HTTPS in an old version of Safari, you’re greeted with an error message like this:</p><blockquote><p><em>Safari can’t open the page “<a href="https://th.adde.us">https://th.adde.us</a>” beacuse it couldn’t establish a secure connection to the server “<a href="http://th.adde.us">th.adde.us</a>”.</em></p></blockquote><h1>An Idea</h1><p>While I was setting up a network connection on the G4 yesterday, I took a detour through a couple of the lesser-visited tabs like AppleTalk, reminscing about days of old. Then the Proxies tab triggered an idea.</p><img src="/2024/01/08/https-proxy-g4-imac/g4-proxy-settings-disabled.png" title="Mac OS X Network Preferences Panel" loading="lazy"><span class="image-caption">Mac OS X Network Preferences Panel</span><p><em>What if I set up a proxy on my local network that handled HTTPS, and then provided an insecure interface for the iMac to connect to?</em></p><p>… in effect making it possible for the old version of Safari to communicate with modern web servers?</p><p>After a few minutes of Googling, I found a <a href="https://github.com/rdmark/macproxy">fork</a> of <a href="https://github.com/tghw/macproxy">macproxy</a>, a Python script that implements a simple proxy that does exactly what I had in mind.</p><h1>Macproxy Docker Image</h1><p>To be totally honest, Python is kind of a mess these days (IMHO). I always seem to have the wrong version on my system, a messed up virtualenv, or some other kind of compatibility drama. Like Ruby, Python feels really complicated if you don’t use it every day, so I try and avoid it for the most part.</p><p>Since I use python so infrequently and Macproxy has pretty clean requirements (python3 and a small handful of modules), it seemed like a good candidate for a container. I’ve been using Docker a lot recently at work to deal with these kinds of scenarios and it’s been wonderful.<sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup></p><p>So <a href="https://github.com/tternes/macproxy/commit/f95ccd7aeb669ff45096108c12d606290110d72b">I wrote a Dockerfile</a>.</p><p>I ran the proxy on my Macbook Air for a few minutes with Docker and tested it with the iMac. It worked great, and I was pretty excited. But I didn’t really want to run the proxy on my laptop all the time.</p><p>I really wanted to be able to (easily) run it from my Synology NAS.</p><p>So <a href="https://hub.docker.com/r/eveningindie/macproxy">I published an image on Docker Hub</a>.</p><img src="/2024/01/08/https-proxy-g4-imac/ss-synology-docker-registry-macproxy.png" title="Searching the Registry in Synology's Docker app returns my image." loading="lazy"><span class="image-caption">Searching the Registry in Synology's Docker app returns my image.</span><p>With the image published, I was able to simply search the Docker registry for my image, which I could then Download right in the Synology Docker app.</p><p>Once downloaded, creating a local container with the image is a breeze.</p><img src="/2024/01/08/https-proxy-g4-imac/ss-synology-docker-running-container.png" title="macproxy container running on Synology" loading="lazy"><span class="image-caption">macproxy container running on Synology</span><p>By default, the proxy listens for connections on port 5000. My Docker image supports passing command line args to the script through the <code>PROXY_ARGS</code> environment variable, but I’m opting to map port 5000 to 8081 on my NAS.<sup class="footnote-ref"><a href="#fn2" id="fnref2">[2]</a></sup></p><h1>iMac Configuration</h1><p>With the image published and a container running on my local network, I turned to finalizing configuration on the iMac.</p><img src="/2024/01/08/https-proxy-g4-imac/g4-proxy-settings-enabled.png" title="Updated Network Proxy settings" loading="lazy"><span class="image-caption">Updated Network Proxy settings</span><p>For the Web Proxy (HTTP) Server, I specified the hostname of my NAS (storage.local)<sup class="footnote-ref"><a href="#fn3" id="fnref3">[3]</a></sup>, as well as the port number I’d mapped to the container (8081). With this configuration applied, the iMac will now send web requests from Safari through the NAS using an insecure connection<sup class="footnote-ref"><a href="#fn4" id="fnref4">[4]</a></sup>. The proxy will relay requests to the upstream host via HTTPS, then modify the responses it receives and send them back to the iMac.</p><img src="/2024/01/08/https-proxy-g4-imac/g4-safari-eveningindie-with-proxy-enabled.png" title="Safari displaying my website without HTTPS" loading="lazy"><span class="image-caption">Safari displaying my website without HTTPS</span><p>Success! 🎉</p><p>Macproxy also <a href="https://github.com/rdmark/macproxy/blob/master/html_utils.py">strips a handful of HTML tags</a> and modifies the source a bit with help from the <a href="https://pypi.org/project/beautifulsoup4/">BeautifulSoup</a> module, so most pages look fairly vanilla, but they’re usually <em>somewhat</em> usable (especially when a solid document hierarchy is in place with basic HTML).</p><p>With this in place, I was able to download a copy of LineIn from <a href="https://rogueamoeba.com/legacy/">Rogue Amoeba’s Legacy</a> page without having to use modern devices.</p><p>Now it’s time to find a copy of my blog from 2004.</p><p>Long live Web 1.0.</p><hr class="footnotes-sep"><section class="footnotes"><ol class="footnotes-list"><li id="fn1" class="footnote-item"><p>I should write up some of the quick tips I’ve been using for creating clean environments with Docker, especially for legacy NodeJS applications 🤔 <a href="#fnref1" class="footnote-backref">↩︎</a></p></li><li id="fn2" class="footnote-item"><p>8081 just feels like a good port number for a proxy <a href="#fnref2" class="footnote-backref">↩︎</a></p></li><li id="fn3" class="footnote-item"><p>It’s pretty great that OS X supports multicast DNS names at this level of system configuration. mDNS and Bonjour still shine in terms of how simple and effective they are in creating great experiences. <a href="#fnref3" class="footnote-backref">↩︎</a></p></li><li id="fn4" class="footnote-item"><p>Obviously this should not be used for anything confidential or sensitive! I’m pretty comfortable with my casual browsing requests being transmitted over my personal local network, but definitely don’t run this on a public-facing host ⚠️ <a href="#fnref4" class="footnote-backref">↩︎</a></p></li></ol></section>]]></content>
    
    
    <summary type="html">&lt;p&gt;In my &lt;a href=&quot;/2024/01/02/my-new-g4-imac/&quot; title=&quot;My New G4 iMac&quot;&gt;previous post&lt;/a&gt;, the footnotes mentioned one of the biggest challenges when using old systems online today: their outdated versions of security protocols like SSL are usually unsupported by modern services.&lt;/p&gt;</summary>
    
    
    
    
  </entry>
  
  <entry>
    <title>My New G4 iMac</title>
    <link href="https://th.adde.us/2024/01/02/my-new-g4-imac/"/>
    <id>https://th.adde.us/2024/01/02/my-new-g4-imac/</id>
    <author>
      <name>Thaddeus Ternes</name>
    </author>
    <published>2024-01-02T05:30:00.000Z</published>
    <updated>2024-01-02T05:30:00.000Z</updated>
    
    <content type="html"><![CDATA[<p>Somewhere around 2006 or 2007, through a series of trades that involved a sibling, a friend of my girlfriend<sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup>, and my G4 iBook, I briefly owned a <a href="https://en.wikipedia.org/wiki/IMac_G4">G4 iMac</a>. I say briefly, because I think I traded my iBook for the iMac, and then the iMac for a PC all within a month or so. It sounds like a crazy trade in retrospect, but it (sort of) made sense at the time.</p><p>A few months ago, my friend <a href="https://hachyderm.io/@heyjeffg">Jeff</a> asked if I’d be interested in one. I couldn’t believe it, and jumped at the chance.</p><img src="/2024/01/02/my-new-g4-imac/IMG_9020.jpeg" title="The G4 iMac sits confidently in our dining room nook, waiting for accessories and upgrades." loading="lazy"><span class="image-caption">The G4 iMac sits confidently in our dining room nook, waiting for accessories and upgrades.</span><p>The fact that I let a G4 iMac slip away has bothered me for years, especially as my nostolgia has deepened. The “lamp shade” has become more than just an iconic version of that product line - it’s a reflection of how provocative Apple was at the time. The G4 iMac was originally released in January of 2002, not even three full months after the first iPod, so it very much embodies what really made Apple special back then.</p><p>The harsh reality, though, was the Macintosh product line was lagging behind in terms of performance, especially for desktop systems. The web was starting to become more complex and applications were much more sophisticated, so even casual users demanded more speed. Just as the PowerPC was running out of steam, Intel and AMD were in an arms race.</p><p>Apple knew it, and famously released <a href="https://en.wikipedia.org/wiki/Mac_transition_to_Intel_processors">Intel-based products</a> in 2006.<sup class="footnote-ref"><a href="#fn2" id="fnref2">[2]</a></sup></p><h1>Hardware Updates</h1><p>This iMac is in incredible condition, but even the most cared-for devices need some maintenance after 20 years. Fortunately, there’s a large community of enthusiasts that are interested in maintaining these devices, so aftermarket parts are abundant.</p><img src="/2024/01/02/my-new-g4-imac/IMG_9029.jpeg" title="Access to the internals of the iMac is granted through the bottom panel. The first cover protects an AirPort slot and a user-accessible RAM slot." loading="lazy"><span class="image-caption">Access to the internals of the iMac is granted through the bottom panel. The first cover protects an AirPort slot and a user-accessible RAM slot.</span><p>When this computer was built, the <a href="https://en.wikipedia.org/wiki/AirPort#AirPort_cards">AirPort</a> card was an optional upgrade, but the lack of ubiquitous wifi made them fairly uncommon features to include. Fortunately, they’re easy to come by these days on eBay, and an easy upgrade to complete thanks to the pre-populated antenna cable. I was happy to see the user-accessible RAM slot was occupied, bringing this system to 768 MB of RAM. Curiously, these machines use both 200-pin and 184-pin RAM modules. I’d love to know the story about that decision.</p><img src="/2024/01/02/my-new-g4-imac/IMG_9400.jpeg" title="The inner RAM slot uses the larger 184-ping SO DIMM RAM modules. Apple didn't consider these user-accessible, and were intended to be the "base" RAM in the system." loading="lazy"><span class="image-caption">The inner RAM slot uses the larger 184-ping SO DIMM RAM modules. Apple didn't consider these user-accessible, and were intended to be the "base" RAM in the system.</span><h2 id="Battery">Battery</h2><p>When I gave the computer an initial test run after bringing it home, the operating system complained about an incorrect system time, so I knew the battery was probably drained and ordered a <a href="https://www.amazon.com/gp/product/B08K4L2S9J">replacement</a>. This was an easy bit of maintenance work since I was already deep inside the computer.</p><img src="/2024/01/02/my-new-g4-imac/IMG_9402.jpeg" title="Clock batteries for the iMac: the original on the left, and a new one on the right." loading="lazy"><span class="image-caption">Clock batteries for the iMac: the original on the left, and a new one on the right.</span><p>I was fortunate to find these 1/2 AA batteries, which are almost identical to the originals.</p><h2 id="Hard-Drive">Hard Drive</h2><p>Jeff gave me a heads up that the hard drive was failing, so I knew I’d need to do some work on the machine. <a href="https://www.ifixit.com/Guide/iMac+G4+17-Inch+Model+M9168LLA+Hard+Drive+Replacement/4176">Hard drive replacement</a> is one of the trickiest jobs on these computers, but it also gives you such a deep appreciation for the integrated design required for these systems since it takes you pretty deep into the machine. I ordered a <a href="https://eshop.macsales.com/item/OWC/SSDMXLE500/">500 GB drive</a> with an IDE adapter and mounting sled from MacSales.</p><img src="/2024/01/02/my-new-g4-imac/IMG_9428.jpeg" title="The 500 GB drive and sled installed above the optical drive." loading="lazy"><span class="image-caption">The 500 GB drive and sled installed above the optical drive.</span><p>The drive installed pretty easily, but definitely wasn’t designed specifically for this application. Here are a few quirks I ran in to:</p><ul><li>The sled’s mounting holes don’t align with  standard 3.5&quot; IDE side-mount locations, so I was only able to attach it with two screws.</li><li>The IDE-to-SATA adapter board is compact, but is slightly taller than the IDE drive it is meant to replace. The clearances are pretty close, especially since the IDE ribbon cable loops upward - which isn’t a problem with the original drive, since the connector is on the bottom of the back.</li><li>There’s a bit of excess wire for the power connections, and they could potentially wander up into the fan in the top of the computer. I opted to tape them down to the sled after a few test fits, just to be safe.</li></ul><h1>Software</h1><p>Since all of this surgery has to be done with the patient face-down, it isn’t clear how you’d do any testing without reassembling… so I buttoned everything back up and hoped for the best.</p><p>Jeff was kind enough to share a handful of discs with the iMac, including installers for Puma (10.1) and Tiger (10.4). My plan was to run Tiger, so that’s the disc I inserted first. The installer launched (after powering up and holding down the C key). However, when it came time to select an installation target disk, the installer beachballed. I tried a few times, with the same result. After a few failed attempts, restarted again, booted from the installation  media, and then launched Disk Utility, hoping I could just format the drive and then proceed. Unfortunately, Disk Utility also beachballed when it attempted to detect the disk.</p><p>At that point, I started to worry the disk was bad, or that I’d messed something up.</p><p>On whim, I swapped the Tiger disk for Puma and tried again. Amazingly, the installer breezed right through. The system rebooted, and a few minutes later I found myself staring at a clean 10.1.5 installation.</p><img src="/2024/01/02/my-new-g4-imac/IMG_9444.jpeg" title="A fresh install of Puma, with the whole 500 GB drive detected correctly." loading="lazy"><span class="image-caption">A fresh install of Puma, with the whole 500 GB drive detected correctly.</span><p>I was really impressed that Puma correctly identified the capacity of the drive. I wish I would have spent a few more minutes poking around; I’ve never actually used Puma… my first in-depth Mac OS X experiences were on 10.3, so it would have been fun to look around for a few minutes.</p><p>Instead, I was feeling energized, so I tossed the Tiger disk back in and ran the installer from inside Puma. It gave me the option of either moving the current system folder to the side or formatting the drive. The <a href="https://www.macworld.com/article/206417/delete-previous-system.html">Previous System Folder</a> feature is one of those Mac OS things that was always enviable as a Windows user, but I opted to format the drive to see what would happen.</p><img src="/2024/01/02/my-new-g4-imac/IMG_9451.jpeg" title="Tiger successfully installed, with the drive internal hard drive correctly reported" loading="lazy"><span class="image-caption">Tiger successfully installed, with the drive internal hard drive correctly reported</span><p>Thankfully, the Tiger installer worked correctly this time, and I was running 10.4 about 20 minutes later.</p><h1>Testing</h1><p>Obviously the first thing I did was text my pal <a href="https://mastodon.social/@marioguzman">Mario</a> and share my excitement. We were able to sign in to a Jabber server<sup class="footnote-ref"><a href="#fn3" id="fnref3">[3]</a></sup> and enjoy the beautiful iChat UI like it was the mid-2000s all over again. I also installed iLife '04, in anticipation of this machine’s upcoming workload.</p><img src="/2024/01/02/my-new-g4-imac/g4-imac-ichat-screenshot.png" title="Desktop screenshot of Mac OS X 10.4 with an iChat conversation in the foreground. It's still one of the nicest OSes of all time." loading="lazy"><span class="image-caption">Desktop screenshot of Mac OS X 10.4 with an iChat conversation in the foreground. It's still one of the nicest OSes of all time.</span><p>After some silly chats, it was time to move the iMac back into my home office and give it a test drive for its real purpose: capturing home movies from VHS tapes.</p><img src="/2024/01/02/my-new-g4-imac/IMG_9463.jpeg" title="The iMac nestled into the corner of my office, importing VHS tapes through a FireWire capture device." loading="lazy"><span class="image-caption">The iMac nestled into the corner of my office, importing VHS tapes through a FireWire capture device.</span><p>It seems a little counter-intuitive to be using a machine this old to be doing a task that is easiliy accomplished on more modern hardware, but that’s a story for another time.</p><p>So there it is - a revived G4 iMac. A few things I was surprised by along the way:</p><ol><li>Mac OS has supported larger disk volumes for a <em>long</em> time. <a href="https://en.wikipedia.org/wiki/HFS_Plus">HFS+</a> (or Mac OS Extended) file systems supported <a href="https://web.archive.org/web/20100730000158/http://support.apple.com/kb/ht2422">unthinkably-large disks</a> back in the early 2000s. 10.0 - 10.1.5 supported up to 2 TB, 10.2 supported 8 TB, 10.3 was 16 TB, and 10.4 was a staggering  8 EB.</li><li>Spinning drives hurt our computing experience more than we realized. I’ve known this to be true for a long time, and comparing a failing 3.5&quot; IDE drive to an SSD isn’t fair… but this computer is so snappy now.</li><li>I’m increasingly frustrated by how much e-waste we produce through the incessant upgrade cycles of phones and computers. This machine remains a nice computer, and could easily fulfill many modern computing tasks, but its software is no longer maintained, leaving it largely incompatible with the world around it. Fortunately, <a href="https://github.com/ssshake/retro-computing-internet-resources">there are lots of projects</a> aiming to help make the modern internet more accessible to older computers.</li></ol><hr><p>Jeff - many, many thanks again for this treasure. It was such a pleasure to see it come back to life with new energy and I’m sure it will be a thrill to use any chance I get.</p><hr class="footnotes-sep"><section class="footnotes"><ol class="footnotes-list"><li id="fn1" class="footnote-item"><p>Thankfully, the girlfriend later agreed to be my wife. <a href="#fnref1" class="footnote-backref">↩︎</a></p></li><li id="fn2" class="footnote-item"><p>In my opinion, the <a href="https://www.cnet.com/tech/tech-industry/apples-intel-switch-jobs-keynote-transcript/">Intel transition keynote</a> is among the best of Steve’s theatrics. The “secret double life” line was such a thrill, especially as someone who had recently spent an internship working with a cross-compiling build environment. Targeting multiple architectures really reasonated with me. <a href="#fnref2" class="footnote-backref">↩︎</a></p></li><li id="fn3" class="footnote-item"><p>Unfortunately, most online services are incompatible with software this old, due to necessary improvements in SSL and TLS, so using insecure services is necessary these days. <a href="#fnref3" class="footnote-backref">↩︎</a></p></li></ol></section>]]></content>
    
    
    <summary type="html">&lt;p&gt;Somewhere around 2006 or 2007, through a series of trades that involved a sibling, a friend of my girlfriend&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn1&quot; id=&quot;fnref1&quot;&gt;[1]&lt;/a&gt;&lt;/sup&gt;, and my G4 iBook, I briefly owned a &lt;a href=&quot;https://en.wikipedia.org/wiki/IMac_G4&quot;&gt;G4 iMac&lt;/a&gt;. I say briefly, because I think I traded my iBook for the iMac, and then the iMac for a PC all within a month or so. It sounds like a crazy trade in retrospect, but it (sort of) made sense at the time.&lt;/p&gt;</summary>
    
    
    
    
  </entry>
  
  <entry>
    <title>Do What I Want</title>
    <link href="https://th.adde.us/2023/07/06/do-what-i-want/"/>
    <id>https://th.adde.us/2023/07/06/do-what-i-want/</id>
    <author>
      <name>Thaddeus Ternes</name>
    </author>
    <published>2023-07-06T00:10:47.000Z</published>
    <updated>2023-07-06T00:10:47.000Z</updated>
    
    <content type="html"><![CDATA[<p>After I graduated college, I had the good fortune of joining an R&amp;D team at <a href="https://en.wikipedia.org/wiki/Intermec">Intermec</a>, where I was surrounded by incredibly talented engineers.</p><p>I was constantly learning from the many senior people in our department, observing and supporting their work on some incredibly impressive things.<sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup> What made them really unique was that they were all willing to teach. They were generous with their time and patient with their explanations, which made them invaluable to my personal growth.</p><p>But this isn’t about my time at Intermec. It is about a phrase one of the Principal Engineers on our team would often say in moments of frustration:</p><blockquote><p><em>“Do what I want, not what I said.”</em></p></blockquote><p>This was never aimed at a person on our team; his quip was always directed at the computer in front of him. He was badgering the compiler and code he had just written, or the command he’d just typed in a terminal window.</p><p>His frustration was that what he had in mind didn’t match what it actually did. He knew the computer was merely executing the request he’d provided - and that the real issue was that he’d made a mistake in communicating his desired outcome. He would have to change the structure or syntax of his code or command and try again in order to achieve his goal.</p><p>Computers always do what they’re told, right?</p><h1>Command Line Tools</h1><p>This post from <a href="https://social.jvns.ca/@b0rk">Julie Evans</a> showed up in my timeline this afternoon, and got me thinking about that Principal Engineer.</p><div class="oembed-outer oembed-jvns-ca"><div class="oembed-inner"><blockquote class="mastodon-embed" data-embed-url="https://social.jvns.ca/@b0rk/110657425256191872/embed" style="background: #FCF8FF; border-radius: 8px; border: 1px solid #C9C4DA; margin: 0; max-width: 540px; min-width: 270px; overflow: hidden; padding: 0;"> <a href="https://social.jvns.ca/@b0rk/110657425256191872" target="_blank" style="align-items: center; color: #1C1A25; display: flex; flex-direction: column; font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Oxygen, Ubuntu, Cantarell, 'Fira Sans', 'Droid Sans', 'Helvetica Neue', Roboto, sans-serif; font-size: 14px; justify-content: center; letter-spacing: 0.25px; line-height: 20px; padding: 24px; text-decoration: none;"> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="32" height="32" viewBox="0 0 79 75"><path d="M63 45.3v-20c0-4.1-1-7.3-3.2-9.7-2.1-2.4-5-3.7-8.5-3.7-4.1 0-7.2 1.6-9.3 4.7l-2 3.3-2-3.3c-2-3.1-5.1-4.7-9.2-4.7-3.5 0-6.4 1.3-8.6 3.7-2.1 2.4-3.1 5.6-3.1 9.7v20h8V25.9c0-4.1 1.7-6.2 5.2-6.2 3.8 0 5.8 2.5 5.8 7.4V37.7H44V27.1c0-4.9 1.9-7.4 5.8-7.4 3.5 0 5.2 2.1 5.2 6.2V45.3h8ZM74.7 16.6c.6 6 .1 15.7.1 17.3 0 .5-.1 4.8-.1 5.3-.7 11.5-8 16-15.6 17.5-.1 0-.2 0-.3 0-4.9 1-10 1.2-14.9 1.4-1.2 0-2.4 0-3.6 0-4.8 0-9.7-.6-14.4-1.7-.1 0-.1 0-.1 0s-.1 0-.1 0 0 .1 0 .1 0 0 0 0c.1 1.6.4 3.1 1 4.5.6 1.7 2.9 5.7 11.4 5.7 5 0 9.9-.6 14.8-1.7 0 0 0 0 0 0 .1 0 .1 0 .1 0 0 .1 0 .1 0 .1.1 0 .1 0 .1.1v5.6s0 .1-.1.1c0 0 0 0 0 .1-1.6 1.1-3.7 1.7-5.6 2.3-.8.3-1.6.5-2.4.7-7.5 1.7-15.4 1.3-22.7-1.2-6.8-2.4-13.8-8.2-15.5-15.2-.9-3.8-1.6-7.6-1.9-11.5-.6-5.8-.6-11.7-.8-17.5C3.9 24.5 4 20 4.9 16 6.7 7.9 14.1 2.2 22.3 1c1.4-.2 4.1-1 16.5-1h.1C51.4 0 56.7.8 58.1 1c8.4 1.2 15.5 7.5 16.6 15.6Z" fill="currentColor"/></svg> <div style="color: #787588; margin-top: 16px;">Post by @b0rk@jvns.ca</div> <div style="font-weight: 500;">View on Mastodon</div> </a> </blockquote> <script data-allowed-prefixes="https://social.jvns.ca/" async src="https://social.jvns.ca/embed.js"></script></div></div><p>Julia is right - the output from <code>dig</code> is particularly arcane, at least in terms of being able to easily integrate with other tools.</p><p>But command line tools have a tendency to be esoteric. One of my personal favorite mistakes is usage of <code>service</code> on Linux:</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">~$ sudo service restart nginx</span><br><span class="line">[sudo] password for thaddeus: </span><br><span class="line">restart: unrecognized service</span><br></pre></td></tr></table></figure><p>The astute reader will recognize that I’ve flipped the <code>service_name</code> and <code>command</code> parameters around in that command. However… my <em>intent</em> is pretty clear.</p><p>I have absolutely muttered the words, <em>“oh just do what I want.”</em> while using command line tools.</p><h1>Does GPT Understand?</h1><p>Well, it turns out there <em>are</em> some computers that appear to understand what I’m trying to do.</p><p>I asked <a href="https://chat.openai.com">ChatGPT</a> the following question:</p><blockquote><p>What am I trying to do when I type “sudo service restart ssh”</p></blockquote><p>Here was the response:</p><blockquote><p>When you type “sudo service restart ssh,” you are attempting to restart the SSH (Secure Shell) service on your computer.</p><p>Let’s break down the command:</p><ul><li><p>“sudo”: It stands for “superuser do” and is used to run the command with administrative privileges. By using “sudo,” you elevate your user permissions to execute the following command as the superuser or administrator.</p></li><li><p>“service”: It is a command used in Unix-based systems to manage system services. It allows you to start, stop, restart, enable, disable, and manage various services running on your computer.</p></li><li><p>“restart”: It is an argument passed to the “service” command, indicating that you want to restart the specified service.</p></li><li><p>“ssh”: It refers to the SSH service, which is responsible for secure remote access and communication with your computer using the SSH protocol.</p></li></ul><p>Therefore, the complete command “sudo service restart ssh” is used to restart the SSH service, which may be useful if you need to apply changes to the SSH configuration or if you’re experiencing issues with SSH and want to restart it to resolve them.</p></blockquote><p>Hilariously, it doesn’t correct the mistake I’ve made, but it does correctly explain what I was attempting to do. Other incantations of similar mistakes produce similar results: ChatGPT can produce the correct syntax for my desired outcome pretty consistently.</p><p>But…</p><h1>It’s Not Understanding</h1><p>If there was actual understanding, it would have also corrected my mistake.</p><p>To me, this is a really interesting application of <a href="https://en.wikipedia.org/wiki/Generative_pre-trained_transformer">GPT</a> technology. Fundamentally, GPT, like other LLMs, isn’t actually <em>understanding</em>, but instead <em>predicting</em> what you want to hear.</p><p>Today’s “AI” is like the friend who lies to you and says exactly what you want to hear. It will happily tell you those shoes look great, or that you were right… even if you were wrong.</p><p>However, sometimes what you want is actually the right outcome. Here’s another take at the service restart request with ChatGPT:</p><blockquote><p>Give me a bash command to restart nginx. Return it without description or other information so I can pipe it to /bin/sh</p></blockquote><p>Answer:</p><blockquote><p>sudo service nginx restart</p></blockquote><p>Dang. That’s pretty cool. It did a good job of predicting what I wanted, and gave me exactly what I needed in a format that’s usable in my described context.</p><p>Maybe it can do what I want, exactly the way I say it.</p><hr class="footnotes-sep"><section class="footnotes"><ol class="footnotes-list"><li id="fn1" class="footnote-item"><p>I got my first exposure to neural networks at Intermec, in what would be come foundational technology in a patent I helped author. The models required days of training, but ran on embedded hardware with a fraction of the computing capabilities of modern cell phones. <a href="#fnref1" class="footnote-backref">↩︎</a></p></li></ol></section>]]></content>
    
    
    <summary type="html">&lt;p&gt;After I graduated college, I had the good fortune of joining an R&amp;amp;D team at &lt;a href=&quot;https://en.wikipedia.org/wiki/Intermec&quot;&gt;Intermec&lt;/a&gt;, where I was surrounded by incredibly talented engineers.&lt;/p&gt;</summary>
    
    
    
    
  </entry>
  
  <entry>
    <title>My Backup System (2023 Edition)</title>
    <link href="https://th.adde.us/2023/06/19/my-backup-system-2023/"/>
    <id>https://th.adde.us/2023/06/19/my-backup-system-2023/</id>
    <author>
      <name>Thaddeus Ternes</name>
    </author>
    <published>2023-06-19T16:00:00.000Z</published>
    <updated>2023-06-19T16:00:00.000Z</updated>
    
    <content type="html"><![CDATA[<p>Every few years, folks start talking about backup solutions for their personal computing needs. In fact, I wrote the <a href="/2020/12/14/my-backup-system/" title="My Backup System">original version of this post</a> a few years ago when it popped up in my Twitter feed.</p><p>While personal documents, photos, and other files are increasingly distributed across third-party services in the cloud, finding secure, no-fuss, cost-effective backup solutions is <em>still</em> surprisingly difficult. Fortunately, this setup has been almost perfectly that: no-fuss and cost effective after almost three years of use.</p><p>I made some improvements in 2021 after we refreshed a couple computers. To help with planning, I sketched out this diagram in <a href="https://linea-app.com">Linea Sketch</a>.</p><img src="/2023/06/19/my-backup-system-2023/system-diagram.png" title="Backup System Diagram" loading="lazy"><span class="image-caption">The basics of how backups and file storage work for our family computers.</span><p>A few things have changed from that original post, but much has remained the same. Below is an edited version of the post that matches what I’m doing right now.</p><h1>Requirements</h1><p>When I set this up a few years ago, I had some pretty specific requirements:</p><ul><li>Multiple machines: we have a family iMac, and a couple of Macbook Airs that need to be backed up. Everything runs recent versions of macOS.</li><li>Large storage: our family Photos.app library is over 1TB. We’ve begun to use iCloud Library to improve access across devices. However, I’m unwilling to trust iCloud solely with this data, so we have full-resolution versions on the iMac, and thus need destinations that have at least that much capacity</li><li>Automatic: this needs to run continuously and cannot depend on plugging in USB drives or remembering to run a script</li><li>Encrypted: data stored on third-party systems must be encrypted</li><li>Offsite: I want to be sure we have a copy offsite (ideally in another city/state) in case of natural or other disaster that could affect our home in the future</li><li>Immediate Access: if something happens to my computer, I want to be able to restore immediately, without having to wait for a recovery disk to be shipped to me</li><li>No-fuss: I don’t want to mess around with complex scripts, fiddle with config files, or other fragile DIY contraptions. While I love *nix, I don’t want to read a man page to figure it out.</li><li>Versioning: being able to rewind time and get a past version of a file is great. In reality, I use this to peek in on backups occasionally… just to double-check recent updates have been backed up properly</li></ul><h1>Backup Data</h1><p>I don’t back up applications, OS files, or anything else I can reproduce from the App Store or internet; my backups only contain data I can’t (easily) replace. A good backup allows me to treat a computer and its OS as a commodity.</p><p>I keep some scripts to install apps I use and set preferences with <code>defaults</code> in my <code>$HOMEDIR</code>, so I can also selective about config backups, since I can recreate a machine with a fresh OS and my restored data. I only choose a couple of directories within <code>~/Library</code> for inclusion (Mail.app mailboxes, notably).</p><h1>Software</h1><p>I use <a href="https://www.arqbackup.com/">Arq 7</a>. I’ve been a paid user since Arq 5 and am a big fan of the software.</p><p>Arq’s feature list is extensive and easily covers all of my requirements. I gave their trial a spin a few years ago and was very excited with how it worked. I paid a one-time cost for the full version of the application.</p><p>The application runs quietly and offers plenty of flexibility. This version of the app has been solid, efficient, and stable. I have yet to upgrade to the latest release, due to common issues the developer is well-aware of, but look forward to the improvements in version 7 (expected late this year or early next). I’ll be happy to pay for an upgraded version when its ready.</p><h1>Destinations</h1><p>I’m using multiple backup destinations: one cloud-based and one onsite. I chose to have a mix for redundancy, flexibility, and cost.</p><img src="/2023/06/19/my-backup-system-2023/arq-screenshot.png" title="Arq Screenshot" loading="lazy"><span class="image-caption">Arq 7 on my laptop. There are two backup destinations. The additional Restore location is my old Linux machine I used initially to restore my new laptop in 2021.</span><h2 id="Offsite-Storage">Offsite Storage</h2><p>I subscribe to <a href="https://wasabi.com/">Wasabi</a>, an affordable, S3-like service for offsite storage. Arq supports Wasabi natively, so setup is a breeze. Wasabi’s current pricing is about $11/month for 2TB of immediately-available storage.</p><p>Both of our computers push to buckets configured on Wasabi (each with different keys to limit data exposure, should the keys be compromised). Arq encrypts data before sending it to Wasabi, so there are multiple levels of data protection here.</p><p>Our initial push from the family computer to Wasabi took a few weeks. Arq dutifully chipped away at the upload process without ever saturating our home internet. I was initially concerned about uploading this much data, but it went without a hitch. Once a backup is seeded, Arq pushes incremental changes to its destinations, so there is only a swell of data pushed when we import a large number of new photos or other large media.</p><h2 id="Onsite-Storage">Onsite Storage</h2><p>I also have a local backup destination. In 2021, I ditched the Linux machine I’d built and bought a <a href="https://www.synology.com/en-us/products/DS1621+">Synology DS1621+</a>. I loaded it up with six 12TB Seagate Ironwolf drives and haven’t looked back. We also use it for long-term storage of documents and offloading large files and media.</p><p>Arq is configured to use the Synology as a network storage location. It can automatically mount the remote volume, so I don’t need to make sure macOS is configured to mount/remount the volume if I’m away from home when the job runs. Arq will happily resume backups once I’m back on my home network and the device is available.</p><h1>Final Comments</h1><p>Having onsite storage is great - it’s fast, rock solid, and available if I need quick access to an old version. The offsite, cloud-based backups in case of local disaster, but enjoy the quicker access my local NAS provides me.</p><p>I’ve had a couple of opportunities to test this system over the past few years; a few times for  <a href="https://support.apple.com/keyboard-service-program-for-mac-notebooks">Macbook keyboard repairs</a> and some other file recovery needs. Remember - test your backups!</p><p>Have some questions? Reach out to me on <a href="https://mastodon.social/@thaddeus">Mastodon</a>. Good luck, and may your backups be safe, up-to-date, and unneeded!</p>]]></content>
    
    
    <summary type="html">An updated overview of how I back up my personal computers</summary>
    
    
    
    
  </entry>
  
  <entry>
    <title>Apple&#39;s AR Glasses Could Slip To 2026</title>
    <link href="https://th.adde.us/2022/11/08/apples-ar-glasses-could-slip-to-2026/"/>
    <id>https://th.adde.us/2022/11/08/apples-ar-glasses-could-slip-to-2026/</id>
    <author>
      <name>Thaddeus Ternes</name>
    </author>
    <published>2022-11-08T05:22:00.000Z</published>
    <updated>2022-11-08T05:22:00.000Z</updated>
    
    <content type="html"><![CDATA[<p>An <a href="https://www.tomsguide.com/news/apples-ar-glasses-could-slip-to-2026-says-analyst">article on Tom’s Guide</a> says Apple’s infamously rumored AR glasses, which have been “coming soon” since the late 2010’s, are now at least another year or two away:</p><blockquote><p>“We now expect the AR Glass to be postponed to 2025-2026, due to design issues,” Pu wrote</p></blockquote><p>I’d suggest reframing “design difficulties” to something like “lack of use case.”</p><blockquote><p>But it’s striking that nearly a decade after <a href="https://www.tomsguide.com/us/google-glass-enterprise-edition-2,news-30120.html">Google Glass</a> became available to ‘Explorers’ in the US, companies are still struggling to make the form factor work, despite the considerable technological improvements we’ve seen in the intervening years.</p></blockquote><p>The technology hasn’t been <a href="https://en.wikipedia.org/wiki/Wikipedia:Solutions_looking_for_a_problem">the problem</a> for a while.</p><p><em>Via <a href="https://apple.slashdot.org/story/22/11/07/2153240/apples-ar-glasses-could-slip-to-2026-says-analyst">Slashdot</a></em></p>]]></content>
    
    
    <summary type="html">&lt;p&gt;An &lt;a href=&quot;https://www.tomsguide.com/news/apples-ar-glasses-could-slip-to-2026-says-analyst&quot;&gt;article on Tom’s Guide&lt;/a&gt; says Apple’s infamously rumored AR glasses, which have been “coming soon” since the late 2010’s, are now at least another year or two away:&lt;/p&gt;</summary>
    
    
    
    
    <category term="apple" scheme="https://th.adde.us/tags/apple/"/>
    
    <category term="xr" scheme="https://th.adde.us/tags/xr/"/>
    
  </entry>
  
</feed>
