Plugging in Power Tools

I’ve been slowly chipping away at Power Tools in little spurts over the past few weeks. Right now I have a very basic set of graph manipulation logic that lets you hook up nodes and then push events through the resulting mesh, and I’m working on putting a database behind the system so that graphs can be stored and fetched dynamically instead of via config files. As I’ve been working on it, applications for the system keep coming to mind along with some design patterns that might be interesting.

Background

Let’s start with a little background. Power Tools is a system that I’m building to add some more oomph to IFTTT (read more here). It’s based around building a program which reacts to IFTTT events and outputs IFTTT triggers using the Maker API. These programs are represented as a graph of nodes connected over channels, and each node can receive events or produce events on multiple channels depending on their type. Some basic types of nodes include timers, counters, splitters/joiners, and state machines, in addition to the IFTTT inputs and outputs.

All good? Ok, let’s look at some applications.

Application: Timer commitment contracts

Suppose you want to do something that you know you have a hard time stopping, like taking a short nap or playing a video game. You want to make sure that after a certain amount of time you’ll be forced to stop doing that thing and move on to something else. Sounds like a commitment contract, right? Normally that’s something that Beeminder would be well suited for, but as things stand it isn’t set up for this kind of thing.

Enter Power Tools. With an IFTTT hookup to Beeminder and a timer node, you can do a countdown which is only stopped when you hit a button (say, from a Flic.io device).

clojure.lang.LazySeq@aa5875bc

In the example, two buttons are connected (or one button, it doesn’t really matter) to the Power Tools graph as IFTTT input nodes. Button B starts the countdown, and when Button A is pushed the timer is stopped. If the timer fires to its output channel IFTTT will receive a trigger event, which in this case is hooked up to the Beeminder channel’s “Charge Me” action.

Application: QS Rate Limiter

Next, let’s explore how a Latch node can combine with a Timer to create a rate limiter. This can be useful if you have a noisy input stream that you want to down-sample, such as if you had an IoT device that sent events every 5 minutes but you only want to look at one event every hour. A latch allows the first event it receives to pass through, and then blocks all further events; combined with a timer that resets it each hour, you have a 1/hr rate limiter.

clojure.lang.LazySeq@f8826877

Note: We also include a splitter to reset the timer. The splitter needs to be on the output side of the latch or else the will be reset for each event on the input. You can also have the splitter attached to the timer output to get a 1 hour reciprocating countdown.

Application: Combining Inputs with Voting

What if when you checked in at the gym, logged a workout, and posted an Instagram picture of your healthy dinner IFTTT would automatically tweet about how awesome you are and send an email to your parents/spouse/bestie? With an N-of-M voting system, you can!

clojure.lang.LazySeq@2f4b9b56

When each of the connected channels (in this case FourSquare, Evernote, and Instagram) fires an event the Vote node records it, and when all three have triggered then an event is sent on the “vote carried” output to a Splitter node. The splitter triggers the Twitter and email channels.

Other ideas

There’s a ton of things you can do with these building blocks, and I’m sure people will come up with much more interesting applications than these. Of course, many will share some basic arrangements of nodes that perform useful functions together, like these:

  • Combine a timer and a latch that starts closed for a gate that opens after a certain amount of time.
  • Combine a voting system with a joiner to allow “and-of-or” style logical combination.
  • Use a state machine with a timer to require a sequence of steps be completed with a set period of time.

Like I said above, I’m making slow progress on this. My hope is to have something functioning well enough to start testing some of these ideas in the next few weeks; keep an eye out for more updates, and be sure to leave a comment if you think of other cool ways to use these features.

If you like what I write, you can subscribe to my mailing list to get new posts in your inbox: