• Reducing Raspberry Pi power consumption

    I’m currently working a project that will put my Raspberry Pi 3 B to work as an embedded system running primarily on battery power. Naturally one of my goals became to reduce the power consumption of the Raspberry Pi as much as possible to make the most of battery life. I saw tips for disabling the activity LEDs, switching off HDMI, and a few other things, but none seemed to move the needle at all on power consumption. It still used about 140 mA (0.7 W) at idle.

    Then I checked if you could disable the USB hub since I don’t need it. After disabling the USB hub the power consumption dropped to 20 mA (0.1 W). That’s a huge power savings.

    One caveat with this approach is that it also disables the Ethernet controller. So if you need wired LAN, don’t do this.

    The quick way to disable the USB hub:

    echo '1-1' | sudo tee /sys/bus/usb/drivers/usb/unbind
    

    This won’t persist across reboots, so I wrote a script to do it for me and set it to run on startup via /etc/rc.local. In case I need to do some manual fixes on the device with a keyboard and/or Ethernet, I have the script check if any USB devices are plugged-in or if the Ethernet cable is connected. Only if nothing is connected will it disable the USB hub. So if I need a keyboard, I just plug it in and power cycle the Pi!

    #!/bin/bash
    
    # With no devices plugged-in, there will only be "devices" at "1" and "1.1"
    # If any devices beyond that are detected, such as 1.2, don't disable USB.
    cat /sys/bus/usb/devices/**/devpath | grep -Eq '^[1-9]+\.[2-9]'
    
    if [ $? -eq 0 ]; then
      echo "USB devices attached. Aborting."
      exit 1
    fi
    
    # Disabling the USB controller also disables Ethernet, so don't do that
    # if there's an Ethernet cable plugged-in.
    if [ `cat /sys/class/net/eth0/carrier` != "0" ]; then
      echo "Ethernet cable is plugged-in. Aborting."
      exit 2
    fi
    
    echo "Disabling USB interface"
    echo '1-1' > /sys/bus/usb/drivers/usb/unbind
    
  • git: using the --fixup flag for commits

    I like to keep my git commit history clean and concise. If each commit is a clean package of atomic changes, a larger pull request is easier to review commit by commit. Conversely, if you have a history littered with fixes and changes, reviewing each commit doesn’t work.

    git rebase -i is a great way to re-order commits, drop commits, or merge commits together with squash or fixup. The only difference is that fixup discards the commit message whereas squash appends it.

    Consider a workflow where you’ve added a feature to your app and commit this change.

    git add app/
    git commit -m "Add feature"
    

    Now let’s say you notice you forgot your new test files to this commit so you add them. At this point you can easily do a git commit --amend --no-edit which will amend the previous commit and use the original commit message. Easy!

    But what happens if you’ve made a commit since then that has nothing to do with this feature? You could just make a separate commit:

    git add test/
    git commit -m "oops, forgot the test files for the new feature"
    

    A better way is to use the --fixup flag.

    First, use git log to get the hash of the commit you want to amend. Then commit your amendment like so:

    git add test/
    git commit --fixup=hash_of_commit_to_amend
    

    This creates a normal commit with a special message. In this case it would be !fixup Add feature. Now, run git rebase -i --autosquash and you’ll see the magic.

    pick f0f6a56 Add feature
    fixup 7897d4d fixup! Add feature
    pick 03b9a80 Fix unrelated bug
    

    Git recognises the !fixup commit and places it after the commit to amend and automatically sets it as a fixup. Now when you quit the editor, history will be re-written.

    By default when you use git rebase -i --autosquash it only shows commits that have happened since your last push. So if you use --fixup on a commit already pushed to the remote, it won’t do anything. You can work around this by rebasing farther into the past, but that will then require a force push and all the usual caveats there. If your branch history needs that much re-working, you might just want to create a new one.

  • Back to Linux

    This past summer I treated myself to building a new PC. I hadn’t built a PC in over ten years ever since I got a MacBook Pro that could do everything I needed for both work and personal use. I’ll skip the part where I fall out of love with MacBooks and sell my 2017 MacBook Pro.

    After watching so many YouTube videos about PC builds, and wanting to do some PC gaming, I had to build one. So I built a modest system, trying not to go beyond the point of diminishing returns for components. For example, the i7-8700K is twice the price as an i5-8400. Is it twice as good for what I’ll be doing? Highly doubt it.

    I installed Windows 10 and Windows Subsystem for Linux. I have to say, Microsoft did a truly impressive job there making that work. It worked really well. The problem is I just didn’t enjoy using Windows, it was sluggish at times, and I was spending all my time in WSL anyway. So I wiped it all out and installed Arch Linux.

    I hadn’t used Linux on the desktop since Gentoo back on my Dell Latitude D400. That was back circa 2005. Gentoo was a great distro for get started with Linux since you had no choice but to learn how the whole system is put together. So if something goes wrong, you know how to help yourself through it and you learn a lot along the way. The other factor I valued is that your system would only have software you asked for and nothing else. I don’t like bloat, so Gentoo was perfect. But for a new install I wasn’t interested in Gentoo, as compiling everything from source is just a waste of time. Arch looked like the worthy successor. It’s a roll-your-own OS like Gentoo with rolling releases and an enthusiastic community; the value of which should never be underestimated.

    After having Arch Linux setup for some weeks, I’ve compiled a list of packages that I had installed and why. So next time I setup Arch I’ll have a good list of packages for my base system. I’ve left off the stuff that’s quite obvious for me to install straight away like a web browser, editor (Sublime Text), and things like that. I’ll probably update this as I make changes.

    Read on →

  • Triple-booting Windows 98, NT 4, and 2000

    With my Dell Dimension XPS T450 ready hardware-wise, I needed to get some operating systems installed. My ideal setup is triple-booting Windows 98, NT Workstation 4, and 2000 Professional. This isn’t as straight forward as you’d imagine and it took me more than one total reformat to get it working. This is a tale of many, many failures finally leading to some success.

    Read on →

  • Keeping track of Magic Trackpad 2 battery life

    Fetching the Magic Trackpad 2 battery level from the command line and logging it to a file!

    Read on →

  • Power strip mod for US plugs in Europe

    When I moved to Germany, I brought a bunch of electronics with me that I had acquired in Japan, Thailand, and the US. Fortunately they all had switching power supplies, so the voltage and frequency difference (110v @ 60 Hz vs 220v @ 50 Hz) wasn’t an issue. The issue was the plugs themselves, so a solution was required.

    Read on →

  • Dream PC: Dell Dimension XPS T450 - 1999 Glory (Part 1)

    Recently I’ve been having a lot of 90s nostalgia, especially related to technology. I fully blame YouTube channels like LGR, 8-Bit Guy, Phil’s Computer Lab, Adrian Black, and a dozen others I’ve spent countless hours watching. Plus it’s part of getting older; you romanticise the past.

    I started thinking about what hardware from the past I felt the most affinity towards. It took me no time at all: I wanted a Dell Dimension XPS from the 90s. This is my history with Dell.

    Read on →

  • Active Directory, DNS, and a Ubiquiti EdgeRouter

    You’ve got a Ubiquiti EdgeRouter and an Active Directory domain. Here’s how you make them play nicely together.

    Read on →

  • Policy-based routing over VPN with Ubiquiti EdgeRouter

    Let’s route specific LAN devices over persistent VPN connections!

    Read on →

  • Reverting to Readline 6.3.8 to unbreak the Rails console

    When running a brew upgrade, it upgraded readline to version 7.0. This broke the Rails console. Here’s how that looked:

    $ bundle exec rails c
    Running via Spring preloader in process 69075
    /Users/mroach/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/activesupport-5.0.0.1/lib/active_support/dependencies.rb:293:in `require':
      dlopen(/Users/mroach/.rbenv/versions/2.3.1/lib/ruby/2.3.0/x86_64-darwin15/readline.bundle, 9):
      Library not loaded: /usr/local/opt/readline/lib/libreadline.6.dylib (LoadError)
    

    Here’s how I reverted to readline 6.3.8 to fix this:

    # Uninstall this incompatible version
    brew uninstall readline
    
    # Go to the local clone of homebrew-core
    cd $(brew --prefix)/Homebrew/Library/Taps/homebrew/homebrew-core
    
    # Move to the homebrew-core revision that had 6.3.8
    git checkout 35fed817726f61a9d40c8420582f6fde59eb5f14
    
    # Re-install readline
    brew reinstall readline
    
    # Switch back to HEAD
    git checkout master
    
    # Pin readline so this can't happen again
    brew pin readline