Dial-O-Spresso – a phone controlled coffee machine

You’ve got a fancy instant espresso coffee maker but you miss talking to your barista? Crisis averted, Ninja Blocks & Twilio are here to help.

NinjaBlocks made this hack as a bit of fun for the recent TwilioCon conference in San Francisco. It might not be 100% practical, however it is a great demonstration of how easy it is to create high-level apps with the Ninja API.

Dial-O-Spresso from ninjablocks on Vimeo.

Lets take a look at how they did it.

The Hardware

They have connected 3 wired relays (made with the the Ninja Breakout Kit) to the buttons of the machine (an Espressi, which is a $79 Nespresso knockoff).

Certainly not the most elegant solution, but it does look cool. Also by using standard relay boards they just pop up on the Ninja dashboard auto-magically when they are plugged in. The developers then used the dashboard widgets to toggle them and figure out which is which so the developers could give them meaningful names.

The Software

Using the Ninja Blocks node library and the Twilio node library there really isn’t much too it. Because its a hack which is just hardcoded Ninja API token (which means no messing with OAuth) and Twilio credentials.

The only slightly tricky part was “pressing” the buttons because the machine uses long presses for programming. You’ll see the developers pressed the buttons for a second to turn it on and make the coffee and for 5 seconds to turn it off.

1. var ninjaBlocks = require(ninja-blocks);
2. // IMPORTANT – express 2.x must be availailable for the node-twilio lib to work
3. var TwilioClient = require(twilio).Client,
4. Twiml = require(twilio).Twiml;
5.
6. // Instantiate a Ninja Blocks client – get your _user_access_token from a.ninja.is/hacking
7. var ninja = ninjaBlocks.app({user_access_token:YOUR_API_TOKEN});
8.
9. // Instantiate a Twilio client and phone number – note the host must be publicly accessible
10. var client = new TwilioClient(TWILIO_SID, TWILIO_TOKEN, HOSTNAME);
11. var phone = client.getPhoneNumber(+14158309667);
12
13. var STR = {
14. POWER : Power,
15. SHORT : Espresso,
16. LONG : Long Black
17. }
18.
19. // Fetch our ninja devices
20. ninja.devices(function(err,devices) {
21. if (err) {
22. throw Error fetching devices: “+ err.error +
23. } else {
24.
25. // Create a quick map of device name to guid and check that the required relays exist
26. var guids = {};
27. Object.keys(devices).forEach(function(guid) {
28. guids[devices[guid].shortName] = guid;
29. });
30. if (!guids[STR.POWER] || !guids[STR.SHOT] || !guids[STR.LONG]) {
31. throw ERROR: You must have relays named “+STR.POWER+“, “+STR.SHORT+“, and “+STR.LONG+
32. }
33.
34. phone.setup(function(){
35. // Listen for incoming calls
36. phone.on(incomingCall, function(reqParams,res){
37.
38. res.append(new Twiml.Say(Hi there . . . Coffee is delicious! . . . Would you like a cup?));
39. res.append(new Twiml.Pause());
40.
41. // Gather a response from callers (times out after 5 seconds)
42. var gather = new Twiml.Gather(new Twiml.Say(Press 1 for Espresso, Press 2 for Long Black));
43. gather.on(gathered,function(gParams,gRes){
44. var choice = never enough;
45. if (gParams.Digits == 1){
46. coffee.pour(STR.SHORT);
47. } else if (gParams.Digits == 2) {
48. coffee.pour(STR.LONG);
49. } else {
50. choice = bad for you;
51. }
52. // send positive reinforcement
53. gRes.append(new Twiml.Say(Good choice. Too much coffee is +choice)).send();
54. });
55. // send twiml response to twilio
56. res.append(gather).send();
57. });
58.
59. })
60.
61. var coffee = {
62. // using a relay to do a button press requires the relay to be turned on (press
63. // down) and turned off (relase). This machine goes into programming mode if the
64. // button is held too long, and doesn’t trigger if not pressed long enough
65. pressButton : function(relayName, delay) {
66. ninja.device(guids[relayName]).actuate(1);
67. setTimeout(function(){ninja.device(guids[relayName]).actuate(0)},delay);
68. },
69. pour : function(coffeeType){
70. // Power up machine with a short press of the power button
71. coffee.pressButton(STR.POWER,1000);
72. // wait 5 seconds for machine to start then press appropriate coffee button
73. setTimeout(function(){
74. coffee.pressButton(coffeeType,1000)}
75. ,5000);
76. // wait 20 seconds then power down machine with a long press
77. setTimeout(function(){
78. coffee.pressButton(STR.POWER,5000)}
79. ,25000);
80. }
81. };
82.
83. // Test pour on start
84. // coffee.pour(STR.SHORT);
85. }
86. });
view rawcoffee.js hosted with ❤ by GitHub
1. {
2. name: dial-o-spresso,
3. author : @askpete,
4. version: 0.0.1,
5. dependencies: {
6. express: 2.x,
7. ninja-blocks : latest,
8. twilio : latest
9. }
10. }
view rawpackage.json hosted with ❤ by GitHub

I hoped you enjoyed seeing this hack.

Links:

We will be happy to hear your thoughts

Leave a reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.