iPhone + ifttt = IoT wifi sensor platform

Can't wait for Twine, Ninja Blocks or Node? Use an old iPhone or iPod Touch as an Internet of Things wifi accelerometer (movement sensor) with a simple app and if-this-then-that.

Prerequisites

This requires a little background information if you don't already know what the Internet of Things, Twine, Ninja Blocks, Node or ifttt are.

The "Internet of Things" is the idea of having individual objects be uniquely addressable, and connected. Your washing machine knows which clothes it's washing. Your water filter knows it needs to be replaced. Your front door knows someone is knocking at it. Maybe it even knows who. The connection to the broader network can be "smart," where the device can connect to other services on its own, or the connection can be "dumb," where it needs another device to ask it what it knows.

Twine is a "smart" wireless sensor. You place it on or near something that could use a little unique addressing and connected intelligence, and it provides it. Place it on your washer and it knows when your washer starts moving and stops moving, signaling the beginning and end of cycles. Place it in your water pitcher and it knows how many times it got wet from refills. Place it on your door and it knows it's being vibrated from knocks. Twine connects over wifi and supports a custom plug for additional sensors.

Ninja Blocks are "smart" wired sensors. They're fundamentally similar to Twine sensors, except their hardware specifications are publicly available, they require a wired network connection, and their additional sensors connect via USB.

Node is a "dumb" wireless sensor. It connects over Bluetooth to a smartphone or other device, which reads the sensor data and handles actions based on the results.

ifttt is a web site which lets you connect services together using "tasks," which are made up of "triggers" and "actions." A trigger might be, "if I am tagged in a photo on Facebook," and an action might be "then save a copy of that photo to my Dropbox." "If this then that."

The network services powering both Twine and Ninja Blocks work like ifttt: the smart sensor is the trigger, and the "Spool" service (for Twine) or the "Ninja Cloud" service (for Ninja Blocks) perform the appropriate action you've configured when the sensor notifies it that something has happened. "If the sensor in the basement detects moisture then text me 'The basement is flooding.'"

Twine, Ninja Blocks and Node were all funded this year through Kickstarter (I backed Twine, the first project out of the gate, myself), so none of them are out yet. When they're released, they'll be the easiest ways yet to connect the real world to the internet. The next "easiest" way is to buy and build wireless networked sensors out of Arduino computer chips and other electronics; "easy" enough if you're handy with a soldering iron, but not if you're a designer who just wants to do something with that data.

Which brings you up to speed.

Old iPhones

I have three first-generation iPhone 2G models. I bought them for around $50 each, two years ago, from friends and coworkers who were upgrading to the iPhone 3GS. They're becoming less and less valuable. Without a cellular contract, first-gen iPhones are just heavier iPod Touch models, and for our purposes today, an old iPod Touch works just as well.

They can connect over wifi on their own (no cellular data plan necessary for this), they have built-in sensors (an accelerometer, a proximity sensor and an ambient light sensor) and they have two plugs that can be used for additional sensors: the headphone jack (via the microphone) and the dock connector.

That description should sound familiar now: old iPhones can be an Internet of Things "smart" sensor platform. iOS development is well understood: you need a Mac, you pay $99 a year to Apple, and you need to have a little programming knowledge.

I'm not the first to have this idea. I posed the question to Supermechanical, the makers of Twine, if they'd consider producing an app that exposed the iPhone to their Spool service, but their focus is understandably on the Twine hardware.

Still, if you have a Mac and a disused iPhone or iPod Touch, you're ready to go. You don't even need to be a "real programmer," using Objective C to write a native iOS app. If you know JavaScript, you can use software called PhoneGap to access the iPhone accelerometer and notify ifttt whenever you detect movement.

Using PhoneGap

(Developing for the iPhone means paying $99 a year to Apple for a developers license, but strictly speaking, this isn't necessary if you like doing things the hard way. You can also jailbreak your iPhone, which allows arbitrary, third-party programs to run on it. For a first-gen iPhone, you might use directions like these. A jailbroken iOS 3 device will also need Cydia installed and set up with the http://cydia.iphone.org.hk/apt/ source to get the "Installd patch," which will allow arbitrary code to be run. On a first-gen device, be prepared to be very patient with Cydia. It's much, much easier just to pony up the cash.)

You'll need to register with the Apple Developer Center as an iOS developer (if you jailbreak, you don't have to go so far as paying the $99) to get access to Xcode and the iOS SDK, which is the programming environment you'll use. (Jailbreakers will need to create a self-signed signing certificate with which to sign their apps to stop Xcode from complaining. Again, it's easier to just pay the $99.)

If you're really using a first-generation iPhone or iPod Touch, they're limited to iOS 3, so you'll need an older version of PhoneGap (here's PhoneGap 0.9.6, which I used below). If you're using a newer device on iOS 4 or above, you should be fine with whatever the latest code is.

Follow PhoneGap's getting started instructions to set up a new project for your Xcode and PhoneGap version. Then, take a look at their documentation for the accelerometer (the only sensor you can access via PhoneGap): it provides a full example that shows regularly checking the accelerometer and displaying its values on the screen. Integrate the sample code with your new PhoneGap project and get it working on your iPhone (you can't test the accelerometer in the simulator).

We also don't want the iPhone shutting off when we're using it as a sensor platform. To do this, you have to tell the iPhone to not go idle. You can manually add Objective C code to do that as detailed here, or you can add the PowerManagement plugin to your project. Get that working and tested on your iPhone as well, since that's another thing you can't test in the simulator.

Connecting to ifttt

If you browse the channels list on ifttt, the only real way (as of this writing) to notify ifttt is via email. Triggers are checked every fifteen minutes: this means the associated action will only be notified that there was movement every fifteen minutes, even if movement happened multiple times (it'll get multiple notifications at that time).

There's no sense in being too sensitive with the iPhone, then. We can watch the accelerometer pretty frequently, say, every 100ms (ten samples a second). If there's been any change, we can save the value and compare it to the previous one, and only trigger within a certain threshold, say, >= 0.10 difference. If there's a great enough change, we can set a flag, and then once a minute, we can see if the flag has ever been set. If it has, we can clear it and send an email. When ifttt checks its email trigger, it'll send out at most fifteen notifications, and we can have it show when they were received.

For this toy app, set up a new task in ifttt. My task sends me a text message with the word "Movement!" and the timestamp whenever an email with a subject of "#twineapp9" (my app name) arrives.

In the application itself, you'll need to write some code that sends an email to ifttt. This is a little tricky: by default, the built-in mail handler on the iPhone shows you the email and makes you press send. We want to do it automatically, so we'll need to actually connect to a mail server and send it manually. Raw connections to internet servers are done using sockets, and the PhoneGap plugin that allows that is called GapSocket. GapSocket relies on two files from CocoaAsyncSocket, so pull all of those things down and add them to your app project in Xcode (if you're on iOS 3 and PhoneGap 0.9.6, GapSocket will work as-is, but you'll need an older version of CocoaAsyncSocket's AsyncSocket.m).

Sending email over the internet is done using SMTP. Your ISP or mail service might provide you instructions on how to use their mail servers in this way, but if you use Gmail, you're out of luck: Gmail requires a secure SSL connection for SMTP, and GapSocket doesn't let you do that (the underlying CocoaAsyncSocket code supports it, though; you could conceivably add support into GapSocket).

There are third-party services that don't require SSL, however. One of them is Mandrill, from the makers of MailChimp, in public beta as of this writing. You can sign up for a free MailChimp account, and then sign up for a beta Mandrill account, which would allow you to send 12,000 notification emails to ifttt. Either talk with your mail account provider for their SMTP settings (the code I'll give below requires no SSL or TLS, and SMTP AUTH LOGIN support), or sign up with Mandrill and set it up so the email address you registered with ifttt can send emails through Mandrill.

SMTP is a plain text, challenge-and-response protocol. The mail server says something, and then you say something, and then the mail server responds, back and forth. Each thing the mail server says starts with a code number, so we can look at that code and base our responses on that, based on where we think we are in the conversation. From our side, the conversation looks like this:

 HELO iphone.twineapp9.wifi.accelerometer.test
 AUTH LOGIN
 (base64-encoded username)
 (base64-encoded password)
 MAIL FROM:<(email address ifttt is expecting)>
 RCPT TO:<trigger@ifttt.com>
 DATA
 From: twineapp9 <(email address ifttt is expecting)>
 To: ifttt <trigger@ifttt.com>
 Subject: #twineapp9

 Movement!

 .
 QUIT

The mail server is responding in between each of those, starting with a 250 after the HELO, a 334 to request the username and password, a 235 to say they were accepted, a 250 after the valid commands, and 354 to say it's ready to accept the email itself, and a 250 after the period that terminates the email.

Write a little code that, once a minute, sees if any accelerometer events have happened in the last minute, and if so, opens a socket to your mail server and has that conversation listed above. If you like reading some truly amateur JavaScript, it might look something like this, but it really is just a toy: for example, I include some form fields in the HTML rather than hardcode everything, but I didn't include any way to save that data, so I have to re-enter all of my credentials every time I run the app.

Pics or it didn't happen

Once you have it all working (or if you use my toy code), you'll have an iPhone app that gives you a screen like this:

The toy "twineapp9" app

Provide the credentials, press "Start Watching" and wiggle the phone around and you'll see:

The toy "twineapp9" app with credentials

Within a minute, you'll see this in your Mandrill dashboard (or, presumably, your mail service's Sent folder):

Mandrill dashboard

Within fifteen minutes, your ifttt task will run, and the trigger will cause your action to run, visible in your ifttt activity log:

ifttt dashboard

My ifttt action was to send me a text message, which I successfully received:

Incoming text message

Left as an exercise for the reader

iPhones have two additional sensors: the ambient light sensor and the proximity sensor, neither of which is exposed by PhoneGap. A native iOS application in Objective C (or a PhoneGap plugin in the same) could, though.

If all you really wanted to do was send text messages, routing through iftttt via email via Mandrill via SMTP is a little circuitous. You could simplify it by using Mandrill's API instead of SMTP. You could you use a service like Twilio to send text messages directly. You could beg, borrow or steal access to Spool or Ninja Cloud. You could send the raw accelerometer data much more frequently to a service like Pachube instead.

iPhones and iPod Touches also have microphones: native iOS code could listen to the microphone and react based on noise or other ambient audio changes.

Three sensors isn't a lot, but hardware like the Square credit card reader demonstrates that the microphone jack can also be used for data collection. You could hook any custom sensor up that way (see Project HiJack or this blog post on using an Arduino for the same), as the dock connectors require special hardware (unless you have sensors that can talk over a serial port, in which case this serial cable from Redpark is for you).

I have no plans to or interest in building out this particular toy app into an experimental sensor platform for the App Store. But, hopefully I've demonstrated that even basic Internet of Things design and implementation work is possible with only a little bit of JavaScript knowledge and a disused iPhone as your sensor platform. This allows you to collect accelerometer data over wifi and practice working with and visualizing it without waiting for a new hardware platform to launch.

Colophon

This has detailed a toy IoT sensor platform app I wrote over the course of three nights the week of April 9, 2012. It took one night to jailbreak my first-gen iPhone and get the installd patch on it, a second night to figure out which PhoneGap version would work and test the accelerometer, and a third night to get the connection to ifttt working. I had been using my own mail server, but the Mandrill connection "just worked" and I took these screenshots as I was writing this document to serve as illustrations (my actual ifttt task has around 15 firings from last week).

This was produced as a demo for IxDA Austin's Making the Internet of Things meeting, April 17, 2012.

It's April 17, 2012. I'm Vitorio, thanks for reading.