Just add them to ~/Library/Sounds!
Author: Tanner
Added to the labs, a proof of concept page turning button: https://github.com/twstokes/labs/tree/master/pageturn
I’ve always wanted to play around with Menu Bar apps, so I decided to make an easy to access retro calculator in SwiftUI.
I’ve never made a Menu Bar app, so I decided to create a retro calculator in #SwiftUI. 🧮 pic.twitter.com/cFBVDK0dm7
— Tanner Stokes (@TannerStokes) February 9, 2020
APC UPS data in Grafana
I don’t know why I didn’t do this long ago. With the Telegraf apcupsd plugin it’s trivial to add your APC UPS data to Grafana.
I did have to manually install the latest binary from Telegraf’s site instead of the version that comes with Ubuntu, but that wasn’t a problem at all.
A Tree Divided
See the GitHub Repo!
Idea
Every year Clemson plays USC for their state rivalry game. I pull for Clemson and my wife pulls for USC, so we’re what you call a “House Divided”. Since this game takes place on or after Thanksgiving, it’s a great time to incorporate the LED Christmas tree and troll my spouse!
The tree works like this:
- When a team scores, it plays their fight song and lights up with their primary and secondary colors.
- The lights on the tree are distributed by the ratio of points. When it’s tied, they each get 50% of the lights. If Team A has 2/3 more points, they get 2/3 more lights in their color.
- The ring under the star at the top of the tree is the color of winning team. If they’re tied, it’s split.
- When the game is finished, the tree is the color of the team that won.
Software
I used Golang for the software since I primarily write code in another language and want to get better at it. It makes use of various interfaces to aid in testing and abstration:
- The Fetcher interface gets the latest game state from a data source
- The Player interface plays audio at the given path
- The Illuminator interface controls a light source (in this case the LED tree)
The source code for a local data fetcher is included in this repo only. The remote fetcher I built may or may not have used an API meant for this sort of consumption. It simply fetched from a remote data source, unmarshalled a JSON data structure, and supplied what the Fetcher interface needed.
The code runs on a Raspberry Pi and communicates with the MCU via serial. An iHome IBT63 speaker is used to play audio from the Raspberry Pi. I didn’t use the Bluetooth connection and instead used the shared power and audio connector, plugging one end into the RPi’s stereo jack and the other into the USB port.
I cross-compiled from my Mac using the rpi.sh
script in the executable’s directory.
Firmware
- Uploaded using PlatformIO
- Runs on a NodeMCU ESP8266
Diving into SwiftUI
Nerd Sniped
When I saw https://cacheflowe.com/art/digital/deepflat I was “nerd sniped”. I had to figure out how to do it. A bunch of coffees later…
What’s better? I have source code!
Over the past few months our team at Clemson worked with TigerOne, our card services department, and Apple to successfully bring mobile ID provisioning to campus. We were the first school to integrate this functionality into our own app, my.Clemson, and that integration correlated with the success we saw on launch day – around 4500 students, faculty, and staff were able to add their TigerOne Mobile ID to their phone and Watch. These are record numbers to date. 🎉
There were a lot of unknowns when we started the project, one being that we’d never integrated Duo (the University’s two factor system) with a native client. It made sense to reuse the embedded web version so we didn’t have to reinvent the wheel, but we weren’t sure of how to combine this with our current method of authentication via SwiftECP, whose goal is to avoid the browser!
We ended up with a pretty slick solution. After configuring the IdP to allow a Duo flow from a client that authenticated ECP, it worked like this:
- Authenticate via ECP
- Try to load the resource that’s protected by Shibboleth + MFA
- If the resource needs MFA authentication, show it in a WKWebView and use the navigationDelegate methods to determine when the user has responded
- Finally, inject the cookies provided by the Duo flow back into the native client so that it could be used for subsequent requests with a URLSession
A good Raspberry Pi 4 case
My excitement for the new Raspberry Pi 4 turned into disappointment upon learning it couldn’t handle sustained loads without some sort of extra cooling solution. After installing it in this case, I’m happy to say things are looking stable.