Press "Enter" to skip to content

nuxx.net Posts

All-City Electric Queen: Rugged XC / Trail Hard Trail Bike

Nearly four years after getting a full suspension XC / trail bike (2016 Specialized Camber) and beginning to really enjoy riding with a bit more travel and a dropper post I started getting the itch to build a similarly spec’d hard tail. Picking up a few particularly good deals (frame/fork), shopping smartly, using some parts I’d collected over the years, and getting some parts from friends, I ended up putting together an All-City Electric Queen.

This steel frame from a QBP brand best known for urban bikes, fitted with a smart choice drivetrain (SRAM GX), higher end wheels (I9 Hydra hubs) and suspension (Fox 34), and reliable brakes (Shimano SLX) is the solid spec build that I was wanting. The frame came complete with a matching rigid fork, and I anticipate switching over to the rigid fork in springtime or when the Fox 34 is out for service.

After the first shakedown ride at Stony Creek I’m pretty happy with the bike. The geometry of the frame itself is a little curious, but it seems to fit me well. Specifically, it has a fairly slack seat tube, tall head tube, tall seat tube, and rather high top tube. This means I have minimal stand-over (akin to the Titus Racer X 29er) and the saddle has to sit quite-forward on the rails, but it seems to work and feels good when pedaling. It also results in the controls (dropper lever and shifter) hitting the top tube when turning the bars, so I’ve had to pad the top tube with some 3M mastic tape.

I suspect this frame would work well for the sort of long-leg/short-torso rider who often finds themselves on a custom frame, but it also works well for me. It also means that a slim top tube bag like the Relevate Designs Tangle would fit along with bottles. Or, it could have been placed almost 1.5″ lower (with a shorter head tube and seat tube) and still been good… But I’m not a frame designer, so I suspect there’s some good but unknown-to-me reason why this was done.

Coming in at 28 pounds it’s not a light bike, but being a cheaper steel frame, 120mm fork with 34mm stanchions, 2.4″ wide quite-knobby tires, dropper post, and aluminum rims I’m okay with it. Going to some carbon bits (eg: bar) I could drop some weight, but I don’t think it’ll matter much, as this is roughly the same weight as the Camber, which I love riding.

Part details are below, and photos of the build showing everything from parts to checking clearances, can be found here: All-City Electric Queen.

Frame: All-City Electric Queen (Large, Lavender/Lime w/ Splatter)
Fork: Fox 34 Step-Cast (Factory, FIT4 damper, Black Upper Tube Finish, 120mm, 51mm offset, 15QR)
Headset: Cane Creek SlamSet (Black, ZS44/EC44/40)
Crankset: SRAM X1 1400 GXP
Bottom Bracket: SRAM GXP (Black)
Chainring: SRAM X-SYNC 2 (32t, steel, Direct Mount, 3mm / Boost)
Derailleur: SRAM GX Eagle
Shifter: SRAM GX Eagle
Shift Cables / Housing: Shimano Bulk
Cassette: SRAM XG-1275
Brakes: Shimano SLX M7100 (Levers: BL-M7100, Calipers: BR-7100)
Front Rotor: SM-RT86-L (203mm)
Rear Rotor: SM-RT86-M (180mm)
Front Brake Adapter: SM-MA-F203P/P (160mm Post to 203mm Post)
Rear Brake Adapter: Shimano SM-MA-R180P/S (IS to 180mm Post)
Stem: Specialized Stout XC, (+6°, 75mm)
Bar: Salsa Salt Flat (750mm)
Wheels: Industry Nine Trail S Hydra 28H (29″)†
Tires: Maxxis Rekon (29 x 2.4″, 3C/EXO/TR)
Seatpost: Fox Transfer Performance Elite (2020, Black, 125mm, 30.9mm, Internal)
Dropper Lever: Wolf Tooth ReMote Light Action (Black, 22.2mm Clamp)
Seatpost Collar: Salsa Lip-Lock (Black, 33.3mm)
Saddle: Specialized Power Expert (143mm)
Pedals: Crank Brothers Eggbeater 3 (Blue, from El Mariachi Ti)
Grips: ESI Extra Chunky (Black)
Bottle Cages: Specialized Zee Cage II (Black Gloss, 1x Left, 1x Right)
Computer: Garmin Edge 530, Garmin Speed and Cadence Sensors (v1)
Bell: Mirracycle Original Incredibell (Black)
Derailleur Hanger: QBP 687
Frame Protection Tape: 3M 2228, McMaster-Carr UHMW PE

Rigid Fork: All-City Electric Queen (Large, Lavender/Lime w/ Splatter)
Crown Race: Cane Creek BAA0009S (40-Series 52/30mm Steel)
Front Brake Adapter: Shimano SM-MA-F203P/S (IS to 203mm Post)

† Per I9, these are built with Sapim Race Straight-Pull spokes, 303mm all around. (For 29er. If these were 27.5 wheels they’d be 285mm.)

Comments closed

High Resolution Strava Global Heatmap in JOSM

Mapping trails in OpenStreetMap (OSM), using JOSM, is done by overlaying one or more data sources, then hand-drawing the trail locations using this background data as a guide. While not a default in JOSM, with a little know-how and a paid Strava Subscription the Strava Global Heatmap data for this can be used as well.

While there’s a fair bit of info about doing this scattered across some JOSM tickets (eg: #16100), this post is to document how I make this work for me by creating a custom Imagery provider. Because there isn’t an official (and robust) plugin to authenticate JOSM against Strava it’s a little tricky, but overall isn’t bad.

First, you need to sign into Strava, then go to the Global Heatmap and get the values of the three cookies CloudFront-Key-Pair-ID, CloudFront-Policy, and CloudFront-Signature. These values are essentially saved credentials, and by using them in a custom Imagery provider URL, JOSM will use these to access the Global Heatmap data via your account and make it available as an Imagery layer.

The easiest way to get these cookie values is to use the Developer Tools built into your web browser:

  1. Launch your web browser, either Firefox, Chrome, or Edge.
  2. Go to the Strava Global Heatmap, sign in if needed (check the Remember me checkbox), and be sure it’s properly displaying high resolution data.
  3. Load the developer tools for your browser to show cookie details:
    • Firefox: Click the Hamburger MenuWeb DeveloperStorage Inspector (or press Shift-F9), expand Cookies and click https://www.strava.com.
    • Chrome: Click the Three Dots Menu → More tools → Developer tools (or press Ctrl-Shift-I), select the Application tab, expand Cookies, then click https://www.strava.com.
    • Edge: Click the Three Dots Menu → More tools → Developer Tools (or press F12), select the Storage tab, expand Cookies, then click heatmap.
  4. Get the value of three cookies, CloudFront-Key-Pair-ID, CloudFront-Policy, and CloudFront-Signature, and make note of them (in Notepad or such). You’ll need them to build the custom URL. Here’s examples of what the three cookies will look like:
    • CloudFront-Key-Pair-ID: VB4DYFIQ7PHQZMAGVMOI
    • CloudFront-Policy: FTUGYikErADOqGmqEnPTaaZ3LCE2QbOJSSsmPD9vdY0hfjSWWHZBgnRai1aQcvUe
      2YtgkG3KdP8IencRaGrS3I5bHAeabQ4I776T7UipDPFzNVh9PBIRvb3DjDqVfssp
      mBA5IrxacQGfB2YmKwegp9OTBfUFkvtEQOlzeXfqeuc34cp408GYXSvp2DsnxKFh
      ofbwygraae3VZqnZxp3vBpz3lBoyPnBEN1djJkxpU1fF_
    • CloudFront-Signature: lrMJG0L6zJilpSdGEnWug0zskcMDD5VVGdSRu~P4OOVp5z8iCMBRBO040wxunEQQ
      p0wVHdaCaTFAVqiM0jC0AApW7HigXjx57nsoEVslOzRuoX9S3g-
      FCePWYNPyZcJ95~6SoGdNRHz-
      b-ZZxk4ERhjzXCNIEE8Gt5uImitcPN3HRlhXexS39g30~5OEv~4FHzXfOOIhQ5X5
      cGUD0SpdYviBE~vkAJCk3TbQMXxlJbyX4OOL5xvVPv5WjzMKTuvEk6Z9m6iFBbZc
      8ov4qS60th0tZ1RM4pNMoIWKoqPS3~UPGISe6Xa8Kq-
      tQPxHlfGciI5uhoTp4b7lPussh52QaN__

(Note: These are not real values, you’ll need to look up your own.)

Next is to add a custom imagery provider for the Strava Global Heatmap to JOSM using a URL that you build with these cookie values:

  1. EditPreferences… (F9)Imagery preferences
  2. Create a new TMS string by replacing the [] sections in the following string with the cookie values from above, without the []s:
    • tms[15]:https://heatmap-external-{switch:a,b,c}.strava.com/tiles-auth/all/hot/{zoom}/{x}/{y}.png?Key-Pair-Id=[CloudFront-Key-Pair-ID]&Policy=[CloudFront-Policy]&Signature=[CloudFront-Signature]
  3. Add a new TMS entry by clicking the +TMS button.
  4. Paste the string from Step 2 into Box 4, Edit generated TMS URL (optional), and then give it a name in Box 5, such as Strava Global Heatmap High-Res.
  5. Click OK twice to return to the main JOSM window, and then try to use this layer over some existing data, just as you would aerial imagery.

If it doesn’t work, double-check your URL and be sure the entered cookie values are right, including the underscores after CloudFront-Policy and CloudFront-Signature. Also be sure you haven’t logged out of Strava, as this will expire the cookies. (If you make changes to the URL in JOSM you will need to delete the existing imagery layer and then re-add it to have the new URL used.)

These cookie values, in particular CloudFront-Signature, will occasionally change as cookies are expired and reset or if you log out of Strava. If things were working and then stopped, you may need to get new cookie values from your browser and update the TMS strings.

By default the TMS URL we started with shows the default heatmap, for all activity types, with Hot coloring. Depending on what other data you are working with it may be useful to show just Ride or Run data, perhaps in different colors. In the TMS URL, the first part after tiles-auth is the type of data, and the second is the color. By using this format, replacing [data] and [color], you can create additional heatmap layers:

tms[15]:https://heatmap-external-{switch:a,b,c}.strava.com/tiles-auth/[data]/[color]/{zoom}/{x}/{y}.png?Key-Pair-Id=[CloudFront-Key-Pair-ID]&Policy=[CloudFront-Policy]&Signature=[CloudFront-Signature]

Valid values for type of data: all, ride, run, water, winter.

Valid values for heatmap color: hot, blue, purple, gray, bluered.

Creating multiple layers, riding-only and running-only, of different colors was extremely useful when mapping Avalanche Preserve Recreation Area in Boyne City as cyclists tend to stick to the mountain bike trails and runners to the hiking trails. While I had orthorectified maps from both the city and TOMMBA, the separate riding and running heatmaps made the routes much clearer. In the example image above (link) I have the Ride data as color Hot and the Run data as color Blue; perfect for illustrating the mountain bike vs. hiking trails.

If you’d like to see this area as an example load the are around changeset 85690641 or a bounding box with the following values and see for yourself:

  • Max Lat: 45.2077126
  • Min Lat: 45.1878747
  • Min Lon: -85.0339222
  • Max Lon: -84.9832392
Comments closed

BorgBackup Repository on Synology DSM 6.2.2

(UPDATE: With the release of Synology DSM 7.0 this setup will break. It’s easy to fix and I’ve updated added this post describing how to make this system work under the new version.)

Lately I’ve become enamored with BorgBackup (Borg) for backups of remote *NIX servers, so after acquiring a Synology DS1019+ for home I wanted to make it the destination repository for Borg-based backups of nuxx.net. While setting up Borg is usually quite straightforward (a package or stand-alone binary), it’s not so cut and dry on the Synology DiskStation Manager (DSM); the OS which runs on the DS1019+ and most other Synology NAS’.

What follows here are the steps I used to make and the reason for each step. In the end it was fairly simple, but a few of the steps are obtuse and only relevant to DSM.

These steps were written for DSM 6.2.2; I have not checked to see if it applies to other versions. Also, I leave out all details of setting up public key authentication for SSH as this is thoroughly documented elsewhere.

  1. Enable “User Home Service” via Control PanelUserAdvancedUser HomeEnable user home service: This creates a home directory for each user on the machine and thus a place to store .ssh/authorized_keys for the backup user account.
  2. Create a backup user account and make it part of the administrators group: Accounts must be part of administrators in order to log in via SSH. Starting with DSM 6.2.2 non-admin users do not have SSH access.
  3. Change the permissions on the backup user’s home directory to 755: By default users’ home directories have an ACL applied which has too broad of permissions and SSH will refuse to use the key, instead prompting for a password. Home directories are located under /var/services/homes and this can be set via chmod 755 /var/services/homes/backupuser. (See this thread for details.)
  4. Put ~/.ssh/authorized_keys, containing the remote user’s public key, in place under the backup user’s home directory and ensure that the file is set to 700: If permissions are too open, sshd will refuse to use the key.
  5. Test that you can log in remotely with ssh and public key authentication.
  6. Place the borg-linux64 binary (named borg) in the user’s home directory and confirm that it’s executable: Binaries available here.
  7. Create a directory on the NAS to be used the backup destination and give the backup user read and write permissions.
  8. Modify the backup user’s ~/.ssh/authorized_keys to prevent remote interactive logins and restrict how borg is run: This is optional, but a good idea.

    In this example only the borg serve command (the borg repository server) can be run remotely, is restricted to 120GB of disk, in a repository on DSM under the backup directory of /volume2/Backups/borg, and from remote IP of 192.168.0.23:

    command="/var/services/homes/backupuser/borg serve --storage-quota 120G --restrict-to-repository /volume2/Backups/borg",restrict,from="192.168.0.23" ssh-rsa AAAA[...restofkeygoeshere...] remoteuser@remoteserver.example.com

Please note, there are a number of articles about enabling public key authentication for SSH on DSM which mention uncommenting and setting PubkeyAuthentication yes and AuthorizedKeysFile .ssh/authorized_keys in /etc/ssh/sshd_config and restarting sshd. I did not need to do this. The settings, as commented out, are the defaults and thus already set that way (see sshd_config(5) for details).

At this point DSM should allow a remote user, authenticating with a public key and restricted to a particular source IP address, to use the Synology NAS as a BorgBackup repository. For more information about automating backups check out this article about how I use borg for backing up nuxx.net, including a wrapper script that can be run automatically via cron.

Comments closed

Using borg for backing up nuxx.net

For 10+ years I’ve been backing up the server hosting this website using a combination of rsync and some homegrown scripts to rotate out old backups. This was covered in Time Machine for… FreeBSD? and while it works well and has saved me on some occasions it had downsides.

Notably, the use of rsync’s --link-dest requires a destination filesystem that supports shared inodes, limiting me to Linux/BSD/macOS for backup storage. Also, while the rotation was decent, it wasn’t particularly robust nor fast. Because of how I used rsync to maintain ownership with --numeric-ids it also required more control on the destination than I preferred. And, the backups couldn’t easily be moved between destinations.

In the years since, a few backup packages have come out for doing similar remote backups over ssh, and this weekend I settled on BorgBackup (borg) automated with borgbackup.sh.

Borg and a single wrapper script (that I based on dailybackup.sh) executed from cron simplifies all of this; handling compression, encryption, deduplication, nightly backups, ssh tunneling, and pruning of old backups. More importantly, it removes the dependence on shared inodes for deduplication, eliminating the Linux/BSD/macOS destination requirement. This means my destination could be anything from a Windows box running OpenSSH to a NAS to rsync.net.

Here’s a brief overview of how I have it set up:

  1. Install BorgBackup on both the source and destination (currently Linux nuxx.net server and a Mac at home).
  2. Put a copy of borgbackup.sh on the source, make it executable, and restrict it just to your backup user. Edit the variables near the top as needed for your install, and the paths to back up in the create section.
  3. Create an account on the destination which accepts remote SSH connections via key auth from the backup user on the source.
  4. Restrict the remote ssh connection to running only the borg serve command, to a particular repository, and give it a storage quota:
    restrict,command="borg serve --restrict-to-repository /Volumes/Rusty/borg/servername.nuxx.net” from=“10.0.0.10” ssh-rsa AAAAB3[…snipped…] root@servername.nuxx.net
  5. On the remote server, turn off history (to keep the passphrase from ending up in your history; in bash: set +o history), set the BORG_REPO, BORG_PASSPHRASE, BORG_REMOTE_PATH, and BORG_RSH variables from the top of the script to test what the script defines:
    export BORG_REPO='ssh://user@server.example.com:220/path/to/repo/location/'
    export BORG_PASSPHRASE='PASSPHRASEGOESHERE'
    export BORG_REMOTE_PATH=/usr/local/bin/borg
    export BORG_RSH='ssh -oBatchMode=yes'
  6. From the source, initialize the repo on the destination (this uses the environment variables): borg init --encryption=repokey-blake2
  7. Perform the first backup as a test, backing up just a smallish test directory, such as /var/log: borg create --stats --list ::{hostname}-{now:%Y-%m-%dT%H:%M:%S} /var/log
  8. Remotely list the backups in the repo: borg list
  9. Remotely list the files in the backup: borg list ::backupname
  10. Test restoring a file: borg extract ::backupname var/log/syslog
  11. Back up the encryption key for the repo, just in case: borg key export ssh://user@server.example.com:220/path/to/repo/location/
  12. Define things to exclude in /etc/borg_exclude on the source per the patterns. In my I use shell-style patterns to exclude some cache directories:
    sh:**/cache/*
    sh:**/locks/*
    sh:**/tmp/*
  13. Create the log directory, in the example as /var/log/borg.
  14. Run the backup script. Tail the log file to watch it run, see that it creates a new archive, prunes old backups as needed, etc.
  15. Once this all works, put it in crontab to run every night.
  16. Enjoy your new simpler backups! And read the excellent Borg Documentation on each command to see just how easy restores can be.
Comments closed

Using OsmAnd Offline Maps during Remote Rides

Many of the popular, long cycling events — or even just solo rides — require a GPS so that one can follow a route in order to navigate. While most of us have bike computers that will show the route, most folks don’t have a GPS with the kind of detailed base maps that become useful for detours, emergencies, or just as an additional tool… Much less something that works when outside of cellular coverage areas.

For this, I recommend you look at offline maps using OsmAnd.

I have (and love) the Garmin Edge 130 as it’s perfect for my riding and training. It’s been great for displaying recording data and following routes from the unmarked 100 mile versions of The Crusher and Barry-Roubaix, to augmenting signage in Marji Gesick and following a route through remote parts of Batchawana River Provincial Park. But occasionally I need a bit more; something to help find a detour around a flooded road, a quick way back to the car in a rainstorm, or just a sanity-check of which branch to take at a fork on the road.

Sure, I could buy a super-high-end bike computer that features detailed base maps, but I rarely need these and don’t want the physically large computer on my bike. So I use my phone, running OsmAnd, loaded with offline maps that display without requiring a data connection. Coupled with putting one’s phone in Airplane mode (turns off the cellular and WiFi radios and saves battery — yet GPS still works) a modern phone will typically get days of battery life while sleeping, with maps and a route quick to access.

Whenever I actually need to see this map I simply pull it out of my pocket or bag, wake it up, get what I need from the map, and carry on. No screwing around with a small touch screen and funky zooming on a Garmin or Wahoo. (I believe that, to date, neither Garmin nor Wahoo have made map perusal as straightforward as it is on a basic mobile phone.)

This is also a great way to get maps on your phone when traveling somewhere costly for cellular data, like during a day-trip to Canada.

Whether you’re doing Marji Gesick or The Crusher or just following a route found on a cycling club’s website, I recommend augmenting your navigation with offline maps in OsmAnd by doing the following:

  1. Visit the OsmAnd site and follow the links to your phone’s store to install the software.
  2. Get a copy of the GPX file on your phone; for Android phones this is often as simple as visiting the download website and downloading the file.
  3. In OsmAnd‘s menu, pick Download Maps and download maps for the regions you want. I personally have Standard Maps, Contour Lines, and Hillshades for Michigan installed all the time, and then if traveling will install for other states/provinces/countries.
  4. Once the offline maps are installed, pick Configure map from the menu, then Map source, and ensure Offline vector maps are selected. The default, OsmAnd (online tiles), is an online map source that requires data.
  5. To display a particular route, pick GPX files…, Add More…, and then browse your phone to add the downloaded GPX file. Ensure this file is enabled (checked), and then go back to the map screen.
  6. You’ll now see the route overlaid on offline maps, easy to zoom in and out of and find your way around. Try turning on Airplane Mode and see that it all still works.

Once I have everything set up, here’s some tips about how I actually use OsmAnd while out on my bike:

  • If in an area with minimal or no cellular service, put the phone in airplane mode so the battery doesn’t get used up while it searches for a signal.
  • Turn off all lock features on my phone (fingerprint / pattern / PIN unlock), so I can wake it up with just a press of the power button.
  • You can use this at the same time as Strava, and Strava generally works in Airplane mode as well.
  • If I’m at a spot where I’m not quite sure which way to turn (based on the single line on my Edge 130), use the map to figure out which branch to turn on. Even the remotest of fire roads and two track are often mapped.
  • If I think I might have missed a route sign (say, in Marji Gesick) I’ll use OsmAnd to see if I’m still on route, and to get back if needed.
  • Look for other nearby roads or trails if I need to detour or shortcut back. I had to do this yesterday during the Founders Fall Fondo as part of the 62 mile Barry-Roubaix route was flooded.
  • Many small, old, sometimes abandoned, yet somewhat navigable roads are still listed in the OpenStreetMap (OSM) data that OsmAnd uses. While these aren’t great for cars and won’t show up on things like Google or Apple Maps, they are often quite useful when on a bike. Look to these for exploring / finding new routes.
  • Many trails open to mountain bikes are included in the OSM data. This includes all CRAMBA trails and most trails in the NTN and RAMBA areas. (Note: Trailforks is a better source for discovering MTB trails themselves.)
  • Periodically update maps to get new OSM data. As roads and trails change, maps get updated.
  • Pay For OsmAnd+ Live ($5.99/year) to get access to more-frequent, automatic map updates and support the open mapping community. 

While this is just a basic overview of using OsmAnd and how I use it when cycling; it does a whole lot more including recording routes, navigation, editing map data, sharing location between contacts, and more. Give the online Help and Features a look for more information.

 

Comments closed

Torklift EcoHitch 2″ Hitch for my 2015 Outback

IMG_0249.jpg

Back in 2015 when I purchased a Subaru Outback, I ordered it with a OE hitch. At the time it was the best (and thanks to IMBA discount the cheapest) option for mounting a bike rack on the back of the car. Due to load limits on what the vehicle can tow there was only a 1-1/4″ receiver available, and while this fit the 1Up USA rack previously used on my Civic it just didn’t provide the stability of a 2″ receiver.

Fast forward to late 2018 and, out of the blue, I was contacted by Torklift, via Reddit, where they offered to send me their Torklift EcoHitch 2″ receiver hitch in exchange for providing feedback to their designers and engineers. After some email back and forth this was all set up, and a few days ago I received the rack: Torklift 2015-2018 Subaru Outback EcoHitch, part number x7266.

Beyond the 2″ receiver, the biggest difference between the EcoHitch and OE hitches is how they mount. While the EcoHitch sandwiches between the bumper beam and the chassis, held in place by the bumper’s eight fasteners (photo 1, 2), the OE hitch both replaces the bumper beam and mounts inside of the frame rails (photo). While it appears that the OE hitch may be a bit more resistant to very high tongue weights, the Torklift seems plenty solid and is made of thicker material, so I’ve got no concerns with the differences. The other significant difference is that the Torklift EcoHitch doesn’t come with a wiring harness, but only ever having bike racks on my car this doesn’t really affect my usage. When the OE hitch was installed on my Outback this included a wiring harness along with a nifty mount to hold it next to the receiver (photo). I considered adapting this mount to the EcoHitch, but instead took some inspiration from Torklift Central’s (frankly overpriced) Eclipse 4-Flat Plug and fit a neodymium magnet to the cable (photo), then stuck the magnet to the back side of the receiver.

Needing to remove the OE hitch my install was bound to be a bit more complicated than someone who is putting the EcoHitch on a new vehicle, but even this ended up being pretty straightforward.

Whole rack, rear view, with installation instructions and parts bundled to the center.

Whole rack, rear view, with installation instructions and parts bundled to the center.

Unboxing the rack revealed a well-packed (photo), nicely powder coated (photo), solid rack that ships with an instruction manual, the eight nuts (for attaching it to the bumper mount bolts), and a piece of rubber trim gasket to cover the cut edges on the underside of the bumper cover (photo).

Besides the printed instructions (which I wish Torklift posted as a PDF on their website), there are two instructional videos (1, 2) which show the installation on everything from 2015 to 2018 models of the vehicle. These do a good job of showing the basics of the installation, but they gloss over what I think is the most difficult part; removing the bumper cover:

  1. Removing the bumper cover itself works best if you push up on the sides from the bottom, then pull out the at top. Going off of just Torklift’s instruction I first thought to pull straight outward, but this wasn’t working well and — per Subaru — can risk breaking retention clips. Thankfully I have access to Subaru’s service manual which described pushing up from the bottom, and with this technique the cover came off easily.
  2. My vehicle has splash guards installed, which had to be removed before all the bumper clips could be accessed. These guards came off via six screws and four push-lock plastic clips, but I had to use a right-angle screwdriver to fit around the tires. (There is a note in the Torklift instructions mentioning these may need to be removed.)
  3. Three out of the myriad push lock clips used to hold the bumper and splash guards on broke during removal. This is likely due to my Outback being nearly four years old. Thankfully replacements are readily available online and at dealerships and can easily be identified via Subaru Parts Online.

For this installation Torklift instructs that the hitch be fitted, then the bumper beam reinstalled. However, during the install of the OE hitch, the bumper beam and foam energy absorber is removed and discarded. Since my Outback came with the OE hitch installed, I didn’t have these pieces. After consulting with both Torklift and some auto engineer friends we concluded that the Torklift hitch will be fine without the bumper beam.

Despite this, I contacted my local dealer (Sellers Subaru) and to my surprise they gave me discarded/scrap bumper beam from an Outback where they’d recently installed a hitch. It’s maroon, but being hidden the color doesn’t matter. With the purchase of a replacement foam energy absorber ($79.95 MSRP) I was all set part-wise to remove the OE hitch and install the EcoHitch to spec. While this likely wasn’t needed, it makes me feel better about the overall install. (Photos 1, 2)

Removing the OE hitch was a bit of a hassle, as getting to two of the hitch bolts required removing the muffler and heat shield. (Another plus for the EcoHitch.) Thankfully none of the bolts were seized and removal this went smoothly. Before long I also had the OE rack completely removed, exhaust re-fitted, and it was time to install the EcoHitch.

Foam cushion over the bumper beam, and hitch installed.

Foam cushion over the bumper beam, and hitch installed.

At this point — just after bumper cover removal on a normal install — installation is very straightforward: folding a thin metal bumper cover mounting tab up against the body, bolting the hitch and bumper back on, torquing some nuts, and cutting a notch out of the bumper cover. After this it’s just a matter of putting the the bumper cover, tail lights, splash guards, and some plastic covers back in place.

From the OE hitch I already had a notch cut in my bumper cover, but it was pretty easy to cut the wider notch required by the EcoHitch. The OE hitch uses a longer notch than the EcoHitch, and thankfully Torklift provides enough trim to cover the extra-large notch present after a bumper’s been cut for both (photo). The cutting itself went easily, as the plastic is pretty soft and can either be scored and folded or cut with anything from a rotary cutter to a jigsaw.

During installation one of the bumper cover mounting tabs is folded out of the way and the mounting hole cut out of the bumper cover during the notching, which eliminates one of the points where the bumper mounts to the chassis. While initially concerning, this part of the cover rests on the top of the receiver after everything’s put back together, so this lack of retention point isn’t a problem.

With everything put back together I’m currently quite happy. The TorkLift EcoHitch looks good and sits nice and close to the underside of the bumper; I don’t think it could go much higher. While the OE hitch had 14.5″ of ground clearance, this drops to 13.5″ with the EcoHitch, an acceptable change for adding 0.75″ to the receiver’s height. This hitch is a great choice for either new installs on an Outback or retrofitting an OE hitch to a 2″ receiver.

I particularly like how the powder coating has a thick, textured look to it, and the end of the receiver has a nice TORKLIFT logo. The whole unit looks like it’ll hold up nicely to Michigan winters (and road salt). Now to wait for a new, matching black 1UP USA 2″ Super Duty Single rack to arrive!

Click here or on the large photo above to see a complete album of photos from the install.

Leave a Comment

Pi-hole and NBC Sports Gold

I use Pi-hole to block some ads on my home network, but I also pay for a NBC Sports Gold Cycling Pass to easily watch cycling events. Unfortunately, the default block list for Pi-hole will keep NBC Sports Gold from working, breaking it in a somewhat odd way: pages load, but the list of events doesn’t display.

So, how do you make it work? Easy! Whitelist these three sites:

  • experience.tinypass.com
  • geo.nbcsports.com
  • nbc.demdex.net
Leave a Comment

New Gravel Bike Day: 2019 Salsa Warbird Carbon 105 700

It feels like only yesterday, but five years ago I got my hands on a Salsa Vaya 2 which had an unexpected, but significant, impact on how I ride bikes. Prior to this (and despite brief flirtations with a CX bike that didn’t fit me well) whenever I would set out to do longer rides it’d be on a mountain bike. On dirt roads or local neighborhood streets, gravel road races or the Macomb Orchard Trail, I’d be on an MTB. This… worked… but after getting the Vaya things clicked and I found myself routinely doing things like 50+ mile paved rides after work in springtime, gravel road centuries, and fast-paced road rides with buddies. It really showed me how much fun a drop bar, skinnier tire bike—but one still with enough tire to ride off road—can be. By late 2018 I’d racked up over 10,000 miles on the Vaya.

As new gravel-optimized frames came about and components on the Vaya started to wear, I kept looking around for something new. Despite flirting with ideas for everything from a Trek Checkpoint to an ALLIED ALFA ALLROAD, from the Specialized Diverge to the Canyon Grail—all great bikes—nothing really clicked until Salsa announced the Warbird v4. Carbon and a very well designed dampening system, through axles, internal routing for everything, four bottle cage mounts, and overall standard parts it was just what I wanted. While I wasn’t too keen on the color patches on the white frame, the new R7000 105 group is perfect and I figured I could do something creative to change up the coloring.

After a boat load of geometry-checking, email back and forth with the ever-excellent Mike Wirth at Tree Fort Bikes, and some help and information from my friend and Salsa/QBP’s rep Jeff Buerman, a 2019 Warbird Carbon 105 700 was on order just for me. While driving up to Iceman this past weekend, where I raced my beloved Salsa El Mariachi Ti, I got an email notification that the Warbird was in, and I could pick it up! Kristen and I swung by Ypsilanti on the way home, and voilà, I’ve got a new gravel bike!

The stock build on the Warbird 105 is really well chosen, but like any bike there’s always some things to tweak or add. I added  the usuals like bottle cages, speed/cadence sensors, saddle, seatpost, and pedals, but I also had some spare parts sitting around home (eg: Thomson X4 stem, XT brake rotors) that were a bit nicer than stock so I swapped them on during the build.

I also unexpectedly got a too-good-to-pass-up deal on some DT Swiss wheels (CR 1600 SPLINE 23). While the CR 1600 wheelset has the same rims as the well-chosen stock C 1800 SPLINE 23 wheels, the CR 1600s have DT Swiss’ Star Ratchet in the hub. I prefer this freewheel design over all others, and switching to these wheels also let me upgrade to 54 points of engagement; right in line with all my other bikes. (High engagement is a luxury, sure, but this Warbird is a really nice bike already so why not.) It also doesn’t hurt that the silver and black hubs go wonderfully with the grey Salsa graphics on the frame. Finally, I’ve been wanting to try the well-regarded Panaracer GravelKing SK, so I set up a tubeless-ready 43mm pair of the blackwall tires on the new wheels.

As an experiment I covered the purple/blue/red patches on the seat tube and fork with self-adhesive, black reflective Scotchlite tape. This both serves as a reflector and brings almost the entire bike together in shades of grey. While I’m not completely happy with the tape job, it’s smoothly applied and covers the colors, bringing the entire frame to a very sharp black/white/grey color scheme. It looks good.

The four water bottle cages are all usable, with the super-common 24oz Specialized 1st Generation Big Mouth Water Bottles fitting in three of the cages with a 21oz in the upper downtube cage, giving 93oz of on-bike fluid storage. Without a bottle in the upper downtube cage I can fit an even larger bottle in the lower one, giving plenty of options. Mounting a Revelate Designs Mag-Tank Bolt-On top tube bag behind the stem provides ~65 in3 of storage for food, roughly equal to what I can fit in one jersey pocket. Coupled with or in place of jersey pockets this should be good for carrying food and drink for quite-long rides; a nice upgrade over the Vaya. It’s a tight fit to stand over the bike with this bag attached, but as an optional accessory for longer rides it could work out real well.

I’ve yet to figure how I’ll carry for tools, but with the relatively low pressure tires I’ll put together another Mobo Pocket Air Pump-based setup fit into the Specialized seat bag.

Weight was not a primary concern with this build, but I’m quite happy with 21.08 pounds for the completely bike as pictured above. This includes a Garmin Edge 130, sensors, pedals, rear light, empty saddle bag, and bottle cages. Not bad for a bike capable of everything from pavement to single track. Not bad at all.

Here’s the details of the complete build:

Frame / Fork: 2019 Salsa Warbird Carbon / Salsa Waxwing (White)
Wheelset: DT Swiss CR 1600 SPLINE 23
Ratchets: DT Swiss HWTXXX00NSK54S (54T)
Tires: Panaracer GravelKing SK (RF743-GKSK-B, 700x43c, Black Sidewall)
Group: Shimano 105 (R7000)
Crank:
 Shimano FC-R7000 (50-34T, 172.5mm)
Bottom Bracket: Shimano SM-BB72-41
Cassette:
 Shimano CS-R7000 (11-32)
Shift/Brake Levers:
Shimano ST-R7020 (Left, Right)
Brake Calipers:
Shimano BR-R7070 (Front, Rear)
Brake Rotors: Shimano SM-RT81-S (160mm)
Brake Pads:
Shimano K02S (Resin)
Chain:
Shimano CN-HG601-11
Front Derailleur:
Shimano FD-R7000-F
Rear Derailleur:
Shimano RD-R7000-GS
Bar Tape:
MSW HBT-210 Anti-Slip Gel (Black)
Handlebar: Salsa Cowbell Deluxe (42cm)
Headset: Cane Creek 40 (IS41/28.6/H9 | IS52/40)
Stem: Thomson Elite X4 (SM-E139 10° X 100mm X 31.8 1-1/8 X4 Black)
Spacers: Generic Aluminum
Stem Cap: MASH Donut 2.0
Seatpost: Thomson Elite (SP-E101 27.2 X 330 Black, Straight)
Seatpost Clamp: Salsa Lip Lock
Saddle: Specialized Power Expert (143mm, Black)
Pedals: Crank Brothers Candy 3 (rev. C, Black)
Bottle Cages: Specialized Zee Cage II (2x Left, 2x Right)
Rear Light: Planet Bike Superflash Turbo
Bell: RockBros Bell (Black)
Sensors: Garmin Bike Speed Sensor (Front Wheel), Wahoo RPM Cadence Sensor (Crank)
Reflective Tape: 3m / Scotchlite Black
Mastic Tape: 3M 2228
Mounting Hole Plugs: Heyco 2590
Top Tube Bag: Revelate Designs Mag-Tank Bolt-On
Saddle Bag: Specialized Seat Pack (Medium, Black)
Derailleur Hanger: 465 / QBP FS2322

During assembly I encountered three wrinkles, none of which affected the final build:

Seat Tube Bottle Mount: When using the bottle mount on the seat tube, spacers are needed otherwise the center of the bottle cage will bottom out on the front derailleur mount. Problem Solvers SpaceOut Spacers, left over from the downtube mount on my original Mukluk 2, solved this.

Cadence Sensor Fitment: A typical problem on modern gravel road bikes with large tire clearance and narrow Q factors; there is not much room between the crank arm and the chainstays. The Warbird v4 is no exception, and I was not able to fit the standard Garmin Cadence sensor safely. It fit, but left around 2mm of clearance. This tight clearance may also preclude the use of a Stages-type power meter on the Warbird.

To fit a cadence sensor on the bike I fashioned an aluminum plate which spans two chainring bolts opposite the crank arm, then sticking a self-adhesive Wahoo RPM Cadence Sensor to this plate. It has a look not unlike a power meter, allows for easy battery changes, and is tucked nicely out of the way. (Picture)

Fork Crown Light Mount Screw: I typically replace all unneeded mount screws on my bikes with Heyco 2590 plastic plugs. These small plastic plugs press snugly into M5 bottle/fender/accessory screw mounts, keeping out water and giving a smooth, finished look. At ~$0.10/each (via Mouser) they are much cheaper than bike-specific parts. Compared to aluminum screws this doesn’t save much weight, but I think it’s much more attractive and likely slightly safer than a protruding screw head.

When unscrewing the upper fork light mount screw the head came off, and the screw was stuck in the hole. As I was turning the screw it felt quite stiff, and I suspect it was either cross threaded, or the hole contaminated with paint which locked the soft aluminum screw in place. This was not an issue with any other screw on the bike.

I was unable to drill out the screw, so I carefully ground it flat and painted the remaining end black. I have no intention to use this light mount, but if this ever changes I’ll deal with the problem later. (Unfortunately while attempting to drill it out I slipped with a tool, bumped the fork crown, and put a small, 4mm chip in the paint. This got touched up with some white enamel paint and now blends in nicely, but it was a really frustrating way to get the first chip in the paint. Oops.)

UPDATE: Due to Tree Fort Bikes swapping the fork after a recall affecting a handful of the Waxwing forks, the problems with the crown light mount screw and the chipped paint are gone.

There’s still a few things left to do, and the inevitable tweaking of things like bar position, steerer length, and all those fun things. But after a lot of work to clone the Vaya’s fit I think it’s good, so hopefully not too much work be needed. That which is probably won’t happen until spring when the weather turns nice and is a bit more conducive to long rides… Exactly what this bike is made for.

Pictures from the unboxing, assembly, and of the complete bike can be found here in my photo gallery: Salsa Warbird 105 (2019)

4 Comments

2018 Marji Gesick 100: #QUITTER

IMG_6420.jpg

After successfully finishing the Marji Gesick 50 in 2017 I got a strange desire to do it again, but this time trying the 100 mile option. Most of my difficulties with MG50 were due to the heat, dehydration, and not being sufficiently familiar with technical trail riding. Having completed Lumberjack 100 numerous times, finished the Barry-Roubaix Psycho-Killer, and done a bunch of not-easy 100+ mile gravel rides I’m no stranger to completing ultra endurance events, and I figured that with the right preparation I’d be able to finish.

From great fat biking to a solid Lumberjack, from long endurance rides to getting a smart trainer, preparation worked out really well this year. I was fortunate to be able to spent a lot of time up in the Marquette area riding bikes, getting plenty of experience with technical sections (both up and down) that I was previously too afraid to ride. I got a lot of climbing in, did a number of long rides, had a solid nutrition plan, had the requisite lighting set up, and was ready to go.

Unfortunately, it didn’t work out. I DNF’d. Why? Fatigue.

And I just didn’t have it in me.

The course wore me out. Whether you are doing it as a race or just to finish, Marji Gesick 100 is a serious event, awarding a beautiful belt buckle to anyone who crosses the finish line in under 12 hours. With only a bit over 12 hours of daylight on race day, and buckles typically only going to elite-level racers, most normal humans (such as myself) who manage to finish will be in for a long day with the most technical of the riding — the end of the route — happening in darkness. I definitely underestimated the toll the first part of the race would take on me. Before starting I roughly figured race day would take ~15 hours, and with the low heart rate I tend to have on these technical routes (compared to long pre-race rides), I thought that I’d be fine. With my longest rides of the last three years being 9-10 hours moving time, about half way through the route I realized I hadn’t had enough long days. As the day wore on and I hit ~11 hours I was feeling pretty cooked.  The first time I reached the bag drop† I was feeling spent, but decided to go back out and see how I felt; clear lenses in my glasses and lights in my pack I kept riding.

While I could still put out power, as I got into the very-technical RAMBA trails I was feeling sleepy and a little light headed at the top of climbs. I didn’t have the focus to climb nor descend well, feeling like I was constantly about to make mistakes, walking much more than the last time on those trails. My upper body was getting sore from handling the bike and I stopped having fun. I kept riding, telling myself that when I reached the Iron Ore Heritage Trail (IOHT) as the course passes through Ishpeming I’d decide what to do.

While I probably could have finished, I stopped half-way up the switchback climbs of Last Bluff, looking out at the setting sun, and decided my day was over. Three miles later, where Partridge Knob splits off from the IOHT I stopped my Garmin, put on arm warmers, chatted with some support folks on an ATV, and texted Kristen to let her know I’d be meeting her in 20 minutes.

This was a real good day, and I had a lot of fun for the amount of race route that I did ride. To some extent I think I could possibly have finished, but I don’t think it would have been any fun, and I really didn’t feel like trying. Getting those remaining 20-some miles done would have involved hours of walking in the dark and not riding what’s otherwise super-fun trail. I don’t regret my decision, and even as I quit I was looking forward to coming back and having fun with the MG50 in 2019.

Two days later I ended up back out on the RAMBA trails, starting a ride from where I dropped out of the race. GPS data, memories of last year, and a few lingering signs pointing the way I finished up the race course and realized two things:

  1. I really, really like these trails.
  2. The choice to DNF was the correct one.

So, beyond quitting? It was a great race, and I’m really glad I did it. But I really do think the MG50 is more for me.

Here’s some data on Strava of my race day and the finishing-it-up ride:

My remaining thoughts about the race are best captured as points:

  • Having someone to meet you and help you out with nutrition (the only kind of outside aid you’re allowed to accept) is amazing. Kristen met me at the South Trailhead with a half a burrito and mixed up bottle. Seeing her, eating that burrito, and only having to worry about filling my pack with water was mentally amazing and hugely helpful.
  • Starting off the MG100 is a 0.5 mile run. I was worried this would cause me problems, but I sort of trotted / jogged along and it was fine. Running along with my friend Erik and chatting it sort of just went, and next thing I knew I was at the start area and my bike and it was time to ride.
  • The weather was intimidating at first, but otherwise amazing. It was in the 40s at the start, but most of the day hovered nicely in the 50s and 60s. I mostly had a chilly/cool feeling on my arms, but never felt cold.
  • The route is mostly great. Starting out heading into Harlow Lake strings things out nicely, and by the time we reach the first seriously technical section (Top Of The World) things are fairly spread out.
  • There were two not-very-hard parts of Harlow Lake that I did not enjoy riding, especially in a group. The first was the Lower Hogback single track, which is rocky and wet. The second was the swampy portion through the power line corridor when heading south. The latter soaked my feet, and they remained wet until I changed socks at the bag drop lots of hours later. I’m glad I had good socks.
  • It was clear climbing the back side of Marquette Mountain was going to be tough, but I figured we’d be taking the usual double track to the top. Instead we turned off of the double track and climbed Snake Oil before descending Ezy-Rider. That climb, and seeing only 51 miles on my computer when I reached the top, was when I started to question if I could finish.
  • The mix of folks I ended up near on the MG100 seemed to be a bit more serious / less talkative than those I rode with last year in the MG50. I’ll chalk this up to nerves and lots of people taking the race more seriously than I apparently did.
  • While difficult, the whole route remains great. There’s a good number of parts I can’t yet ride (Gurly, some climbs, a fair number of things in RAMBA-land), but otherwise it’s outstanding.
  • After climbing Lowe’s the race route passes through a box culvert. I was afraid this would be full of water, but no… it was fine. It was just dark. There are far swampier areas within a few miles of the end of the race.
  • There were many, many ad hoc aid stations. At almost every major road crossing or parking area there were folks set up. Beyond what Kristen got me, I also ate a couple granola bars, a banana, and some water. At almost every significant point there was someone offering food, water, and even whisky and beer. These aid stations are MUCH less frequent around the RAMBA trails.

If you are trying to decide if you should try this race, do it. You will need to prepare, those who haven’t ridden in the UP should plan a trip or two to get a sense of the trails before race day, but do it. When registration opens at 12:01am on October 13th, sign up. Consider doing the MG50 as it’s a good bit easier than the full MG100, but do it. It’s worth it. These are phenomenal trails in an amazingly beautiful area. You will struggle and suffer a bit, but you will have fun doing it. And you’ll want to come back again and again.


† While the race is officially unsupported, it passes through a bag drop area at Jackson Mine Park — a de facto aid station — twice. Once around 70 miles in, and a second time at around 95 miles.

‡ The MG100 race is officially 100 miles, most riders who complete it with a wheel sensor see ~110 miles total. I believe the higher number to be correct, based on:

  1. Recording 59 miles for last year’s MG50.
  2. Seeing 51 miles on my bike computer when the 50 and 100 courses converged.
  3. My experience with assessing under recording on GPS-only vs. GPS-and-wheel-sensor setups.
  4. Detailed analysis of the official GPX route files compared to my recordings of the same trails.
2 Comments

defaults on macOS Can Break Otherwise Usable plist Files

Today I learned that the defaults(1) command on macOS can break otherwise-parsable plist files.

I found this when trying to change selectedThrottleIndex in the Arq config (~/Library/Arq/config/app_config.plist) to adjust a bandwidth usage setting. I didn’t have access to the GUI, wanted to change things from CLI, and whoops! After changing this things broke.

Consider this… First I read out the setting with defaults read ~/Library/Arq/config/app_config.plist selectedThrottleIndex, then set it with defaults write ~/Library/Arq/config/app_config.plist selectedThrottleIndex 2, then read it again to verify the change. All looked good, so I figured I was done and I let things bake.

Upon getting physical access to the machine and launching the GUI, I found that Arq was no longer activated, needed my license info again, and then (uggh!) had lost my configuration. This was fixed by first restoring the whole of ~/Library/Arq from Time Machine, launching Arq, browsing to the backup destination, and clearing it’s cache. After rescanning the destination all was good.

So, why did it happen? Well, it turns out that Arq uses a headerless XML-ish text file with the suffix .plist. Even though it’s not in the same format as plutil(1) outputs, defaults(1) will still read it and modify it… But the resulting file is a plist binary! It seems that Arq only likes to parse its format (note: I did not exhaustively test this — plutil(1)‘s xml1 format may work), so upon seeing the binary version it the program presumed no config and started over. Whoops! Interestingly, the defaults(1), plutil(1), and pl(1) commands will all happily parse the Arq format file.

Note that after launching Arq with the broken config and re-adding the license, restoring just the app_config.plist file didn’t make things better, which is why I jumped right to restoring the whole ~/Library/Arq directory. There must be some config caching somewhere or so…

Leave a Comment