ruby tuesday — 2008 – 2024

Age 7 — 2015

We sent Ruby yesterday to join her companion Max. Max had left us back in July 2015. She could no longer stand, let alone walk, and slept nearly the entire time over the weekend and Monday. Yet she still recognized when Annie was getting fed and would raise her head, letting us know she wanted some food as well. We lavished her with peanut butter laced with her final medications, as well as little treats. And lots of rubs and kisses.

And she still smiled that sweet Ruby smile when she was awake.

Ruby Tuesday and Dreamboat Annie — 2015

Ruby leaves behind her companion Annie, who it shocks me to realize is nine years old, and will be ten next Valentine’s Day.

Max and Ruby Tuesday — 2011

No tribute to little Ruby would be complete without a photo of her with her companion Max. Ruby was always friendly with her companions, both canine and feline, but Max was her first, and a bit more special to her than all the others I think. She always remembered Max, and if I made the mistake of mentioning his name in her presence, she would always look up as if expecting him to re-appear. Dogs never forget, especially female Labs. I saw the same behavior with Katie when Rhett left us.

While we still have a vibrant Annie, and six healthy cats, there is a Ruby-sized hole in the household at the moment. She will be missed, as they have all been.

going back to go

My mind appears unable to fully embrace how Rust is meant to be idiomatically used. I guess I’m too old. I’ve gone back to the Go language and discovered, once again, that it’s excellent at easily expressing complex ideas in code and having that code execute the way I expect. I see myself going back to Go over Rust and C++, and using Python in its MicroPython variant for embedded development. For software I write for others, I want a language that wraps everything up into a single binary executable that doesn’t require special support libraries be installed along side it. I can produce these types of binaries with C++, Go, and Rust. Python is complete on embedded devices, which is why I now do heavy development using MicroPython.

For this post I’ve written my devices listing application in Go, which I’ve previously written in Python, C++, and Rust. Here’s the Go listing.

package mainimport (  "errors"  "fmt"  "log"  "os"  "path/filepath"  "strings"  "encoding/json")func main() {  executable, error := os.Executable()  if error != nil {log.Fatal(error)  }  var annotations = make(map[string]string)  jsonPath := filepath.Dir(executable) + "/devices.json"  rawJSON, error := os.ReadFile(jsonPath)  if errors.Is(error, os.ErrNotExist) {fmt.Println("Annotations JSON file not found at:", jsonPath)  } else {json.Unmarshal(rawJSON, &annotations)  }  deviceById := "/dev/serial/by-id/"  files, error := os.ReadDir(deviceById)  if error != nil {log.Fatal(error)  }  for _, file := range files {symlink, _ := filepath.EvalSymlinks(deviceById + file.Name())device := filepath.Base(symlink)suffix := file.Name()[strings.LastIndex(file.Name(), "_")+1:]hexid := strings.Split(suffix, "-")[0]annotation, found := annotations[hexid]if found == true {  fmt.Println(device, "  ", annotation)} else {  fmt.Println(device, "  ", hexid)}  }}

Here’s a typical output. In this example I have three boards plugged into my Linux system, an ESP32-S3, an ESP32-C3, and a Raspberry Pi Pico 2:

ttyACM0Raspberry Pi Pico 2 - MicroPython 1.24.0 - RP2-EC93ttyUSB1ESP32-C3-DevKitC-1-N4 - ESP-IDF 5.3.1 DisplaysttyUSB0ESP32-S3-DevKitC-1.1-N32R8 - MicroPython-1.25.0-preview-xtensa-IDFv5.2.2 2024-11-08 - ESP32S3-7814

You can see the application’s found them all and their associated TTY port. This is quite useful when using command-line tools to communicated with them individually.

And finally, here’s a section of the JSON file the application reads in in order to match annotations with devices I have plugged in:

{  ...  "7a1c74c68740ec93": "Raspberry Pi Pico 2 - MicroPython 1.24.0 - RP2-EC93",  "7eab1642dbfaeb1198773ca4c6d924ec": "ESP32-C3-DevKitC-1-N4 - ESP-IDF 5.3.1 Displays",  "cc2ba0cbe2cfec11973d262686bdcd52": "ESP32-S3-DevKitC-1.1-N32R8 - MicroPython-1.25.0-preview-xtensa-IDFv5.2.2 2024-11-08 - ESP32S3-7814",  ...}

Quick Operational Description.

Here’s a bulleted list of what I’m trying to accomplish with the Go code.

  1. When started, determine where in the file system we were started (lines 14 and 18).
  2. With that file path, append our annotations file name to it so we can open it (lines 20 through 28). Note that the annotations file is in JSON.
  3. If the annotations file exists, read it in and unmarshal it as a map. If the file doesn’t exist, emit a message saying it couldn’t be found and where it is supposed to be located.
  4. Look for any devices plugged into the Linux system (line 31).
  5. Assuming you find any devices, extract the hex ID from each device name found (lines 38 through 42). Those hex IDs are unique.
  6. Try to look up the hex ID in the dictionary you loaded in step 3. If you find an entry, that’s your annotation. Print it out with the device you found in line 41. If there is no entry then print the device with the raw hex ID.

That’s basically it.

Final Thoughts

Life is way too short for me these days. I still like to write software, but now I want a language and supporting tools that make my efforts far more efficient. Go gives me all of that, and more. I started with Go over ten years ago (you can search for my entries in this blog) on very early Raspberry Pis, specifically the 3 and 4. Then I just sort of let it fade away while chasing other new and shiny languages like Rust. Now I’ve come back to Go for good, and will continue to use it for my purposes until I can no longer think in code, let alone write it.