My name is Nick Madrid and I'm a graduate student at UC Davis. I'm working on developing sensor systems for various applications and I'd like to share my experience integrating my sensor system with the new PI UFL Connector. The PI UFL Connector is a RESTful service that accepts PI data in the form of a HTTP PUT request and automatically stores it in the PI System (see link for more info).
The particular project I'll be describing here is designed to monitor air parameters (T, RH, CO2, VOCs, airborne particulates) within wineries and creameries where researchers use swab sampling to learn about the environment's microbial community. The sensor units are battery powered and fully automated. They use an ARM Cortex-M3 microcontroller to periodically read from the sensors and send the data wirelessly from an XBee radio to a ConnectPort gateway. The gateway is wired to the facilities network over ethernet and performs the HTTP PUT request to send the data to the UFL Connector. The UFL Connector and PI System both run on the same system at the UC Davis winery.
I was very pleased with how easy it was to get the UFL Connector installed and running and the minimal amount of code required on the ConnectPort gateway to send data to the Connector. The gateway runs python, so I will share the simple python function I wrote to perform this PUT request:
def sendToPI(body): global httpError httpError = 0 request = urllib2.Request(REST_address, data=body) request.add_header('Content-Type', 'text/plain') base64string = base64.encodestring('%s:%s' % (username,password)).replace('\n','') request.add_header("Authorization", "Basic %s" % base64string) request.get_method = lambda: 'PUT' try: urllib2.urlopen(request) except: httpError = 1
Certain rooms in a facility can be tough to consistently access wirelessly from the static ethernet-wired gateway (e.g. wine barrel rooms), so a version of the sensor units was developed to send the sensor data over Bluetooth to an iPhone which relays the data to the UFL Connector. I am still working on the firmware but have all the necessary functionality working. The UFL Connector treats incoming data the same as long as its formatted correctly so no modification of the Connector was necessary. The iPhone app that performs the PUT request was written in the Qt Creator IDE. Here is my (still in progress) code:
QNetworkAccessManager manager; QNetworkRequest request(QUrl(REST_address)); request.setHeader(QNetworkRequest::ContentTypeHeader, QString("text/plain")); QString concatenated = username + ":" password; QByteArray basicAuth = concatenated.toLocal8Bit().toBase64(); QString headerData = "Basic" + basicAuth; request.setRawHeader("Authorization",headerData.toLocal8Bit()); QSslConfiguration conf = request.sslConfiguration(); conf.setPeerVerifyMode(QSslSocket::VerifyNone); request.setSslConfiguration(conf); QNetworkReply* reply = manager.put(request, body); QEventLoop loop; connect(reply, SIGNAL(finished()), &loop, SLOT(quit())); loop.exec();
One issue I ran into developing the app was an SSL handshake error when performing the PUT request. The code gets around this issue by ignoring certification and I'm still looking for a better (or more secure) way of doing this.
Hope this is useful to someone and please let me know if I should go into more detail about any aspect of the project.