Epic Family Road trip – 2019 edition

My daughter Abby was in the Robotics class at school this year. This gave her (and us as a family) the opportunity to go to the Global Conference on Educational and Robotics which was held in Norman, Oklahoma.

Being in Oklahoma we had a golden opportunity to road trip from Oklahoma back to home in California, so we did.

The trip went like this:

Fly from San Diego to Oklahoma City via Phoenix. Once we landed we were in the Oklahoma City / Norman area for a week as Abby competed in GCER.

While there, Emily and I were able explore quite a bit visiting Down Town Norman very nearly every day we were there. The neatest part of the Oklahoma segment was our drive down to Washington, OK where Emily’s grand father was born (or spent time as a child … I’m not really sure).

Once we left Oklahoma we started the road trip in earnest. I’ve tried to create a Google Maps version of the trip, but the number of places we stopped is more than you can enter into a trip in Google maps.

Here are the vital statistics:

  • miles driven: 3730
  • cities visited: 17
  • national parks visited: 7
  • Baseball games seen: 3

And here are the details:

  • Norman, OK
  • Joplin, MO
  • St. Louis, MO
  • Hermann, MO
  • Jefferson City, MO
  • Kansas City, MO
  • Omaha, NE
  • Sioux Falls, SD
  • De Smet, SD
  • Pierre, SD
  • Black Hills, SD
  • Box Elder, SD
  • Rapid City, SD
  • Jewel Cave
  • Wind Cave
  • Hot Springs, SD
  • Cheyenne, WY
  • Greely, CO
  • Denver, CO
  • Grand Junction, CO
  • Arches National Park, UT
  • Cedar City, UT

We got to watch the OKC Dodgers, St. Louis Cardinals, and Kansas City Royals all play and in each case the home team won. This was good because none of the MLB teams we saw were playing the LA Dodgers, and it’s always fun to see the home team win.

Finally, I also learned some things on the trip:

  • There’s a ton of stuff to do in Norman
  • Missouri is really into World War I and its kind of weird
  • Omaha is the Silicon Valley of the midwest … so much so that they call it the Silicon Prairie
  • Denver isn’t actually in the mountains. It’s just really high in the Great Plains on the way to the Rockies
  • Grand Junction In NOT a mountain town
  • Cedar City is more than just the little Main Street that I’ve seen before … we stayed at a farm while we were there

The family is all glad to be home, and tomorrow it’s back to normal life. I have to say, I’m really looking forward to it.

Taking Down the RPi Camera Over My Hummingbird Feeder

As the temperature heats up it’s time to take down my hummingbird feeder. While the winds have cooled down the valley for the last few days, 100+ days are slowly creeping in and I need to take it down before the CPU melts.

When I took it down last year I though, meh, how hard could it be to put back up. And then I put it back up in the Fall last year and had nothing but problems.

This year, I wanted to document the wires and what not so that I can just put it back up once the temps cool down outside.

Anyway, I could describe it or just take some pictures … so here are some pictures for when I need to set it up again later this year.

Above the feeder:

Wires to the sensor:

Wires to the GPIO pins:

Figuring out how Drafts REALLY works

On my way back from Arizona a few weeks ago I decided to play around with Drafts a bit. Now I use Drafts every day. When it went to a subscription model more than a year ago it was a no brainer for me. This is a seriously powerful app when you need it.

But since my initial workflows and shortcuts I’ve not really done too much with it. But after listening to some stuff from Tim Nahumck I decided I needed to invest a little time … and honestly there’s no better time than cruising at 25k feet on your way back from Phoenix.

Ok, first of all I never really understood workspaces. I had some set up but I didn’t get it. That was the first place I started.

Each workspace can have its own action and keyboard shortcut thing which I didn’t realize. This has so much potential. I can create workspaces for all sorts of things and have the keyboard shortcut things I need when I need them! This alone is mind blowing and I’m disappointed I didn’t look into this feature sooner.

I have 4 workspaces set up:

  • OF Templates
  • O3
  • Scrum
  • post ideas

Initially since I didn’t really understand the power of the workspace I had them mostly as filtering tools to be used when trying to find a draft. But now with the custom action and keyboards for each workspace I have them set up to filter down to specific tags AND use their own keyboards.

The OF Template workspace is used to create OmniFocus projects based on Taskpaper markup. There are a ton of different actions that I took from Rose Orchard (of Automators fame) that help to either add items with the correct syntax to a Task Paper markdown file OR turn the whole thing into an OmniFocus project. Simply a life saver for when I really know all of the steps that are going to be involved in a project and I want to write them all down!

The O3 workspace is used for processing the notes from the one-on-one I have with my team. There’s really only two actions: Parse O3 notes and Add to O3 notes. How are these different? I have a Siri Shortcut that populates a Draft with a template that collects the name of the person and the date time that the O3 occurred. This is the note that is parsed by the first action. The second action is used when someone does something that I want to remember (either good or bad) so that I can bring it up at a more appropriate time (the best time to tell someone about a behavior is right now, but sometimes circumstances prevent that) so I have this little action.

In both cases they append data to a markdown file in Dropbox (i have one file per person that reports to me). The Shortcut also takes any actions that need to be completed and adds them to OmniFocus for me to review later.

The third workspace is Scrum. This workspace has just one action which is “Parse scrum notes”. Again, I have a template that is generated from Siri Shortcuts and dropped into Drafts. During the morning standup meetings I have with my team this Draft will have the things I did yesterday, what I’m working on today, and any roadblocks that I have. It also create a section where I can add actions which when the draft is parsed goes into OmniFocus for me to review later (currently the items get added with a due date of today at 1pm … but I need to revisit that).

The last workspace is post ideas (which is where I’m writing this from). Its custom keyboard is just a markdown one with quick ways to add markdown syntax and a Preview button so I can see what the markdown will render out as.

It’s still a work in progress as this draft will end up in Ulysses so it can get posted to my site, but I’ve seen that I can even post from Drafts to WordPress so I’m going to give that a shot later on.

There are several other ideas I have bouncing around in my head about ideas for potential workspaces. My only concern at this point is how many workspaces can I have before there are too many to be used effectively.

So glad I had the time on the flight to take a look at workspaces. A huge productivity boost for me!

Upgrading Python in a Virtual Environment

I have been wanting to use my Heroku account for a while with something a little more interesting than a Jupiter Notebook.

I was hoping to try and do something with Django … but there’s a lot to using Django. I have some interesting things I’m doing on my local machine, but it’s not quite ready yet.

I had googled to find other Python Web frameworks and saw that Bottle was an even more light weight framework than Flask, so I thought, hey, maybe I can do something with that.

I found this tutorial on how to do something relatively simple with Bottle and deploying to Heroku. Just what I wanted!

I got through to the end of the tutorial and deployed to Heroku. The terminal output from the Heroku command indicated that a newer version of Python (3.7.3) was available than the one I was on (3.7.1).

I figured it would be easy enough to upgrade to the newest version of Python on my Mac because I had done it before.

I don’t know why I thought the virtual environment would be different than the local install of Python 3 but it turns out they are more tightly coupled than I thought.

Upgrading to 3.7.3 broke the virtual environment I had in PyCharm. I did a bit a googling to see how to upgrade a virtual environment and found nothing. Like literally nothing.

It was … disheartening. But after a good night’s sleep I had a thought! What if I just delete the virtual environment directory and then recreated it.

I ran this command to remove the virtual environment:

rm -R venv

Then created a virtual environment in PyCharm and now I have 3.7.3 in my virtual environment.

I had to make some changes to the files for deployment to Heroku, but that’s all covered in the tutorial mentioned above.

Sometimes the answer is to just restart it … and sometimes the answer is delete it and start over.

Update

I was listening to an episode of Python Bytes and heard Michael Kennedy (of Talk Python to Me fame) describing basically the same issue I had. Turns out, he solved it the same way I did. Nice to know i’m In good company.

Did you try restarting it?

The number of times an issue is resolved with a simple reboot is amazing. It’s why when you call tech support (for anything) it’s always the first thing they ask you.

Even with my experience in tech I can forget this one little trick when troubleshooting my own stuff. I don’t have a tech support line to call so I have to google, and google and google, and since the assumption is that I’ve already rebooted, it’s not a standard answer that’s put out there. (I mean, of course I rebooted to see if that fixed the problem).

I’ve written before about my ITFDB and the announcement from Vin Scully “It’s Time for Dodger Baseball!”. With the start of the 2019 season the mp3 stopped playing.

I tried all sorts of fixes. I made sure the Pi was up to date with apt-get update and apt-get upgrade. I thought maybe the issue was due to the version of Python running on the Pi (3.4.2). I thought maybe the mp3 had become corrupt and tried to regenerate it.

None of these things worked. Finally I found this post and the answer was so obvious. To quote the answer:

Have you tried rebooting?

It’s a total shot in the dark, but I just transitioned from XBMC to omxplayer and lost sound. What I did:

apt-get remove xbmc

apt-get autoremove

apt-get update

apt-get upgrade

After that I lost sound. 10 minutes of frustration later I rebooted and everything worked again.

It wasn’t exactly my problem, but upon seeing it I decided “What the hell?” And you know what, it totally worked.

I wish I would have checked to see when the last time a reboot had occurred, but it didn’t occur to me until I started writing this post. Oh well … it doesn’t really matter because it works now.

Creating Hastags for Social Media with a Drafts Action

Creating meaningful, long #hastags can be a pain in the butt.

There you are, writing up a witty tweet or making that perfect caption for your instagram pic and you realize that you have a fantastic idea for a hash tag that is more of a sentence than a single word.

You proceed to write it out and unleash your masterpiece to the world and just as you hit the submit button you notice that you have a typo, or the wrong spelling of a word and #ohcrap you need to delete and retweet!

That lead me to write a Drafts Action to take care of that.

I’ll leave others to write about the virtues of Drafts, but it’s fantastic.

The Action I created has two steps: (1) to run some JavaScript and (2) to copy the contents of the draft to the Clipboard. You can get my action here.

Here’s the JavaScript that I used to take a big long sentence and turn it into a social media worthy hashtag

var contents = draft.content;
var newContents = "#";


editor.setText(newContents+contents.replace(/ /g, "").toLowerCase());

Super simple, but holy crap does it help!

Making it easy to ssh into a remote server: Addendum

I recently got a new raspberry pi (yes, I might have a problem) and wanted to be able to ssh into it without having to remember the IP or password. Luckily I wrote this helpful post several months ago.

While it go me most of the way there, I did run into a slight issue.

First Issue

The issue was that I had a typo for the command to generate a key. I had:

ssh-keyken -t rsa

Which should have been:

ssh-keygen -t rsa

When I copied and pasted the original command the terminal said there was no such command. 🤦‍♂️

Second Issue

Once that go cleared up I went through the steps and was able to get everything set up. Or so I thought. On attempting to ssh into my new pi I was greeted with a password prompt. WTF?

The first thing I did was to check to see what keys were in my ~/.ssh folder. Sure enough there were a couple of them in there.

ls ~/.ssh
id_rsa             id_rsa.github      id_rsa.github.pub  id_rsa.pub         known_hosts        read_only_key      read_only_key.pub

Next, I interrogated the help command for ssh-copy-id to see what flags were available.

Usage: /usr/bin/ssh-copy-id [-h|-?|-f|-n] [-i [identity_file]] [-p port] [[-o <ssh -o options>] ...] [user@]hostname
	-f: force mode -- copy keys without trying to check if they are already installed
	-n: dry run    -- no keys are actually copied
	-h|-?: print this help

I figured let’s try the -n flag and get the output from that. Doing so gave me

ryan@Ryans-MBP:~/Desktop$ ssh-copy-id -n pi@newpi
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/Users/ryan/.ssh/id_rsa.github.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed

/usr/bin/ssh-copy-id: WARNING: All keys were skipped because they already exist on the remote system.
		(if you think this is a mistake, you may want to use -f option)

OK … why is it sending the GitHub key? That’s a different problem for a different time. I see another flag available is the -i which will allow me to specify which key I want to send. Aha!

OK, now all that I need to do is use the following command to test the output:

ssh-copy-id -n -i ~/.ssh/id_rsa.pub pi@newpi

And sure enough it’s sending the correct key

/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/Users/ryan/.ssh/id_rsa.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed

/usr/bin/ssh-copy-id: WARNING: All keys were skipped because they already exist on the remote system.
		(if you think this is a mistake, you may want to use -f option)

Remove the -n flag to send it for real

ssh-copy-id -i ~/.ssh/id_rsa.pub pi@newpi

And try to ssh in again

ssh pi@newpi

Success!

I wanted to write this up for 2 reasons:

  1. So I can refer back to it if I ever need to. This blog is mostly for me to write down technical things that I do so I can remember them later on
  2. This is the first time I’ve run into an issue with a command like tool and simply used the help to figure out how to fix the problem and I wanted to memorialize that. It felt forking awesome to do that.

Footnote: Yes … calling my new raspberry pi newpi in my hosts file is dumb. Yes, when I get my next new Raspberry Pi I will be wondering what to call it. YEs, I am going to try and remember to make the change before it happens so that I don’t end up with the next Pi being called newnewpi and the one after that being newnewnewpi

Receipts

Every month I set up a budget for my family so that we can track our spending and save money in the ways that we need to while still being able to enjoy life.

I have a couple of Siri Shortcuts that will take a picture and then put that picture into a folder in Dropbox. The reason that I have a couple of them is that one is for physical receipts that we got at a store and the other is for online purchases. I’m sure that these couple be combined into one, but I haven’t done that yet.

One of the great things about these shortcuts is that they will create the folder that the image will go into if it’s not there. For example, the first receipt of March 2019 will create a folder called March in the 2019 folder. If the 2019 folder wasn’t there, it would have created it too.

What it doesn’t do is create the sub folder that all of my processed receipts will go into. Each month I need to create a folder called month_name Processed. And each month I think, there must be a way I can automate this, but because it doesn’t really take that long I’ve never really done it.

Over the weekend I finally had the time to try and write it up and test it out. Nothing too fancy, but it does what I want it to do, and a little more.

# create the variables I'm going to need later

y=$( date +"%Y" )
m=$( date +"%B" )
p=$( date +"%B_Processed" )

# check to see if the Year folder exists and if it doesn't, create it
if [ ! -d /Users/ryan/Dropbox/Family/Financials/$y ]; then
	mkdir /Users/ryan/Dropbox/Family/Financials/$y
fi

# check to see if the Month folder exists and if it doesn't, create it
if [ ! -d /Users/ryan/Dropbox/Family/Financials/$y/$m ]; then
	mkdir /Users/ryan/Dropbox/Family/Financials/$y/$m
fi

#check to see if the Month_Processed folder exists and if it doesn't, create it
if [ ! -d "/Users/ryan/Dropbox/Family/Financials/$y/$m/$p" ]; then
	mkdir "/Users/ryan/Dropbox/Family/Financials/$y/$m/$p"
fi

The last section I use the double quotes “” around the directory name so that I can have a space in the name of the processed folder. Initially I had used an underscore but that’s not how I do it in real life when creating the sub directors, so I had to do a bit of googling and found a helpful resource.

The only thing left to do at this point is get it set up to run automatically so I don’t have to do anything.

In order to do that I needed to add the following to my cronjob:

0 5 1 * * /Users/ryan/Documents/scripts/create_monthly_expense_folders.sh

And now I will have my folder structure created for me automatically on the first of the month at 5am!

Keeping Python up to date on macOS

Sometimes the internet is a horrible, awful, ugly thing. And then other times, it’s exactly what you need.

I have 2 Raspberry Pi each with different versions of Python. One running python 3.4.2 and the other running Python 3.5.3. I have previously tried to upgrade the version of the Pi running 3.5.3 to a more recent version (in this case 3.6.1) and read 10s of articles on how to do it. It did not go well. Parts seemed to have worked, while others didn’t. I have 3.6.1 installed, but in order to run it I have to issue the command python3.6 which is fine but not really what I was looking for.

For whatever reason, although I do nearly all of my Python development on my Mac, it hadn’t occurred to me to upgrade Python there until last night.

With a simple Google search the first result came to Stackoverflow (what else?) and this answer.

brew update
brew upgrade python3

Sometimes things on a Mac do ‘just work’. This was one of those times.

I’m now running Python 3.7.1 and I’ll I needed to do was a simple command in the terminal.

God bless the internet.

An Evening with Post Modern Jukebox

About a month ago I discovered a kitschy band that did covers of current pop songs but re-imagined as Gatsbyesque versions. I was instantly in love with the new arrangements of these songs that I knew and the videos that they posted on YouTube. I loved it so much that I’ve been listening to them in Apple Music for a couple of weeks as well (time permitting).

I mentioned to Emily this new band that I found and she told me that they would be playing at the McCallum Theatre and I was in utter disbelief. We bought tickets that night (DD 113 and 114 … some of the best in the house!) and we were all set.

To say that I’ve been looking forward to this concert is an understatement. For all the awesomeness that the YouTube videos have, I knew that a live performance would be a major event and I was not disappointed.

I think this is a concert that anyone could enjoy and that everyone should see. This was the first concert where I was both glad to be there AND glad that I had gone (usually I’m just glad that I have gone and have a hard time enjoying the moment while I’m there).

I have the set list below, mostly so I don’t forget what songs were played. It’s also really cool because some of the performers at the concert were the ones in the YouTube videos. Miche (pronounced Mickey) Braden was an amazingly soulful singer, and her part of ‘All about that Bass’ was on point and breath taking!

It was such an awesome concert. I can’t wait to see them again!

First Set

Thriller

Sweet child o mine

Just Like Heaven

Are you going to be my girl

Africa

Lean on

All about that bass

Second Set

Umbrella

Story of my life

Since you been gone

Crazy – Gnarls Barkley

Heart of glass

Habits – Tove Lo

Time after time

Encore

Stacy’s mom

Creep – Radiohead

Such Great Heights

Band

Hannah Gill – vocals

Demi Remick – Tap

Miche Braden – vocals

Natalie Angst – vocals

Casey Abrams – MC / vocals

Ryan Quinn – Vocals

Ben the Sax Guy – Sax and clarinet

Dave Tedeschi – drums

Steve Whipple – bass

Logan Evan Thomas – Piano

The trombone player was amazing, but I wasn’t able to find him on the PMJ Performers page.