Skip to content

Ryan Thomas

  • Home
  • About
  • GitHub
  • Archive
  • Getting a FriendlyElec NanoPC-T6 to appear on the “My Spectrum” app

    July 27, 2026

    Last week I installed Armbian on a FriendlyElec NanoPC-T6 LTS and added it to my home network on Spectrum. DHCP worked fine out of the box and the router assigned an IP without issue, but the device never showed up on the Devices page of the My Spectrum app, preventing me from setting a stable IP or enabling port forwarding. After a dizzying labyrinth of guesswork and an uninspiring interaction with Spectrum support chat, it finally occurred to me as a last-ditch effort to try changing the MAC address.

    For whatever reason, Spectrum seems to restrict visibility of devices on the network to those with officially registered MAC address vendor prefixes or OUIs. The NanoPC-T6’s real MAC address doesn’t meet that criteria, presenting a generic, auto-generated address stored on the boot media. This made the device completely invisible to the app despite being fully online and connected.

    A MAC address has six colon-separated pairs (XX:XX:XX:XX:XX:XX). Apparently, the first three pairs identify the manufacturer; the last three are supposed to be unique to a specific device. I took the manufacturer prefix from another device on my network that Spectrum already recognized, and combined it with the last three pairs (the unique identifier) from the NanoPC’s actual hardware address. With the help of a robot slave, let’s call him Clark, I saved this new address in a netplan configuration file as follows:

    /etc/netplan/99-end0-mac-override.yaml:

    network:
      version: 2
      renderer: networkd
      ethernets:
        00-end0-override:
          match:
            name: end0
          dhcp4: yes
          dhcp6: yes
          macaddress: XX:XX:XX:XX:XX:XX
          set-name: end0
    

    Replace end0 with your board’s actual interface name, and the MAC with your own spliced address. You should run sudo chmod 600 on this file as well.

    The arbitrary key name “00-end0-override” used above is intended to alphabetically precede “all-eth-interfaces” (or whatever else is listed in /run/systemd/network/10-netplan* ) to take precedence — a file will be generated in that folder with with “10-netplan-” prefixed to it, and this one just needs to come first in the list.

    Run sudo netplan apply as well as an optional reboot and the override should take effect immediately. You can can confirm it successfully overwrote defaults by running

    networkctl status end0 | grep 'Network File'

    After applying this, the device showed up in the Spectrum app immediately, with a normal IP reservation and port forwarding available like any other device.

  • Guardianship of the traitorous

    November 11, 2025

    Donald Trump and rest of the US political establishment’s warm reception of al Qaeda terrorist Abu Mohammad al-Julani aka Ahmed al-Sharaa into Washington this week is not surprising and nothing new; it is nonetheless an act of treason and national disgrace.

    Any media personalities that pretend to go after Trump but have no problem with this are de facto state media.

    Any journalist or news anchor that refer to Assad and Maduro “dictators” any time they are mentioned are doing the bidding of the Trump Administration.

    The function of mainstream media “resistance” types is, to paraphrase Noam Chomsky, to encourage very lively criticism of Trump within an extremely narrow spectrum of acceptable opinion and thereby absorb, redirect, or suppress all actual dissent.

    Republicans and Democrats both support al Qaeda head-choppers. This is not only speculation but has been a matter of established public record for over a decade.

    On the campaign trail in 2015, Trump criticized the Obama administration for arming al Qaeda and suggested we instead form an alliance with Assad and Russia to fight them. This allowed me to empathize with his supporters and grow for a time quite interested in the outcome of that election.

    What we got, however, was another Obama administration, as within months of inauguration, Trump increased sanctions on Russia, continued our support for the “moderate rebels” who helped do 9/11, and began bombing the Syrians directly.

    May God have mercy on the soul of every individual who has ever been gullible enough to vote for any of these people and contribute to this. And may God give the monsters what they deserve.

  • Open Letter to Georgetown University

    July 23, 2025

    I wholeheartedly endorse CAIR’s petition for your institution to immediately revert any and all disciplinary action against Dr. Jonathan A.C. Brown in response to the manufactured controversy around recent statements he had made. Georgetown must not allow their disciplinary processes to be hijacked by ideological pressure campaigns or online outrage mobs.

    Dr. Brown’s statement explicitly called for an end to the war and a minimization of causalities in the midst of the retaliatory strikes by a nation under attack by an outside aggressor. To claim this was in any way a call for violence against anyone requires a wilful and deliberate misreading of the facts. This will do far greater damage to the credibility of Georgetown as an academic institution than it will to Dr. Brown should this recent course of events remain uncorrected.

    https://www.cair.com/press_releases/cair-urges-georgetown-university-to-fully-reinstate-professor-jonathan-brown-after-bad-faith-attacks-over-misrepresented-tweet/

  • Linux foundation cowers to state pressure, bans Russian contributors

    October 23, 2024

    Under pressure from US federal law, all Russian contributors have been removed from the Linux maintainers file. Read the thread here

  • A very simple weather application for the terminal

    June 14, 2024

    There are many ways to check the weather on my computer but all are slightly inconvenient. I’d rather not open a browser when I don’t need to, and the very popular wttr.in includes tons of information and ASCII art that I don’t need.

    The following script can be called from the command line to pull data from pirate-weather.apiable.io, a free service fully compatible with the once popular and now defunct Dark Sky Forecast.io API.

    This script simply lists (see screenshot) the current temperature and conditions, as well as an hourly forecast with the same information over the next 24 hours.

    This was thrown together unpolished for personal use, and so for example usage of Fahrenheit is assumed. This can be easily modified as needed.

    #!/usr/bin/env bash
    #~rts/oarion7
    
    # Takes 1 optional argument N number of hours to forecast (max 48)
    
    myapikey='' # Get one from: https://pirate-weather.apiable.io/
    coordinates='40.713914010140385,-73.98905208987489' # A good place to get slapped hard in the face
    custom_number='24' # No. of hours if not specified in arg. Comment to default to API (48).
    
    if [[ -n "$1" ]] && [[ ! -z "${1##*[!0-9]*}" ]] && [[ "$1" -le 48 ]] ; then
        custom_number="$1"
    fi
    
    data="$(curl -LSs "https://api.pirateweather.net/forecast/${myapikey}/${coordinates}")"
    
    [[ -z "$data" ]] && { echo "Error fetching API data."; exit 1; }
    
    date="$(date -d "@$( jq '.currently.time' <<< "$data" )" +'%A, %d %B %Y %H:%M' )"
    
    printf "\n"
    
    printf '%s\n%s \n\nCurrently %s F and %s' \
    "Weather Report by Pirate Weather API" "$date" \
    "$(jq '.currently.apparentTemperature' <<< "$data")" \
    "$(jq '.currently.summary' <<< "$data" | sed 's/\"//g' )" 
    
    printf "\n\n"
    
    forecast="$(jq '.hourly[]' <<< "$data" | egrep -v '^\"' )"
    
    if [[ -n "$custom_number" ]] ; then
        readarray -t times < <( echo "$forecast" | jq ".[:$custom_number] | .[] | .time" )
    else
        readarray -t times < <( echo "$forecast" | jq '.[] | .time' )
    fi
    
    readarray -t summaries < <( echo "$forecast" | jq '.[] | .summary' | sed 's/\"//g' )
    
    readarray -t temps < <( echo "$forecast"  | jq '.[] | .apparentTemperature' )
    
    tabs 3
    
    for i in $(seq 0 $(( ${#times[@]} - 1 )) ) ; do 
    
        printf '%s\t\t%s\t\t%s\n' "$(date -d "@${times[$i]}" +'%H:%M')" "${temps[$i]} F" "${summaries[$i]}"
    
    done 
    
    printf "\n"

    At a glance, I know before heading out for the day if I’m properly dressed and if I need to bring an umbrella, and that’s exactly all I need.

  • Installing Linux on a 2008 Intel-based iMac

    January 6, 2024

    This weekend I decided to install Linux on an early 2008 24-inch iMac (3.06 GHz Intel Core 2 Duo).

    This machine was at some point upgraded to a 1TB HDD with 4 GB of RAM, but has been stuck on an outdated version of Mac OS X and thus for example limited to very outdated versions of Firefox. All in all, it’s functioned in recent years as little more than an elegant, oversized paperweight.

    As the terabyte of storage was mostly unused, and it may be useful at some point to access the MacOS installation, I decided to build a dual boot setup.

    I followed this guide to create the new root and swap partitions ahead of time from inside MacOS rather than in the Ubuntu/Mint installer, as well as downloading and installing rEFInd. This machine was running MacOS 10.9.5, pre-dating the introduction of System Integrity Protection (SIP) and thus there was no need to boot into Recovery mode to disable it.

    While I tinkered with Macintosh computers in my childhood during the PowerPC era and use modern Apple silicon at work, I’m less familiar with Apple’s 14-year Intel era between the two, and I’ve never installed Linux on such a machine before. I was therefore relatively surprised as to how seamless the process was.

    I opted to stick to territory as familiar as possible, and used a USB stick I had already recently used to install Linux Mint MATE Edition 21.1 Vera (based on Ubuntu 22.04 LTS). Everything worked out of the box (apart from WiFi until the automatically recommended Broadcom drivers were added) and, a bit more critically, proper fan control.

    Just don’t let it overheat

    This machine will run very hot on Linux without some mitigation, typically provided by either macfanctld or mbpfan, both available in the Ubuntu/Mint repositories, but primarily targeting MacBooks.

    I first installed mbpfan via apt, as this one is more actively maintained. However, the machine ran quite a bit warmer than I’d expect and, I’m not sure the fans were running at all despite confirming the applesmc and coretemp kernel modules were loaded.

    After some research, I removed mbpfan and opted for Anton Lundin’s fork of macfanctld, specifically modified to enable control of all 3 fans on the iMac:

    git clone --single-branch --branch fan3 https://github.com/glance-/macfanctld.git
    sudo apt build-dep macfanctld 
    cd macfanctld/
    make
    sudo make install

    I then ran sudo macfanctld -f and immediately noticed a difference. To automate this, I created a systemd service. I created shell script /opt/root-launches-macfanctld with contents:

    #!/bin/sh
    /usr/sbin/macfanctld -f

    Then I made that file executable, and created another file named /etc/systemd/system/macfanctld.service:

    [Unit]
    Description=Mac Fan Control Daemon
    Documentation=man:macfanctld(1)
    
    [Service]
    Type=idle
    ExecStart=/opt/root-launches-macfanctld
    Restart=on-failure
    RestartSec=1
    
    [Install]
    WantedBy=multi-user.target

    Finally, the service can be started and enabled, and thus launched by root at system startup moving forward:

    sudo systemctl start macfanctld
    sudo systemctl enable macfanctld

    Finally, just for fun, I installed a simple dock as well as Amiga icons and metacity themes.

    I also installed Mikhail Shchekotov’s “flying toasters” screensaver, a more faithful port the classic After Dark screen saver than that long bundled with xscreensaver.

    Addendum

    Performance has been very impressive considering the age of this machine. It’s definitely usable for browsing the web and playing music and video. I also did some writing and edited some icons in GIMP and the interface was surprinsgly snappy. Nonetheless, I’ve found one more issue.

    When using ethernet, the wired connection becomes disabled after waking from suspend. After running sudo lshw -C network, I discovered I am using the sky2 driver. A few solutions/workarounds are possible.

    In my case I added pci=nomsi,noaer to the GRUB_CMDLINE_LINUX_DEFAULT line in file /etc/default/grub and then ran update-grub. After rebooting, I confirmed this resolved the issue for me.

    Another workaround is simply to remove and re-add the module, i.e.

    sudo modprobe -r sky2 && sudo modprobe sky2

    The latter could then be toggled manually or triggered by wake events in a systemd service or udev script.

  • Search for Rumble videos in the terminal

    September 30, 2023

    Rumble has some documentation suggesting the existence of an official API, but it appears all requests for API keys have fallen on deaf mailboxes. This is working, for now:

    
    
    #!/usr/bin/env bash
    #rts/oarion7
    
    # Search for videos on rumble.com, returns url(s) for selected results; tab key to select multiple
    
    # Dependencies: xmllint, rlwrap, jq, fzf https://github.com/junegunn/fzf
    # Needs a recent enough fzf to support {n} placeholders and the become() event
    
    # Recommended: https://github.com/yt-dlp/yt-dlp/
    
    history_file="$HOME/.config/rumble_search_history"
    UA=$(<"$HOME/scripts/UserAgent/string.txt") #Spoof an updated UA string just in case.
    
    if [[ -z "$@" ]] ; then
        printf '\n%s\n' '=>> Search for Rumble videos'
        #read -p "> " readitem
        readitem=$(rlwrap -S '> ' -H "$history_file" -o cat) 
    else
        readitem="$@"
    fi
    
    query="$( printf '%s\n' "$readitem" | tr -d '\n' | tr -d '!' | tr -d "'" | jq -sRr @uri )"
    
    [[ -z "$query" ]] && exit
    
    html=$(curl -A "$UA" -Ss "https://rumble.com/search/all?q=$query")
    
    [[ -z "$html" ]] && { printf '%s\n' "Error fetching results." ; exit 1; } 
    
    list=$(for i in $(seq "$(printf '%s\n' "$html" | xmllint --html --xpath 'count((//li/article//a/div/img))' - 2>/dev/null)") 
        
        do
    
            title="$(printf '%s\n' "$html" | xmllint --html --xpath "string((//img[@class='video-item--img']) [$i]/@alt)" - 2>/dev/null )"
            url="$(printf '%s\n' "$html" | xmllint --html --xpath "string((//a[@class='video-item--a']) [$i]/@href)" - 2>/dev/null )"
            time="$(printf '%s\n' "$html" | xmllint --html --xpath "string((//time[@class='video-item--meta video-item--time']) [$i]/@datetime)" - 2>/dev/null )"
    
            printf '%s:\t %s\n' "$(printf '%s\n' "$time" | cut -c-10)" "$title" | tr -cd '.,?!`!@#$%^&*()"-=_+[]{}|:;<>a-zA-Z0-9 \n'
    
        done)
    
    [[ -z "$list" ]] && { printf '%s\n' "No results found." ; exit 1; } 
    
    _conv() { printf '%s\n' $(( "$1" + 1 )) ; }
    
    for i in $( printf '%s\n' "$list" |  fzf -m --bind 'enter:become(printf "%s\\n" {+n})') ; do 
        url_part="$(printf '%s\n' "$html" | \
            xmllint --html --xpath "string((//a[@class='video-item--a']) ["$(_conv "$i")"]/@href)" - 2>/dev/null )"
        printf 'https://rumble.com%s\n' "$url_part"
    done
    
    
    
  • Chris Hedges: Lynching the Deplorables

    March 9, 2023

    “There is little that unites me with those who occupied the Capitol building on Jan. 6. Their vision for America, Christian nationalism, white supremacy, blind support for Trump and embrace of reactionary fact-free conspiracy theories leaves a very wide chasm between their beliefs and mine. But that does not mean I support the judicial lynching against many of those who participated in the Jan. 6 events, a lynching that is mandating years in pretrial detention and prison for misdemeanors. Once rights become privileges, none of us are safe.”

    Chris Hedges: Lynching the Deplorables

  • Seymour Hersh: How America Took Out The Nord Stream Pipeline

    February 8, 2023

    The New York Times called it a “mystery,” but the United States executed a covert sea operation that was kept secret – until now.

    https://seymourhersh.substack.com/p/how-america-took-out-the-nord-stream

  • Notice

    October 2, 2022

    I have archived my pier and incorporated an affected opposition to Urbit as a core component of my self-marketing strategy for the remaining quarter of 2022.

1 2 3
Next Page→

Copyright © 1989-2031 Ryan Thomas. Verbatim copying and redistribution of this page in part or entirety is permitted provided this notice is preserved. Buy me a coffee