GPS Event [17] – Coral8 [5]
Last time we detected when a device stops streaming data, however the message remained within Coral8. Today, I would like to attach an output adapter to send the message out. Coral8 comes with several output adapters, including XML over HTTP. This one seems appropriate for any kind of server based application. Just for fun, I decided to transfer data to an application running on Google App Engine.
Note:
Starting with Google App Engine is fairly easy; detailed instructions are available, so I will not describe it here.
The to-do list:
- Add a XML over HTTP output adapter to the Coral8 example;
- Write an application on Google App Engine to receive, store and display Coral8 messages;
- Test.
1. The Output Adapter
ATTACH OUTPUT ADAPTER WriteXMLOverHTTP
TYPE WriteXmlOverHttpAdapterType
TO STREAM sAlarm
PROPERTIES
URL = "http://192.168.xxx.76:8080",
XSLTEMPLATE =
[[<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:OUTPUT method="text" />
<xsl:template match="/">
<xsl:text>{</xsl:text>
<xsl:for-each SELECT="*">
<xsl:for-each SELECT="*">
<xsl:text>'</xsl:text>
<xsl:value-of select="@Name" />
<xsl:text>':'</xsl:text>
<xsl:value-of select="." />
<xsl:text>',</xsl:text>
</xsl:for-each>
</xsl:for-each>
<xsl:text>}</xsl:text>
</xsl:template>
</xsl:stylesheet>
]]
;
The adapter has two properties:
- URL of the server, including the port number;
- XSLTEMPLATE for an optional XSL transformation.
If the XSLTEMPLATE is not specified, Coral8 sends a raw XML string like this one:
<field name="Entity">DS_1</field>
<field name="Msg">Stream stopped</field>
<field name="AlmTime">2009-01-23 19:41:09.788000</field>
</tuple>
The template in the adapter transforms the XML to a dictionary-like string:{'Entity':'DS_1','Msg':'Stream stopped','AlmTime':'2009-01-23 19:41:09.788000',}.
Using the XSL I have simply avoided parsing the XML on the server side.
2. The Application
Capture Coral8 messages to DB.
Display last 10 messages.
"""
from google.appengine.ext import webapp
from google.appengine.ext.webapp.util \
import run_wsgi_app
from google.appengine.ext import db
class Dta(db.Model):
content = db.StringProperty(multiline=True)
date = db.DateTimeProperty(auto_now_add=True)
class MainPage(webapp.RequestHandler):
def get(self):
self.response.headers \
['Content-Type'] = 'text/plain'
dt = db.GqlQuery \
("SELECT * FROM Dta ORDER BY date DESC LIMIT 10")
for d in dt:
try:
dic = eval(d.content)
self.response.out.write('\n%s' % ('-' * 40))
for k in dic.keys():
self.response.out.write \
('\n%s = %s' % (k, dic[k]))
except:
pass
def post(self):
rec = Dta()
doc = str(self.request.body)
rec.content = ' '.join(doc.split())
rec.put()
application = webapp.WSGIApplication \
([('/', MainPage)], debug=True)
def main():
run_wsgi_app(application)
if __name__ == "__main__":
main()
May seem complicated, but here is the basics:
class Dta(db.Model) defines a "database table" with two columns:
content– a string column for Coral8 data;date– a timestamp column;
post(self) method is activated when Coral8 sends data to the application's web page;
get(self) method is activated when a browser visits the web page.
3. Test
For testing, I have used the same example as in the previous post — send several messages to Coral 8 and then stop. Here is the result in a browser window:


Coral8 communicates with MS SQL Server using an ODBC connection, so one has to be added for the database. The dialog can be accessed via Start >>> Administrative Tools >>> Data Sources (ODBC). For SQL Server 2005 — and latter — specify SQL Native Client for the driver.

Ever heard about that hotel that didn’t have the 13th floor? Empty superstition, I don’t believe in things like that. Now where was I? Yes, GPS data to

This small series of moving event around, would not be complete without 