Home

Processing is a simple programming language to create interactive graphics and visualisations. In contrast to photoshop, gimp, omnigraffle, etc. the big benefit of Processing is that it makes it very easy to embed interactive elements into a graphic. It is Open Source and comes with many plug-ins / libraries that enable communication with other software and hardware platforms. You can for example make a graphic respond to your mouse movement, keyboard entries, sensor-data coming from a microcontroller or selected live-feeds from the Internet.

Here is a short tutorial how to create an interactive graphic that responds to external data. I just ran a 101 “Bread n Butter” introduction workshop on Processing at The Edge / State Library of Queensland in Brisbane and will use the same example scenario here. We will create a thermometer visualisation that is fed by real-time temperature sensor data for different cities from Pachube, an online sensor data streaming platform. The final visualisation looks something like this:

 

Thermometer graphics fed with real-time temperature data from Pachube

Thermometer graphics fed with real-time temperature data from Pachube

 

Here’s how you do it:

1) If you haven’t done anything in Processing before, the best way to get started are the tutorials on the official Processing website: http://www.processing.org/learning/. You don’t need to go through all of them for now, but check out Getting Started, Overview and Coordinate System and Shapes. That will be enough to give you a smooth start, and be ready for the next step, even if you’re completely new to the world of programming and Processing.

 

2) Test your skills and try to build a thermometer sketch from what you’ve just learned in the short tutorials above. Here’s the source code of my thermometer. Not very cute, but it does the job for now;)

 

void setup(){

 size(500, 500);
}

void draw() {

 //fill background in gray
 fill (227,227,227);
 smooth();

 //build thermostat
 rectMode(CORNER);
 rect (50, 50, 20, 200);
 ellipse (60, 270, 40, 40);

 //build quicksilver reservoir
 fill(255, 0, 0);
 ellipse (60, 270, 20, 20);

 //quicksilver
 rect(57, 57, 6, 200);

 //define stroke
 stroke (255,0,0);
 strokeWeight(2);

}
Static thermometer graphic build in Processing

Static thermometer graphic build in Processing

 

 

3) In order to make our thermostat represent real-time temperature, we need to connect it with a data source that provides real-time temperature for different cities. We’ll use Pachube for this example. Pachube a popular platform for real-time sensor data sharing. You can think of it as YouTube for sensor data. Anyone can upload any sensor data to Pachube and make them openly accessible for others through so-called “feeds”. For our thermometer, we will work with a weather station “feed” from Perth. This feed, when called through Processing, returns real-time temperature data for Perth in various formats, such as JSON, XML or CSV. You won’t need to deal with those data structures manually, as Processing provides a library that does the job for us.

 

4) This Processing library is called eeml library and that makes it very easy to send requests and process data from Pachube. You can download the latest eeml library here. Unzip the download and move the “eeml” folder to the Processing’s library folder, i.e. a folder called “libraries” within the Processing installation folder / default Sketchbook location. If you don’t know where your Processing installation folder is go on Menu -> Processing -> Preferences and you can see the path marked as “Sketchbook location”. Restart Processing so the new eeml library can be used.

 

5) Now we’re ready to feed data from Pachube through Processing. The eeml-library comes with  is a nice example that provides a skeleton code for handling communication to and from Pachube. However, you first need to register with Pachube and create your own API key. Copy/paste your personal API key to the PACHUBE-KEY variable in below’ code.

 

 
// Basic example to retrieve data from an existing Pachube feed
import eeml.*;

DataIn dIn_perth;
final String PERTH_FEED = "http://api.pachube.com/api/22587.xml";
final String PACHUBE_KEY = "YOUR_PACHUBE_API_KEY"; 
float temp;

void setup(){
    size(500, 500);
    // set up DataIn object; indicate the URL you want, your Pachube API key, and how often you want it to update, e.g. every 3000 milliseconds    
    dIn_perth = new DataIn(this, PERTH_FEED, PACHUBE_KEY, 3000);
}

void draw() {
}
// onReceiveEEML is run every time your app receives back EEML that it has requested from a Pachube feed. 
void onReceiveEEML(DataIn d){ 
    String url = d.getURL();
    temp = d.getValue("temperature");
    println(url);
    println(temp);
}

 

If you run this script, you should see the current temperature values being printed in the console. Our selected weather channel  for Perth has several sensor data, such as temperature, light, humidity, noise, air quality, etc. Since we are only interested in temperature we select temp = d.getValue(“temperature”);

 

Console shows real-time temperature received from the Pachube API

Console shows real-time temperature received from the Pachube API

 

 

6) Note that the draw() method in step 5 is empty. That’s why you didn’t see any visual outputs, but only sensor data printed in the console. The next step is to combine the source code from step 2 and step 5, i.e. feed the static thermometer graphic with real temperature data from Pachube. Copy/Paste the draw() method from step 2 to the code of step 5. Your result should look something like this:

 

import eeml.*;
DataIn dIn_perth;

final String PERTH_FEED = "http://api.pachube.com/api/22587.xml";
final String PACHUBE_KEY = "YOUR_PACHUBE_KEY";
float temp;
void setup(){

 size(500, 500);

 // set up DataIn object; indicate the URL you want, your Pachube API key, and how often you want it to update
 // e.g. every 3000 milliseconds 

 dIn_perth = new DataIn(this, PERTH_FEED, PACHUBE_KEY, 3000);
}
void draw()
{
//fill background in gray
 fill (227,227,227);
 smooth();

 //build thermostat
 rectMode(CORNER);
 rect (50, 50, 20, 200);
 ellipse (60, 270, 40, 40);

 //build quicksilver reservoir
 fill(255, 0, 0);
 ellipse (60, 270, 20, 20);

 // quicksilver
 // rect(57, 57, 6, 200);

 //quicksilver
 float thermometer_value = map(temp,0,40,200,0);
 rect(57, 57 + thermometer_value, 6, (200 - thermometer_value));

 //define stroke
 stroke (255,0,0);
 strokeWeight(2);

}
// onReceiveEEML is run every time your app receives back EEML that it has requested from a Pachube feed.
void onReceiveEEML(DataIn d){
 String url = d.getURL();
 temp = d.getValue("temperature");

 println(url);
 println(temp);
}

 

Note the little adjustment of the red-filled rectangle that represents the quicksilver. These two lines of code will make it dynamically respond to the temperature data, i.e. temp variable.

 //quicksilver
 float thermometer_value = map(temp,0,50,200,0);
 rect(57, 57 + thermometer_value, 6, (200 - thermometer_value));

 

The quicksilver needs to go up and down according to the temperature value temp. The thermostat is 200 pixels high, whereas we assume our temperature will be somewhere between 0 and 50 Celsius. I use the map function to re-map the temp variable from the temperature range (0-50) to the pixel range (200-0). For higher temperatures, we need a higher quicksilver rectangle, i.e. a lower y-value. That’s why we do reverse mapping to the range of 200-0 rather than 0-200. Don’t forget to subtract the mapped thermometer_value from the rectangle’s lower bound, so you keep the quicksilver in the thermometer.

 

7) Last but not least, we’ll create a label so know what exact value and city the thermometer represents.

 

Dynamic thermometer graphic with a label that shows the exact temperature value

Dynamic thermometer graphic with a label that shows the exact temperature value

 

Just paste following code at the end of the draw() method.

//draw font
 textFont(f,20);
 text ( "Perth", 35, 330);
 text ( "(" + temp + ")", 35, 360);

 

and make sure to initialise a font variable in the beginning of the script

PFont f;

 

and specify in the setup() method what font the label should have, e.g.

f = createFont("Arial",20);

 

If you run the script now, you’ll see a how different temperature values overwrite each other after a while. To avoid this just redraw the background at the beginning of each loop:

background(211,211,211);

 

The final code should look similar to this:

import eeml.*;
PFont f;
DataIn dIn_perth;

final String PERTH_FEED = "http://api.pachube.com/api/22587.xml";
final String PACHUBE_KEY = "YOU_PACHUBE_KEY";
float temp;
void setup(){

 size(500, 500);
 f = createFont("Arial",20);

 // set up DataIn object; indicate the URL you want, your Pachube API key, and how often you want it to update
 // e.g. every 3000 milliseconds 

 dIn_perth = new DataIn(this, PERTH_FEED, PACHUBE_KEY, 3000);
}
void draw()
{
//fill background in gray
 background(211,211,211);

 fill (227,227,227);
 smooth();

 //build thermostat
 rectMode(CORNER);
 rect (50, 50, 20, 200);
 ellipse (60, 270, 40, 40);

 //build quicksilver reservoir
 fill(255, 0, 0);
 ellipse (60, 270, 20, 20);

 //quicksilver
 float thermometer_value = map(temp,0,50,200,0);
 rect(57, 57 + thermometer_value, 6, (200 - thermometer_value));

 //define stroke
 stroke (255,0,0);
 strokeWeight(2);

 //draw font
 textFont(f,20);
 text ( "Perth", 35, 330);
 text ( "(" + temp + ")", 35, 360);

}
// onReceiveEEML is run every time your app receives back EEML that it has requested from a Pachube feed.
void onReceiveEEML(DataIn d){
 String url = d.getURL();
 temp = d.getValue("temperature");

 println(url);
 println(temp);
}

 

 

8 ) If you want you can take this further and display a number of thermometers for different cities within one Processing script. You’ll need to include dedicated feeds for the cities that you want to represent. Find below an example for Berlin, Beijing and Perth.

 

Thermometer graphics fed with real-time temperature data from Pachube

Thermometer graphics fed with multiple real-time temperature streams from Pachube

 

 

import eeml.*;
PFont f;
DataIn dIn_berlin;
DataIn dIn_beijing;
DataIn dIn_perth;
final String BERLIN_FEED = "http://www.pachube.com/api/17475.xml";
final String BEIJING_FEED = "http://www.pachube.com/api/17473.xml";
final String PERTH_FEED = "http://api.pachube.com/api/22587.xml";
final String PACHUBE_KEY = "01b252e6eb9bdcc5554fbed108fcd673be05a31d5bc54de12830ec3aedc0bc1d";
float temp;
float[] temp_values = new float[3];
void setup(){

 size(500, 500);
 background(211,211,211);
 f = createFont("Arial",20);

 // set up DataIn object; indicate the URL you want, your Pachube API key, and how often you want it to update
 // e.g. every 15 seconds 

 // Berlin - Weather Tunnel
 dIn_berlin = new DataIn(this, BERLIN_FEED, PACHUBE_KEY, 3000);
// Beijing - Weather Tunnel
 dIn_beijing = new DataIn(this, BEIJING_FEED, PACHUBE_KEY, 3000);

 // Perth - Weather Tunnel
 dIn_perth = new DataIn(this, PERTH_FEED, PACHUBE_KEY, 3000);
}
void draw()
{
 background(211,211,211);
 smooth();
 // THERMOSTAT 1
 //fill background in gray
 fill (227,227,227);

 //build thermostat
 rectMode(CORNER);
 rect (50, 50, 20, 200);
 ellipse (60, 270, 40, 40);

 //build quicksilver reservoir
 fill(255, 0, 0);
 ellipse (60, 270, 20, 20);

 //quicksilver
 float thermometer_value = map(temp_values[0],0,40,200,0);

 rect(57, 57 + thermometer_value, 6, (200 - thermometer_value));

 //define stroke
 stroke (255,0,0);
 strokeWeight(2);

 //draw font
 textFont(f,20);
 text ( "Berlin", 30, 350);
 text ( "(" + temp_values[0] + ")", 30, 380);

 // THERMOSTAT 2
 //fill background in gray
 fill (227,227,227);

 //build thermostat
 rectMode(CORNER);
 rect (150, 50, 20, 200);
 ellipse (160, 270, 40, 40);

 //build quicksilver reservoir
 fill(255, 0, 0);
 ellipse (160, 270, 20, 20);

 //quicksilver
 float thermometer2_value = map(temp_values[1],0,40,200,0);

 rect(157, 57 + thermometer2_value, 6, (200 - thermometer2_value));

 //define stroke
 stroke (255,0,0);
 strokeWeight(2);

 //draw font
 textFont(f,20);
 text ( "Beijing", 130, 350);
 text ( "(" + temp_values[1] + ")", 130, 380);

 // THERMOSTAT 3
 //fill background in gray
 fill (227,227,227);

 //build thermostat
 rectMode(CORNER);
 rect (250, 50, 20, 200);
 ellipse (260, 270, 40, 40);

 //build quicksilver reservoir
 fill(255, 0, 0);
 ellipse (260, 270, 20, 20);

 //quicksilver
 float thermometer3_value = map(temp_values[2],0,40,200,0);

 rect(257, 57 + thermometer3_value, 6, (200 - thermometer3_value));

 //define stroke
 stroke (255,0,0);
 strokeWeight(2);

 //draw font
 textFont(f,20);
 text ( "Perth", 230, 350);
 text ( "(" + temp_values[2] + ")", 230, 380);

}
// onReceiveEEML is run every time your app receives back EEML that it has requested from a Pachube feed.
void onReceiveEEML(DataIn d){
 String url = d.getURL();
 temp = d.getValue("temperature");

 println(url);
 println(temp);

 if (url == BERLIN_FEED){
 temp_values[0] = temp;
 }
 else if (url == BEIJING_FEED){
 temp_values[1] = temp;
 }
 else if (url == PERTH_FEED){
 temp_values[2] = temp;
 }

}

 

 

 

Advertisements

2 thoughts on “Processing: How to create real-time info-graphics with sensor data from Pachube?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s