Script to reserve Wilson Gym weightlifting slots

Posted on 30 March 2021

Due to COVID-19 protocol, lifting at Wilson Gym at Duke requires reservations ahead of time. These open up 48 hours before and fill up relatively quickly. Here's a script to automatically pick up those slots and never have to worry about whether or not you can get a reservation in time again. read more

How To: Create adaptive HLS/MPEG-DASH videos for your static site

Posted on 21 March 2021

Why use Youtube when you can use way more effort to replicate the functionality youself? Here’s how to create an adaptive video.

read more

How To: Downgrade Google Fit on WearOS for weightlifting/strength training tracking

Posted on 23 November 2020

For some reason, Google decided it was a good idea to replace the feature in Google Fit on WearOS watches that detects which lift and how many sets/reps you’re doing with a glorified stopwatch. Here’s how to get the old version back:

  1. Enable debugging and adb connect to your watch
  2. Run adb uninstall This erases your data, but it should still be there stored on the cloud under your Google account so NBD. Unfortunately Android 7+ doesn’t let you downgrade non-debuggable apps while keeping data due to security risks.
  3. Download the latest version of Google Fit for WearOS that still has this feature (2.44.14).
  4. Install it: adb install

I would recommend disabling debugging after because sometimes my watch stays connected to wifi for no reason and drains battery when it’s on.

Hope that helps. Make sure to ask Google to bring this feature back (instructions here). Now if only I lived in a state where people at the gym can actually care there’s a global pandemic going on…

Wilson Peak

Posted on 23 October 2020

Easily the coolest and also most technical hike I’ve done. It’s the one on the Coors light can! Plus, the more near death experiences you can squeeze into one hike, the more rewarding it is at the end (disclaimer: please don’t see this as inspiration and get yourself killed). We wanted to send one final 14er on our last weekend in Colorado and this seemed like the one to do it. Winds and temperature weren’t ideal compared to the weeks before, but there was a storm arriving the next day so it was pretty much the only possible day to do it. We also got the whole hike to ourselves, didn’t see a single other person for almost 24 hours. Now that’s social distancing :)

Weekend in Moab

Posted on 11 October 2020

So lucky to live in this awesome state.

Uncompahgre Peak

Posted on 04 October 2020

Was my first 14er. That was a rough dirt road up to the trailhead. Jack’s car paid the price for that one. Also camping at 12k ft is cold! Kville trained me so I lived.

We need police accountability and oversight

Posted on 03 June 2020

read more

How to game on Azure while minimizing cost

Posted on 28 April 2020

I left my desktop at school when I left when the campus got shut down, but I still wanted a way to ‘play warzone with the boys’. I experimented a bit and have found what as far as I can tell, is the cheapest way to set up a cloud machine game on Azure.

Costs/Savings for a cloud gaming machine breaks down like this:

  • VM per hour pricing
    • Switch to spot pricing
    • Deallocate (stop from portal) when not in use
  • Storage: monthly cost + disk operations cost
    • Avoid managed disks: by default, VMs are provisioned with a 127 GB OS disk. If you make this an HDD, this runs up to ~5/month in fixed costs. And then expanding this or making a data disk for game data runs up your costs a lot more, and charges you even when you’re not using the machine. What’s more, you get charged for disk operations when it’s in use
    • Store game data as a block blob and extract to the temp disk to avoid page blob charges and the associated disk operations costs. The temp disk also has almost 5x the performance of a premium SSD managed disk in my experience. Downloading/uploading is incredibly fast with 40 gigabit network interfaces installed on the VMs (although storage performance will bottleneck)
  • Network costs: only outbound data is charged
    • Make sure all storage and VM resources are in the same region
read more

Dry Canyon Hike

Posted on 26 April 2020

Trail conditions as of 4/26/20: Towards the end of the dry canyon trail, there’s a bit of snow, but nothing I couldn’t handle with my pair of trailrunners. As you can see from the Strava recording, I went past that and to the trail to the top of big baldy, where there’s quite a bit of snow. I ultimately didn’t attempt the final summit of big baldy because I was alone due to social distancing so wanted to err on the super safe side, but it looked doable. It’s about half a mile out from where my recording ends.

read more

Social Distancing

Posted on 04 April 2020

I have done this trail so many times in my life, still never gets old.


Posted on 08 March 2020

View this post on Instagram

A post shared by Jimmy Xiao (@jimmyjxiao) on

Making RGB LED projects that pull from REST APIs easier

Posted on 30 November 2019

Project Github Link

This is a framework I wrote that helps you create solutions that use a lot of RGB LEDs that are used to indicate statuses of various things pulled from web APIs. It’s written for ESP8266, but I don’t imagine it would be especially hard to adapt to other microcontroller platforms, especially if they’re arduino based. It’s got some nice abstraction logic to help handle multiple port expanders (MCP23017) and addressable LEDs (WS2812). I wrote it initially for this project.

read more

Map with weather of airports around the country

Posted on 29 November 2019

Pictures are worth 1000 words, so here’s what I’m talking about:

I have a friend who’s a private pilot, and bought a map with a bunch of airports and airspace stuff on it (actually two of them on accident). I decided to work with him to put RGB LEDs in various airports to indicate flying conditions in real time. Apparently, these are called METARs, which to save you a search because I had no idea what it meant either, stands for METeorological Aerodrome Reports. We used the API from the Aviation Weather Service from NOAA, which returns the information in XML, which we parsed with TinyXML2.

Since it would be making web requests, an ESP8266 seemed like the logical choice for the platform that controls all of this. A similar project online used a Raspberry Pi, but in my opinion, that’s overkill and more expensive that it needs to be (we’re both college students, cheap = good). We bought the ESP-01 tiny version of it at first, which worked, but using an Arduino to interface with it and dealing with the associated voltage conversions and holding certain pins low to flash and what not was incredibly frustrating so I ended up getting a NodeMCU instead. Much easier to work with.

We pasted the map onto a giant foam board we found with glue, then drilled holes for LEDs. My initial solution had a common annode LED for each of the 20 airports we planned to do, but my friend thought 60 wires running back to the breadboard (3 for each LED) was excessive. I don’t want to admit it, but he’s probably right; it would’ve been a giant pain to wire up. Instead, we got these addressable LEDs. These are pretty nice, I have two rails of 5V and GND that all the LEDs could connect in parallel to, and then they just get daisy chained up to each other through the data pins. The code used is all here.

Since the initial solution involved using a bunch of non-addressable LEDs, and we ended up using the WS2812 based LEDs, I made a framework that simplifies projects that use a lot of RGB LEDs and pull from REST APIs using the ESP8266. Check it out!.

Some the airports were chosen based on sentimental reasons and others just to get a picture of what’s happening around the country. If anyone’s curious here are the airports we did: BOS,​JFK​,PHL​,DCA​,RDU​,ATL​,MSY​,DFW​,MCI​,ORD​,OSH​,DEN​,SLC​,BZN​,SEA​,SFO​,LAX​,CLT

Using LightGallery in Jekyll without tedious configs

Posted on 28 July 2019

I don’t do webdev often, but lately there’s been a small spurt of most of the my projects being websites. Photo galleries and albums are an extremely common thing on websites, and I would assume quite a few have wrestled with yamls describing the file path, name, and caption if they’re trying to do it in Jekyll. Today, I’m going to show you how to configure jekyll to use all files in a folder that’s passed in as an argument. Once it’s set up, all you need to do to create a new album is create a folder, throw your pictures in, and then:

{% include album.html albumname="myAlbumName" %}

You can see the resulting album here: example

read more

The Case For Traveling Alone

Posted on 27 July 2019

And by “travel”, I don’t necessarily mean hopping on some expensive flight and staying at a luxury resort. In my experience, so many people haven’t explored the places they live and work at, and often miss the gems around them that other people take a long trip to see! So by “travel” I simply mean to explore and do things: go on a hike, out to eat, to a concert, with or without somebody to do it with.

In the past year, I’ve had a lot of opportunities to explore places alone, from a long layover to taking extra days at the tail end of a college department organized service trip, to excursions and nights out alone in Houston, where I spent the summer and had few connections. Don’t get me wrong, I love traveling and exploring with other people too, and that has its benefits that are unique from the experience when rolling solo. However, through these opportunities, I’ve had awesome experiences that I wouldn’t have been matched if I were with somebody.

From walking over 30 blocks in San Francisco instead of taking BART just because it was a good day and I wanted to take it all in, to a spontaneous decision to rent a kayak in Austin, being on your own allows you to explore with no compromises (except with your wallet!) about what you want to do. And with all that time you spend thinking about others and what they do or don’t want to do, I think it’s important to take some time and just do what you want to. What I’ve also learned is nobody cares if you’re eating out, going to a concert, or doing anything else alone. As Tom and Donna in Parks and Rec put it, “treat yo self”. It’s during those 6 mile hikes, the gaps between artists at a concert, rental-bike rides at iconic monuments, and amazing dining experiences I enjoyed alone this year that I felt like I grew the most this year. Here are some random pictures from my solo adventures:

Spring Break

Posted on 16 March 2019

For Spring Break, I participated in Duke Energy Initiative’s solar spring break program. Through this, I got to help install solar panels with Grid Alternatives in Salinas, CA. They were super friendly and showed us the various steps in the process, such as siting, dealing with regulations and codes, efficiency considerations, etc as well as letting us gain some hands on experience installing solar panels.

We stayed in a hostel in Monterey, CA which was a pretty cool experience. It’s really an awesome city, and going on runs along its coastline was amazing. I also got to spend my last day in California exploring San Francisco. I decided to walk all the way from 6th st | Market St to Pier 39 and then along the Embarcadero, which was a lot of walking but definitely worth it. Then I biked across the golden gate bridge, took BART back and almost missed my flight

Duke vs UVA

Posted on 19 January 2019

View this post on Instagram

Watched Duke crush UVA and developed an extreme hate for the sound of a siren this week

A post shared by Jimmy Xiao (@jimmyjxiao) on

Winter Break

Posted on 07 January 2019

Winter Break was my first time back home in Utah since August when I left for college, so I was definitely pretty excited (plus I was mentally shot after finals). The trip home was pretty hectic with schedule changes I didn’t know about until the last minute, issues with the plane, and other things, but I made it back in one piece so yay.

As I got home, my dogs were super happy to see me which was awesome, as I had been thinking of them during the whole semester. I made sure they get lots of pats, treats, walks, and adventures with me this break. I had really missed driving too, and I really liked being able to drive again during the break.

I went and visited Lone Peak High School again, and saw some of my teachers, and it was pretty cool visiting as an alumni instead of a student. I also visited In-N-Out for my first meal back, and saw some of the people I used to work with, although many weren’t there either because they had transferred to different stores or quit. I missed that awesome ‘Chz W GR mfd chillies Light S XChz’ so much though, and rewarded myself for finishing a semester with one.

I went skiing, caught up with old friends, avoided things I should’ve been doing, and explored random places. It was kinda weird coming back home and realizing a lot of my friends weren’t around because they were on missions or elsewhere, but I’m still glad I got to see the ones I did.

I’m writing this during my 8 hour layover here in Denver, which actually didn’t end up being very bad because I took the oppurtunity to explore the city. Randomly wandering around an unfamiliar city alone is actually very fun, and I’m actually really glad I had a layover here this long. Denver really is a bigger version of Salt Lake City in many respects (but with breathable air!) and it was fun seeing all the similarities between the cities.

Here’s some random pictures from the break:

Using an Arduino to detect multirotor's RC input

Posted on 20 December 2018

So I had a setup where I had an R9DS RC receiver connected to a Librepilot CC3D with SBUS and I wanted to control two servos with an accessory channel switch on my transmitter. I needed the servos to trigger, but reversed to each other when I flipped the accessory switch on. I figured out it was pretty impossible to do on the CC3D, so here’s how I did it with an arduino nano. NOTE: The exact method I used only works when your receiver can output the channel on SBUS and PWM simultaneously, the arduino will listen to PWM.

  1. Wire up 5v power to the arduino nano and servos
  2. Wire the PWM channel to a digital input on the arduino
  3. Upload this to arduino to see what the on/off PWM values for are by watching the serial window as you flip the transmitter accessory switch
byte PWM_PIN = 3;
int pwm_value;
void setup() {
  pinMode(PWM_PIN, INPUT);
void loop() {
  pwm_value = pulseIn(PWM_PIN, HIGH);

Now you can determine what state the remote acessory switch is in with pulseIn. Here’s my use case:


#include <Servo.h>

Servo LeftServo;  // create servo object to control a servo
Servo RightServo;

void setup() {
  pinMode(3, INPUT);
  LeftServo.attach(9);  // attaches the servo on pin 9 to the servo object
void OperateJaw(bool isOpen)
int pwm_value;
void loop() {
  pwm_value = pulseIn(3, HIGH);
  if(pwm_value > 1200)
    openState = false;
    openState = true;

Using Windows' New Built In OpenSSH to Secure RDP

Posted on 19 December 2018

I have two computers at college, my custom desktop, and my laptop. Both are running Windows 10, but what’s important to this guide is the desktop is running Windows 10 as the client configuration here is trivial to replicate on OSX or Linux, probably even easier. The desktop is definitely the powerhouse, and I do all of my heavier applications and processing on it. However, I’m out and about on campus most of the day, and am sometimes unable to access my desktop when I need to. I was reluctant to just open up RDP on my firewall given the security risks, and I thought setting up a personal VPN to access one port on one computer would be overkill, so I decided to go with SSH port forwarding.

Server Configuration

  1. Install OpenSSH on Windows. It’s pretty simple, just use add/remove features and check ‘OpenSSH Server’. Detailed guide here.
  2. (optional but highly recommended) Edit to disable password authentication and force pub/priv key authentication for maximum security.
  3. (optional) Change the listening port for SSH for security through obscurity and allow the new port through the firewall

The sshd_config file on windows is located at %programdata%\ssh\sshd_config

I recommend adding this line: PasswordAuthentication no to disable less secure password authentication and only rely on more secure pub/priv keys. If you do this, run ssh-keygen on the client, go to %userprofile%\.ssh, and copy the contents of the id_rsa file on the client to a file on the server in the same location called authorized_keys.

You can change the port from 22 if you want security through obscurity with this line in sshd_config: Port [port number] Make sure to allow the port through on your firewall and forward through your router if necessary.

Client Configuration

  1. Install an OpenSSH client. On Windows, I highly recommend OpenSSH, installable through add/remove features. You just need the client.
  2. Test
    1. Connect to the remote computer while forwarding the port: ‘ssh -L 4000:localhost:3389 [IP address] -p (port set in sshd_config)’
    2. Initiate RDP by opening remote desktop connection or a VNC client on Linux and connect to ‘localhost:4000’
  3. If that works, write a script to run it! Here’s a super crappy one in powershell:
$ArgumentList = '-L 4000:localhost:3389 ' + $content + ' -p 31825'
Start-Process ssh -ArgumentList $ArgumentList -NoNewWindow
Start-Sleep 5 
mstsc /v localhost:4000
wait-process -name mstsc

Looking Back at 2018

Posted on 19 December 2018

2018 was a big year for me. It was a year of firsts and lasts, of learning and growing, and one full of highs and lows and everything in between.

read more

Drone Based Leaf Sampler Poster Presentation

Posted on 07 December 2018

Presenting a poster for our semester project. Hit up the resume section of my site for more details!
View this post on Instagram

A post shared by Jimmy Xiao (@jimmyjxiao) on


Posted on 02 December 2018

View this post on Instagram


A post shared by Jimmy Xiao (@jimmyjxiao) on

Thanksgiving Break

Posted on 27 November 2018

View this post on Instagram

Thanks for temporarily adopting me for a week Surrett family!

A post shared by Jimmy Xiao (@jimmyjxiao) on