Friday, August 12, 2011

Adding Pachube readings to any PHP website

Whew, finally got to clean up almost all the frenchisms from the code...

As promised earlier, here is a PHP code snippet to fetch data from the Pachube web service using their API. If this is the first time you are using a web service, there is something you need to know first : web services don't run for free. So even if you are paying for some service, it does not mean you can abuse it by querying for some information every second.

As any API-backed service, Pachube will require you to sign-up in order to get your API-key that can be used in your scripts. This key is identifying you and must thus not be handed around. For those who do not have an account, obviously go ahead and create one. You might want to start with a 'Basic' plan which is free, until you find that you are reaching the limits of the system and want to switch to something more beefy.

When you're done registering, you need to create an API key for use by the PHP script. One way to go is to use the master API key in your script but this is not such a great idea. Instead, create a "secure sharing key" so that if someone gets to see your code, he won't be able to do much to your existing feeds and so on. You can find these options on the right-hand side menu of the Pachube website, after you have logged-in. It is called "My API keys" and resides withing the "My account" section. Now that you have created some key with at least the 'GET' permission, write it down, we'll use it later.


Now the other thing to take into account is, you only have a limited number of queries available over time. Depending on the web service provider, the type of account (free vs premium for example) and other likely parameters, you can find out this number. In the case of the Pachube Basic account, the limit is 5 requests per minute. I wanted to update some Geiger counter reading every 5 minutes, so this is plenty enough, great ! Here is how it looks on our PTA web site, pretty cool huh ?

How we are going to deal with this in the code is by caching the web server response. The example I am showing here is very crude, but at least it works and respects the web service netiquette by not flooding the server with superfluous requests.

Another final word about web services : JSON. This stands for JavaScript Object Notation. It used to be a very convenient way for service to return data, because you would just get a bit JS code that once evaluated would have populated your namespace with the data you had requested. Obviously, evaluating data returned by a service that can potentially host data created by malicious users is never a good idea. Well, we are doing PHP anyway so we don't care, plus PHP provides json parsing functions.

Now let's have a look at the code :


$json = file_get_contents('json.txt');


$flux = json_decode($json);

$right_now = new DateTime();
$seconds_now = $right_now->format('U');
$json_cache_date = new DateTime($flux->datastreams[0]->at);
$seconds_then = $json_cache_date->format('U');


What we have here is pretty simple. We open the cached json data (once again, crude example, this should probably be stored in a better place like your website database, and named in a more multi-feeds friendly way) and extract the information about when this data was returned. This is specific to Pachube's data format, other web services
might store this information in another place/way. We also generate information about current time, for comparison. Both times are expressed in epoch unit, which is a number of secondes elapsed since a specific event (guess which :P).


if ( (($seconds_now - $seconds_then) > 300) || (property_exists($flux, 'errors')) )

{ /* fetch and cache JSON data from feed every 5 minutes */
$request = curl_init();
curl_setopt($request, CURLOPT_URL, "http://api.pachube.com/v2/feeds/26485.json");
curl_setopt($request, CURLOPT_HTTPHEADER, array("X-PachubeApiKey: your_own_key") );
curl_setopt($request, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($request, CURLOPT_BINARYTRANSFER, TRUE);
$json = curl_exec($request);


Now we have some check about whether the data should be fetched again or not. The interval I chose is 5 minutes because it does not really make sense to get the radiation reading in realtime except for some specific events from March. If the data is stale, we build the web service request using the curl library. Note the line that adds a header with your API key. This is where you should put the information you wrote down earlier. Don't forget the space between the double-colon and the start of your key. When the request is built, we throw it at the Pachube API server and get ready to handle the result.


if (($json !== FALSE) && (curl_getinfo($request, CURLINFO_HTTP_CODE) < 400)) 

{
$flux = json_decode($json);
if ($flux !== FALSE)
file_put_contents('json.txt', $json);
}
}


Several things can happen here. The server can return an error, it sometimes happen at night for some reasons I could not find out because I was sleeping... Or the fetching can fail if you have network connectivity problems, etc... So we check that we got an answer from the API server and that this answer was a real json object. In which case we cache it and decode it.


if ($flux !== FALSE)

{
$date = new DateTime($flux->datastreams[0]->at);
$date->setTimeZone(new DateTimeZone("Asia/Tokyo"));
echo 'On : ' . $date->format('Y-m-d') .' at '. $date->format('H:i:s');
echo '<br>';
echo 'value was: ' . $flux->datastreams[0]->current_value;
echo ' ' . $flux->datastreams[0]->unit->label;
}


Whether we got the information from the cache or from the API web server, there are cases where the data has errors, in which case you do not want to show it. But if we got the requested information, all that's left to do is parse it and push it to the user in a human readable way. Et voila !

Accelerometer + Xbee = geekish fun



Hi there, I hope you are all having a nice holiday season.
As for me, I am keeping quite busy despite the loneliness and am desperately trying to do my job, some volunteer help for the Tohoku area, turning the website for our PTA upside-down, transforming a two storeys (stories?) open room type house in a 3+LDK, and helping out my lil brother on his science assignment. And there's today's story.

So introduce my brother, who has been playing with water rockets since he was in high school. Now for his first year at university he managed to get himself a science assignment dealing with those

very things. I won't explain the principle at hand here because I already have lots of things to say, so look up wikipedia (I suggest reading the discussion page there too, it is abysmal in epic proportions) or check out this NASA picture.

Now you can imagine that you can do lots of fun stuff with your own rocket, especially when you learn that the record height achieved is around 600 meters... Well, a 2L soda bottle won't go that high, but it is still a very interesting way to conduct extreme experiments around embedded/autonomous systems.

When I was around the parents' home back in France, he tells me about his latest experiments
and how they thought they wanted to get telemetry readings for the system. That sounded cool, and I was thinking about my co-worker here who does all those neat things with arduinos, xbees, sensors and so on...

Actually, my brother and his friends' main skills are neither geekygadgetry nor computer science, so the final picture is not as complex as I imagined, but still beyond their reach. Based on a survey around his friends and professors, he gathered that Xbees are cool and can work in an autonomous way without any microcontroller, which is good when you don't have a clue. They are small chips (see pic on the right) that do 802.15.4, present a serial emulation to the user, feature 5 analog inputs and an associated ADC, and have a decent (depending on your own definition of decent) sampling frequency.

Well, to be honest he actually told me about this all on the phone before I came back, so that I could do a small shopping trip around akiba and bring an accelerometer. There it is : KXM52-1050, straight from Akizukidenki, behind the now defunct Yamagiwa/Livina (just saw they were doing some construction work there, something happening soon I guess). So this little chip eats 3.3V which is all great because most of the boards that can host the Xbee provide a 3.3v regulator to feed the sensors.

Now here's his plan : one Xbee on the rocket, with some form of power supply, hosted on a regulated board, where to hook the accelerometer sensor as well. On the receiving side, another Xbee (using just one doesn't make sense, does it ?) on a USB board plugged directly into a computer, and voila. It sounded so EASY.

Now that I look back on the whole process, it was. But for some reasons, the Xbee manufacturers went through great pain to write a very detailed yet completely useless documentation. All the information needed is inside, but after reading the whole 68 pages, I felt like I did not know what to do. Also there has been several versions of the chip, things changed, and there is no clear history of what went and what didn't. One important thing I learned at my expense is that the ADC used to do the conversion on the fixed 0~1.2V range only. But, in the latest document there is no mention about the voltage range. There is a two-line section about ADC that states that "Xbee supports ADC and here is how to enable it". Period. After lots of digging I found out that the "Pin signals" table stated that Pin14 is for "Voltage reference for A/D input". If the 68 pages were a haystack, this line would be the needle.

And then, the plan worked ! That is, until I saw the "software" that some friend gave to him in order to do the Xbee monitoring. If you can call a VB 20-liner a software, that is. Which is way I made another one for him that does .csv export and much more. More on it in another article but meanwhile, enjoy the output. Guess which line's the Z ?


PS: I know I am getting behind schedule with the follow-up to the pachube article. It is still in the pipeline...