<?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[Matt's Stream of Consciousness Ramblings]]></title><description><![CDATA[A Boston-area geek.]]></description><link>https://ghost.n1zyy.com/</link><image><url>https://ghost.n1zyy.com/favicon.png</url><title>Matt&apos;s Stream of Consciousness Ramblings</title><link>https://ghost.n1zyy.com/</link></image><generator>Ghost 3.13</generator><lastBuildDate>Sat, 14 Feb 2026 03:23:50 GMT</lastBuildDate><atom:link href="https://ghost.n1zyy.com/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[Mass State Police Helicopters]]></title><description><![CDATA[<p>The Massachusetts State Police Airwing operates four helicopters. I just learned some interesting trivia–the last two characters of the tail numbers of each of them honor the four people killed when <a href="https://www.upi.com/Archives/1995/02/22/Four-die-in-Mass-helicopter-crash/2561793429200/">an MSP helicopter crashed in 1995</a>.</p><p>MSP's four helicopters:</p><ul><li><a href="https://flightaware.com/live/flight/N822PP">N822<strong>PP</strong></a></li><li><a href="https://flightaware.com/live/flight/N823JM">N823<strong>JM</strong></a></li><li><a href="https://flightaware.com/live/flight/N824AH">N824<strong>AH</strong></a></li><li><a href="https://flightaware.com/live/flight/N825MM">N825<strong>MM</strong></a></li></ul><p>And</p>]]></description><link>https://ghost.n1zyy.com/mass-state-police-helicopters/</link><guid isPermaLink="false">6386cc87de23327a2867303c</guid><dc:creator><![CDATA[Matt]]></dc:creator><pubDate>Wed, 30 Nov 2022 03:42:08 GMT</pubDate><content:encoded><![CDATA[<p>The Massachusetts State Police Airwing operates four helicopters. I just learned some interesting trivia–the last two characters of the tail numbers of each of them honor the four people killed when <a href="https://www.upi.com/Archives/1995/02/22/Four-die-in-Mass-helicopter-crash/2561793429200/">an MSP helicopter crashed in 1995</a>.</p><p>MSP's four helicopters:</p><ul><li><a href="https://flightaware.com/live/flight/N822PP">N822<strong>PP</strong></a></li><li><a href="https://flightaware.com/live/flight/N823JM">N823<strong>JM</strong></a></li><li><a href="https://flightaware.com/live/flight/N824AH">N824<strong>AH</strong></a></li><li><a href="https://flightaware.com/live/flight/N825MM">N825<strong>MM</strong></a></li></ul><p>And the four victims of the 1995 crash in Cambridge?</p><ul><li>MSP Trooper Paul Perry (<strong>PP</strong>)</li><li>MSP Trooper James Mattaliano (<strong>JM</strong>)</li><li>AT&amp;T Technician Arthur Howell (<strong>AH</strong>)</li><li>AT&amp;T Technician Michael McCarthy (<strong>MM</strong>)</li></ul><p>Confusingly, at least for someone like me not too familiar with the exact area, the helicopter (N20SP) crashed onto Harvard University's Sailing Pavilion, but <a href="https://news.mit.edu/1995/helicopter">MIT's rescue team was first to arrive</a> as they were training across the street.</p><p>In the worst PR move in history, <a href="https://www.thecrimson.com/article/1996/9/19/harvard-seeking-damages-for-1995-helicopter/">Harvard sought damages from the state for damage to its boathouse</a>, citing "negligence of the Mass. State Police."</p>]]></content:encoded></item><item><title><![CDATA[Impres batteries]]></title><description><![CDATA[<p>It took me a long time to really pay them any attention, but Motorola has offered Impres-branded batteries for their handheld radios for a long time, and they're actually pretty nifty.</p><p>The idea is that there's a chip on the batteries giving them some "smarts." Particularly in the days of</p>]]></description><link>https://ghost.n1zyy.com/impres-batteries/</link><guid isPermaLink="false">62f9a9e0de23327a28672d9d</guid><dc:creator><![CDATA[Matt]]></dc:creator><pubDate>Mon, 15 Aug 2022 02:54:49 GMT</pubDate><content:encoded><![CDATA[<p>It took me a long time to really pay them any attention, but Motorola has offered Impres-branded batteries for their handheld radios for a long time, and they're actually pretty nifty.</p><p>The idea is that there's a chip on the batteries giving them some "smarts." Particularly in the days of Ni-Cd batteries, their "reconditioning" step could help minimize the impact of the memory effect, with the charger periodically running the battery down all the way and then refilling it.</p><p>It turns out there's a lot more going on behind the scenes. During the reconditioning step, the charger also keeps track of how much of a charge the battery takes and calculates what percentage of its rated capacity remains. Some of the fancier gang chargers have LCDs and will display this information, but even the simpler chargers will start giving you a flashing red-and-green light to let you know the battery is wearing out. It seems like the "killer app" here is public safety applications–it's a minor annoyance for me if a radio I'm effectively using as a scanner starts to only last a few hours before I have to swap batteries. But for something like law enforcement, being able to know whether your battery will last your full shift seems like a much bigger deal.</p><p>I recently picked up an Impres "Battery Data Reader," which looks a lot like a standard charger, but it has a USB port on the back and doesn't charge. It reports data like this:</p><figure class="kg-card kg-image-card"><img src="https://ghost.n1zyy.com/content/images/2022/08/Screenshot-2022-08-14-210749.png" class="kg-image"></figure><p>This is the case of a totally dead battery, and which seems to have suffered some data corruption. (Not a great example, Matt!) The red/pink fields couldn't be read due to corruption, but we can see that the battery was rated for 2100 mAh, but now only supports a "potential capacity" of 474 mAh.</p><p>It also reveals that Motorola's "rated capacity" is actually conservatively rated; it's apparently the minimum spec for warranty purposes. This one apparently took 2781 mAh when it first went into use (April 10th, 2014).</p><p>Reading a bit about this and the extended user guide, the battery also has a real-time clock and some memory. It appears that the clock is set at the factory and only needs to be accurate to within months, so periodic syncing isn't supported (AFAICT), except for the special case when the battery has been "overdischarged" and, I infer, the RTC stops ticking. The reader is seemingly the only way to reset it.</p><p>The memory supports more than just a simple count of charge cycles; it differentiates Impres from non-Impres cycles, and even keeps a histogram of the battery's charge level when first inserted into the charger:</p><figure class="kg-card kg-image-card"><img src="https://ghost.n1zyy.com/content/images/2022/08/Screenshot-2022-08-14-210734.png" class="kg-image"></figure><p>You can see that this one tended to be put back in the charger when it was still 50-60% full. I'm not sure what you're supposed to do with that data; the whole idea of Impres batteries is that you shouldn't need to run the batteries out before charging them. This particularly battery looks like (based on its labels) like it came out of a prison facility; perhaps what the graph shows is that the battery was typically listing more than a shift, with the user presumably dropping it in a charger at the end of the day with 50-60% charge still left?</p><p>I've learned from reading a bit that the "potential capacity" (474 mAh in this case) is computed when the radio goes through a reconditioning cycle, and is used by the "fuel gauge" on radios to show how full the battery is. This also matches my experience with some old batteries that came from a lot of radios I bought at a hamfest–capacity indications were all over the place until a few conditioning cycles.</p><p>Also interesting–at least to me–the application keeps a running CSV file of everything it reads. It'd be interesting to write a little app that would take that file and track this data over time.</p><p>As an aside, the gang chargers have what's apparently an HD15 port on the back (which looks suspiciously like, but is not, a VGA port). There's not a whole lot of information out there except for <a href="https://batboard.batlabs.com/viewtopic.php?t=93669">this Batboard thread</a> about it. There's apparently <a href="https://www.radioparts.com/motorola-nntn7677">this adapter</a> for it that will hook up to a PC, which can integrate with their "Fleet Management Software." The Impres reader app also supports sending data there. It appears that there's a trial at <a href="https://www.motorolasolutions.com/en_us/products/two-way-radio-accessories/batteries/impres.html">https://www.motorolasolutions.com/en_us/products/two-way-radio-accessories/batteries/impres.html</a>, but what I'm really interested in is what's reported off the back of the charger. You could rig up something with a Raspberry Pi to grab the data without all this stuff?</p><p>In conclusion, I lead a pretty exciting life.</p>]]></content:encoded></item><item><title><![CDATA[RISC, SET, Match!]]></title><description><![CDATA[<p><strong><em>Subtitle: Deciphering WTF RISC and SSE are.</em></strong></p><p>This is a published work in progress.</p><p>I was recently asked to help with a RISC project. After wondering if that meant I'd finally get a SPARCstation, I was relieved to learn that the acronym now refers to <em>Risk Incident Sharing and Coordination</em></p>]]></description><link>https://ghost.n1zyy.com/risc-set-match/</link><guid isPermaLink="false">6299033ede23327a28672c55</guid><dc:creator><![CDATA[Matt]]></dc:creator><pubDate>Thu, 02 Jun 2022 19:31:49 GMT</pubDate><content:encoded><![CDATA[<p><strong><em>Subtitle: Deciphering WTF RISC and SSE are.</em></strong></p><p>This is a published work in progress.</p><p>I was recently asked to help with a RISC project. After wondering if that meant I'd finally get a SPARCstation, I was relieved to learn that the acronym now refers to <em>Risk Incident Sharing and Coordination</em> at the OpenID foundation.</p><p>My relief soon turned to panic as I saw how ethereal and acronym-heavy the available documentation was. RISC is one of two applications implementing SSE (Shared Signals and Events), the other being CAEP (Continuous Access Evaluation Protocol). It describes a framework for Transmitters to send information about Events about Subjects to Receivers, over a Stream. The "streams" are formatted as SETs (Security Event Tokens), which are implemented as JWTs. Quoting the RFC, "A SET describes statements of fact from the perspective of an issuer about a subject.  These statements of fact represent an event that occurred directly to or about a security subject, for example, a statement about the issuance or revocation of a token on behalf of a subject."</p><p>Any remaining questions you have can be answered by the RFCs.</p><p>Unless your question is, "<strong>Huh?</strong>", which is where I found myself. Maybe we can figure this out together.</p><h2 id="google-does-it">Google Does It</h2><p>Google implements this as <a href="https://developers.google.com/identity/protocols/risc">Cross-Account Protection</a>, and provides a succinct introduction that's helpful.</p><p>So let's start somewhere nice and concrete. We use Gmail / Google Apps for email at work. Beyond email, the Google account is used for authentication, via their <a href="https://developers.google.com/identity/gsi/web">Sign in With Google feature</a>. Logging into our software for scheduling interviews, for example, I just sign in with Google. A lot of other software works the same way.</p><p>But what if my Google account was compromised? Sure, IT at work can lock the account or force a password reset–after I figure out how to contact them without being able to look up their info in my email account. But what about all the SaaS services I've logged into?</p><p>Sites using Sign In With Google (aka Google Identity) can request that Google notify them via a webhook of important security events. For example:</p><ul><li>If a Google account is compromised, a site can expire that user's session cookies in our app.</li><li>If Google closes the account for being a spammer, we can get an <code>account-disabled</code> event with the <code>reason=bulk-account</code> attribute set, and we probably want to do something on our side to see if they're sending spam in our app.</li></ul><p>And suddenly, this all feels less ethereal. Google even calls out near the top that this is an implementation of RISC. Those webhooks/callbacks are the Security Event Tokens, submitted to a Receiver endpoint.</p><p>This also helps me understand something else: what stops me from creating a malicious Receiver and requesting notice of what happens with <em>all</em> Google accounts? Isn't this a security risk?</p><p>It's not actually addressed, but the concrete example makes this easier to reason about. If I implement Sign In With Google on my site, Google already knows who's used Google to log into my site. It would only be reasonable for them to ignore requests for events concerning unrelated third parties.</p><h2 id="microsoft-does-it">Microsoft does it</h2><p>We saw RISC at Google. <a href="https://techcommunity.microsoft.com/t5/azure-active-directory-identity/continuous-access-evaluation-in-azure-ad-is-now-generally/ba-p/2464398">Microsoft's Azure AD implements</a> the other half of SSE, the Continuous Access Evaluation Protocol.</p><h2 id="-gov-does-it">.gov does it</h2><p>login.gov, providing OpenID Connect access to various government sites, also implements <a href="https://developers.login.gov/security-events/">Security Events</a> – bidirectionally. Sites using login.gov can <a href="https://developers.login.gov/security-events/#receiving-a-security-event-token-set">receive</a> SETs, but they also accept <a href="https://developers.login.gov/security-events/#supported-incoming-events">incoming events</a>. (One presumes a greater degree of trust exists between .gov sites than with random sites letting people log in via Google.)</p><h2 id="event-types">Event Types</h2><p>The full list of supported event types in RISC is here:</p><figure class="kg-card kg-bookmark-card"><a class="kg-bookmark-container" href="https://openid.net/specs/openid-risc-event-types-1_0-ID1.html"><div class="kg-bookmark-content"><div class="kg-bookmark-title">OpenID RISC Event Types 1.0</div><div class="kg-bookmark-description">This document defines the RISC Event Types. Event Types are introduced and defined in</div><div class="kg-bookmark-metadata"></div></div></a></figure>]]></content:encoded></item><item><title><![CDATA[Smashing Pumpkins - Chicago, 1993]]></title><description><![CDATA[<p>It's apparently been five years since I last updated <a href="https://thesesongsilike.tumblr.com/">These Songs I Like</a>, and I started to gravitate away from Tumblr as a whole when their "adult content" restrictions turned into restricting non-sexual LGBTQ-related content.</p><p>Anyway, here's Wonderwall. Err, an almost-2-hour Smashing Pumpkins concert from 1993:</p><figure class="kg-card kg-embed-card"><iframe width="200" height="150" src="https://www.youtube.com/embed/DZBmU6_N4Lc?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></figure><p>As someone who generally</p>]]></description><link>https://ghost.n1zyy.com/smashing-pumpkins-chicago-1993/</link><guid isPermaLink="false">625f798ede23327a28672afa</guid><category><![CDATA[song of the day]]></category><dc:creator><![CDATA[Matt]]></dc:creator><pubDate>Wed, 20 Apr 2022 03:33:34 GMT</pubDate><content:encoded><![CDATA[<p>It's apparently been five years since I last updated <a href="https://thesesongsilike.tumblr.com/">These Songs I Like</a>, and I started to gravitate away from Tumblr as a whole when their "adult content" restrictions turned into restricting non-sexual LGBTQ-related content.</p><p>Anyway, here's Wonderwall. Err, an almost-2-hour Smashing Pumpkins concert from 1993:</p><figure class="kg-card kg-embed-card"><iframe width="200" height="150" src="https://www.youtube.com/embed/DZBmU6_N4Lc?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></figure><p>As someone who generally resents the live version of songs, this whole set is a rare exception. In particular, the version of Starla here is incomprehensibly better.</p><p>Delightfully, the concert opens with Rocket, one of my favorites but for some reason not a chart-topper. It also led to me discovering <a href="https://genius.com/The-smashing-pumpkins-spaceboy-lyrics">the charming story behind Spaceboy</a>, which is really relatable for me.</p><p>As an aside, <a href="https://genius.com/10975689/The-smashing-pumpkins-hummer/Lifes-a-bummer-when-youre-a-hummer">the explanation for Hummer</a> I've since learned makes me laugh. Lots of theories have been advanced for what it might mean for someone to be "a hummer," and the answer is delightfully matter-of-fact:</p><blockquote>Ever since I wrote that song I’ve heard many definitions for the word <em>'hummer'</em>. I’ve heard that there’s a car called a Hummer, I heard that Monica gave Bill a hummer in the White House, but quite honestly in my innocent youth, I  imagined it being someone who just walked around humming a song to himself.</blockquote>]]></content:encoded></item><item><title><![CDATA[pg_trgm migrations with alembic and SQLAlchemy]]></title><description><![CDATA[<p>I'm a Rails engineer working on a Flask app. We use alembic and SQLAlchemy against a Postgres database. Even though I miss ActiveRecord dearly, for the most part what I know has mapped pretty well.</p><p>Until today.</p><p>I've been trying to create a <a href="https://www.postgresql.org/docs/current/pgtrgm.html#id-1.11.7.42.8">pg_trgm</a> index on one of our</p>]]></description><link>https://ghost.n1zyy.com/pg_trgm-migrations-with-alembic/</link><guid isPermaLink="false">625f71c2de23327a28672a5e</guid><dc:creator><![CDATA[Matt]]></dc:creator><pubDate>Wed, 20 Apr 2022 03:00:44 GMT</pubDate><media:content url="https://ghost.n1zyy.com/content/images/2022/04/uriel-sc-11KDtiUWRq4-unsplash.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://ghost.n1zyy.com/content/images/2022/04/uriel-sc-11KDtiUWRq4-unsplash.jpg" alt="pg_trgm migrations with alembic and SQLAlchemy"><p>I'm a Rails engineer working on a Flask app. We use alembic and SQLAlchemy against a Postgres database. Even though I miss ActiveRecord dearly, for the most part what I know has mapped pretty well.</p><p>Until today.</p><p>I've been trying to create a <a href="https://www.postgresql.org/docs/current/pgtrgm.html#id-1.11.7.42.8">pg_trgm</a> index on one of our tables, which is easy enough to do if I just drop some raw SQL into a migration. But we can do better–and besides, an in-house code quality tool we use fails to reconcile the model with the state of the database.</p><p>The solution lies somewhere between <a href="https://stackoverflow.com/questions/36389166/how-to-create-a-pg-trgm-index-using-sqlalchemy-for-scrapy/36389792#36389792">this StackOverflow answer</a> and <a href="https://gist.github.com/jakerobers/fb9f7f1dac923aec766237c64a006e49">this gist</a>.</p><p>What ended up working for me was:</p><ul><li>Define the index in the model using <code>__table_args__</code>, and then</li><li>Let alembic generate a migration automatically from it.</li></ul><p>Genericizing the model to not be insanely domain-specific, it might look something like this:</p><pre><code class="language-python">class Book():
  __tablename__ = "book"
  __table_args__ = (Index(
      "ix_book_author_name_trgm", "author_name",
      postgresql_ops={"author_name": "public.gin_trgm_ops"},
      postgresql_using="gin"
    ),
  )
  book_id = Column(PostgreSQLUUID, primary_key=True, default=uuid_gen)
  author_name = Column(Text, index=True)</code></pre><p>The <code>__table_args__</code> bit is the magic sauce, and the variable must be a tuple or dict (or None...), so the trailing comma is needed here. (Did I mention I miss Ruby sometimes?) In terms of attributes:</p><ul><li><code>ix_book_author_name_trgm</code> is the name of the index. You can call it whatever you want.</li><li><code>author_name</code> is the column name.</li><li><code>postgresql_ops</code> is a Postgres-specific field; <code>author_name</code> is the affected column name, and <code>public.gin_trgm_ops</code> is the schema name (public) and index operation (gin_trgm_ops) to use. Without the schema name, you may run into <a href="https://dba.stackexchange.com/questions/234463/gin-trgm-ops-index-creation-fails">this error</a>. (Your schema name might not be "public".)</li><li><code>postgresql_using="gin"</code> tells Postgres this is of the generalized inverted index (GIN) class.</li></ul><p>And then, running <code>poetry run alembic --config ./alembic.ini revision --autogenerate</code> set me up with a migration to apply this to the database.</p><p>It's very possible there's room for improvement here, but this got things working. The two examples I had come across happened to have columns named <code>title</code> and <code>description</code>, which confused me initially into thinking that <code>"title": "public.gin_trgm_ops"</code> was (for some reason) the key name <code>postgresql_ops</code> looked for, or that <code>"description"</code> was a placeholder for a comment about the migration, leading to me just omitting it. 🤦</p><p>Hope my struggles help someone in the future. (Possibly my future self, even...)</p><hr><p>Cover photo by <a href="https://unsplash.com/@urielsc26?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Uriel SC</a> on <a href="https://unsplash.com/s/photos/database?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></p>]]></content:encoded></item><item><title><![CDATA[Free weather and geocoding APIs]]></title><description><![CDATA[<p>I wanted to hack together a little weather app, and here's a few services I've found that look interesting.</p><h2 id="openweather">OpenWeather</h2><figure class="kg-card kg-bookmark-card"><a class="kg-bookmark-container" href="https://openweathermap.org/"><div class="kg-bookmark-content"><div class="kg-bookmark-title">Сurrent weather and forecast - OpenWeatherMap</div><div class="kg-bookmark-description">Get current weather, hourly forecast, daily forecast for 16 days, and 3-hourly forecast 5 days for your city. Historical weather data for 40 years</div></div></a></figure>]]></description><link>https://ghost.n1zyy.com/free-weather-and-geocoding-apis/</link><guid isPermaLink="false">61d7baa0de23327a2867260e</guid><dc:creator><![CDATA[Matt]]></dc:creator><pubDate>Fri, 07 Jan 2022 04:24:43 GMT</pubDate><content:encoded><![CDATA[<p>I wanted to hack together a little weather app, and here's a few services I've found that look interesting.</p><h2 id="openweather">OpenWeather</h2><figure class="kg-card kg-bookmark-card"><a class="kg-bookmark-container" href="https://openweathermap.org/"><div class="kg-bookmark-content"><div class="kg-bookmark-title">Сurrent weather and forecast - OpenWeatherMap</div><div class="kg-bookmark-description">Get current weather, hourly forecast, daily forecast for 16 days, and 3-hourly forecast 5 days for your city. Historical weather data for 40 years back for any coordinate. Helpful stats, graphics, and this day in history charts are available for your reference. Interactive maps show precipitation, c…</div><div class="kg-bookmark-metadata"><img class="kg-bookmark-icon" src="https://openweathermap.org/themes/openweathermap/assets/vendor/owm/img/icons/logo_60x60.png"><span class="kg-bookmark-author">OpenWeatherMap.org</span><span class="kg-bookmark-publisher">OpenWeatherMap</span></div></div><div class="kg-bookmark-thumbnail"><img src="https://openweathermap.org/themes/openweathermap/assets/img/mobile_app/android-app-top-banner.png"></div></a></figure><p>Registration is required, but their <a href="https://openweathermap.org/price">free plan</a> allows 60 API calls a minute, up to a million a month. They have a <a href="https://openweathermap.org/current">current weather API</a>, <a href="https://openweathermap.org/api/air-pollution">air pollution API</a>, and a <a href="https://openweathermap.org/api/one-call-api">"One Call" API</a> that returns current weather and a forecast.</p><p>They also implement a <a href="https://openweathermap.org/api/geocoding-api">Geocoding API</a>, which supports forward and reverse geocoding. This is useful for when you want to allow app users to put in, say, "Boston" and see weather, which is often best done with lat and long. (Their current weather API has some support for cities, though.)</p><h2 id="nominatim">Nominatim</h2><p>OpenStreetMap's <a href="https://nominatim.openstreetmap.org/ui/search.html">Nominatim</a> is a free (no registration required) geocoding API based on the OpenStreetMap dataset. Do see the <a href="https://operations.osmfoundation.org/policies/nominatim/">usage policy</a> before hammering the API.</p><p>The neat thing is that, because it's based on, you know, <strong>Open</strong> Street Maps, they don't have the goofy "no caching allowed!" requirements that some other applications do. In fact, you can <a href="https://nominatim.org/release-docs/latest/admin/Installation/">run your own Nominatim server</a>, but <a href="https://nominatim.org/release-docs/latest/admin/Installation/#hardware">it requires some beefy hardware</a> since it's got an enormous database. But the ability is pretty nifty nonetheless.</p>]]></content:encoded></item><item><title><![CDATA[Getting something useful from a 3B Luna CPAP and iCodeConnect]]></title><description><![CDATA[<p>I was recently prescribed a CPAP for sleep apnea. I ended up with CPAP machine called the Luna by 3B. As many machines do, it records data to an SD card.</p><p>The <em>idea</em> is useful: the CPAP machine can display a QR code on-screen which you can scan with <a href="https://www.icodeconnect.com/pages/learn_more">a</a></p>]]></description><link>https://ghost.n1zyy.com/getting-something-useful-from-a-3b-luna-cpap-and-icodeconnect/</link><guid isPermaLink="false">61aab14fde23327a28671f25</guid><dc:creator><![CDATA[Matt]]></dc:creator><pubDate>Sat, 04 Dec 2021 02:13:35 GMT</pubDate><content:encoded><![CDATA[<p>I was recently prescribed a CPAP for sleep apnea. I ended up with CPAP machine called the Luna by 3B. As many machines do, it records data to an SD card.</p><p>The <em>idea</em> is useful: the CPAP machine can display a QR code on-screen which you can scan with <a href="https://www.icodeconnect.com/pages/learn_more">a mobile app</a>. Neat!</p><p>The app has terrible ratings, and they are deserved. It shows only very basic information; a nightly average. More baffling, although there's an "Upload" tab, there is no apparent way to actually upload the results anywhere.</p><p>Frustrated by the only-marginally-useful mobile app, and the fact that none of their software could read the data on the SD card, my doctor found some information and gave me a printout steering me to <a href="https://www.icodeconnect.com/">iCodeConnect</a> (also stylized as ICODECONNECT which is how I have started referring to it, because it's impossible to discuss without screaming about it).</p><p>The instructions suggest to click "Quick Report" on the main page. Doing so brings up a page asking for a ton of information, and noting, in bold:</p><blockquote>It is strongly recommended that you sign up for a provider account on iCodeConnect so that all of your data will be preserved and accessible from anywhere.</blockquote><p>Signing up for a provider account required me to designate a HIPAA compliance officer (I nominated myself). This got my account rejected, with a note that patients are not allowed to register accounts.</p><p>On the "Quick report generator," it appears that basically all of the information you input is just displayed back to you. There is no apparent purpose to filling in any of your information, much less your provider or physician information, except that it will display on the next page.</p><p>And then there's this box at the bottom:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://ghost.n1zyy.com/content/images/2021/12/Screen-Shot-2021-12-03-at-7.17.56-PM.png" class="kg-image"><figcaption>Report Type: "SD card" or "iCode"</figcaption></figure><p>You would think you would select iCode, but this results in a comically bad experience. You are expected to type in the strings that appear on the CPAP's screen.</p><p>What you actually want to do: turn off the CPAP machine, remove the SD card ("chip"), insert it into your computer (if you have an adapter), and then press "SD card" instead of the default "iCode". This will allow you to select a file with a .USR extension on the SD card.</p><p>(Aside: the .USR file on the SD card is only 1MB for me; maybe it will expand with usage, but I suspect it's actually a circular log and will always be 1MB. In that case, a tech-savvy patient could email the .USR file to their doctor directly, rather than dealing with the SD card itself.)</p><p>You'll probably want to change the "Select date range" bit to "Select all days with data" or something useful like that, because the default appears to only be the current day.</p><p>At the bottom of that page, it displays a helpful daily chart of how your sleep went. <em>This</em> is what I was after, and it seems this data is only accessible from the SD card.</p><figure class="kg-card kg-image-card"><img src="https://ghost.n1zyy.com/content/images/2021/12/Screen-Shot-2021-12-03-at-7.32.23-PM.png" class="kg-image"></figure><p>Now <em>this</em> is useful! It shows I started around midnight, at the starting 5 cmH₂O, climbing slowly over the night and peaking around 8. But more interesting:</p><ul><li>Several times, especially around 2-3am, I had several apnea events.</li><li>Around 6am (and a bit earlier), the mask leaked a lot. I probably rolled over and had it come off in my sleep.</li></ul><p>Note that the bars for apnea (red) and hypopnea (orange) are not too easily distinguished. Also, because I had to look it up:</p><ul><li><em>Apnea</em> is loosely defined as when you stop breathing; we probably know this since we've been diagnosed with sleep apnea. The textbook definition is apparently that your airflow is reduced at least 90% for 10 seconds or more.</li><li><em>Hypopnea</em> is a lesser version: your airflow is reduced at least 30%, but less than 90%, or it would be apnea. WebMD refers to it as "shallow breaths." Like apnea, it must last at least 10 seconds.</li></ul><p>(I presume the 10-second limit is less that a 9.9-second cessation of breathing doesn't matter, and more that your respiration rate while sleeping is pretty low, so going a few seconds without breathing is normal.)</p><p>There's a Windows software app for these called RESmart, which seems to cover machines made by both BMC and B3. It's available through ApneaBoard.com; not sure if it's available from a more official source or not. It is similarly clunky to use, but something it shows that the iCode Connect site doesn't is a breathing/airflow chart. It makes individual apneic episodes a lot more visible.</p>]]></content:encoded></item><item><title><![CDATA[You don't have permission to access "website" on this server error]]></title><description><![CDATA[<p>Someone just asked me about receiving an error like this one:</p><pre><code>You don't have permission to access "http://www.gap.com/" on this server.

Reference #18.c6a50517.1514639126.176b29a</code></pre><p>There are several garbage articles out there talking about this without any indication of what is actually generating this error message.</p>]]></description><link>https://ghost.n1zyy.com/you-dont-have-permission-to-access-website-on-this-server-error/</link><guid isPermaLink="false">6189cd64de23327a28671ee6</guid><dc:creator><![CDATA[Matt]]></dc:creator><pubDate>Tue, 09 Nov 2021 15:00:06 GMT</pubDate><content:encoded><![CDATA[<p>Someone just asked me about receiving an error like this one:</p><pre><code>You don't have permission to access "http://www.gap.com/" on this server.

Reference #18.c6a50517.1514639126.176b29a</code></pre><p>There are several garbage articles out there talking about this without any indication of what is actually generating this error message.</p><p><a href="https://social.technet.microsoft.com/Forums/en-US/0786bfec-306b-4ee1-bea3-a7bf479cdc79/access-denied-you-dont-have-permission-to-access?forum=win10itprogeneral">This Microsoft TechNet post</a> reveals the answer: <strong>it comes from the Akamai CDN</strong>, a content delivery network used by large sites to speed them up.</p><p>Akamai has <a href="https://community.akamai.com/customers/s/article/Why-is-Akamai-blocking-me?language=en_US">a helpdesk article</a> about this, including a link to their <a href="https://www.akamai.com/us/en/clientrep-lookup/">Client Reputation lookup tool</a>.</p><p>Microsoft, which apparently also uses Akamai, has <a href="https://docs.microsoft.com/en-us/troubleshoot/windows-server/networking/access-denied-visit-website-hosted-akamai-cdn">a post of their own about it</a>, noting:</p><blockquote>This issue occurs because of the measures that Akamai has implemented to protect its websites from denial-of-service attacks. If a single origin or source tries to connect too frequently, these measures automatically block any IP addresses from that origin or source.</blockquote><blockquote>The blockage is usually temporary. As soon as the connection volume remains below the defined thresholds for a while, the block on the affected TCP/IP address is expected to be removed.</blockquote><p>From the posts I've seen, it is perhaps a touch too sensitive and sometimes blocks legitimate users. (Perhaps triggered by rapidly opening multiple links in tabs, or multiple people in the same household browsing concurrently?) The fix is to simply wait a bit and try again, though.</p>]]></content:encoded></item><item><title><![CDATA[Tower Babble]]></title><description><![CDATA[<p>As I've started to look at real estate, something in the back of my mind as a radio nerd is where I'd put a tower.</p><p>In the course of doing some reading, I've learned a fair bit that I thought I'd try to summarize here.</p><p>Beyond obvious stuff like height,</p>]]></description><link>https://ghost.n1zyy.com/tower-babble/</link><guid isPermaLink="false">61226405de23327a286719dd</guid><dc:creator><![CDATA[Matt]]></dc:creator><pubDate>Sun, 22 Aug 2021 15:39:42 GMT</pubDate><media:content url="https://ghost.n1zyy.com/content/images/2021/08/Screen-Shot-2021-08-22-at-11.38.21-AM.png" medium="image"/><content:encoded><![CDATA[<img src="https://ghost.n1zyy.com/content/images/2021/08/Screen-Shot-2021-08-22-at-11.38.21-AM.png" alt="Tower Babble"><p>As I've started to look at real estate, something in the back of my mind as a radio nerd is where I'd put a tower.</p><p>In the course of doing some reading, I've learned a fair bit that I thought I'd try to summarize here.</p><p>Beyond obvious stuff like height, the big issue with towers is wind loading. This is typically measured in square feet, but not much of what is attached to towers is actually a square cube. Antennas or microwave dishes therefore have an <strong>"effective projected area" (EPA)</strong> in square feet, identified by the antenna manufacturer.</p><p>Towers have a certain maximum EPA windload rating, but in reality, it's usually stated multiple ways. The applicable standards are in <a href="https://wirelessestimator.com/articles/2019/ansitia-222-the-design-bible-for-towers-steps-proudly-into-its-sixth-decade-of-guidance/">TIA-222</a>, which is... a lot. But here are some of the summaries.</p><p>For a long time, Revision F ("TIA-222-F" or "Rev F") was the applicable standard, but <strong>Revision G ("Rev G")</strong> came out in 2005. It substantially changed how wind loading was calculated. Rev F used a "fastest mile" measurement for wind loading: <a href="http://www.rohnnet.com/revg">tower manufacturer Rohn describes this as</a>, "the average wind speed over the time required for one mile of wind to pass the site." Rev G switched to using a <strong>3-second wind gust</strong>. Even though Rev G is 16 years old at this point, windloading specs typically still show both Rev F and Rev G ratings. Note that the linked Rohn page includes a link to a PDF explaining all of this in more depth.</p><p>These specifications are then stated for different wind speeds, typically 90 to 130 mph, with allowable EPA dropping off as 3-second gust speed increases.</p><p>The other big consider is structure classification.</p><p><strong>Class I</strong> structures specifically list ham radio towers as an example, and have a 25-year <a href="https://en.wikipedia.org/wiki/Return_period">return period</a> (probability of occurrence, more or less). They're towers where, although it would stink if they collapsed, it's not going to affect any mission-critical systems.</p><p><strong>Class II</strong> structures are based on a 50-year return period and are specified as including things like broadcast TV/FM towers and cell towers. There's probably <em>some</em> redundancy in the systems: your cell phone might fail over to a further cell tower, or you might have to get news in an emergency from a more distant TV station.</p><p><strong>Class III</strong> structures have the lowest risk tolerance, based on a 100-year return period. They include things like emergency radio systems or navigation beacons, and they may include systems where there's no redundancy available.</p><p>Most tower specifications I've seen only show Class I and Class II loadings. There can be a tremendous drop in allowable wind loading from Class I to Class II.</p><p>Another consideration is <strong>Exposure Category</strong>, based on surrounding terrain. They range from Exposure B (least exposed) to Exposure D (most exposed); there is apparently no Exposure A. <strong>Exposure B</strong> is an urban, suburban, or wooded area; winds at ground level are typically low, broken by homes and trees. <strong>Exposure C</strong> is more flat, open terrain; buildings or other obstructions are less than 30', and the tower therefore sees greater wind speeds. <strong>Exposure D</strong> is reserved for shorelines and the surrounding area, where there is no protection from wind.</p><p>The loading for <a href="http://www.rohnnet.com/files/2015_Rohn_Full_Catalog.pdf#page=178">Rohn RSL self-supporting towers (PDF)</a> is a good illustration of some of this.</p><p>With Class I loading, a 70' RSL70L40 can support 80 square feet EPA designed for a 3-second gust of 90mph, or 56 square feet at 100mph. Designing for a 140mph 3-second gust drops you all the way down to 5 square feet of allowable surface area.</p><p>Things change drastically if you design for Class II loading, though. On the same 70' tower, you're only allowed 35 square feet at 90mph, and the maximum wind speed with any loading is at 110mph, where you're permitted 8 square feet.</p><p>Hapco, which appears to be a manufacturer of light poles and such, has a <a href="https://www.hapco.com/design/wind-speed-map/">3-second gust map</a> on their site. Much of the country is in the 90mph category, but those of us within perhaps 100 miles of the Atlantic (or Gulf) coastline are exposed to higher wind speeds.</p><p><em>Cover image photo credit: <a href="https://unsplash.com/@thimo?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Thimo Pedersen</a> on <a href="https://unsplash.com/?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a>, showing a site in Zürich.</em></p>]]></content:encoded></item><item><title><![CDATA[Better to ask for forgiveness]]></title><description><![CDATA[<p>A speech by Grace Hopper at Lake Forest College <a href="https://quoteinvestigator.com/2018/06/19/forgive/">in 1982 contains this gem</a>:</p><blockquote><strong>“Always remember that it’s much easier to apologize than to get permission,”</strong> she said. “In this world of computers, the best thing to do is to do it.”</blockquote><p><a href="https://changelog.com/posts/what-admiral-grace-hopper-really-meant">Her point, of course</a>, was about avoiding</p>]]></description><link>https://ghost.n1zyy.com/better-to-ask-for-forgiveness/</link><guid isPermaLink="false">6099bb22aab0a84673a849ab</guid><category><![CDATA[tech]]></category><category><![CDATA[ham radio]]></category><dc:creator><![CDATA[Matt]]></dc:creator><pubDate>Tue, 11 May 2021 00:02:18 GMT</pubDate><content:encoded><![CDATA[<p>A speech by Grace Hopper at Lake Forest College <a href="https://quoteinvestigator.com/2018/06/19/forgive/">in 1982 contains this gem</a>:</p><blockquote><strong>“Always remember that it’s much easier to apologize than to get permission,”</strong> she said. “In this world of computers, the best thing to do is to do it.”</blockquote><p><a href="https://changelog.com/posts/what-admiral-grace-hopper-really-meant">Her point, of course</a>, was about avoiding bureaucracy while doing good, not about taking liberties with ethics. Especially in large organizations, I think this can be helpful advice, at least when employed with care.</p><p>Towards the end of <a href="http://www.repeater-builder.com/tech-info/weather-radios.html">this Repeater Builder article on NOAA weather radio</a> is hidden an absolute gem. While it's astute advice on dealing with the Federal Communications Commission, it almost seems to double as a life lesson. Credit for the below goes to Mike, WA6ILQ.</p><p>First, he sets some good background on how the amateur radio service is regulated:</p><blockquote>Second, please note that the USA FCC rules for ham radio are written very, very differently than any other portion of the FCC's rules. In fact, amateur radio, part 97, could have been written by a different person (or team).<br><br>In broadcast, land mobile (i.e. commercial / business 2-way), GMRS, marine radio, forestry, aircraft, paging, public safety (police, fire, etc)  and all the other services their rules are written in the format of "you can do X, you can do Y, you can do Z", and that's it. The FCC has to be petitioned for permission to do anything else. </blockquote><p>[snip]</p><blockquote> On the other hand the amateur rules are written in the reverse format of "you can't do A, you can't do B, you can't do C". And the amateur rules - part 97 - is the ONLY section of the FCC rules that is written that way. NO PETITION IS REQUIRED for permission to do anything else.<br><br>In other words the hams can do D, E, F, G, H, etc. <u>without asking</u> and we can't afford to lose this privilege. This is how innovation happens - like RTTY, FSTV (ATV), SSTV, packet, PSK, AX.25, APRS, IRLP, etc. Rule change petitions are required only if the hams want changes to A, B or C.</blockquote><p>And then, he brings it home:</p><blockquote>On the other hand, <u>if you ask in advance</u> some low level FCC flunkie will be told to send you a letter that covers everybody's ass by saying DON'T - because <u>every other part of the FCC rules that they deal with every day is full of Thou Shalt Nots, and their day-to-day mindset is such that they can't comprehend anything else</u>.<br><br>I repeat - <u>the amateur radio service is the only one</u> where the rules say "You can't do A, B or C and you CAN do anything else". The average FCC flunkie that spends their whole career handling broadcast, land mobile, public safety, aircraft, forestry, business, public safety, pagers or cellphones totally forgets that.<br><br>But from then on that "DON'T" letter becomes official policy and can be referred to in future cases - something that anybody else at the FCC can point to from the time that said flunkie wrote that letter onwards. And <u>only because you just had to ask</u> all hams lose one more privilege.</blockquote><p>In short: asking permission unnecessarily can hurt not just you, but also risk establishing a bad precedent. If what you're doing is ethical and easily explained, it's better to just do it.</p>]]></content:encoded></item><item><title><![CDATA[RubyMine Bookmarks]]></title><description><![CDATA[<p>A friend and mentor once told me that it's almost always worth taking a moment to figure out the optimal way to do something in your IDE or editor, because the couple minutes it will take you will be amortized over the rest of the years you use the tool</p>]]></description><link>https://ghost.n1zyy.com/rubymine-bookmarks/</link><guid isPermaLink="false">6054fd52aab0a84673a84882</guid><category><![CDATA[mastering rubymine]]></category><category><![CDATA[tech]]></category><dc:creator><![CDATA[Matt]]></dc:creator><pubDate>Fri, 19 Mar 2021 20:06:14 GMT</pubDate><content:encoded><![CDATA[<p>A friend and mentor once told me that it's almost always worth taking a moment to figure out the optimal way to do something in your IDE or editor, because the couple minutes it will take you will be amortized over the rest of the years you use the tool for.</p><p>With that in mind, I'm going to start a series of posts with nifty things I learn about using RubyMine. (Most should probably transfer to other IntelliJ-based IDEs like PhpStorm.) Up first: Bookmarks.</p><p>I've often abused the ability to set breakpoints in the margins as a way to dog-ear the page of something I know I want to come back to:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://ghost.n1zyy.com/content/images/2021/03/Screen-Shot-2021-03-19-at-3.41.09-PM.png" class="kg-image"><figcaption>Setting a breakpoint just for visibility</figcaption></figure><p>The problem is that (1) this isn't what breakpoints are for, and (2) they're not particularly easy to find again. (Run &gt; View Breakpoints will get you there, though.)</p><p>The right way to do this is with bookmarks!</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://ghost.n1zyy.com/content/images/2021/03/Screen-Shot-2021-03-19-at-4.02.34-PM.png" class="kg-image"><figcaption>A bookmark set on line 483</figcaption></figure><p>These can be set by right-clicking in the margin and selecting "Set Bookmark", or by simply pressing F3 on your keyboard.</p><p>Then, Navigate &gt; Bookmarks gives you a variety of options for viewing or cycling through bookmarks.</p>]]></content:encoded></item><item><title><![CDATA[No record, NOERROR, no NXDOMAIN, no problem]]></title><description><![CDATA[<p>CircleCI's currently having a sad:</p><pre><code>% dig app.circleci.com
; &lt;&lt;&gt;&gt; DiG 9.10.6 &lt;&lt;&gt;&gt; app.circleci.com
;; global options: +cmd
;; Got answer:
;; -&gt;&gt;HEADER&lt;&lt;- opcode: QUERY, status: NOERROR, id: 10705
;; flags: qr rd ra; QUERY: 1, ANSWER: 0,</code></pre>]]></description><link>https://ghost.n1zyy.com/no-record-noerror/</link><guid isPermaLink="false">604aa15aaab0a84673a84816</guid><dc:creator><![CDATA[Matt]]></dc:creator><pubDate>Thu, 11 Mar 2021 23:17:08 GMT</pubDate><content:encoded><![CDATA[<p>CircleCI's currently having a sad:</p><pre><code>% dig app.circleci.com
; &lt;&lt;&gt;&gt; DiG 9.10.6 &lt;&lt;&gt;&gt; app.circleci.com
;; global options: +cmd
;; Got answer:
;; -&gt;&gt;HEADER&lt;&lt;- opcode: QUERY, status: NOERROR, id: 10705
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;app.circleci.com.		IN	A
;; AUTHORITY SECTION:
circleci.com.		181	IN	SOA	ns-1572.awsdns-04.co.uk. awsdns-hostmaster.amazon.com. 1 7200 900 1209600 86400
;; Query time: 89 msec
;; SERVER: 1.1.1.1#53(1.1.1.1)
;; WHEN: Thu Mar 11 15:43:15 EST 2021
;; MSG SIZE  rcvd: 129</code></pre><p>The response that comes back shows <code>NOERROR</code> as a status, but there's no A record returned like I asked for. Instead, there's an unsolicited SOA record. Why is there an SOA record? And why <code>NOERROR</code> instead of <code>NXDOMAIN</code> like I'd expect?</p><p>It turns out that <code>NXDOMAIN</code> means the <em>record</em> (<code>app.circleci.com</code> here) doesn't exist. In this case, though, apparently it <em>does</em> exist; it just doesn't have an A record.</p><p>A missing A record is kind of a weird case; this all makes more sense with, say, an MX record:</p><pre><code>% dig -t MX www.google.com

; &lt;&lt;&gt;&gt; DiG 9.10.6 &lt;&lt;&gt;&gt; -t MX www.google.com
;; global options: +cmd
;; Got answer:
;; -&gt;&gt;HEADER&lt;&lt;- opcode: QUERY, status: NOERROR, id: 60708
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;www.google.com.			IN	MX

;; AUTHORITY SECTION:
google.com.		60	IN	SOA	ns1.google.com. dns-admin.google.com. 362007607 900 900 1800 60

;; Query time: 75 msec
;; SERVER: 1.1.1.1#53(1.1.1.1)
;; WHEN: Thu Mar 11 18:07:13 EST 2021
;; MSG SIZE  rcvd: 93</code></pre><p>Of course www.google.com <em>exists</em>, so returning an <code>NXDOMAIN</code> in response to our query asking for an MX record would be incorrect. Instead, the response shows <code>ANSWER: 0</code> because there are no MX records to return, and <code>ADDITIONAL: 1</code> for the unsolicited SOA record. Because the query completed successfully, the status is set to <code>NOERROR</code>.</p><p>The same thing is happening with CircleCI's broken DNS when we try to find an address record. Arguably, the lack of an A record for a production website <em>is</em> a big error, but the DNS server cannot prognosticate about the state of the world. It's been incorrectly told that app.circleci.com exists, but doesn't have an A record, and the response reflects that.</p>]]></content:encoded></item><item><title><![CDATA[On Programming]]></title><description><![CDATA[<figure class="kg-card kg-embed-card"><blockquote class="twitter-tweet"><p lang="en" dir="ltr">wait, people use programming to SOLVE problems?!?!</p>&mdash; Yoz Grahame (@yoz) <a href="https://twitter.com/yoz/status/1370046546780188674?ref_src=twsrc%5Etfw">March 11, 2021</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
</figure>]]></description><link>https://ghost.n1zyy.com/programming/</link><guid isPermaLink="false">604aa0faaab0a84673a8480e</guid><dc:creator><![CDATA[Matt]]></dc:creator><pubDate>Thu, 11 Mar 2021 23:00:20 GMT</pubDate><content:encoded><![CDATA[<figure class="kg-card kg-embed-card"><blockquote class="twitter-tweet"><p lang="en" dir="ltr">wait, people use programming to SOLVE problems?!?!</p>&mdash; Yoz Grahame (@yoz) <a href="https://twitter.com/yoz/status/1370046546780188674?ref_src=twsrc%5Etfw">March 11, 2021</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
</figure>]]></content:encoded></item><item><title><![CDATA[An Invocation for Beginners]]></title><description><![CDATA[<figure class="kg-card kg-embed-card kg-card-hascaption"><iframe width="200" height="113" src="https://www.youtube.com/embed/RYlCVwxoL_g?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe><figcaption>zefrank1 - An Invocation for Beginners</figcaption></figure><p>I'm extremely late to the party on this one, but this is ❤️.</p><p>And someone else put together <a href="http://rkuykendall.com/articles/an-invocation/">a transcript</a> here.</p>]]></description><link>https://ghost.n1zyy.com/an-invocation-for-beginners/</link><guid isPermaLink="false">60356f1faab0a84673a847fd</guid><dc:creator><![CDATA[Matt]]></dc:creator><pubDate>Tue, 23 Feb 2021 21:11:19 GMT</pubDate><content:encoded><![CDATA[<figure class="kg-card kg-embed-card kg-card-hascaption"><iframe width="200" height="113" src="https://www.youtube.com/embed/RYlCVwxoL_g?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe><figcaption>zefrank1 - An Invocation for Beginners</figcaption></figure><p>I'm extremely late to the party on this one, but this is ❤️.</p><p>And someone else put together <a href="http://rkuykendall.com/articles/an-invocation/">a transcript</a> here.</p>]]></content:encoded></item><item><title><![CDATA[10 BitTorrent Trackers That Still Work]]></title><description><![CDATA[<p>It's February 2021, and several of the commonly-used open torrent trackers have gone away. (RIP, Coppersurfer!)</p><p>I spent a bit going through some lists and wrote a script to run scrape requests against them. I eliminated the ones that often failed to respond; some were unreliable and some just don't</p>]]></description><link>https://ghost.n1zyy.com/20-bittorrent-trackers-that-still-work/</link><guid isPermaLink="false">6032c5c2aab0a84673a8473d</guid><dc:creator><![CDATA[Matt]]></dc:creator><pubDate>Sun, 21 Feb 2021 21:40:06 GMT</pubDate><content:encoded><![CDATA[<p>It's February 2021, and several of the commonly-used open torrent trackers have gone away. (RIP, Coppersurfer!)</p><p>I spent a bit going through some lists and wrote a script to run scrape requests against them. I eliminated the ones that often failed to respond; some were unreliable and some just don't seem to exist anymore.</p><p>A few things to note first:</p><ul><li>I genuinely don't recommend using any of these for doing anything illegal. Public trackers are low-hanging fruit for lawyers to find copyright infringers.</li><li>All of these are UDP-based. This was not intentional–I included both HTTP-based and UDP-based trackers. None of the HTTP-based ones responded reliably or could meet the 2-second timeout my script imposed. UDP is faster for you and less overhead for the tracker operators.</li><li>I strongly recommend enabling peer exchange (PEX) and distributed hash table (DHT) to find more peers. I have seen cases where <em>most</em> of my peers in a swarm were located this way.</li><li>Most UDP tracker URLs are typically shown with <code>/announce</code> on the end. It is unused! <a href="http://bittorrent.org/beps/bep_0041.html">BEP41</a> would give it meaning, but it's not necessary for announce URLs. I've omitted it because it serves no purpose.</li></ul><p>In the list below, I show the sum of peers returned from a handful of queries. As an absolute number, it's meaningless; it's a sampling of some random content. But it's useful as a relative metric. Here is the list, sorted from most peers to least:</p><ol><li><code>udp://tracker.opentrackr.org:1337</code> – 4,441 peers for the searches I ran. <a href="https://opentrackr.org/">Public stats</a> show that it's handling something like 300,000 connections per second, which is bonkers. Apparently located in the Netherlands.</li><li><code>udp://tracker.internetwarriors.net:1337</code> – 2,773 peers. Apparently located in Chile.</li><li><code>udp://exodus.desync.com:6969</code> – 2,169 peers. Apparently located in USA.</li><li><code>udp://tracker.cyberia.is:6969</code> – 1,944 peers. <a href="http://www.cyberia.is/tracker.html">Website</a>. Apparently located in Ukraine.</li><li><code>udp://opentracker.i2p.rocks:6969</code> – 820 peers. Apparently located in the US.</li><li><code>udp://explodie.org:6969</code> – 764 peers. <a href="https://explodie.org/opentracker.html">Website</a>. Apparently located in the US.</li><li><code>udp://open.stealth.si:80</code> – 223 peers. Apparently located in Norway.</li><li><code>udp://tracker.tiny-vps.com:6969</code> – 210 peers. Apparently located in Russia.</li><li><code>udp://tracker.torrent.eu.org:451</code> – 200 peers. Apparently located in France.</li><li><code>udp://retracker.lanta-net.ru:2710</code> – 197 peers. Apparently located in Russia.</li></ol><p>I found more, but they're all at less than 5% the number of peers discovered in my queries than the #1 entry so I don't find them particularly useful.</p>]]></content:encoded></item></channel></rss>