SMS Tracker

My wife and I have a senior dog who is starting to show his age. He has been having a lot of the issues that come with old age, and we needed a way to make sure that we were doing everything we can to keep him healthy. One of the big issues we were running into is remembering all of the stuff that happens daily: did he poop, did he get his medicine, etc.

The initial approach we took was to use a printed paper calendar and just write things down each day. It’s an effective, low-tech solution, but obviously has a lot of drawbacks. We went out to Colorado to ski and had to train our pet sitter on how our calendar worked, and also had no visibility into it while we were gone.

I decided to throw together a small web application which allows us to just send an SMS message to track things. This solution is great, since all that is involved is adding phone numbers to an allow list (and anyone we need to have tracking stuff already has shared their number with us), so there is no need to worry about logins, passwords, etc.

Anatomy of the Application

The application (creatively called SMS Tracker) is a pretty standard .Net 6 web application, using Razor pages for the UI and a couple of more traditional Asp.Net MVC controllers for processing Twilio messages and handling a few AJAX calls. The backend database is just SQLite, using EF Core as an ORM (basically the exact web application template that Microsoft ships with Visual Studio).

You can find the code on my Github here.

Functionality

The app uses Asp.Net Core Identity to authenticate the two users who actually have access (myself and my wife), and I’ve disabled the registration page to attempt to prevent others from registering. I’ve designed the data model in such a way that even if others did register accounts, they wouldn’t be able to see anything that isn’t part of their account.

One of the more interesting parts of the app is that it allows multiple “profiles”, basically you can have one profile for pills, one profile for poops, etc. By using a prefix to disambiguate which profile the SMS is for, multiple things can be tracked.

There is a calendar view which can either display tracked events across all profiles that the user has access to, or it can be filtered to show only a specific type of tracked event (i.e., only check for “pill” events to see if we remembered to give him his medicine today).

Hosting

Since this is a small app that is consumed a majority of the time from within my home, I decided to just host it on my PC. It literally is just deployed from Visual Studio and running inside of IIS. I have CloudFlare in front of everything (right now it’s using a CNAME to my dynamic IP, but eventually I want to get Argo running to hopefully lock things down a bit more). My PC is on a majority of the time, so hosting it there doesn’t really impact anything – the app itself is using ~64 MB RAM, while I have 128 GB in the PC.

One very interesting thing with this app is that I actually wrote ~95% of the code on Mac with an Arm chip, and with absolutely zero changes it’s now running on Windows with an AMD processor.

Reception

I built this mostly for an audience of one other (my wife), and she has been pretty enthusiastic about it, so I’d say it’s been an effective application. Getting rid of the paper tracking has been nice and being able to see when things have happened (the tracked events record their received timestamp), lets us easily make sure that nothing has been forgotten.

Conclusion

I would love to hear if anyone else decides to borrow this code, it’s a pretty nice basis and hosts pretty easily. I had previously built a docker container for it but decided to just go down the path of hosting it on my PC directly in IIS for now. I am moving in a few weeks to a house and am planning on doing a bit of home automation there, so I may repurpose a Raspberry Pi as a docker host and move it docker at that point.

Migrating from G Suite Legacy Free to iCloud

For those of us who are on Google’s Legacy Free G Suite plan, there was an announcement the other day that all good things must come to an end. Sometime in the July timeframe everyone will need to either start paying or stop using the service. Fortuitously, Apple recently (in October) announced custom domain support for iCloud. For people who were using G Suite only as an email service (i.e. no Google Docs, or other Google Apps), and are only using it for personal accounts, iCloud can serve as a perfectly acceptable email host.

The migration path is pretty straight forward:

  1. Go to iCloud Settings and click on the Manage button under Custom Email Domain
    1. Click Add a domain you own
    2. Select if this is for a single person or for a family account (I believe this controls if the domain is made eligible for family sharing)
    3. Enter the domain
    4. When entering existing emails, only enter the ones that already exist
    5. Enter the DNS records (MX, SPF, DKIM, TXT, etc) that Apple provides into your DNS configuration
    6. Test sending an email
    7. If you have the legacy Gmail account and the new/updated iCloud account both in the Apple Mail app on a Mac, you can just copy and paste to migrate all old emails (I moved thousands of messages going all the way back to October 2010 in about 5 minutes with this process)

At this point my plan is to just let my old Google account exist, but I expect Google will make it inoperable on their announced timeline.

Update March 8, 2022

It looks like one thing that doesn’t work all that well is sharing the account to children accounts. This reddit thread goes into detail: https://www.reddit.com/r/iCloud/comments/pttz4q/custom_domain_not_working_for_child_account/. Not a big deal for me right now, but hopefully something that will be addressed in the next couple of years.

Duo Desire (a small IoT project)

My wife was watching Shark Tank a few weeks ago and we were both chatting about a thing we saw (which wasn’t funded). It was kind of a clever idea, and I’ll sidestep the entire discussion of whether or not it is a “good” product or not, I just wanted to see what it would take to build something kind of like it (this is loosely inspired by LoveSync, but the LoveSync does have some interesting features around time and also their hardware is much prettier than what I’m using).
The Rebutton (ignore the dirty valet box)
As a quick aside: this method of asynchronous communication in which parties are only notified after reaching consensus seems like an interesting UX pattern. I was very interested to see almost the same pattern pop up (in almost the exact opposite context of LoveSync) in the form of the Bail App, which I believe is still in development (if it’s even feasible).

Quick Overview

So, to the meat of the project: this project is 2 IoT buttons hooked up to an Azure IoT Hub which trigger Azure functions and make use of Azure Table Storage for data persistence. When consensus is reached, a notification is sent via Twilio to all interested parties. Why Azure you ask? Easy: the buttons that were in stock only had the Azure model available, so that made the decision pretty easy. Amazon’s infamous IoT button is apparently no longer for sale to individuals (or if it is it is so well hidden I gave up on looking). Developing this on Azure worked pretty well, although there were some weird issues when I attempted to interact with the IoT Hub service using C#, so I ended up doing everything in Javascript (I know, IoT in JS, I never thought I’d see the day).

Bill of Materials

Building It

To start, configure the Rebutton to communicate with your IoT Hub. The docs do a pretty good job of describing this. Ensure that the buttons are communicating with the hub. This command will let you see events as they come from the event hub: az iot hub monitor-events -n <yourapp> --properties anno sys --timeout 0 In the Azure Function Apps blade, you’ll need to create the following functions

Event Hub Function

The first of the three functions needed is the function which will process event hub messages. At a high level all this is doing is being invoked any time an event occurs and then just writing the event data to the Azure Table Storage table defined in the configuration. You’ll need to configure it something like:
The Azure IoT Event Hub function
The code for the function is here. As I alluded to above, I was having some weird issues with the C# bindings in Visual Studio, so I ended up just writing everything in Javascript directly in browser. Not the greatest development environment…

Timer Function

The timer is the next function. It runs on whatever cron schedule is defined (I currently have it running every 10 minutes), and it just looks for consensus in the table for both configured devices. Consensus in this case is defined as one or more single-click events from each device. If any non-single-click events are discovered, then it is assumed that consensus is impossible, and the messages will not go out. It would be an interesting exercise to extend the current logic and use the other button events (double-click, long-press, super-long-press) for other functions. Upon discovering consensus, the timer function writes to an Azure Queue and writes a “FINISH” record to the table storage to prevent the next run of the function from also triggering a message.
The timer configuration
The code for it is here.

Queue Trigger Function

The final function needed is the queue trigger which is responsible for actually sending the messages to Twilio. The code is incredibly simple as Azure has a pre-built integration with Twilio which abstracts away the vast majority of the code that would otherwise need to be written.
The Queue Trigger configuration
At this point, everything should be wired up, so pressing both buttons should trigger the Twilio message.

Worth It?

Assuming usage remains fairly constant, Azure forecasts that I’ll spend ~$0.30 per month, plus ~$50 for the buttons. I think it’s worth it for the fun I had building this, plus if the current application of the buttons gets stale, I’m sure I can repurpose them for something else. Interestingly, these buttons are built on the Arduino platform, so conceivably I could do a whole lot of customization by changing the firmware around (which might happen eventually).

In Closing

This was a fun project which didn’t take very long to put together and entertained me. It was a timely project for Valentine’s Day. If you end up building something like it or have any feedback on this article, please reach out, I’d love to hear!