Also from Andrew Faraday

Where else can you find me?

Wednesday, 26 June 2013

Introducing: The Teabot

Regular readers may notice that I've not written much in my blog recently. Meaning my Pure Data tutorials have dropped off slightly. I've been a little busy with a side-project of mine which has take n a lot of my spare time and thought to produce, and is mostly pointless. Anyway, here's a post telling you all about it, and hopefully I'll manage to explain some programming concepts while I'm at it...

Basically it started with the office teapot, which reflects some basic courtesy in hot beverages at my office. When you make a brew, make one for everyone, and alert folks to the fact that it's there. It's a simple workflow, but there's a few too many variables. I have a few basic issues with it, the teapot readily changes location, people forget (or "forget") to let you know it's there, and there's frankly not enough technology involved. 

This mild daily frustration, and, frankly, the fact that I quite like to play with technology, lead me to produce one of the more useful side-projects in my recent life. The Teabot, the idea was simply this:
  • Read a scale with a computer
  • Show the result on a web page
  • Let people know when the tea's ready to drink
This plan, being quite simple, lead me to explore methods of producing web pages with Ruby (my main programming language) which use much less processing power, memory and hard-drive space than Ruby on Rails (my main web framework). The result I settled on was Sinatra, which does just about nothing as standard except output the result of methods you write over http, the web standard for data transfer.

Then all I had to do was add in the RoR library for embedding ruby to generate files (erb, or embedded ruby) and I could create a front-end to the Teabot that didn't take too much out of the computer. That's exactly what I did, long before I got my hands on some USB readable scales to test it out on. I actually completed a first draft of the application entirely without it. The result looks something like this:

During development (as programmers often do, in the absence of hardware or software they are developing something to integrate with), I used a 'pretend' scale, or mock, which works like this. I know what a scale does, the computer asks it what the weight it's measuring is, and it passes the number back to the computer. This is what's known as a contract, describing how something will work, from the point of view of another application. So as far as my Teabot program's concerned:

  • A request goes to the scale 
  • The scale returns a number
So as long as the mock fulfils the same contract, the Teabot doesn't care whether or not it's a real scale. So I wrote a script that keeps asking me to type a number in, and the Teabot responds to that number in the same way (by saving the number to a file, which is read in various places in the application).

The next thing I had to think about is use cases which is, simply put, the ways in which a program will be used, you can think of these as the success conditions, when you can perform all your use cases the application is finished. Okay, this is a part-truth, but it's usually the right way to go about it. The Teabot is a very simple application, so I can think of around 4 simple use cases (using the standard software personalities, Alice and Bob):
  1. Alice wonders if there is tea, she opens the teabot page to see how much is in the pot, and how long it's been there.
  2. Bob makes a pot of tea, when it's brewed, Alice wants to know about it without constantly checking the page.
  3.  Alice makes a pot of tea, she would like Bob, and other co-workers (lets call them Charles and Deirdre), to know she made it, and what type of tea it is (she made Earl Grey this time).
  4. There are two teapots (used depending on how many people are in the office that day), if the teapot says full, it should mean the pot is full, whichever is being used. 
You can easily expand on these, for instance, a new teapot could be bought for formal occasions, a new 
co-worker could be added to the list, but these are essentially what should be possible. 

Use case one is simple, you can see the result in the screenshot above, users can't see the scale reading and refill-detection algorithm I created with my mocks, but they can see the level indicator in the teapot, and the time since the last refill was detected. 

Use case two means it has to provide users with similar information but in real-time. Now this presents a problem with a basic web interface. HTTP (protocol used to bring websites to your computer, there's loads to read about it online, if you wat to) works like this: Your computer sends a request, asking another computer (identified by a URL) for a particular page, the page is sent back to your browser which then displays it. Most of the time, you have to take some action to make the request, either typing in the address of a site and page, or clicking a link

To fix this, I've introduced polling, in which the Teabot main page automatically sends a request every 10 seconds, the Teabot app then sends back a response containing information about the teapot's current level and whether the other information on the page changes. 

But wait a second, all these people (Alice, Bob, Charles, Deirdre and perhaps someone beginning with E) have the Teabot open, and every ten seconds they're all sending a request, and only a small amount of the information on the page has changed (the headers, links, and footer are the same as well as the teapot image), so why should we re-load all of these?

Actually, the teapot doesn't reload everything every ten seconds, the polling request only returns the working data (who made the current pot, how full it is (in percent), what tea it is, when it was last made, and a few other odds and ends). This is then read (as JSON) and used to update relevant parts of the page are updated. 

There's an opportunity here for some stone soup, I could go in to the story of this term, but instead I could tell you what I mean by it. Stone soup refers to something which doesn't actually serve the purpose of the application, but which intrigues people and makes it seem interesting. In turn the interest generated makes it easier, politically or financially, to continue making it into a better application. 

The stone soup in the Teabot takes the form of an animated teapot! It's actually fairly simple, the outside of the teapot is an image with a transparent space in the centre of it (the outside of this image is the same colour as the background), there's a white space behind it, and a darker brown block between the two which changes it's size to indicate the level of the tea. Using the jQuery 'animate' method the tea moves up and down when the amount of tea in the pot on the scale changes. 

So far, everyone who's seen it working has been fascinated to see this happen, and this has helped me to discuss the future direction of the Teabot with my co-workers, and helped me to spend a little time at work on the Teabot. The little bit of interest generated in it allowed me a little extra resources to make it better, stone soup!

One of the pieces of data returned every ten seconds is whether or not to notify users that tea's ready. This gave me the opportunity to explore the HTML5 audio tag. I'm not going in to detail here, but 5 minutes after a new pot is detected, teabot plays a sample of my own dulcet tones declaring "There's tea!". 

This sounds like stone soup, but it's very directly meeting the conditions for our second use case. When the tea's had time to brew, it only takes one computer open and audible in each room of our office and everyone knows it's ready. In the second day of testing this in my office, there's an almost Pavlovian response, within a minute of this sound the brew-wanting masses descend on the teapot. Usually, a conversation ensues. 

Use cases 3 and 4 are fairly simple, there's a form to add pourers and teas, and a simple page called the "Teapot Station Interface" where, most of the time, users can simply click their name and/or the name of the tea, and change which one's currently in use.

Hidden under the Show List Manager link, there's a simple way to add to these lists.

You'll also notice a list of teapots there, which hints at the fourth use-case. You'll see at the top the button 'Calibrate Scale', this leads to a simple Wizard (multi-step form) which gathers three pieces of data about a teapot...

  • How heavy it is with nothing in
  • How heavy it is when it's got one cup of water in
  • How heavy it is when it's completely full
You can then give it a name, and it' on the list. This allows us to find the percentage of the teapot that's currently full of tea, and also, you guessed it, about how many cupfuls are left. 

That's pretty much what it does, and hopefully I've explained a bit about how I go about making web applications. I've not gone into much detail here, but there is one thing I had HUGE problems with that I've not talked about here. 

I could find nothing at all online which told me how to go about reading data from USB (from the scale) and how to go about interpreting this in ruby. So, mark my words, there will be a post giving you a step-by-step rundown of how I went about making the teabot happen. 

Oh, very last thing, here's what it actually looks like, in development at my flat, and at the office.

Oh, and the scale with my prototype hardware branding...

Also, if you're au fait with github, you can go there and take a look at the Code for the Teabot there. And as ever, I'm always up for discussing my fun coding, so feel free to get in touch on twitter (@MarmiteJunction) and have a chat, ask any questions, look into how to get your own teabot, whatever you fancy. Or just leave me a comment here. 

1 comment:

  1. I did not know about this app but after reading about it I am desperate to use this app,programming is definitely not easy !Hat's off to you.