Introduction
What is it?
The Internet of Things Assistant is a Ruby on Rails application that can act as a front-end for an Adafruit Internet of Things Printer. It turns your IoT Printer into a handy assistant that will print out snippets of information you tell it to at a certain time each day, or on demand.
Screenshots
A picture tells a thousand words.
Features
- Multi-user support. Any number of users can share one printer (for example a team in an office, or a family at home).
- A web-based interface to pick what you want printed and when.
- Scheduled-based printing; print once a day at the time you specify on the days you specify.
- On-demand printing; print whenever you like at the touch of a button.
- Administration interface for configuring your Assistant; e.g. disallowing new user creation and downloading the code for your Printer.
- The application can be deployed on Heroku.
In addition, the following ‘modules’ for the printouts are included by default:
- Google Calendar daily agenda.
- Unread email count + top 3 emails in your inbox.
- A fortune cookie (if fortune is installed, unfortunately not available on Heroku).
- Recent news stories from The Times.
- Latest tweets from your Twitter timeline.
Contact and Contribution
Getting in touch
You can email the Research & Development Laboratory or contact @jalada or @petermacrobert on Twitter.
Contributing
- Please feel free to fork and submit a pull request.
- You can also raise an issue on Github if you find a bug!
Getting Started
Requirements for deployment
- Ruby 1.9 (tested on Ruby 1.9.2)
- Rubygems
- SQL database (tested with PostgreSQL and MySQL)
- Bundler
If you are going to deploy to Heroku, you do not need these things set up locally.
Get the code
All the code is available on Github, you can download a copy using Git:
git clone git://github.com/newsinternational/iot-assistant.git
Or you can download it as a Zip file.
Configuration
Configuration is done through config/config.yml which by default uses environment variables (which is suitable for deployment to Heroku). You can change config.yml for your set-up, but we advise using environment variables as part of the Twelve-Factor App methodology. The environment variables are listed below.
| Variable | Description |
|---|---|
GOOGLE_CLIENT_ID |
Your application's Google OAuth 2.0 Client ID. See the 'Google' section below for more information. |
GOOGLE_CLIENT_SECRET |
Your application's Google OAuth 2.0 Client Secret. See the 'Google' section below for more information. |
TWITTER_CONSUMER_KEY |
Optional. Your application's Twitter Consumer Key. See the 'Twitter' section below for more information. |
TWITTER_CONSUMER_SECRET |
Optional. Your application's Twitter Consumer Secret. See the 'Twitter' section below for more information. |
SIGNUPS_ENABLED |
Whether to allow new user signups or not. Default is true. |
PRINTER_KEY |
A secret unique string (valid in a URL) that makes up part of the URL the IoT Printer itself polls to check for printouts. This is a simple security through obscurity to avoid others scraping your printouts. |
IoT Assistant requires a set of Google API keys for authentication, and accessing the user’s calendar and email. In the future these may be optional, but as these are core features of the printout Google API access is required, and as such it is also used for logging in to the application.
For more information about using OAuth 2.0 to access Google APIs, have a look at Google’s documentation. In short, create an application using the Google API console, set up OAuth 2.0 for that application and then copy the client ID and secret. The callback URL should be set based on where you are going to deploy IoT Assistant, for example:
http://my-iot-assistant.herokuapp.com/auth/google/callback
Also ensure the application has access to the calendar API, this can be switched on in the ‘Services’ section of the Google API console for the application.
You can optionally configure IoT Assistant with a set of Twitter OAuth keys so that users can opt to have their printout include recent tweets from people they follow. You can get a set of these from the Twitter Developer site.
Deployment
On Heroku
You need a Heroku account in order to deploy to Heroku. It’s free to sign up.
-
Having cloned down a copy of the code and obtained all the necessary API credentials, change into the directory the code resides in.
-
Install the Heroku toolbelt.
-
Create a new Heroku app (pick a unique name), remember to pick the Cedar stack:
$ heroku apps:create davids-iot-assistant --stack cedar Creating davids-iot-assistant... done, stack is cedar http://davids-iot-assistant.herokuapp.com/ | git@heroku.com:davids-iot-assistant.git Git remote heroku added $ -
Give Heroku your API keys and configuration. Here’s a complete example set:
$ heroku config:add \ > GOOGLE_CLIENT_ID="1234.apps.googleusercontent.com" \ > GOOGLE_CLIENT_SECRET="DPk7lQsWS1CrzaMuVfD" \ > TWITTER_CONSUMER_KEY="Yn3pPCweFENRmku6AABgY" \ > TWITTER_CONSUMER_SECRET="PioxXkHoHRb2bCIwRecx0SaED" \ > SIGNUPS_ENABLED=true \ > PRINTER_KEY=asf324tdsf2 Adding config vars and restarting app... done, v2 GOOGLE_CLIENT_ID => 1234.apps.googleusercontent.com GOOGLE_CLIENT_SECRET => DPk7lQsWS1CrzaMuVfD TWITTER_CONSUMER_KEY => Yn3pPCweFENRmku6AABgY TWITTER_CONSUMER_SECRET => PioxXkHoHRb2bCIwRecx0SaED SIGNUPS_ENABLED => true PRINTER_KEY => asf324tdsf2 $ -
Now push the code to Heroku:
$ git push heroku master Counting objects: 7, done. Delta compression using up to 4 threads. Compressing objects: 100% (4/4), done. Writing objects: 100% (4/4), 379 bytes, done. Total 4 (delta 3), reused 0 (delta 0) -----> Heroku receiving push <snip> -----> Compiled slug size is 20.6MB -----> Launching... done, v3 http://davids-iot-assistant.herokuapp.com deployed to Heroku $ -
Set up the Heroku database:
$ heroku run rake db:setup Running rake db:setup attached to terminal... up, run.1 -- create_table("printouts", {:force=>true}) -> 0.1443s -- create_table("users", {:force=>true}) -> 0.0780s -- initialize_schema_migrations_table() -> 0.0009s -- assume_migrated_upto_version(20120402101359, ["/app/db/migrate"]) -> 0.0014s $ -
You’re done! Now go visit your Heroku app (whatever name you gave it) and log in. The first user that logs in will be the first admin user.
Setting up your printer
You should probably be familiar with the basics of the Arduino development process. Given that you have bought an IoT Printer, this documentations assumes you are.
-
Assemble your IoT Printer.
-
Log in to your IoT Assistant and click on Admin, then ‘Printer’.
-
Fill in the form. Make sure the auto-filled server and URL look correct.
-
Click to download the .ino file.
-
Open it in the Arduino IDE (you will probably get a prompt about moving it to a folder. Accept. If it fails, do it yourself).
-
Compile and upload to your IoT Printer Arduino.
-
You’re all set! Hook it up to a network and try manually printing something from your IoT Assistant (on the home page when you are logged in).
If you have problems, try using the serial console which will output some debug information.
How it works
Architecture
IoT Assistant is a Ruby on Rails application which provides the web-based interface for users and also sends printout information to the associated printer. Only one printer can be associated with an instance of the IoT Assistant (because as printouts are fetched by the printer they are automatically removed from the queue as they are considered ‘printed’). Future versions of IoT Assistant may support a multiple printer deployment scenario (it’s on the roadmap).
When a user configures a scheduled print, or requests a print on demand, a printout is constructed. This is in a machine-readable format (but also very human readable) and contains information for the printer telling it how the text should be styled and what to print out.
The IoT Printer repeatedly polls a URL configured during deployment, and this URL contains either the latest printout scheduled, or nothing (if no printouts are scheduled). The URL for this is /printer/:secret where :secret is defined in the configuration. This stops anyone guessing the URL if they know you have the app deployed.
Printer file format
The IoT Printer is loaded with a program to fetch + parse from a particular endpoint. If the endpoint returns a blank file, it doesn’t print anything, otherwise it attempts to parse what it receives.
The code has very little error-handling, so you must make sure your output is well formatted.
Each line must be of the following format (the chevrons are not present in the final file):
<s><j> <line>
where:
-
s is the style of the line. This can be one of:
- n for normal text.
- b for bold text.
- u for underlined text.
- i for inverse (white on black) text.
-
j is the justification of the text. This can be one of:
- l for left justification.
- c for center justification.
- r for right justification.
these two characters must then be followed by a space, and then the rest of the text on the line will be printed. Unexpected behaviour may occur if there is nothing in <line>. For blank lines, use something like nl followed by at least 2 spaces.
- Do not omit the control characters, you are likely to get unexpected results (e.g. missing letters on lines, wrongly formatted text, or missing lines entirely).
- Do not start lines with whitespace, I don’t know what happens if you do, but please fix the Arduino code so that it accepts it, because lack of indentation is a pain.
- The printer prints 32 characters per line and will perform automatic line-breaks mid word. For optimum formatting, you should line-break your text in Ruby if possible.





