Pachube provides an API-exposed store of sensor data from pretty much anything, but with a focus on sensor data. Â It’s free to use and has what seems to be a pretty complete, reasonably designed, and easy to use API with a nicely flexible authorization model.
I’ve been working on some code to scrape data out of the Netbotz web UI (which does not have an easy to use API) and, as I got to working on the data storage backend for the scraper, remembered Pachube and decided to give it a try rather than reinventing what was effectively the same wheel.
I have generally positive impressions of Pachube after a couple of days messing around with it. Â It was pretty easy to get going, and after stumbling into one quickly-fixed bug was up and sending data in from my prototype scraper pretty quickly.
I’m using the following python class to simplify the interaction. Â It’s trivial, but I didn’t see anything similar already done, so am throwing it here for future google results:
#!/usr/bin/python
# This code is released into the public domain (though I'd be interested in seeing
#  improvements or extensions, if you're willing to share back).
import mechanize
import json
import time
class PachubeFeedUpdate:
  _url_base = "http://api.pachube.com/v2/feeds/"
  _feed_id = None
  _version = None
  ## the substance of our update - list of dictionaries with keys 'id' and 'current_value'
  _data = None
  ## the actual object we'll JSONify and send to the API endpoint
  _payload = None
  _opener = None
  def __init__(self, feed_id, apikey):
    self._version = "1.0.0"
    self._feed_id = feed_id
    self._opener = mechanize.build_opener()
    self._opener.addheaders = [('X-PachubeApiKey',apikey)]
    self._data = []
    self._payload = {}
  def addDatapoint(self,dp_id,dp_value):
    self._data.append({'id':dp_id, 'current_value':dp_value})
  def buildUpdate(self):
    self._payload['version'] = self._version
    self._payload['id'] = self._feed_id
    self._payload['datastreams'] = self._data
  def sendUpdate(self):
    url = self._url_base + self._feed_id + "?_method=put"
    try:
      self._opener.open(url,json.dumps(self._payload))
    except mechanize.HTTPError as e:
      print "An HTTP error occurred: %s " % e
Usage is pretty straightforward. Â For example, assuming you have defined key (with a valid API key from Pachube) and feed (a few clicks in the browser once you’ve registered) it’s basically like:
pfu = PachubeFeedUpdate(feed,key) # do some stuff; gather data, repeating as necessary for any number of datastreams pfu.addDatapoint(<datastream_id>,<data_value>)) # finish up and submit the data pfu.buildUpdate() pfu.sendUpdate()
The resulting datapoints basically end up looking like they were logged at the time the sendUpdate() call is made. Â In my situation, I want to send readings from a couple of dozen sensors each into their own Pachube datastream in one shot, so this works fine. Â If, instead, for some reason you need to accumulate updates over time without posting them, you’d need to take a different approach.


recent comments