pebble
  • Tutorials
  • Get the SDK
  • Guides
  • Documentation
  • Examples
  • Community
  • Blog
  • More
Privacy
Cookies
Publish
Get Updates
Follow Us
Subscribe to the Newsletter

Pebble and the Wolfram Cloud

  • 16 January 2015
  • Arnoud Buzing, Wolfram Research
  • At the Pub
  • Comments

This is a guest blog post by Arnoud Buzing at Wolfram Research about how to use the power of the Wolfram Cloud in a Pebble watchapp. You can find out more information about the Wolfram Cloud in the links posted throughout the post. Enjoy!

Greetings!

In this post I will describe how to create an app for the Pebble watch that uses the Wolfram Cloud.

The Wolfram Cloud offers an integrated solution for data storage and knowledge-based computing using the Wolfram Language, a high level programming language. Specifically in this post, I will use so-called 'instant APIs' which allows you to associate an arbitrary Wolfram Language computation with a uniquely generated URL (we call them 'Cloud Objects'). This means that you can use any function from the Wolfram Language (over 5,000 high level functions) and any Wolfram|Alpha functionality (including all data from its underlying Wolfram Knowledgebase) and expose this in your Pebble app.

So let's get started by making a sample app!

First let's look at the user interface of this app and how to navigate to the various elements. The app opens with a splash screen listing its app title and which action to take to continue ('Press SELECT'):

splash

Upon pressing SELECT (the middle button on the right-hand side of the Pebble watch), you are offered a menu list with seven choices. You can scroll to each choice by using the UP and DOWN buttons (also on the right-hand side of the Pebble watch). Here is a table of images of each menu item and the result window that is shown when a particular menu item is selected (with the SELECT button).

Menu Selection Result of Computation
date date2
ip ip2
location location2
temperature temperature2
version version2
sunset sunset2
stock stock2

So now we need to create Wolfram Cloud 'instant API' calls for each of the individual menu items. I will show one example here, the remaining six are similar and the full source code can be obtained from this URL (cloud object): https://www.wolframcloud.com/objects/c68a118b-ad29-4ebf-b330-d1f4549d8ecb.

This utility function creates a named cloud object (using name) and an expression you want it to execute, like DateString[]:

Attributes[CreateCloudObject]={HoldAllComplete};
CreateCloudObject[name_String,expr_]:=Module[{cloudObject,apiFunction},
  cloudObject=CloudObject["pebble/"<>name];
  apiFunction=APIFunction[{},ExportForm[{"result" ->ToString[expr]}, "JSON"] &];
  CloudDeploy[apiFunction, cloudObject, Permissions -> "Public"]
]

Then for each menu item you create one cloud 'instant API' function:

CreateCloudObject["date",DateString[]]

That's all the code that it required on the Wolfram Cloud side.

Next, we need to write the app for the Pebble. Pebble provides an online cloud IDE for this called CloudPebble. One of the options is the use Pebble.js, a javascript environment which Pebble uses to control a binary application that is executed on the watch.

The full javascript source code is included at the bottom of this post. Here are a few key highlights of this implementation.

First import the required libraries and set the base URL for all the cloud calls:

var ui = require('ui');
var ajax = require('ajax');
var base = 'https://www.wolframcloud.com/objects/user-7053ce31-817f-4643-aec1-eda27051bba6/pebble/';

Define the splash card (window) and show it on the watch:

var main = new ui.Card({
  title: ' Wolfram',
  icon: 'images/wolfram.png',
  subtitle: 'Cloud App',
  body: 'Press SELECT' 
});

main.show();

This code is part of the SELECT click handler and defines the menu that is shown to the user:

var menu = new ui.Menu({
  sections: [{
    items: [
      { title: 'DateString[]', subtitle: 'get the date' }, 
      { title: '$RequesterAddress', subtitle: 'get the ip' }, 
      { title: '$GeoLocation', subtitle: 'get the location' }, 
      { title: 'WeatherData[]', subtitle: 'get the temperature' }, 
      { title: '$Version', subtitle: 'get the version' },
      { title: 'Sunset[]', subtitle: 'get the sunset' }, 
      { title: 'FinancialData', subtitle: 'get a stock' }]
  }]
});

menu.show();

This code is executed when the user selects a given menu item:

switch(e.itemIndex) {
  case 0: displayResults( base + 'date', 'DateString[]' ); break;
  case 1: displayResults( base + 'address', '$RequesterAddress' ); break;
  case 2: displayResults( base + 'location', '$GeoLocation' ); break;
  case 3: displayResults( base + 'weather', 'WeatherData[Here,"Temperature"]' ); break;
  case 4: displayResults( base + 'version', '$Version'); break;
  case 5: displayResults( base + 'sunset', 'Sunset[]'); break;
  case 6: displayResults( base + 'stock', 'FinancialData["GE"]'); break;
  default: console.log('e.itemIndex is out of bounds: ' + e.itemIndex);
} 

The displayResults function is a function which shows a temporary 'Loading' card and then retrieves the cloud 'instant API' result from the cloud and displays it:

function displayResults(url, title) {
  var wait = new ui.Card({title: 'Loading...', subtitle: 'Please wait'});
  wait.show();
  ajax( { url: url, type:'json' }, 
    // success
    function(json) {
      var result = new ui.Card({ title: title, body: json.result });
      result.show();
      wait.hide();
    }, 
    // error
    function(error) {
      console.log('Error during displayResults');
      console.log(url);
      console.log(title);
    });
}

And that's it! You can now upload the app to your watch from the Pebble cloud IDE and make calls to the Wolfram Cloud! And it's easy to completely customize it with any Wolfram Language function you find useful.

And finally, here is the complete Pebble.js source code for this sample project:

var ui = require('ui');
var ajax = require('ajax');

var base = 'https://www.wolframcloud.com/objects/user-7053ce31-817f-4643-aec1-eda27051bba6/pebble/';

var main = new ui.Card({
  title: ' Wolfram',
  icon: 'images/wolfram.png',
  subtitle: 'Cloud App',
  body: 'Press SELECT'
});

main.show();

main.on('click', 'select', function(e) {
  var menu = new ui.Menu({
    sections: [{
      items: [
        { title: 'DateString[]', subtitle: 'get the date' }, 
        { title: '$RequesterAddress', subtitle: 'get the ip' }, 
        { title: '$GeoLocation', subtitle: 'get the location' }, 
        { title: 'WeatherData[]', subtitle: 'get the temperature' }, 
        { title: '$Version', subtitle: 'get the version' },
        { title: 'Sunset[]', subtitle: 'get the sunset' }, 
        { title: 'FinancialData', subtitle: 'get a stock' }]
    }]
  });

  menu.show();

  menu.on('select', function(e) {
    switch(e.itemIndex) {
      case 0: displayResults( base + 'date', 'DateString[]' ); break;
      case 1: displayResults( base + 'address', '$RequesterAddress' ); break;
      case 2: displayResults( base + 'location', '$GeoLocation' ); break;
      case 3: displayResults( base + 'weather', 'WeatherData[Here,"Temperature"]' ); break;
      case 4: displayResults( base + 'version', '$Version'); break;
      case 5: displayResults( base + 'sunset', 'Sunset[]'); break;
      case 6: displayResults( base + 'stock', 'FinancialData["GE"]'); break;
      default: 
        console.log('e.itemIndex is out of bounds: ' + e.itemIndex);
    } 
  });
});

function displayResults(url, title) {
  var wait = new ui.Card({title: 'Loading...', subtitle: 'Please wait'});
  wait.show();
  ajax( { url: url, type:'json' }, 
    // success
    function(json) {
      var result = new ui.Card({ title: title, body: json.result });
      result.show();
      wait.hide();
    }, 
    // error
    function(error) {
      console.log('Error during displayResults');
      console.log(url);
      console.log(title);
    });
}

You need JavaScript enabled to read and post comments.
Get Updates
Follow Us
Subscribe to the Newsletter

Categories

  • All Posts
  • #makeawesomehappen
  • At the Pub
  • Beautiful Code
  • CloudPebble
  • Down the Rabbit Hole
  • Freshly Baked
  • Timeline

Authors

  • Thomas Sarlandie
  • Niharika Bedekar
  • Katharine Berry
  • Jon Barlow
  • Cherie Williams
  • Chris Lewis
  • Team Pebble
  • Katherine McAuliffe
  • Cat Haines
  • Alex Lin
  • Kirby Kohlmorgen
  • Brad Murray
  • Alexey Komissarouk
  • Ɓukasz Zalewski
  • Tom Maremaa
  • Ryan Case
  • Ryan Perry-Nguyen
  • Keegan Lillo
  • Meiguro

Subscribe to the Pebble Developers Newsletter