<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[autologue]]></title><description><![CDATA[self discourse]]></description><link>https://autologue.io/</link><image><url>https://autologue.io/favicon.png</url><title>autologue</title><link>https://autologue.io/</link></image><generator>Ghost 3.42</generator><lastBuildDate>Sat, 11 Apr 2026 00:20:19 GMT</lastBuildDate><atom:link href="https://autologue.io/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[On Federalized Murder and the Erosion of Language]]></title><description><![CDATA[This Administration's use of language is particularly pernicious, and we must not grow numb, nor succumb, to their "narrative"]]></description><link>https://autologue.io/fuck-ice/</link><guid isPermaLink="false">697630cd2e714c039dd4e4f0</guid><category><![CDATA[fucked]]></category><dc:creator><![CDATA[me]]></dc:creator><pubDate>Sun, 25 Jan 2026 16:42:24 GMT</pubDate><media:content url="https://autologue.io/content/images/2026/01/fucked.png" medium="image"/><content:encoded><![CDATA[<img src="https://autologue.io/content/images/2026/01/fucked.png" alt="On Federalized Murder and the Erosion of Language"><p>Renee Good. Alex Pretti. It's a sickness.</p><h3 id="fuck-this-shit-">Fuck this shit.</h3><p>These current events transcend politics. It is not a "left" or a "right" issue; it is an <em>American</em> issue. For this Administration to immediately come out after each of these killings with their "narrative" of easily disputed "facts" that blindly support Federal agents is fundamentally un-American.</p><p>It is incredibly disconcerting that this Administration has no interest in investigating these tragedies. Rather, such blind support operates to instead encourage future attacks.</p><p>In a sane government, facts would be collected and a thorough investigation would be completed before any official statement is made. While the outcome of such investigations has historically been met with mixed reception (i.e., depending on one's political leaning), it is critical that these investigations be undertaken. The Federal government cannot be permitted to execute people with no due process and no oversight.</p><p>Instead, Donald and his Toadies have characterized both Renee Good and Alex Pretti as domestic terrorists. The Department of JuStIcE even declined to investigate Good's killing, instead attempting to launch an investigation into Good's partner. How asinine.</p><p>I write this as I watch a steady stream of shit flow from Greg Bovino's lips, dodging questions by claiming that there will be an investigation. And yet, he already characterizes Pretti as a "suspect" and not a "victim". Even in the face of the utter absence of evidence (and, indeed, ample evidence to the contrary), Bovino repeatedly asserts Pretti was there to assault ICE agents and commends the ICE agents for moving quickly to preserve their own lives. Righteous mag dump, maaan! So strange that the "life-saving aid" administered to Pretti was ineffective. Fuck all these assholes.</p><p>You'll have to forgive me if I don't trust this Administration to effectuate a thorough, unbiased investigation. This Administration has given us reason to distrust them at literally every turn.</p><h3 id="which-brings-me-to-the-continued-disintegration-of-our-shared-lexicon-">Which brings me to the continued disintegration of our shared lexicon.</h3><p>The first time I heard the word "insurrection"? Following Donald's "Day of Love" 😍™ on January 6, 2021. I spent the entire day glued to coverage of the US Capitol. You don't even have to take my word for it (or Donald's) that it was <em>not</em> a spirited tour of the Capitol.</p><p>That day was fundamentally un-American and should have disqualified Donald from Office. But heaven forbid his army of delicate snowflakes be offended that their Orange Jesus be prohibited to run again for attempting to interrupt the peaceful transfer of power. Very legal and very cool.</p><p>Now? Donald characterizes people as "seditious" or "insurrectionists" with abandon. The video reminding Service Members of their obligation to disobey illegal orders is factual and, in a sane environment, should not be contentious. And yet, Donald characterized those that participated in the video as seditious insurrectionists. Hang them! But pardon those involved in Donald's Day of Love and settle with Ashli Babbitt's family (who was, rightly, killed while she tried to attack members of Congress). The facts surrounding the killings of Ashli and Renee could not be more different, and yet Ashli apparently should be revered while Renee is villainized? Guess Renee wasn't driving for the benefit of DJT, bummer.</p><p>Even yesterday, as Minneapolis leadership spoke out against the Federal occupation of their state, Donald similarly asserted these leaders are "inciting insurrection" (something with which Donald is, in fact, uniquely familiar).</p><p>"Domestic terrorism" and "enemies from within" are also terms that have been bastardized by this Administration. Forgive me if I find it hard to believe that the unarmed victims who were brutally murdered by the Federal government are the "domestic terrorists" in these tragedies.</p><p>Are people scared to go to the grocery store and get haircuts because of Renee Good and Alex Pretti? Are they really the "terrorists" here?? Or are people staying in because of the current Federal occupation of their city? Gee hmm, I guess it is really hard to say until Bovino finishes his investigation of Pretti's aCtS of TeRrOr. We had best wait with bated breath.</p><p>But don't worry, you can't get shot if you stay indoors. Except maybe now you can, since ICE has decided to not only flout the First and Second Amendments, but now to also, allegedly, flout the Fourth Amendment. I fear next we'll see someone get shot for having a gun in their own house during a Donald-sponsored attempted-kidnapping-turned-murder.</p><p>In closing, I will acknowledge that I, too, have been using loaded language. "Suspect" versus "victim" and, indeed, "killing" versus "murder". As an aside, Babbitt was not just a killing, but actually even a justified "execution" (i.e., having a legal basis). Having cognized videos of these most recent events from many angles, which is more than it seems Donald, Bovino, and Noem have done, I feel at least somewhat more qualified to call Good and Pretti "victims" and these tragedies "murders". There sure is a dearth of facts to support an opposite conclusion.</p><p>We are due investigations that will bear out more facts (even as Bovino decries the "freeze-frame adjudication of a crime scene" that counters his <em>entirely</em> fictitious narrative). I am hopeful Minnesota can effectuate these investigations, as this Administration cannot be trusted. I am comforted that murder does not have a statute of limitations, nor can a State murder charge be pardoned by our malignant-narcissist-in-chief. The pendulum will swing the other way eventually, and I hold out hope for inevitable Justice (not JuStIcE, as Bondi, Noem, and this Administration at large are wont to dispense).</p><p><strong><em>Do not kid yourself: Good and Pretti are not "domestic terrorists". These people are you, and these people are me.</em></strong> They are US citizens who were documenting a tyrannical government as it continues to violate constitutional rights (which are inherent in <em>people</em>, citizens or otherwise), as enabled by a complicit, spineless Congress. We should all aspire to be so courageous as Good and Pretti.</p><p>So fuck Donald. Fuck Hegseth. Fuck Bondi. Fuck Noem. And fuck Bovino.</p><p>These people are dishonest in the worst way (as much as I like to believe that Donald is also incompetent) and are entirely divorced from reality, as it does not serve them. We must reject their fictitious, curated "narrative" and must not lose footing in our shared, fact-based reality, especially as their language is specifically engineered to erode the very words we rightly use to describe them and their abhorrent actions.</p><p>Donald <em>is</em> an insurrectionist, these people <em>are</em> seditious, they <em>do</em> encourage domestic terrorism, Congress <em>is</em> complicit, and Good and Pretti were <em>murdered</em>. May we not be next.</p>]]></content:encoded></item><item><title><![CDATA[On Our Post-Truth Society]]></title><description><![CDATA[I asked ChatGPT to go fuck itself, and this is what it said.]]></description><link>https://autologue.io/on-our-post-truth-society/</link><guid isPermaLink="false">6892b9d14e9a7b0334bcbc8b</guid><category><![CDATA[dumb]]></category><category><![CDATA[fucked]]></category><dc:creator><![CDATA[me]]></dc:creator><pubDate>Wed, 06 Aug 2025 03:30:39 GMT</pubDate><media:content url="https://autologue.io/content/images/2025/08/Screenshot-2025-08-05-at-9.24.38-PM.png" medium="image"/><content:encoded><![CDATA[<img src="https://autologue.io/content/images/2025/08/Screenshot-2025-08-05-at-9.24.38-PM.png" alt="On Our Post-Truth Society"><p>This post has been percolating for a while, and I received an email today that finally helped crystalize some thoughts. The email, titled "We asked ChatGPT what makes the perfect charger", made me wonder: "who even cares?"</p><p>(btw the image for this post is shitty on purpose, so you know a human made it)</p><h3 id="fuck-ai">Fuck AI</h3><p>It isn't like ChatGPT actually <em>reasons</em> or even <em>thinks, </em>as much as the apparent majority of people want to believe that it does. Barring any such genuine thought, why should anybody care what ChatGPT has to say? At best, "AI" mashes up sentiment from various corners of the internet (and other plagiarized sources; pls @me, Zuck) and vomits out seemingly coherent slop that tricks readers into placing some level of importance on its output. But hey, thanks for sending me an email with a bulleted list that your product happens to satisfy. So cool. <em>#unsubscribe</em></p><p>Could "AI" be more useful than a search engine someday? Maybe. Especially given the SEO hell that we've been enduring for some time now. Thanks for sucking, Google. But do I trust "AI" in its current iteration? Not even a little.</p><p>I can't stand when people try to parrot an "AI Summary" at me like it's an authoritative source. The vast majority of questions that I've posed to AI have yielded incorrect answers. I tried my hand at "vibe coding" last weekend (what a rush!), and ChatGPT was wholly ineffective at resolving my issues. They were issues that <em>it</em> even created! It turned out there was a whole separate library that ChatGPT did not know to reveal, but which Google readily surfaced.</p><p>Could it be my own personal failing as a reluctant "prompt engineer"? 🤮 Perhaps, at least in that instance.</p><p>Other "AI" failings include incorrectly listing product specs when asked to compare different binocular offerings (what a challenging problem), manufacturing textual excerpts of website "sources", and providing an incomplete answer when asked for a bike tyre recommendation (i.e., only offering a strong recommendation for a specific rubber compound at the very end of the chat; where was that insight earlier!).</p><p>But does any of this even matter? The public, AI companies, and especially company execs, are blindly forging ahead. Racing, allegedly, ever closer to AGI. <em>So, so magnificent.</em> "It will save time but it still needs human supervision," they say. "Everyone else is doing this, so we must, too."</p><p>To which I says: a tool that is right only 99% of the time is still fundamentally worthless, at least in some applications, as humans will be lulled into a sense of complacency. Either people will not fully appreciate the limits of the tool or they will be too time-constrained to properly review the output, ultimately inadvertently introducing (subtle?) errors into the world. Made all the more dangerous by the heady façade of genuine conception.</p><p>Case in point: people blindly relying on AI summaries; chatting with AI on a daily basis and taking its slop as gospel; or extolling its virtues and claiming it engaged in actual <em>innovation</em> (I had someone tell me they asked it to invent a dog poop removal device). Sure.</p><p>AI slop is also particularly insidious. It is so, so easy to generate an incredible amount of content. Content that is then much more slowly <em>consumed</em> (I absolutely cannot stand that term; that's been a potential post topic for some time). It's basically a DDOS attack, but for the human attention span.</p><p>Why do people pass along content that they themselves likely haven't taken the time to fully digest? (In stark contrast to human-produced content, where the author actually bears the disproportionate burden of creation; btw you're welcome for this absolute <em>gem</em> of a post, and I haven't even been drinking... yet).</p><h3 id="fuck-donald">Fuck Donald</h3><p>Eerily, all of this seems to mirror the current political climate, where a certain orange and not-yet-Luigied snowflake frames anything negative as a hoax, a political hit job, or just plain nasty. Please, slurp down a gigantic bowl of dicks, <em>Donald</em>. Really swish them around on their way down your turkey neck. And maybe give me a mean nickname. That'll really show me.</p><p>The shear amount of <em>shit</em> produced by this administration has been incredible. We are only six months in, and every day feels like we are plumbing new depths, delving ever deeper into the pit of despair.</p><p>Even in spite of Donald's Daily Deluge of Dogshit™, half of the country is still apparently happy to take what he and his other complicit shitbags say as gospel, having no question as to veracity. By contrast, anything from the "legacy media" must be approached with <em>cRiTiCaL ThInKiNg</em>. But yes, please, let's all defer to the octogenarians, pedophiles, influences, and whatever the hell the manosphere is. Praise be, thank God for the new media!</p><h3 id="and-fuck-all-this-shit">And Fuck All This Shit</h3><p>All that to say: there is one population of people who are happy to have AI lube them up in slop, greasing their eyeballs until their brain is numb with content in an effort to stave off boredom from real life, and there is another population of people who have been diverging from our formerly shared political reality, guzzling down asinine falsehoods from our Pedo in Chief (and Karoline Leavitt, what an abhorrent human) and begging for more. These populations are certainly not mutually exclusive.</p><p>I hope there are still (many?🤞🏼) people who fall outside these circles and that actually apply critical thinking, and not in the "Take America Back" (from what, liberty? freedom?) sense of the term.</p><p>Sadly, it is easier to take both ChatGPT's extreme indifference toward accurate/inaccurate statements (again, it can't think; it doesn't <em>know</em> what is true) and Donald's chronic NPD-riddled version reality (he does not know <em>Truth</em>™, either) at face value. To actually interrogate and engage with statements takes time, effort, and care, and sadly most people just don't seem to have that to give. Especially not when faced with the sheer volume of utter tripe that roams the Internet and spews from Donald's gullet.</p><p>I feel like this post has big "old man yells at cloud" energy (BOM-YACE, not to be confused with BDE), and maybe I'm just getting old. But I make no apologies: I don't think this iteration of "AI" is <em>it</em>, and I really don't think subsequent iterations will manifest AGI (as much as Sam, Elon, and Zuck want us all to believe that).</p><p>All that notwithstanding: please, MechaHitler, tell me what to <em>feel.</em></p>]]></content:encoded></item><item><title><![CDATA[CFexpress for Less?]]></title><description><![CDATA[Described as a DIY CFexpress card, I decided to take a look at what's basically a 2230 M.2 to CFexpress adapter.]]></description><link>https://autologue.io/cfexpress-for-less/</link><guid isPermaLink="false">6456a2ced7768205bba49d97</guid><category><![CDATA[modlog]]></category><dc:creator><![CDATA[me]]></dc:creator><pubDate>Sat, 06 May 2023 20:52:18 GMT</pubDate><media:content url="https://autologue.io/content/images/2023/05/cfexpr.jpg" medium="image"/><content:encoded><![CDATA[<h3 id="what-s-this-now">What's this now?</h3><img src="https://autologue.io/content/images/2023/05/cfexpr.jpg" alt="CFexpress for Less?"><p>Imagine my surprise when I learned that CFexpress cards actually use NVMe at their core. It turns out CFexpress Type B uses two PCIe Gen3 lanes, with a maximum duplex speed of 2 GB/s. Conveniently, the Type B form factor is big enough that a 2230 M.2 drive can fit within it.</p><p>As a result, the "DIY CFexpress" adapters use a PCB that has no active components to effectively translate one connector to another connector. I really like that these adapters have no active components, because, it seems to me, that should limit the potential for variability between sellers/products (barring signal quality issues, but the traces are quite short). Also, as compared to a normal CFexpress card, these adapters include an outer case that is entirely CNC'd aluminum. I am hopeful that will to dissipate heat better than the normal plastic/metal mix.</p><p>Pictured above are two adapters from <em>Sintech</em>, which are also linked here for convenience (<a href="https://www.amazon.com/dp/B00KZIB1PU">raw aluminum</a> | <a href="https://www.amazon.com/dp/B0BJKNPPXZ">anodized black</a>). Surprisingly, buying from AliExpress doesn't seem to offer much in the way of savings (at least that I could see).</p><p>That said, going the DIY route has the potential to offer substantial cost savings. Call it $45 for an adapter and $160 for a <a href="https://www.amazon.com/dp/B0BQG6JCRP">1 TB 2230 M.2 drive</a> (or even apparently $170 for a <a href="https://www.cdw.com/product/micron-2400-ssd-2-tb-pcie-4.0-nvme/7393553">2 TB drive</a>), and you have a capac-eous (pronounced kuh-PAY-shus) CFexpress card for ~$150-$750 less higher-end CFexpress card options. As an aside, that 2 TB price seems shockingly low to me; I paid closer ot $400 for the 2 TB drive that I had handy, but that was a long time ago and flash prices are rumored to continue plummeting this year.</p><p>Having put together two DIY cards using the above-linked drives (the raw aluminum is the 1 TB Sabrent 2230 and the anodized black is the 2 TB Micron 2400), I can say that my initial impression was very favorable. Yes, you give up two PCIe lanes and it's <em>only</em> Gen3, but cameras don't really need <em>that</em> much bandwidth (I mean, beyond the already generous 2 GB/s bandwidth contemplated by the Type B specification).</p><h3 id="so-where-s-the-catch">So, where's the catch?</h3><p>Well, physically speaking, it is a tight fit. I think I remember the documentation mentioning not to use too much thermal paste (yes, paste; what a mess), otherwise it could negatively impact the thickness of the card and cause fitment issues. I had initially used a graphite sheet and I also tried a 0.5 mm thermal pad, and both definitely made it difficult to pop the card in and out of the camera. Beyond that, I'm pretty happy with the design and the included stickers are a nice thought (though there is no 2 TB sticker!).</p><p>Technologically speaking, I think there is a bit more of a catch. And that brings us to the motivation for this blog post. After the realization that CFexpress cards are really just NVMe drives, I sicced <code><a href="https://www.smartmontools.org/">smartctl</a></code> on my 256 GB SanDisk card to see what was reported back:</p><pre><code class="language-shell">=== START OF INFORMATION SECTION ===
Model Number:                       WDC SanDisk CFexpress B SDCFE-256G NVMFW
Serial Number:                      --
Firmware Version:                   RO106CFP
PCI Vendor/Subsystem ID:            0x15b7
IEEE OUI Identifier:                0x001b44
Total NVM Capacity:                 256,060,514,304 [256 GB]
Unallocated NVM Capacity:           0
Controller ID:                      1
NVMe Version:                       1.3
Number of Namespaces:               1
Local Time is:                      Sun Apr 30 16:38:47 2023
Firmware Updates (0x14):            2 Slots, no Reset required
Optional Admin Commands (0x0016):   Format Frmw_DL Self_Test
Optional NVM Commands (0x001f):     Comp Wr_Unc DS_Mngmt Wr_Zero Sav/Sel_Feat
Log Page Attributes (0x02):         Cmd_Eff_Lg
Maximum Data Transfer Size:         8192 Pages
Warning  Comp. Temp. Threshold:     80 Celsius
Critical Comp. Temp. Threshold:     90 Celsius

Supported Power States
St Op     Max   Active     Idle   RL RT WL WT  Ent_Lat  Ex_Lat
 0 +     2.50W       -        -    0  0  0  0        0       0
 1 +     2.50W       -        -    1  1  1  1        0       0
 2 +     1.70W       -        -    2  2  2  2        0       0
 3 -   0.0250W       -        -    3  3  3  3     5000    9000
 4 -   0.0025W       -        -    4  4  4  4     5000   44000

=== START OF SMART DATA SECTION ===
SMART overall-health self-assessment test result: PASSED

SMART/Health Information (NVMe Log 0x02)
Critical Warning:                   0x00
Temperature:                        31 Celsius
Available Spare:                    100%
Available Spare Threshold:          10%
Percentage Used:                    0%
Data Units Read:                    702,309 [359 GB]
Data Units Written:                 622,354 [318 GB]
Host Read Commands:                 4,701,192
Host Write Commands:                630,513
Controller Busy Time:               40
Power Cycles:                       5,015
Power On Hours:                     61
Unsafe Shutdowns:                   43
Media and Data Integrity Errors:    0
Error Information Log Entries:      0
Warning  Comp. Temperature Time:    0
Critical Comp. Temperature Time:    0
Thermal Temp. 1 Transition Count:   15
Thermal Temp. 1 Total Time:         2554</code></pre><p>Interesting. But mainly for reasons that will become apparent later.</p><p>Now, I didn't actually look at the SanDisk CFexpress card first. I had only looked at the SanDisk card after evaluating the performance of the DIY cards. In testing, the 1 TB card appeared to perform better than the 2 TB card. The 1 TB Sabrent M.2 drive is TLC, while the 2 TB Micron M.2 drive is QLC. There actually isn't much discussion of DIY CFexpress cards that I could find, but I did see some suggestion that TLC flash would fare better than QLC flash, so perhaps that result wasn't surprising.</p><p>Don't get me wrong, I could write unlimited burst RAW to both DIY cards, and 4k30 wasn't a problem either. The difference was only apparent when trying to record 4k60. The 1 TB card seemingly had no problems writing "up to 360 Mbps," per the camera manual, while the 2 TB card would choke. It didn't really make sense though, because, at least in testing using a CFexpress reader, both cards were more than capable.</p><p>I'd also seen something on Anglebird's website that I thought was strange. Angelbird notes that the 4 TB card is only compatible with the Nikon Z9 and a RED 8K camera:</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://autologue.io/content/images/2023/05/Screenshot-2023-05-06-at-1.56.25-PM.png" class="kg-image" alt="CFexpress for Less?" srcset="https://autologue.io/content/images/size/w600/2023/05/Screenshot-2023-05-06-at-1.56.25-PM.png 600w, https://autologue.io/content/images/size/w1000/2023/05/Screenshot-2023-05-06-at-1.56.25-PM.png 1000w, https://autologue.io/content/images/size/w1600/2023/05/Screenshot-2023-05-06-at-1.56.25-PM.png 1600w, https://autologue.io/content/images/2023/05/Screenshot-2023-05-06-at-1.56.25-PM.png 2094w" sizes="(min-width: 1200px) 1200px"><figcaption>Nevermind the $1,799.99 price, why is compatibility limited for the 4 TB card???</figcaption></figure><p>I have nothing to corroborate what follows, because I'm not going to spend $1.8k on a CFexpress card (and I haven't reached out to Angelbird), but I'm wondering if it isn't because of power consumption. I'll note that other (more?) plausible explanations include, but are not limited to, firmware limitations (hellooooo FAT) or even just a slight increase in card thickness.</p><p>But, before I continue blathering, let's take a look at the <code>smartctl</code> output for the other cards.</p><p>For the 1 TB Sabrent card:</p><pre><code class="language-shell">=== START OF INFORMATION SECTION ===
Model Number:                       Sabrent SB-2130-1TB
Serial Number:                      --
Firmware Version:                   R21B47.1
PCI Vendor/Subsystem ID:            0x1987
IEEE OUI Identifier:                0x6479a7
Total NVM Capacity:                 1,024,209,543,168 [1.02 TB]
Unallocated NVM Capacity:           0
Controller ID:                      0
NVMe Version:                       1.4
Number of Namespaces:               1
Local Time is:                      Sun Apr 30 14:47:39 2023 MDT
Firmware Updates (0x14):            2 Slots, no Reset required
Optional Admin Commands (0x0017):   Security Format Frmw_DL Self_Test
Optional NVM Commands (0x005f):     Comp Wr_Unc DS_Mngmt Wr_Zero Sav/Sel_Feat Timestmp
Log Page Attributes (0x1e):         Cmd_Eff_Lg Ext_Get_Lg Telmtry_Lg Pers_Ev_Lg
Maximum Data Transfer Size:         64 Pages
Warning  Comp. Temp. Threshold:     83 Celsius
Critical Comp. Temp. Threshold:     85 Celsius

Supported Power States
St Op     Max   Active     Idle   RL RT WL WT  Ent_Lat  Ex_Lat
 0 +     5.00W       -        -    0  0  0  0        0       0
 1 +     2.40W       -        -    1  1  1  1        0       0
 2 +     1.92W       -        -    2  2  2  2        0       0
 3 -   0.0700W       -        -    3  3  3  3     5000   10000
 4 -   0.0050W       -        -    4  4  4  4     6000   44000</code></pre><p>And for the 2 TB Micron card:</p><pre><code class="language-shell">=== START OF INFORMATION SECTION ===
Model Number:                       Micron_2400_EEFDKBK2T0QFM
Serial Number:                      --
Firmware Version:                   23A24013
PCI Vendor/Subsystem ID:            0x1344
IEEE OUI Identifier:                0x00a075
Controller ID:                      0
NVMe Version:                       1.4
Number of Namespaces:               1
Local Time is:                      Sun Apr 30 14:53:28 2023 MDT
Firmware Updates (0x14):            2 Slots, no Reset required
Optional Admin Commands (0x0017):   Security Format Frmw_DL Self_Test
Optional NVM Commands (0x005f):     Comp Wr_Unc DS_Mngmt Wr_Zero Sav/Sel_Feat Timestmp
Log Page Attributes (0x1e):         Cmd_Eff_Lg Ext_Get_Lg Telmtry_Lg Pers_Ev_Lg
Maximum Data Transfer Size:         32 Pages
Warning  Comp. Temp. Threshold:     87 Celsius
Critical Comp. Temp. Threshold:     90 Celsius

Supported Power States
St Op     Max   Active     Idle   RL RT WL WT  Ent_Lat  Ex_Lat
 0 +     9.00W       -        -    0  0  0  0        0       0
 1 +     4.60W       -        -    1  1  1  1        0       0
 2 +     3.80W       -        -    2  2  2  2        0       0
 3 -   0.0250W       -        -    3  3  3  3     5000    3000
 4 -   0.0040W       -        -    3  3  3  3     8000   35000</code></pre><p>Do you see Watt I mean?</p><h3 id="and-finally-my-theory-">And finally, my theory:</h3><p>I'm wondering if CFexpress cards are as expensive as they are because their firmware is specially tuned to provide consistent/minimum write speeds <em>within a certain power budget</em>. Take a look at the maximum Power State that was reported for each of the three cards:</p><ul><li>2.5 W for the 256 GB SanDisk card</li><li>5.0 W for the 1 TB Sabrent card (+100% compared to SanDisk)</li><li>9.0 W for the 2 TB Micron card (<strong>+260%</strong> compared to SanDisk)</li></ul><p>Interestingly, Angelbird lists the maximum power consumption as 2.4 W for the whole line of <a href="https://www.angelbird.com/prod/av-pro-cfexpress-mk2-type-b-2893/?category=238#specifications">MK2 cards</a>, but maybe the website is wrong and the 4 TB card is different? Who knows. It's literally unknowable.</p><p>But maybe, <em>just maybe</em>, my camera did not like supplying NINE watts to the Micron card. I actually hadn't paid much attention to NVMe Power States in the past, but it turns out that they are configurable!</p><h3 id="throttle-thyself">Throttle Thyself</h3><p>In researching NVMe Power States, I found a <a href="https://medium.com/@krisiasty/nvme-performance-vs-power-management-150f5e2cd94">blog post</a> where one enterprising individual was trying to achieve the opposite goal: they had a drive that was exhibiting reduced performance due to Power State limitations and they were trying to UNLEASH THE DRIVE.</p><p>Armed with the Power States returned by <code>smartctl</code> and the knowledge I'd gleaned from the blog post, I used the command below to set a different, lower maximum power state:</p><pre><code class="language-shell">$ sudo nvme set-feature /dev/nvme1 -f 2 -v 2 -s</code></pre><p>To break it down: <code>nvme</code> is in the <code>nvme-cli</code> package, <code><a href="https://manpages.debian.org/testing/nvme-cli/nvme-set-feature.1.en.html">set-feature</a></code> sets a specified NVMe feature (i.e., <code>2</code> for Power Management, as specified by <code>-f</code>). The value <code>-v</code> is specified to be <code>2</code>, which corresponds to Power State #2 (3.8 W) as reported by <code>smartctl</code>. I'll also note that <code>-s</code> is needed to ensure the change persists across resets (which was unfortunately omitted from the blog post I found). Finally, one can confirm that the change was successful using the  command below, which should thus indicate Power State #2 is set rather than Power State #0.</p><pre><code class="language-shell">$ sudo nvme get-feature /dev/nvme1 -f 2 -H</code></pre><p>In testing the card's speed using a CFexpress card reader, the card definitely does exhibit reduced performance (now writing closer to 400 MB/s), but hopefully it also consumes less power and generates less heat. When tested in the camera, Power State #1 (4.6 W, which is closer to the Sabrent card) enabled longer 4k60 recording, though it still ultimately failed. I eventually settled on Power State #2, since all other functionality remained unchanged at a lower maximum power drawn and 4k60 still failed.</p><h3 id="closing-thoughts">Closing Thoughts</h3><p>Overall, I feel good about the 2 TB Micron card and hopefully having changed the maximum power consumption from 9.0 W to 3.8 W. I say "hopefully", becuase I wonder if the camera might still set its own Power State (in which case real CFexpress cards would still be desirable for their more specialized firmware and Power States). I suppose this could be established through testing, and I will update this post if I do so.</p><p>I may also try to change the maximum Power State for the 1 TB Sabrent card (e.g., from 5.0 W to 2.4 W) to see how that impacts performance, given Power State #1 is the same as the stated power draw for the Angelbird cards and slightly below the SanDisk card that I have. Again, I will update this if I end up testing that.</p><h3 id="other-notes">Other Notes</h3><p>Unfortunately, <code>nvme-cli</code> <a href="https://github.com/linux-nvme/nvme-cli/issues/859">doesn't know how to work with NVMe drives via USB</a>, which is most CFexpress card readers. I have a <a href="https://eshop.macsales.com/item/OWC/TB3CFXRDR/">Thunderbolt CFexpress</a> card reader that I use on my Apple Silicon Mac (which properly reports the cards as NVMe devices), but <code>nvme-cli</code> does not compile on macOS. Super.</p><p>So what did I do? Well, perhaps obviously, you can plop the 2230 M.2 drive in a normal M.2 slot, which is what I did using one of my Linux machines. It was very slow and inconvenient, as I had to move the M.2 drive between the Linux box and the CFexpress card adapter (not to mention the thermal paste mess that ensued).</p><p>To the extent I engage in future testing, I've ordered a CFexpress to PCIe adapter to enable me to use <code>nvme-cli</code> with the DIY CFexpress cards, which should alleviate some of that friction. (And, for those keeping track, will mean I'm going from 2230 M.2 =&gt; CFexpress adapter =&gt; PCIe slot, which just makes sense.)</p><hr><p><em>2023.05.08 Update: The CFexpress to PCIe adapter didn't work... I'll have to see if there's another option.</em></p><hr><p><em>2023.05.17 Update: I ordered Sabrent's new <a href="https://sabrent.com/products/rocket-cfx-type-b-memory-card-2tb">2 TB CFexpress card</a>. Output of <code>smartctl</code> is below:</em></p><pre><code class="language-shell">=== START OF INFORMATION SECTION ===
Model Number:                       Sabrent Rocket CFX Pro
Serial Number:                      --
Firmware Version:                   XXIB47.1
PCI Vendor/Subsystem ID:            0x1987
IEEE OUI Identifier:                0x6479a7
Total NVM Capacity:                 2,048,408,248,320 [2.04 TB]
Unallocated NVM Capacity:           0
Controller ID:                      1
NVMe Version:                       1.4
Number of Namespaces:               1
Local Time is:                      Wed May 17 13:49:04 2023 MDT
Firmware Updates (0x14):            2 Slots, no Reset required
Optional Admin Commands (0x0017):   Security Format Frmw_DL Self_Test
Optional NVM Commands (0x005f):     Comp Wr_Unc DS_Mngmt Wr_Zero Sav/Sel_Feat Timestmp
Log Page Attributes (0x1e):         Cmd_Eff_Lg Ext_Get_Lg Telmtry_Lg Pers_Ev_Lg
Maximum Data Transfer Size:         8192 Pages
Warning  Comp. Temp. Threshold:     83 Celsius
Critical Comp. Temp. Threshold:     85 Celsius

Supported Power States
St Op     Max   Active     Idle   RL RT WL WT  Ent_Lat  Ex_Lat
 0 +     5.00W       -        -    0  0  0  0        0       0
 1 +     2.40W       -        -    1  1  1  1        0       0
 2 +     1.92W       -        -    2  2  2  2        0       0
 3 -   0.0300W       -        -    3  3  3  3     5000   10000
 4 -   0.0050W       -        -    4  4  4  4     6000   44000</code></pre><p><em>I'll note this is largely similar to the 1 TB 2230 NVMe drive, including a max power consumption of 5 W. I may try to set a max Power State of 2.4 W if I can find a good CFexpress/PCIe solution and see what happens. Also, makes me want to get a card that is actually advertised at 2.4 W, but is reduced power consumption worth spending 2x more?? ...probably. I think first I will need to confirm whether these cards actually exhibit increased power consumption.</em></p><p><em>Interestingly, "Maximum Data Transfer Size" for the CFexpress card is 8,192 pages, which is consistent with the SanDisk card and substantially more than either M.2 NVMe drive (32 or 64 pages).</em></p><p><em>My other thought is my DIY 1 TB Sabrent CFexpress card is probably actually pretty close to the actual 1 TB Sabrent CFexpress card, for probably nearly $250 less. Heckin' deal.</em></p>]]></content:encoded></item><item><title><![CDATA[Happy Birthday, "me"]]></title><description><![CDATA[With just over a year since my last post and exactly two years since my first post, I thought perhaps it was time to drop a quick note. Lest 2022 pass with no posts at all. 😔]]></description><link>https://autologue.io/happy-birthday-me/</link><guid isPermaLink="false">637a13ca5dea2f0786450af1</guid><dc:creator><![CDATA[me]]></dc:creator><pubDate>Sun, 20 Nov 2022 21:34:38 GMT</pubDate><media:content url="https://autologue.io/content/images/2022/11/20220812_033505_1FD4F214-1.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://autologue.io/content/images/2022/11/20220812_033505_1FD4F214-1.jpg" alt="Happy Birthday, "me""><p>In short, it's been an incredibly busy year, work-wise. While I have had time for numerous projects and hobbies (yay, photography!), most haven't really warranted a blog post. There hasn't been much (any) progress on the Xsata project, though that remains a priority, time and space permitting.</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://autologue.io/content/images/2022/11/20220730_174404_D1B1F4F0.jpg" class="kg-image" alt="Happy Birthday, "me"" srcset="https://autologue.io/content/images/size/w600/2022/11/20220730_174404_D1B1F4F0.jpg 600w, https://autologue.io/content/images/size/w1000/2022/11/20220730_174404_D1B1F4F0.jpg 1000w, https://autologue.io/content/images/size/w1600/2022/11/20220730_174404_D1B1F4F0.jpg 1600w, https://autologue.io/content/images/size/w2400/2022/11/20220730_174404_D1B1F4F0.jpg 2400w" sizes="(min-width: 1200px) 1200px"><figcaption>Potentially the coolest picture I've ever taken. Love the splayed tail feathers and the tiny feets. Totally unedited.</figcaption></figure><p>I did design two circuit boards this year: one for a totally custom keyboard that I'm working on and the other for a weather station. Both projects are coming along nicely, though I still need to design a case for the keyboard. The goal is to have the keyboard case CNC'd out of aluminum; it should look pretty svelte if it ever comes to fruition.</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://autologue.io/content/images/2022/11/68142275184__267B72FA-F341-4B53-9038-CFA54E6EB19B-1.jpeg" class="kg-image" alt="Happy Birthday, "me"" srcset="https://autologue.io/content/images/size/w600/2022/11/68142275184__267B72FA-F341-4B53-9038-CFA54E6EB19B-1.jpeg 600w, https://autologue.io/content/images/size/w1000/2022/11/68142275184__267B72FA-F341-4B53-9038-CFA54E6EB19B-1.jpeg 1000w, https://autologue.io/content/images/size/w1600/2022/11/68142275184__267B72FA-F341-4B53-9038-CFA54E6EB19B-1.jpeg 1600w, https://autologue.io/content/images/size/w2400/2022/11/68142275184__267B72FA-F341-4B53-9038-CFA54E6EB19B-1.jpeg 2400w" sizes="(min-width: 1200px) 1200px"><figcaption>Controller for the keyboard PCB. It's not stupid if it works? Kinda fucky with the spacebar stabilizer in place though.</figcaption></figure><p>I've built several weather stations over the years, but they've always been handwired and the PCBs definitely make it much easier to assemble more of them. I've toyed with selling them on Etsy, but that's contrary to my goal of never providing support for anything done as a hobby.</p><p>I suppose there are also still a couple blog posts in the works, namely about my VPN/network setup. I think about starting those from time to time, but, again, I've been pretty spent at the ends of most days lately.</p><p>I would also like to continue developing my DNS-based shortcut service that I run on my local network, which is apparently akin to Google's "golinks." [<a href="https://iafisher.com/blog/2020/10/golinks">1</a>] [<a href="https://github.com/ryanpbrewster/golinks">2</a>] [<a href="https://github.com/adamyi/golinks">3</a>] That will also hopefully be the subject of a post someday, though I think at this point I coded a minimum viable product of it about a year ago and it's seen little development ever since.</p><p>And lastly, I still need to finish the blog post that was the reason for starting this blog in the first place. A little ridiculous to think that the primary reason for screaming into the void still hasn't seen the light of day, but here we are. That's been getting less thought in my day-to-day life, but the problem it aims to address is as relevant as ever.</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://autologue.io/content/images/2022/11/20221001_182231_4873A0D7.jpg" class="kg-image" alt="Happy Birthday, "me"" srcset="https://autologue.io/content/images/size/w600/2022/11/20221001_182231_4873A0D7.jpg 600w, https://autologue.io/content/images/size/w1000/2022/11/20221001_182231_4873A0D7.jpg 1000w, https://autologue.io/content/images/size/w1600/2022/11/20221001_182231_4873A0D7.jpg 1600w, https://autologue.io/content/images/size/w2400/2022/11/20221001_182231_4873A0D7.jpg 2400w" sizes="(min-width: 1200px) 1200px"><figcaption>Fall is just the best, isn't it?</figcaption></figure><p>On a personal note, I am pleased to report that I did a good job of getting out and seeing the world this year (thanks, COVID). But really, that is only another excuse to drop one last picture in before wrapping up.</p><p>All that to say: "I'm still here! And I'm not going anywhere." Perhaps I shouldn't be surprised that my initial hopes for this blog were overly ambitious (as so often is the case), but I do hope to have more time in the new year (and to make progress on the Xsata project once I have more space to actually work on it, c'mon housing market 🤞🏼).</p>]]></content:encoded></item><item><title><![CDATA[WG + IPv6 + NAT = Dumb.]]></title><description><![CDATA[<p>There are a variety of reasons why I have always had remote access to my home network when away from home (e.g., privacy, Pi-hole, Plex, <s>p</s>etc.). Throughout the years, it's taken a variety of forms: SSH tunneling, <a href="https://openvpn.net/">OpenVPN</a> (first TUN, then TAP), and now <a href="https://www.wireguard.com/">WireGuard</a>.</p><p>Of the various</p>]]></description><link>https://autologue.io/wg-ipv6-nat-dumb/</link><guid isPermaLink="false">61401a001e4079034d891dff</guid><category><![CDATA[dumb]]></category><category><![CDATA[VPN]]></category><category><![CDATA[firewall]]></category><dc:creator><![CDATA[me]]></dc:creator><pubDate>Sat, 13 Nov 2021 22:39:30 GMT</pubDate><content:encoded><![CDATA[<p>There are a variety of reasons why I have always had remote access to my home network when away from home (e.g., privacy, Pi-hole, Plex, <s>p</s>etc.). Throughout the years, it's taken a variety of forms: SSH tunneling, <a href="https://openvpn.net/">OpenVPN</a> (first TUN, then TAP), and now <a href="https://www.wireguard.com/">WireGuard</a>.</p><p>Of the various solutions, WireGuard has definitely been the most straightfoward to configure. Seriously, 10/10: would recommend. In fact, there are probably some interesting and specific use cases that could be the subject of a future blog post. Unfortunately, none of those are this.</p><h3 id="first-some-background">First, some background</h3><p>WireGuard uses a cryptokey routing table, where each peer (identified by a public key) has an associated set of allowed IP addresses. (<em>See</em> the <a href="https://www.wireguard.com/papers/wireguard.pdf">whitepaper</a>, pg. 4.) This enables some of those interesting use cases to which I alluded, but it also proves problematic in the context of IPv6.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://autologue.io/content/images/2021/09/Screen-Shot-2021-09-13-at-10.11.59-PM-1.png" class="kg-image" alt srcset="https://autologue.io/content/images/size/w600/2021/09/Screen-Shot-2021-09-13-at-10.11.59-PM-1.png 600w, https://autologue.io/content/images/size/w1000/2021/09/Screen-Shot-2021-09-13-at-10.11.59-PM-1.png 1000w, https://autologue.io/content/images/size/w1600/2021/09/Screen-Shot-2021-09-13-at-10.11.59-PM-1.png 1600w, https://autologue.io/content/images/2021/09/Screen-Shot-2021-09-13-at-10.11.59-PM-1.png 1936w" sizes="(min-width: 720px) 720px"><figcaption>An example cryptokey routing table from the <a href="https://www.wireguard.com/papers/wireguard.pdf">WireGuard whitepaper</a></figcaption></figure><p>See, the list of allowed IPs is static (both at the client and the server; both are "peers"), so in instances where there is a changing IPv6 prefix (as is the case with my ISP), there is no easy way to update a client's IPv6 address. Further, in contrast to OpenVPN, there is no mechanism that can be used to push configuration options to a client, nor can DHCP be used.</p><p>That means, absent the drivel that follows, I don't think it would be possible to access the IPv6 internet without a headache every time I get a different IPv6 prefix from my ISP. And you might ask: who even cares about the IPv6 internet (at least right now)? Good question; I ask myself that sometimes. "But it's the future™," they'll say. Anyway, enough about the why (and, apparently most importantly, the why not).‌</p><h3 id="and-now-the-foreground">And now, the foreground</h3><p>The initial solution to my IPv6 problem was to pick an internal prefix for IPv6 traffic, so each WireGuard peer would have its own <a href="https://en.wikipedia.org/wiki/Unique_local_address">unique local address</a> (in the fd00::/8 address space). I then set up an outbound NAT rule to translate traffic having the source IPv6 prefix to the interface address of my WAN interface.</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://autologue.io/content/images/2021/09/Screen-Shot-2021-09-19-at-6.48.52-PM-1.png" class="kg-image" alt srcset="https://autologue.io/content/images/size/w600/2021/09/Screen-Shot-2021-09-19-at-6.48.52-PM-1.png 600w, https://autologue.io/content/images/size/w1000/2021/09/Screen-Shot-2021-09-19-at-6.48.52-PM-1.png 1000w, https://autologue.io/content/images/size/w1600/2021/09/Screen-Shot-2021-09-19-at-6.48.52-PM-1.png 1600w, https://autologue.io/content/images/2021/09/Screen-Shot-2021-09-19-at-6.48.52-PM-1.png 2012w" sizes="(min-width: 1200px) 1200px"></figure><p>I am fairly certain that the general consensus is that IPv6 and NAT don't go together. Not so much that they can't, just that performance may be better and mainly that the vast address space of IPv6 obviates the need for it. So, maybe not <em>so</em> dumb. Also, it isn't dumb if it works.</p><p>And this solution is where things stayed for many months. Working access to IPv6 paired with the fact that most of my VPN-based traffic appeared to still be largely IPv4 meant that I didn't feel the need to address one last qualm, which brings us to the reason for this post: <a href="https://en.wikipedia.org/wiki/IPv6_address#Temporary_addresses">temporary addresses</a>.</p><p>Unfortunately, my hacky solution meant that all of the IPv6 traffic traveling over the VPN appeared to come from my firewall (i.e., {IPv6 prefix}::0). Is this really a big deal? No. It really, <em>really</em> isn't, becuase that's how IPv4 NAT has worked forever. But it bothered me for two reasons:</p><ol><li>I don't want to have tons of traffic seemingly originating from my 
firewall device. I subscribe to the widely held belief that security through 
obscurity is not security, and I have no problem with making that 
address known. I <em>do</em> have a problem with routinely accessing 
websites from a {IPv6 Prefix}::0/56 address (i.e., an IPv6 address ending in 18 zeroes in hexadecimal format), which could potentially be taken to mean
 that all 4,722,366,482,869,645,213,696 (2<sup>72</sup>) of my addresses in that address space are associated with one another. 
Is that paranoid? Most likely (though I have no doubt companies are doing all they can do analyze IPv6 source addresses). Somewhat more reasonably, I don't like the fact that having multiple devices using the same IP address would make it easier to tie the devices together. Either way, I paid for 128 bits, I'm going to use
 128 bits.</li><li>There is something appealing to rotating through source addresses periodically. This is definitely related to #1, but barring some indication made by the device (e.g., cookies, tokens, session identifiers, GET variables, etc.), there is nothing tying one temporary IPv6 address to another temprorary IPv6 address.</li></ol><p>The answer? <a href="https://docs.opnsense.org/manual/aliases.html">Aliases</a>! Instead of having an outbound NAT rule to translate fd00::/8 traffic to my singular WAN interface address, I created a rule that uses an alias for the translation, which is populated with random, rotating IPv6 addresses. Stupid like a fox amirite?</p><p>Unfortunately, that is easier said than done. See, OPNsense (and likely others) don't offer the option to use just any alias for outbound NAT. Rather, the outbound NAT UI only presents "Host(s)" aliases for selection. Further, even if I could select whatever alias I want, there is no way to create an alias with a dynamic prefix. The dream would be an alias that could be specified as "::{suffix}," where the alias prepends the current IPv6 WAN prefix to the alias for use in whatever firewall rules (a la <a href="https://dynv6.com/">dynv6</a>).</p><p>Fortunately, aliases can be maintained from the command line using <code><a href="https://man.openbsd.org/pfctl">pfctl</a></code>. The script below makes use of <code>pfctl</code> and some unimpressive Bash and Python to keep an alias ("wg_IPv6_NAT") stocked with random IPv6 addresses having the prefix that I am currently assigned by my ISP.</p><pre><code class="language-shell">#!/bin/sh

# Get current IPv6 prefix
IPv6_prefix=$(ifconfig wan_stf | grep inet6 | awk -F" " '{print $2}' | sed 's/::/:/')

# Check if we still have the same prefix based on the first entry in the alias
curr_IPv6_prefix=$(pfctl -t wg_IPv6_NAT -T show | head -n 1 | grep -o "[0-9a-f]\+:[0-9a-f]\+:[0-9a-f]\+:[0-9a-f]\+:")

# Expire old table entries
toGen=2
if [ "$curr_IPv6_prefix" == "$IPv6_prefix" ]; then
  # After 20 minutes
  pfctl -t wg_IPv6_NAT -T expire 1200
else
  # Or if we got a new IPv6 prefix
  pfctl -t wg_IPv6_NAT -T flush
  # And if we did, generate 20 addresses instead of just two
  toGen=20
fi

# Store a set of random IPv6 addresses as a pf table
for i in `seq 1 1 $toGen`
do
  # Generate a random /64 suffix
  rand_suffix=$(python3 -c "import random; print(':'.join('{:x}'.format(random.randint(0, 2**16 - 1)) for i in range(4)))")
  randIPv6="$IPv6_prefix$rand_suffix"

  echo Will add $randIPv6
  # Append the random IPv6 address to the list that is passed to pfctl
  randList="$randList $randIPv6"
done

pfctl -t wg_IPv6_NAT -T add $randList</code></pre><p>The main takeaways from the script are that the IPv6 prefix is pulled from the WAN interface, compared to an existing alias entry, and used to either: 1) generate two new addresses if the prefix of the first alias entry is unchanged with respect to the WAN prefix; or 2) flush the entire table and generate 20 new addresses if there is a new prefix. The random addresses are then generated using a quick <a href="https://stackoverflow.com/questions/21016918/generate-random-ipv6-address">Python call</a> and passed to <code>pfctl</code>.</p><p>This script is called every minute to generate two new addresses, and old addresses fall out of the alias after 20 minutes. This means that I will have a rolling pool of ~40 addresses to draw from. Long term, I will likely tidy up the script, but for now it works.</p><h3 id="closing-thoughts">Closing Thoughts</h3><p>I've been running this setup since the week that I started this blog post, which is to say for several months now. It's been a set-it-and-forget-it type deal, which is excellent. Though that could be because IPv6 connectivity is relatively unimportant in today's Internet, so I don't know if I would notice if there were issues.</p><p>Aside from potentially revising the script, there is one other feature that I would consider implementing: word addresses. How cool would it be to always access the internet from an IPv6 address having words in it (e.g., "::dead:beef" or "::b0b:ca7"). A quick search yields a <a href="https://nedbatchelder.com/text/hexwords.html">script for generating hex words</a>. Combining such a technique with my script would be relatively trivial and could even be applied to all traffic out of my network to the open Internet (not just WireGuard traffic). Maybe someday.</p>]]></content:encoded></item><item><title><![CDATA[Adieu, QR Code Menu Ado]]></title><description><![CDATA[The rise in QR-accessible restaurant menus brought with it privacy concerns. I explore potential remedies.]]></description><link>https://autologue.io/qr-code-menu-ado/</link><guid isPermaLink="false">6158e10b1e4079034d89200c</guid><category><![CDATA[privacy]]></category><category><![CDATA[iOS]]></category><dc:creator><![CDATA[me]]></dc:creator><pubDate>Sat, 23 Oct 2021 23:53:42 GMT</pubDate><media:content url="https://autologue.io/content/images/2021/10/nothx.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://autologue.io/content/images/2021/10/nothx.jpg" alt="Adieu, QR Code Menu Ado"><p>With the increasing prevalence of QR code-based menus, there have been a growing number of articles <a href="https://www.businessinsider.com/online-menu-qr-code-restaurants-bars-tracking-privacy-concerns-report-2021-7">discussing</a> <a href="https://www.cbc.ca/radio/costofliving/there-just-aren-t-enough-houses-for-canadians-to-buy-plus-digital-menus-and-getting-into-sports-betting-1.6173009/scan-qr-code-menus-with-a-side-of-caution-say-privacy-experts-1.6188515">privacy</a> <a href="https://www.makeuseof.com/menu-qr-codes-privacy/">concerns</a>. Personally, I've noticed that some of the QR codes I encounter first direct me to a third-party website before redirecting me to the website of the restaurant in question. While this apparently might be done to enable <a href="https://www.qr-code-generator.com/types/dynamic-url-qr-code/">"dynamic" QR codes</a> (where the target of the QR code can be changed after the fact), this bothers me because it introduces a more centralized third party that has the potential to track patrons across multiple restaurants.</p><p>Granted, addressing this issue does nothing to tackle tracking by third-party restaurant platforms (as might be used for online or mobile ordering). However, I would argue that maintaining decentralized <em>access</em> to restaurant websites still improves privacy, especially in instances where such platforms are not used and the websites are instead standalone or, even better, in PDF form. To date, I have only encountered one restaurant that uses a third-party platform for dining in, though I have continued to be a bit of a hermit with the ongoing pandemic so my experience is not likely to be representative.</p><h3 id="anyways-enough-with-the-what-on-to-the-how">Anyways, enough with the "what," on to the "how"</h3><p>This project started by looking specifically at qrco.de, as most of the third-party QR codes I've encountered are for that domain (and who could forget such a memorable domain name). One of the goals going into this project was to have minimal impact on the usual QR code workflow. I really like that the scanner is integrated into the camera on iOS.</p><p>My initial thought was to do some DNS-based request hijacking to intercept requests for qrco.de (and others, as I happen across them) and process them at a server internal to my home network. Turns out qrco.de provides a <code><a href="https://en.wikipedia.org/wiki/HTTP_302">302 Found</a></code> response to redirect requests, which could be processed server-side in a way that doesn't store any cookies (hello, <code><a href="https://linux.die.net/man/1/curl">curl</a> -I</code>). The target URL could then be provided in response to the intercepted request.</p><p>I initially liked this option, because it would enable more complex processing as needed, for example if a site has a landing page prior to redirection. It also sounded like a lot of interesting problems to solve. For example, qrco.de appears to typically use HTTPS, so I would need to generate a TLS certificate using my personal certificate authority. I would also likely do the interception on the same (virtual) machine that serves my Pi-hole, so I was thinking I would need another IPv4 address to receive the intercepted requests. Downsides of this plan? I would need to always be on my VPN and I think it would likely be less robust.</p><p>And so, my focus instead turned client side. How cool would a QR scanner iOS app be?! But seriously, there is a certain amount of sense to having a privacy-minded QR code scanner app. I haven't done any iOS / macOS app development for the better part of a decade (and a whole application does seem a little ham-handed), so that option wasn't a serious one. However, what <em>was</em> a serious option was <a href="https://support.apple.com/guide/shortcuts/welcome/ios">Shortcuts</a>.</p><h3 id="but-seriously-the-how">But seriously, the "how"</h3><p>I think I first looked at Shortcuts becuase I was thinking I could call a script via SSH (to run the <code>curl</code> command) and then open the result in a browser. A little clunky, but it would have worked. Thankfully, it turns out Shortcuts offers an "Expand URL" function, which "expands and cleans up URLs [that] have been shortened using a URL shortening service." Perfect.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://autologue.io/content/images/2021/10/IMG_A9E591AFEE89-1.jpeg" class="kg-image" alt="Adieu, QR Code Menu Ado" srcset="https://autologue.io/content/images/size/w600/2021/10/IMG_A9E591AFEE89-1.jpeg 600w, https://autologue.io/content/images/size/w1000/2021/10/IMG_A9E591AFEE89-1.jpeg 1000w, https://autologue.io/content/images/2021/10/IMG_A9E591AFEE89-1.jpeg 1284w" sizes="(min-width: 720px) 720px"><figcaption>Imagine if this screenshot weren't 6" tall. Seriously, just imagine it, becuase I can't make this better.</figcaption></figure><p>I was curious to see how the "Expand URL" function worked, namely whether it maintainied cookies across invocations. It wouldn't do me much good if I were resolving redirects and passing them to Safari, all the while unknowingly collecting cookies.</p><p>So I did what any self-actualized human bean would do and set up a dummy webserver. With some help from my frriend <code><a href="https://www.php.net/manual/en/features.commandline.options.php">php</a> -S [bind addr]:80</code>, I wrote a simple PHP script to dump cookies and view requests from my phone.</p><pre><code class="language-php">&lt;?php
// Launch PHP server with 'sudo php -S [bind addr]:80'

// Simple console debugging
error_log("\n");
error_log(implode($_SERVER,", "));
error_log(implode($_COOKIE,", "));

// Borrowed function: "based on original work from the PHP Laravel framework"
if (!function_exists('str_contains')) {
    function str_contains($haystack, $needle) {
        return $needle !== '' &amp;&amp; mb_strpos($haystack, $needle) !== false;
    }
}

// Name to easily change the cookie we're setting
$cookieName = "trackingCookie";

// If we are accessing the tracking URL (i.e., '?trackingURL'), set a cookie and redirect
if(str_contains("$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]", "trackingURL")) {
	setcookie($cookieName, time(), time() + 3600, '/');
	header("Location: http://$_SERVER[HTTP_HOST]/?destination");
// If we are accessing a normal URL (e.g., '?destination'), check for tracking cookie
} else if(isset($_COOKIE[$cookieName])) {
	echo "Cookie '" . $cookieName  . "' has been set!&lt;br&gt;";    
	echo "Value in cookie is: " . $_COOKIE[$cookieName];
} else {
	echo "No cookie.";
}

?&gt;</code></pre><p>Super simple. The important bits are where a cookie is set if the URL is accessed with <code>?trackingURL</code> and then a redirect occurs (i.e., to <code>?destination</code>), at which point the destination page prints whether a cookie was actually set. Ideally, the "Expand URL" function would eat the cookie, such that Safari arrives unfed at the <code>?destination</code> URL.</p><h3 id="onwards-to-the-results-">Onwards, to the results!</h3><p>When the <code>?trackingURL</code> URL is called via the Shortcut, a User Agent of <code>BackgroundShortcutRunner/1137.4 CFNetwork/1312 Darwin/21.0.0</code> is used to access the page. The cookie is then set, the redirect to <code>?destination</code> is followed, and the <code>?destination</code> URL is ultimately returned by the function. Not really relevant, but I assume that the function follows the <code>?destination</code> URL to see if there is yet another redirect, which is good to see. Also, it makes sense to collect cookies along the way in case they are needed at the destination URL.</p><p>The important part: when the <code>?destination</code> URL is accessed in Safari (with a User Agent of <code>Mozilla/5.0 (iPhone; CPU iPhone OS 15_0_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.0 Mobile/15E148 Safari/604.1</code>), it is apparent that no cookie is set yet. So, yes! The "Expand URL" function will work to protect from tracking cookies coming from QR code redirects. Super fucking yay.</p><h3 id="but-wait-another-shortcuts-function">But wait: another Shortcuts function?</h3><p>I should mention that there was another candidate function that I encountered when I was evalauting options. Hellooooooo "Show Web Page." Just imagine: you scan a QR code, get redirected to whatever website in a WebKit view, and then, once you're done, you can close the view and all the cookies are gone with it. Bango bongo, right?</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://autologue.io/content/images/2021/10/IMG_7F13A2E49EFA-1.jpeg" class="kg-image" alt="Adieu, QR Code Menu Ado" srcset="https://autologue.io/content/images/size/w600/2021/10/IMG_7F13A2E49EFA-1.jpeg 600w, https://autologue.io/content/images/size/w1000/2021/10/IMG_7F13A2E49EFA-1.jpeg 1000w, https://autologue.io/content/images/2021/10/IMG_7F13A2E49EFA-1.jpeg 1284w" sizes="(min-width: 720px) 720px"><figcaption>Behold its siren song.</figcaption></figure><p>Sadly, not. Interestingly, it turns out that the "Show Web Page" function and Safari share cookies. That means that, unlike "Expand URL," "Show Web Page" can't be used to follow redirects and happily discard cookies at the end of the journey. What a world it almost was, though.</p><h3 id="imple-menu-tation">Imple-<em>menu</em>-tation</h3><p>Enough lollydicking, finally it's actually time the "how." The implementation I arrived at is a Shortcut that either parses a URL (obtained via the Share Sheet) or pops up a QR code capture screen, "Expand[s that] URL," and passes the resulting URL to Safari. This workflow is further simplified by tying the Shortcut to <a href="https://support.apple.com/en-us/HT211781">Back Tap</a>, so I can easily scan the QR code through the Shortcut rather than the Camera app.</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://autologue.io/content/images/2021/10/Privacy-Parse-URL.png" class="kg-image" alt="Adieu, QR Code Menu Ado" srcset="https://autologue.io/content/images/size/w600/2021/10/Privacy-Parse-URL.png 600w, https://autologue.io/content/images/size/w1000/2021/10/Privacy-Parse-URL.png 1000w, https://autologue.io/content/images/size/w1600/2021/10/Privacy-Parse-URL.png 1600w, https://autologue.io/content/images/size/w2400/2021/10/Privacy-Parse-URL.png 2400w" sizes="(min-width: 1200px) 1200px"><figcaption>I honestly don't know enough about how Shortcuts are packaged to trust that they can be distributed anonymously (nor would I personally trust a Shortcut from just anywhere), so this will have to do. For what it's worth, it took a while to doctor up this doublewide beauty, so at least there's that.</figcaption></figure><h3 id="conclusion">Conclusion</h3><p>Is it perfect? No. But it <em>is</em> serviceable, at least to a point. It does not address whatever tracking cookies might be waiting at the destination, which seems like a logical step for implementing tracking across a number of dining establishments. For that, I will rely on pihole-based DNS filtering and whatever tracking protections are offered by Safari, at least for now.</p><p>Which brings me back to my initial comment about a privacy-minded QR scanner. It feels like scanning QR codes involves a certain reduction in control. In closing, it would be really nice if QR code interactions could basically be sandboxed, which would likely make the most sense as an OS-level feature. Even the ability to open a private tab in Safari via Shortcuts would be helpful. Alas, a pipe can dream. Until that day, I guess "Expand URL" it is.</p>]]></content:encoded></item><item><title><![CDATA[Xsata: Caddy PCB Circuit Design]]></title><description><![CDATA[Designing a circuit to convert signals from a SATA PCB to signals usable by Apple's 2003 drive caddy PCB.]]></description><link>https://autologue.io/xsata-caddy-pcb-circuit-design/</link><guid isPermaLink="false">60eb2ac6d4305006c9fa46bf</guid><category><![CDATA[xsata]]></category><category><![CDATA[modlog]]></category><dc:creator><![CDATA[me]]></dc:creator><pubDate>Sun, 11 Jul 2021 19:49:29 GMT</pubDate><media:content url="https://autologue.io/content/images/2021/07/CaddyPCB-PostImage.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://autologue.io/content/images/2021/07/CaddyPCB-PostImage.jpg" alt="Xsata: Caddy PCB Circuit Design"><p>It has been about two months since my <a href="https://autologue.io/exploring-xserve">first post</a> regarding the Xserve RAID ("XR"). Since then, I have explored the caddy design in greater detail, including the PCB discussed in the earlier post, the geometry of the caddy itself, and potential options for a SATA backplane. While the latter two topics will be discussed in forthcoming posts, this post will again focus on the PCB included in every non-blank caddy. Oh, and I've decided to call the (hopefully inevitable) fruit of this project the "Xsata." Cool.</p><p>I think one of the goals of this project will be to mangle as little of the original XR as possible. That said, the chassis will likely be on the receiving end of some more destructive modifications (thanks, rivets). For... some reason, I guess? Though I am pretty sure that most (if not all) of the soon-to-be-redundant parts will likely be never used again.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://autologue.io/content/images/2021/07/IMG_3084-1.jpg" class="kg-image" alt="Xsata: Caddy PCB Circuit Design" srcset="https://autologue.io/content/images/size/w600/2021/07/IMG_3084-1.jpg 600w, https://autologue.io/content/images/size/w1000/2021/07/IMG_3084-1.jpg 1000w, https://autologue.io/content/images/size/w1600/2021/07/IMG_3084-1.jpg 1600w, https://autologue.io/content/images/2021/07/IMG_3084-1.jpg 2000w" sizes="(min-width: 720px) 720px"><figcaption>Look at the little baby 820-1468-A.</figcaption></figure><p>In that <a href="https://en.wiktionary.org/wiki/in_the_same_vane">vein</a>, I started by ordering a new <a href="https://www.molex.com/molex/search/deepSearch?pQuery=productseries:15134@circuitsloaded:6@materialplatingmating:Tin@numberofrows:1@pitchmatinginterface:1.25mm">"cable assembly"</a> that fits the 6-pin header on the PCB (above). That way, the original connector (and associated SCSI PCB) can remain intact. It is probably also worth noting that the <a href="https://www.molex.com/molex/products/part-detail/crimp_housings/0510210600">housing</a> and <a href="https://www.molex.com/molex/search/partSearch?pQuery=&amp;sType=a&amp;query=214921">leads</a> could have each been ordered separately and then assembled, which would likely have been more cost effective at the expense of my time and patience.</p><p>Anyways. Once I had the cable assemblies in-hand, evaluating the PCB was much easier. I started by soldering the leads from the caddy PCB to the pads of a test backplane PCB, as I laid out in my earlier blog post:</p><blockquote>So, my plan will be to find a backplane PCB with activity and power leads / LEDs, so I can wire pins 1, 3, and 6 for power (i.e., yielding a green color on the status LED of the caddy) and pin 4 (and pin 6) for disk activity.<br><a href="https://autologue.io/exploring-xserve">~me, 2021.05.10</a></blockquote><p>Boy, I made it sound so easy. The status/power LED lit up with seemingly no problems. Unfortunately, so did the activity LED, which is to say that both LEDs stayed lit. Not only that, the caddy PCB also became very hot to the touch shortly thereafter. Just super.</p><p>Turns out the caddy PCB isn't used to 5V. After some testing and additional research (<a href="https://en.wikipedia.org/wiki/SCSI_connector">SCSI</a> operated at 15V and 3.3V, instead of SATA's 12V and 5V), it seems that 3.3V likely makes more sense. I have since updated the earlier blog post to include this discovery.</p><p>Now is probably as good a time as any to mention my total lack of experience with circuits. I was supposed to take a class on circuits in college and, yet, I didn't. So this project was coming along exactly as expected.</p><p>I initially considered a <a href="https://en.wikipedia.org/wiki/Voltage_divider">voltage divider</a> as a potential solution to drop 5V to 3.3V, but settled on a <a href="https://www.digikey.com/en/maker/blogs/introduction-to-linear-voltage-regulators">linear voltage regulator</a> for fear that the input voltage and output current draw may not be reliable/constant.</p><p>Failings of yours truly aside, the activity LED was still a problem. I had expected the SATA PCB to signal using the positive pad rather than the negative pad. This wouldn't be a problem if the LEDs of the caddy PCB didn't share a common ground lead. But they do!</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://autologue.io/content/images/2021/07/Caddy-PCB-Pinout.png" class="kg-image" alt="Xsata: Caddy PCB Circuit Design" srcset="https://autologue.io/content/images/size/w600/2021/07/Caddy-PCB-Pinout.png 600w, https://autologue.io/content/images/size/w1000/2021/07/Caddy-PCB-Pinout.png 1000w, https://autologue.io/content/images/2021/07/Caddy-PCB-Pinout.png 1200w" sizes="(min-width: 720px) 720px"><figcaption>Pin 6? More like pin 666 amirite.</figcaption></figure><p>I thought this was an oddity of the SATA PCB that I was using, but, in actuality, it appears this is part of the SATA power connector. Enter: pin 11. Per Wikipedia, pins 1-3 are 3.3v (if you're into shucking HDDs, you may be <a href="https://reddit.com/r/DataHoarder/comments/7g2v9o/33v_pin_reset_directions_d">familiar with pin 3</a>), pins 5-6, 10, and 12 are ground, pins 7-9 are +5V, and pins 13-15 are +12V. Pin 11, however, is described as follows:</p><blockquote>Pin 11 can function for <a href="https://en.wikipedia.org/wiki/Staggered_spinup">staggered spinup</a>, activity indication, both, or nothing. It is an <a href="https://en.wikipedia.org/wiki/Open-collector">open-collector</a> signal, which may be pulled down by the connector or the drive. If pulled down at the connector (as it is on most cable-style SATA power connectors), the drive spins up as soon as power is applied. If left floating, the drive waits until it is spoken to. This prevents many drives from spinning up simultaneously, which might draw too much power. <strong>The pin is also pulled low by the drive to indicate drive activity. This may be used to give feedback to the user through an LED.</strong><br>~Wikipedia, <a href="https://en.wikipedia.org/wiki/Serial_ATA#Standard_connector">Serial ATA § Standard Connector</a> (emphasis mine)</blockquote><p>Based on my incredibly limited understanding, I took this to mean that pin 11 may be left floating, until it is pulled low by the drive to indicate activity. Super helpful; that explained the unexpected-to-me behavior of the "Activity –" pad on the SATA PCB.</p><p>Armed with knowledge and a renewed sense of give-a-fuck-edness, I broke out my super shitty breadboard, 5V power source (USB: putting the "U" in "USB" since 1996), 3.3V linear voltage regulator, resistors, transistors, and, eventually, MOSFETs. Behold the resulting circuit:</p><figure class="kg-card kg-image-card kg-width-full kg-card-hascaption"><img src="https://autologue.io/content/images/2021/07/CaddyPCB.png" class="kg-image" alt="Xsata: Caddy PCB Circuit Design" srcset="https://autologue.io/content/images/size/w600/2021/07/CaddyPCB.png 600w, https://autologue.io/content/images/size/w1000/2021/07/CaddyPCB.png 1000w, https://autologue.io/content/images/size/w1600/2021/07/CaddyPCB.png 1600w, https://autologue.io/content/images/2021/07/CaddyPCB.png 2400w"><figcaption>It <em>almost</em> looks like I know what I'm doing. I still don't, honest.</figcaption></figure><p>It's been a multi-week process at this point, so I am a little foggy on the details (read: past failures), but the ultimate design uses a PNP transistor (Q1) in combination with an n-channel MOSFET (Q2) to control the Activity LED (and, more specifically, to conditionally provide +3.3V from the voltage regulator (U1) to pin 4 of the caddy PCB).</p><p>It will be more soldering than I had wanted to do (especially when I have to do it for each caddy–14 times over), but let's walk through each of the components and why they're there.</p><p>To start, the left connector is intended to connect to the SATA PCB, where pad 1 = power +, pad 2 = power –, pad 3 = activity +, and pad 4 = activity –. The caddy PCB is on the right, where pins 1 and 3 provide +3.3V to the power LED, pin 4 provides +3.3V to the activity LED, and pin 6 is ground.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://autologue.io/content/images/2021/07/CaddyPCB-Top.png" class="kg-image" alt="Xsata: Caddy PCB Circuit Design" srcset="https://autologue.io/content/images/size/w600/2021/07/CaddyPCB-Top.png 600w, https://autologue.io/content/images/2021/07/CaddyPCB-Top.png 885w" sizes="(min-width: 720px) 720px"><figcaption>I don't know if this is helpful, but scrolling back up seems exhausting.</figcaption></figure><p>Moving to the middle of the schematic, the top portion (enlarged above) is easiest to explain. U1 is a 3.3V linear voltage regulator, where pin 1 is VIN (i.e., +5V from pin 1 of the SATA PCB connector), pin 2 in GND (i.e., ground from pin 2 of the SATA PCB connector), pin 3 is the enable pin (which, per the spec sheet, is pulled high to enable the regulator), pin 4 is unused, and pin 5 is VOUT (i.e., +3.3V to one or both caddy PCB LEDs).</p><p>C1 (1µF) and C2 (4.7µF) are capacitors that smooth the input to and output from the voltage regulator, respectively. I can't take credit for the inclusion and values of C1 and C2; the spec sheet recommended their inclusion for improved stability.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://autologue.io/content/images/2021/07/Screen-Shot-2021-07-11-at-1.03.13-PM.png" class="kg-image" alt="Xsata: Caddy PCB Circuit Design" srcset="https://autologue.io/content/images/size/w600/2021/07/Screen-Shot-2021-07-11-at-1.03.13-PM.png 600w, https://autologue.io/content/images/size/w1000/2021/07/Screen-Shot-2021-07-11-at-1.03.13-PM.png 1000w, https://autologue.io/content/images/size/w1600/2021/07/Screen-Shot-2021-07-11-at-1.03.13-PM.png 1600w, https://autologue.io/content/images/2021/07/Screen-Shot-2021-07-11-at-1.03.13-PM.png 1644w" sizes="(min-width: 720px) 720px"><figcaption>This part took longer than it probably should have. Still, probably not bad for a lizard-brained human bean.</figcaption></figure><p>Let's turn now to the bottom portion of the schematic (reproduced above). At its core, Q1 controls the gate of the <a href="http://www.learningaboutelectronics.com/Articles/N-Channel-MOSFETs">MOSFET</a> (i.e., pin 1 of Q2), thereby causing electricity to flow from the linear regulator to the activity LED (i.e., from the drain, pin 3, of Q1 to the source, pin 2) when current flows from pin 2 to pin 1 of the PNP transistor (Q1). Put another way, when current flows from pin 2 to pin 1 of Q1 (as a result of a drive pulling pin 4 of the illustrated connector low), Q1 is "on," such that the voltage at the gate of Q2 is +5V. As a result, Q2 is "on" too, thereby causing the activity LED to be illuminated.</p><p>With respect to the resistors, R1 limits the current passing through Q1 (as well as R3). R3 is a <a href="https://en.wikipedia.org/wiki/Pull-up_resistor">pull-up resistor</a>, which causes the emitter (pin 2) and the base (pin 1) of Q1 to have a similar voltage so Q1 is not "on" when pin 4 of the SATA PCB connector (i.e., pin 11 of the SATA power connector, as discussed above) is floating.</p><p>It is not visible in the excerpt above, but R2 is a pull-down resistor (connecting the gate, a.k.a. pin 1, of Q2 to power –, or ground). This ensures that, unless Q1 is "on," Q2 does not receive a sufficient positive voltage to itself be "on." The values of R1, R2, and R3 were determined experimentally using my breadboard and are deliberately high values in an effort to reduce wasted current. These values may change in the final design, but at least resistors are cheap.</p><p>I have also designed and ordered a batch of PCBs based on the above schematic, but that is the topic for a future post; this one is long enough. Hopefully I will have the PCBs in hand soon (and determine that the design works), at which point I will add another post to the growing Xsata saga (hmm, perhaps this is the Xsaga?). Fingers crossed.</p>]]></content:encoded></item><item><title><![CDATA[Exploring Xserve]]></title><description><![CDATA[My NAS is getting a little full. Could this be an instance of quantity (drives) over quantity (capacity)?]]></description><link>https://autologue.io/exploring-xserve/</link><guid isPermaLink="false">6099df62d4305006c9fa44ad</guid><category><![CDATA[modlog]]></category><category><![CDATA[xsata]]></category><dc:creator><![CDATA[me]]></dc:creator><pubDate>Tue, 11 May 2021 02:51:58 GMT</pubDate><media:content url="https://autologue.io/content/images/2021/05/IMG_3084-1.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://autologue.io/content/images/2021/05/IMG_3084-1.jpg" alt="Exploring Xserve"><p>Last year, I replaced all eight drives in my NAS with larger drives. However, I saved the old drives with the thinking that I could eventually upgrade from an 8-bay NAS to something with more bays. A 24-bay Supermicro device was the original plan, but I recently remembered that the <a href="https://support.apple.com/kb/SP87">14-bay Xserve RAID</a> is gorgeous. Unfortunately, the Xserve RAID was <a href="https://everymac.com/systems/apple/xserve/specs/xserve_raid_sfp.html">discontinued in 2008</a> and, barring the Xeon Xserve (non-RAID) models, never supported modern SATA drives.</p><figure class="kg-card kg-image-card"><img src="https://autologue.io/content/images/2021/05/17044.jpg" class="kg-image" alt="Exploring Xserve" srcset="https://autologue.io/content/images/size/w600/2021/05/17044.jpg 600w, https://autologue.io/content/images/2021/05/17044.jpg 784w" sizes="(min-width: 720px) 720px"></figure><p>This is the first in what will likely be a series of posts regarding my attempt to convert an Xserve RAID (hereinafter "XR") to a modern storage device. To date, I have ordered an XR midplane (pictured above, basically a backplane to which drive caddies connect) and two empty (but not "blank") drive caddies. I have also explored a handful of SATA backplanes, though the backplanes I have found so far do not have the correct drive spacing (≈30mm from the start of one SCSI-esque(?) connector to the start of another). No matter, I have a couple other ideas for how to handle upgrading the XR from Ultra ATA to SATA.</p><p>Which brings me to the topic of this post: the indicator lights in the drive caddies. Even though I would ultimately like all of the LEDs on the front of the XR to work, it makes sense to start with the drive caddies and, more specifically, the tiny PCB used by each drive caddy. Interestingly, there was a related <a href="https://www.insanelymac.com/forum/topic/321893-xserve-raid-mod-the-ultimate-nas/?do=findComment&amp;comment=2385288">project</a> four years ago that seemingly never came to fruition.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://autologue.io/content/images/2021/05/IMG_3079.jpg" class="kg-image" alt="Exploring Xserve" srcset="https://autologue.io/content/images/size/w600/2021/05/IMG_3079.jpg 600w, https://autologue.io/content/images/size/w1000/2021/05/IMG_3079.jpg 1000w, https://autologue.io/content/images/size/w1600/2021/05/IMG_3079.jpg 1600w, https://autologue.io/content/images/2021/05/IMG_3079.jpg 1809w" sizes="(min-width: 720px) 720px"><figcaption>Hello "820-1468-A," I'm Dad.</figcaption></figure><p>The top LED is the status indicator and can be green or red, while the bottom LED is the drive activity indicator is a pleasant shade of blue. Flipping the board over (below), the notable features are the <a href="https://www.molex.com/molex/products/part-detail/pcb_headers/0532610671">6-pin connector</a> (right) and the reflectivity (?) sensor (left, with the two thick horizontal pins). The sensor is interesting, because, using white or black regions on the inside of the caddy, it detects whether the caddy is open / unlocked (e.g., for drive removal) or closed / locked.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://autologue.io/content/images/2021/05/IMG_3083.jpg" class="kg-image" alt="Exploring Xserve" srcset="https://autologue.io/content/images/size/w600/2021/05/IMG_3083.jpg 600w, https://autologue.io/content/images/size/w1000/2021/05/IMG_3083.jpg 1000w, https://autologue.io/content/images/size/w1600/2021/05/IMG_3083.jpg 1600w, https://autologue.io/content/images/2021/05/IMG_3083.jpg 1809w" sizes="(min-width: 720px) 720px"><figcaption>Some trivia: when powered on, the sensor smells just like any other burning chip.</figcaption></figure><p>A thin, tiny cable plugs into the 6-pin connector and runs under the drive area to a PCB in the back of the caddy, where the traces ultimately lead to the connector for the caddy (which is what plugs into the midplane). The connector is interesting, because the ultimate goal is to connect the baby PCB to SATA power and activity leads so the lights on the front of the caddy behave as expected.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://autologue.io/content/images/2021/05/11370.Jpg" class="kg-image" alt="Exploring Xserve"><figcaption>Somehow discontinued even though I ordered it last week?</figcaption></figure><p>Using the above cable, I was able to easily supply +5V/GND to various pins of the PCB. The "V" and associated red coloring on the cable that connects to the PCB (not pictured 🤷🏻‍♂️) was a good indicator of where the positive pin is, but the rest required some guesswork. One fried sensor later, below is the pinout:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://autologue.io/content/images/2021/06/Caddy-PCB-Pinout.png" class="kg-image" alt="Exploring Xserve" srcset="https://autologue.io/content/images/size/w600/2021/06/Caddy-PCB-Pinout.png 600w, https://autologue.io/content/images/size/w1000/2021/06/Caddy-PCB-Pinout.png 1000w, https://autologue.io/content/images/2021/06/Caddy-PCB-Pinout.png 1200w" sizes="(min-width: 720px) 720px"><figcaption>Illustrations really aren't my strong suit. I apologize for nothing.</figcaption></figure><p>A quick edit regarding the voltage: after some additional testing at 5V, parts of the board became extremely hot (but it didn't let the smoke out). Upon further review of the <a href="https://en.wikipedia.org/wiki/SCSI_connector">SCSI connector</a>, it appears SCSI operated at 15V and 3.3V, rather than the 12V and 5V typically used by SATA. So I think 3.3V is a safe bet.</p><p>I am guessing on the pin marked "SENS," but it isn't a pin that I need anyway. I am also unsure whether I'm conforming to normal pinout conventions, so I will write out the various states, too.</p><p>In order to produce a red color on the status indicator, +3.3V is applied to pins 1 and 2, with GND on pin 6. However, I don't anticipate using that state (as much as I would like to, I just don't see how it would be easily implemented). In order to produce a green color on the status indicator, +3.3V is applied to pins 1 and 3, with GND on pin 6. Finally, the activity LED can be illuminated by supplying +3.3V to pin 4 and, unsurprisingly, GND to pin 6. <s>I may play around with supplying lower voltage on pins 1, 2, or 3; I haven't decided yet.</s></p><p>So, my plan will be to find a backplane PCB with activity and power leads / LEDs, so I can wire pins 1, 3, and 6 for power (i.e., yielding a green color on the status LED of the caddy) and pin 4 (and pin 6) for disk activity.</p><hr><p>Edit 2021.06.14: After further experimentation, this post has been updated to reflect a voltage of 3.3V, not 5V.</p>]]></content:encoded></item><item><title><![CDATA[My Own Biggest Fan]]></title><description><![CDATA[I replaced the stock fans on my Radeon VII with 80mm Noctua Fans. The project wasn't a breeze, but overall it was still a wind.]]></description><link>https://autologue.io/my-own-biggest-fan/</link><guid isPermaLink="false">601d7ab6732f3c030e22ba97</guid><category><![CDATA[modlog]]></category><category><![CDATA[3D-printing]]></category><dc:creator><![CDATA[me]]></dc:creator><pubDate>Tue, 11 May 2021 00:44:26 GMT</pubDate><media:content url="https://autologue.io/content/images/2021/05/IMG_2681-4.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://autologue.io/content/images/2021/05/IMG_2681-4.jpg" alt="My Own Biggest Fan"><p>Over the past year, I've become weirdly infatuated with fans. The beginning might actually date back further than that (I rigged some fans to run off a 12V wall wart several years back to keep my media center cool), but things really took off when I became the proud owner of a fanless Core i5 Microsoft Surface that really should've had a fan (and it turns out that even the fan-full Core i7 model needs a fan). Short story long, I've bought probably 15-20 fans over the last year. Quick shout out to <a href="https://www.ebay.com/usr/official_noctuashop">Noctua's eBay shop</a>, where they ship straight from Austria (helpful for when Amazon and Newegg are out of stock). #covidhobbies #onlyfans</p><p>Most recently, a fan on my AMD Radeon VII started sounding sickly: at speeds above ≈70%, there was a high-pitched whine. Unfortunately, the GPU is no longer in production and I was unable to find OEM replacement parts. "But a fan is a fan," you're thinking. Short of buying some off-brand replacement fans off <a href="https://www.aliexpress.com/item/1005001491358453.html">AliExpress</a> or buying a GPU "for parts" off eBay (unappealing since even seemingly dead GPUs seem to be selling for $450+), it seemed I was out of luck.</p><p>Just kidding, I have a 3D printer. Watch out, world.</p><p>The no-name fans off AliExpress probably would have been <em>fine</em> (though they certainly lack the stellar name recognition of the original "First D" brand fans). However, the GPU has always been a little loud, so it seemed this was an opportunity for improvement on many fronts. That said, after finding that AliExpress link, fair warning that what follows is not remotely cost-effective ($14 + free 3-6 <em>week</em> shipping versus $60+ on three fancy-ass chromax.black.swap Noctua fans). But, as momma always heard me say: "anything worth doing is worth overdoing."</p><p>To start, I had to find some potential replacement fans. The original fans are approximately 75mm x 15mm fans. Noctua makes a <a href="https://noctua.at/en/nf-a9x14-pwm-chromax-black-swap">92mm fan</a> that is 14mm thick, but unfortunately the regions in the GPU shroud are too small to accommodate such a large diameter. The next best option turned out to be their <a href="https://noctua.at/en/nf-a8-pwm-chromax-black-swap">80mm fan</a>, which is 25mm thick.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://autologue.io/content/images/2021/05/IMG_2688.jpg" class="kg-image" alt="My Own Biggest Fan" srcset="https://autologue.io/content/images/size/w600/2021/05/IMG_2688.jpg 600w, https://autologue.io/content/images/size/w1000/2021/05/IMG_2688.jpg 1000w, https://autologue.io/content/images/size/w1600/2021/05/IMG_2688.jpg 1600w, https://autologue.io/content/images/size/w2400/2021/05/IMG_2688.jpg 2400w" sizes="(min-width: 720px) 720px"><figcaption>I wasn't sure how the different dimensions would turn out; it definitely <em>looked</em> like a larger fan. Spoilers: it turned out exceedingly okay.</figcaption></figure><p>I had also done some research to see what I was up against. First, this <a href="https://www.youtube.com/watch?v=0b9_c4oJRTE">excellent video</a> from GamersNexus was helpful in disassembling the Radeon VII. Second, I scrubbed through this <a href="https://www.youtube.com/watch?v=hEZELWvQGlk">disassembly video</a> of a Noctua fan. The Noctua video made the disassembly it look harder than it actually is, and I don't know whether a heat gun would actually make things easier.</p><p>In short: there is a bushing that keeps the shaft of the fan in place, and the bushing is retained by friction. Knowing this, I was able to disassemble the fan by firmly pushing the blades out of the case from the back. This is different than other fans I have encountered, where there is a lock ring(?) behind the center label of the fan that can be removed to free the shaft from the bushing. No need to remove the stickers here! (Quick note: I doubt this technique applies to all their fans, since the 120mm fans seem to use a different construction.)</p><p>The next stage of the project was to model a replacement base to hold the PCB in place with respect to the fan rotor. I expected the modeling process to be somewhat tedious and have a low margin for error, given the relatively tight fit between the electromagnets on the PCB and the corresponding magnet in the fan rotor. Thankfully, duplicating Noctua's design was actually surprisingly simple and relatively forgiving.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://autologue.io/content/images/2021/05/Screen-Shot-2021-05-10-at-5.32.33-PM-1.png" class="kg-image" alt="My Own Biggest Fan" srcset="https://autologue.io/content/images/size/w600/2021/05/Screen-Shot-2021-05-10-at-5.32.33-PM-1.png 600w, https://autologue.io/content/images/size/w1000/2021/05/Screen-Shot-2021-05-10-at-5.32.33-PM-1.png 1000w, https://autologue.io/content/images/size/w1600/2021/05/Screen-Shot-2021-05-10-at-5.32.33-PM-1.png 1600w, https://autologue.io/content/images/2021/05/Screen-Shot-2021-05-10-at-5.32.33-PM-1.png 2300w" sizes="(min-width: 720px) 720px"><figcaption>Yep, Blender is my self-flagellation tool of choice.</figcaption></figure><p>I ended up printing five or six iterations of the design, and every single version was functional. Definitely not the norm. It may eventually be worth writing a post about my approach to 3D modeling, but generally I start with a relatively simple / naïve model and iterate from there. It helps make sure I get the dimensions right along the way, and I can also iron out any kinks introduced by FDM printing.</p><p>For example, I had expected the top of the model to be difficult to print given its relatively thin walls and quick print time (some things get melty when that's the case), but it again turned out to be a non-issue. How often and how quickly I can iterate depends on how long the print time is, but thankfully this part only takes 25-30 minutes to print.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://autologue.io/content/images/2021/05/IMG_2684-1.jpg" class="kg-image" alt="My Own Biggest Fan" srcset="https://autologue.io/content/images/size/w600/2021/05/IMG_2684-1.jpg 600w, https://autologue.io/content/images/size/w1000/2021/05/IMG_2684-1.jpg 1000w, https://autologue.io/content/images/size/w1600/2021/05/IMG_2684-1.jpg 1600w, https://autologue.io/content/images/size/w2400/2021/05/IMG_2684-1.jpg 2400w" sizes="(min-width: 720px) 720px"><figcaption>Printed in Carbon Fiber PETG for added street cred.</figcaption></figure><p>There <em>is</em> one trick worth mentioning here, which I think I picked up from <a href="https://www.youtube.com/user/TheMakersMuse">Maker's Muse</a> on YouTube. The original fan has a magnet embedded at the bottom of the rotor shaft. The fan works fine without the magnet, but I assume the magnet is to keep the rotor in place rather than having it inadvertently ride up during operation.</p><p>Being anally <s>receptive</s> retentive, I decided to duplicate this feature anyway, using a 6mm x 1.5mm cylindrical cavity to retain a neodymium magnet. The magnet cavity then gives way to a differently shaped, but narrower, cavity in which the shaft of the rotor can move freely.</p><p>If you are unfamiliar with 3D printing (and more specifically <a href="https://en.wikipedia.org/wiki/Fused_filament_fabrication">FDM</a> 3D printing), moving from a big hole to a small hole is problematic, because the walls for the smaller hole will be printed when the nozzle is over thin air. The trick here is to leave a single solid layer between the boundary for the magnet cavity and the shaft cavity, so there is a thin layer of plastic upon which to build the walls for the shaft cavity.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://autologue.io/content/images/2021/05/IMG_2683-1.jpg" class="kg-image" alt="My Own Biggest Fan" srcset="https://autologue.io/content/images/size/w600/2021/05/IMG_2683-1.jpg 600w, https://autologue.io/content/images/size/w1000/2021/05/IMG_2683-1.jpg 1000w, https://autologue.io/content/images/size/w1600/2021/05/IMG_2683-1.jpg 1600w, https://autologue.io/content/images/size/w2400/2021/05/IMG_2683-1.jpg 2400w" sizes="(min-width: 720px) 720px"><figcaption>That bridging for the cable guide is <em>super</em> fine 🤌🏼</figcaption></figure><p>The sacrificial layer is easy to clean up once the print is done, for example by puncturing it with a screwdriver. I also considered entirely closing off the two cavities from one another, but it turned out to be helpful during assembly and testing for reasons discussed below.</p><p>Anyways, it was upon attempting to assemble the fan using the 3D-printed part that I decided this project was worthy of a blog post. To this point, I hadn't attempted to disassemble the rotor assembly, partly because I <em>hate</em> grease (truly, can't stand it), but also because I was worried it would affect the fan's operation.</p><p><em>{I just returned to finish this post after three months away from it, so I don't fully remember the epiphany that I was building up to here}</em></p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://autologue.io/content/images/2021/05/IMG_2643-1.jpg" class="kg-image" alt="My Own Biggest Fan" srcset="https://autologue.io/content/images/size/w600/2021/05/IMG_2643-1.jpg 600w, https://autologue.io/content/images/size/w1000/2021/05/IMG_2643-1.jpg 1000w, https://autologue.io/content/images/size/w1600/2021/05/IMG_2643-1.jpg 1600w, https://autologue.io/content/images/size/w2400/2021/05/IMG_2643-1.jpg 2400w" sizes="(min-width: 720px) 720px"><figcaption>Check out the gorgeous artifacts from the machined mold between the blades and the hub.</figcaption></figure><p>In short, the rotor assembly is comprised of four-ish pieces: the blades / hub / shaft (effectively all once piece), a ring that sits between the bushing and the hub, the bushing, and a retention washer. Alas, I wish I had a picture of the assembly on its own. In the picture above, you can at least see (from top to bottom): the shaft, the retention washer (with grease!), and a small portion of the copper bushing.</p><figure class="kg-card kg-image-card"><img src="https://autologue.io/content/images/2021/05/IMG_2644.jpg" class="kg-image" alt="My Own Biggest Fan" srcset="https://autologue.io/content/images/size/w600/2021/05/IMG_2644.jpg 600w, https://autologue.io/content/images/size/w1000/2021/05/IMG_2644.jpg 1000w, https://autologue.io/content/images/size/w1600/2021/05/IMG_2644.jpg 1600w, https://autologue.io/content/images/size/w2400/2021/05/IMG_2644.jpg 2400w" sizes="(min-width: 720px) 720px"></figure><p>In my initial reassembly attempts, I put the PCB (above) onto the 3D-printed part and  pushed the whole rotor assembly into the shaft cavity. In doing so, my concern was that the ring between the bushing and the hub (which I assume is to limit grease egress from the shaft cavity) was not positioned correctly. And, based on how the fan rotated in subsequent testing, it seemed I was right: the ring was not seated properly and was in contact with the hub.</p><p>It seems that the only way to properly assemble the fan is to break down the rotor assembly and put its constituent parts into the 3D-printed part one by one. Trying this technique, the retention washer sat nicely at the bottom of the shaft cavity (which I was able to position using tweezers, thanks to the hole between the magnet cavity and the shaft cavity), followed by the bearing. I was then able to press the ring onto the top of the cylinder. It was a perfect, snug fit. I slid the shaft into the bushing and through the retention ring, at which point the rotor assembly was properly reassembled within the 3D-printed part.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://autologue.io/content/images/2021/05/63399850639__4975B78E-5452-4DD7-9270-9AF25E37270E.jpg" class="kg-image" alt="My Own Biggest Fan" srcset="https://autologue.io/content/images/size/w600/2021/05/63399850639__4975B78E-5452-4DD7-9270-9AF25E37270E.jpg 600w, https://autologue.io/content/images/size/w1000/2021/05/63399850639__4975B78E-5452-4DD7-9270-9AF25E37270E.jpg 1000w, https://autologue.io/content/images/size/w1600/2021/05/63399850639__4975B78E-5452-4DD7-9270-9AF25E37270E.jpg 1600w, https://autologue.io/content/images/size/w2400/2021/05/63399850639__4975B78E-5452-4DD7-9270-9AF25E37270E.jpg 2400w" sizes="(min-width: 720px) 720px"><figcaption>When "before" and "after" is the same picture.</figcaption></figure><p>Weird Noctua erotic fan fanfic aside, the result worked perfectly. And so, my epiphany: in modeling a different base for the fan, I'd gained a better understanding for not only the parts that form the fan, but also how the fan is assembled and some of the associated engineering decisions.</p><p>I made two more fans, soldered them all together, and used a <a href="https://www.amazon.com/gp/product/B07T95C68T">GPU fan connector</a> to reassemble the graphics card. The result (#<a href="https://www.reddit.com/r/restofthefuckingowl/">restofthefuckingowl</a>)? Well, having used the fan for nearly three months now (thanks, procrastination!), I can say the project was a resounding success.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://autologue.io/content/images/2021/05/63564018602__1706AAA5-FC96-477F-8B17-43EB3EE23A26.jpg" class="kg-image" alt="My Own Biggest Fan" srcset="https://autologue.io/content/images/size/w600/2021/05/63564018602__1706AAA5-FC96-477F-8B17-43EB3EE23A26.jpg 600w, https://autologue.io/content/images/size/w1000/2021/05/63564018602__1706AAA5-FC96-477F-8B17-43EB3EE23A26.jpg 1000w, https://autologue.io/content/images/size/w1600/2021/05/63564018602__1706AAA5-FC96-477F-8B17-43EB3EE23A26.jpg 1600w, https://autologue.io/content/images/size/w2400/2021/05/63564018602__1706AAA5-FC96-477F-8B17-43EB3EE23A26.jpg 2400w" sizes="(min-width: 720px) 720px"><figcaption>Just blown away.</figcaption></figure><p>I will say that the BIOS of the Radeon VII has no idea what to do with the RPM reported by the new fans, so running the fans at 100% registers as only 60%. Overall, I can't say for a fact that cooling performance has <em>increased</em>, but, even at <s>100%</s> 60%, the Radeon VII stays quite cool and it is so, so much quieter than the stock fans.</p>]]></content:encoded></item><item><title><![CDATA[What Menu Items?]]></title><description><![CDATA[Updating from Catalina to Big Sur wasn't a problem at first, but installing 11.1 was a headache.]]></description><link>https://autologue.io/missing-menu-items/</link><guid isPermaLink="false">5fdac2b83518ea036f84b4f4</guid><category><![CDATA[macOS]]></category><category><![CDATA[quickhacks]]></category><dc:creator><![CDATA[me]]></dc:creator><pubDate>Thu, 17 Dec 2020 04:07:32 GMT</pubDate><media:content url="https://autologue.io/content/images/2020/12/Screen-Shot-2020-12-16-at-8.48.58-PM-2.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://autologue.io/content/images/2020/12/Screen-Shot-2020-12-16-at-8.48.58-PM-2.jpg" alt="What Menu Items?"><p>Long story short, after trying to upgrade to macOS Big <s>Suck</s> Sur 11.1 (but I'm not still bitter, honest), I was left with a computer that no longer booted past the loading screen—though Safe Mode worked for some reason. I thought perhaps downgrading to 11.0.1 might restore things to working order, but after inadvertently <a href="https://bombich.com/kb/ccc5/working-apfs-volume-groups">separating my Data volume from its System sibling,</a> I decided maybe it was time for some long overdue spring cleaning anyway. Well, that paired with noticing files from February of 2012 that were still lingering after many migrations over the better part of a decade. </p><p>After reinstalling applications and copying over associated preference plists, there were some applications whose menu bar icons were missing. There is <a href="https://www.reddit.com/r/MacOSBeta/comments/hgyaxr/menu_bar_icons_missing_in_big_sur/">some</a> <a href="https://www.dropboxforum.com/t5/Dropbox-installs-integrations/Icons-missing-from-MacOS-11-BigSur-menu-and-finder-toolbar/td-p/471183">discussion</a> online of what appeared to be the same issue, but none of the suggested remedies had any effect.</p><p>Back before Apple offered a <a href="https://developer.apple.com/documentation/appkit/nsstatusitem">public API</a> for menu items, <a href="https://ragingmenace.com/software/menumeters/FAQ.html#ishack">developers</a> used the private NSMenuExtra API. SystemUIServer was (and apparently still is, in some cases) responsible for displaying the menu items in the menu bar, so I thought perhaps <code>~/Library/Preferences/com.apple.systemuiserver.plist</code> was a good place to start. Unfortunately, the only menu item mentioned there was for Time Machine. Surprising that the other Apple-approved menu items are no longer technically "menu extras." But I digress.</p><p>I decided it might be helpful to identify which preference plists were updated when I changed the visibility setting for a missing menu item. Fortunately, <a href="https://www.hammerspoon.org/">HammerSpoon</a> has preference window that is both accessible by means other than the menu item and offers the ability to toggle menu item visibility in preferences.</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://autologue.io/content/images/2020/12/Screen-Shot-2020-12-16-at-8.03.00-PM.png" class="kg-image" alt="What Menu Items?" srcset="https://autologue.io/content/images/size/w600/2020/12/Screen-Shot-2020-12-16-at-8.03.00-PM.png 600w, https://autologue.io/content/images/size/w1000/2020/12/Screen-Shot-2020-12-16-at-8.03.00-PM.png 1000w, https://autologue.io/content/images/size/w1600/2020/12/Screen-Shot-2020-12-16-at-8.03.00-PM.png 1600w, https://autologue.io/content/images/2020/12/Screen-Shot-2020-12-16-at-8.03.00-PM.png 2064w" sizes="(min-width: 1200px) 1200px"><figcaption>I guess in light of the public API, a centralized set of menu item preferences doesn't really make sense anymore</figcaption></figure><p>Sorting by "Date Modified," it turns out that the visibility and "preferred position" of an application's menu item is stored in the application's preference plist. Shocker:</p><pre><code class="language-xml">&lt;plist version="1.0"&gt;
&lt;dict&gt;
	&lt;key&gt;NSStatusItem Preferred Position Item-0&lt;/key&gt;
	&lt;real&gt;1018&lt;/real&gt;
	&lt;key&gt;NSStatusItem Visible Item-0&lt;/key&gt;
	&lt;true/&gt;
&lt;/dict&gt;
&lt;/plist&gt;</code></pre><p>I tried changing the <code>NSStatusItem Visible</code> key to <code>&lt;true/&gt;</code> and relaunching the application, but it appears that the property is cached such that it is reset when the application launches.</p><p>While I didn't delve into which process manages the <code>NSStatusItem</code><em> </em>menu items (I can, however, confirm that it definitely isn't SystemUIServer), the solution that I found was to edit the plist and leave the application as-is (either running or closed). After rebooting, the missing menu items were back!</p><hr><p>Quick aside: If you are not familiar with editing plists, they tend to be
 stored in a binary format. They can be converted to XML using the <code>plutil</code> command in Terminal so they can be edited with
 a regular text editor.</p><pre><code class="language-shell">% plutil -convert xml1 /Users/me/Library/Preferences/com.protonmail.bridge.plist</code></pre><p>For example, the above command
 will convert the binary plist file <code>com.protonmail.bridge.plist</code> into a normal XML file. No need to 
convert it back to a binary plist, as that will happen when the file is 
updated by the system (though using <code>binary1</code> in place of <code>xml1</code> will perform the opposite conversion).</p>]]></content:encoded></item><item><title><![CDATA[Well, here we are]]></title><description><![CDATA[After many years of waffling and several (unused) domain expirations later, I finally started a blog.]]></description><link>https://autologue.io/hello/</link><guid isPermaLink="false">5fb89dc127d0b2e81afd3b1e</guid><dc:creator><![CDATA[me]]></dc:creator><pubDate>Sat, 21 Nov 2020 05:51:52 GMT</pubDate><media:content url="https://autologue.io/content/images/2020/11/hello-4.png" medium="image"/><content:encoded><![CDATA[<img src="https://autologue.io/content/images/2020/11/hello-4.png" alt="Well, here we are"><p>In the past, my main hesitation was that I would spend an inordinate amount of time revising content for a blog and nothing would ever get posted. Even now, the preceding sentence underwent countless iterations until it was well-worded. And it still has passive voice. My day job is writing, and blogging is far less appealing if the objective is proper English. Also relevant: my writing in that context typically avoids the first person, so <em>I</em> am adjusting to that as well.</p><p>My next hesitation? Who even cares! I am fighting the urge to delete everything I've written and pick this post up some other day. ⌘𝖠, ⌫, I say. But, over the years I have encountered countless other blogs (as an aside: a list of inspirational blogs will likely be forthcoming). I have looked on with admiration as people seemingly unencumbered by these thoughts publish posts, projects, and other miscellany.</p><p>And I am thankful for it. Typically when Stack Overflow and Wikipedia are unavailing, I happen across the website of some kind Internet stranger that took the time to write about something. Or sometimes, the Internet has no answers. </p><p>So, here's the deal. I am framing this blog as an internal monologue; not polished for public consumption. I am sure I will still get caught up in the details (for example, I just went through and cleaned up most contractions; so informal), but that should take some pressure off.</p><p>I intend to write about various side projects that occupy my free time (thanks, COVID!). I am passionate about most facets of computer technology, from computer networking to cybersecurity, programming to virtualization, and 3D printing to cryptomining. Most recently, it turns out that I also enjoy clocks and I have a couple clock-related posts in mind, so <em>watch</em> out for those. Frankly, someday I would like to also play the role of kind Internet stranger in someone else's search for answers, as I have encountered a handful of issues that, at least at that time, were not discussed anywhere that I could find.</p><p>And my final hesitation? I am incredibly self-conscious. None of this works if I worry that anyone I know will be reading. Which, playing to the preceding hesitation, is probably a moot point anyway. In any event, I intend to remain a kind Internet stranger, occupying only this domain and no other.</p><p>Indeed, as the title says: "here we are;" "we" in the royal sense of the word. And after a long, 19-hour day, <em>we</em> are going to sleep.</p><p>~me</p>]]></content:encoded></item></channel></rss>