summaryrefslogtreecommitdiffstats
path: root/apps
diff options
context:
space:
mode:
authorStefan Radomski <radomski@tk.informatik.tu-darmstadt.de>2013-09-25 13:24:11 (GMT)
committerStefan Radomski <radomski@tk.informatik.tu-darmstadt.de>2013-09-25 13:24:11 (GMT)
commit567df9318fff6d1bb570191c33ea68cd6ef88bee (patch)
tree72e310c422cea117abe859a6bddf0b613a2db589 /apps
parentbe3c180fec71866a91b5f9297708d581bc1d6435 (diff)
downloaduscxml-567df9318fff6d1bb570191c33ea68cd6ef88bee.zip
uscxml-567df9318fff6d1bb570191c33ea68cd6ef88bee.tar.gz
uscxml-567df9318fff6d1bb570191c33ea68cd6ef88bee.tar.bz2
More work on IMInvoker, renamed Blob attributes and some XPath datamodel fixes
Diffstat (limited to 'apps')
-rw-r--r--apps/samples/map/SpatialMapTicker.java160
-rw-r--r--apps/samples/map/click.wavbin0 -> 5058 bytes
-rw-r--r--apps/samples/map/map.html30
-rw-r--r--apps/samples/map/map.js158
-rw-r--r--apps/samples/map/spoken-map-ticker.scxml78
-rw-r--r--apps/samples/map/spoken-map-ticker.xhtml240
6 files changed, 478 insertions, 188 deletions
diff --git a/apps/samples/map/SpatialMapTicker.java b/apps/samples/map/SpatialMapTicker.java
new file mode 100644
index 0000000..9947ffb
--- /dev/null
+++ b/apps/samples/map/SpatialMapTicker.java
@@ -0,0 +1,160 @@
+/**
+ * Compile as:
+ * $ javac -cp .:/usr/local/share/umundo/java/umundo.jar SpatialMapTicker.java
+ *
+ * Run as:
+ * $ java -cp .:/usr/local/share/umundo/java/umundo.jar SpatialMapTicker
+ */
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.LinkedList;
+import java.util.Random;
+
+import org.umundo.core.Greeter;
+import org.umundo.core.Message;
+import org.umundo.core.Node;
+import org.umundo.core.Publisher;
+
+public class SpatialMapTicker {
+
+ Node node;
+ Publisher pub;
+ Greeter greeter;
+ ArrayList<Sensor> sensors = new ArrayList<Sensor>();
+ static ArrayList<SensorMessage> messages = new ArrayList<SensorMessage>();
+ static Random random = new Random(System.currentTimeMillis());
+
+ public class SensorMessage {
+ public String message;
+ public int severity;
+ public SensorMessage(String message, int severity) {
+ this.message = message;
+ this.severity = severity;
+ }
+ public SensorMessage(String message) {
+ this.message = message;
+ this.severity = 3;
+ }
+ }
+
+ public class Sensor {
+ @Override
+ public String toString() {
+ return "Sensor [id=" + id + ", lat=" + lat + ", lon=" + lon
+ + ", html=" + getHTML() + "]";
+ }
+ public String id = "";
+ public Double lat = new Double(0);
+ public Double lon = new Double(0);
+ LinkedList<SensorMessage> messages = new LinkedList<SensorMessage>();
+
+ public void addMessage(SensorMessage message) {
+ if (messages.size() > 15)
+ messages.removeLast();
+ messages.addFirst(message);
+ }
+
+ public String getHTML() {
+ StringBuilder sb = new StringBuilder();
+ for (SensorMessage message : messages) {
+ sb.append(message.severity);
+ sb.append(": ");
+ sb.append(message.message);
+ sb.append("<br />");
+ }
+ return sb.toString();
+ }
+ }
+
+ public class SensorGreeter extends Greeter {
+ public void welcome(Publisher publisher, String nodeId, String subId) {
+ // send all sensors to new subscribers
+ for (Sensor sensor : sensors) {
+ Message msg = new Message(); //Message.toSubscriber(subId);
+ msg.putMeta("id", sensor.id);
+ msg.putMeta("lat", sensor.lat.toString());
+ msg.putMeta("lon", sensor.lon.toString());
+ msg.putMeta("html", sensor.getHTML());
+ pub.send(msg);
+ }
+ }
+
+ @Override
+ public void farewell(Publisher arg0, String nodeId, String subId) {
+ }
+
+ }
+
+ public SpatialMapTicker() {
+ node = new Node();
+ pub = new Publisher("map/tick");
+ greeter = new SensorGreeter();
+ pub.setGreeter(greeter);
+ node.addPublisher(pub);
+
+ double latCenter = 59.32;
+ double lonCenter = 18.08;
+
+ int nrSensors = 15; //(int) (Math.random() * 20);
+ for (int i = 0; i < nrSensors; i++) {
+ Sensor sensor = new Sensor();
+ double latOffset = (Math.random() - 0.5) * 0.3;
+ double lonOffset = (Math.random() - 0.5) * 0.3;
+
+ sensor.id = "Sensor #" + i;
+ sensor.lat = latCenter + latOffset;
+ sensor.lon = lonCenter + lonOffset;
+ sensors.add(sensor);
+ }
+ }
+
+ public static void main(String[] args) {
+ SpatialMapTicker ticker = new SpatialMapTicker();
+ ticker.run();
+ }
+
+ private void run() {
+ messages.add(new SensorMessage("Oil pressure threshold exceeded"));
+ messages.add(new SensorMessage("Equipment is on fire"));
+ messages.add(new SensorMessage("Error #32 in diagnostics unit"));
+ messages.add(new SensorMessage("Unauthorized startup"));
+ messages.add(new SensorMessage("Tire pressure too low"));
+ messages.add(new SensorMessage("Error #145 in diagnostics unit"));
+ messages.add(new SensorMessage("Unit was moved out of construction site area"));
+ messages.add(new SensorMessage("Hydraulic pressure exceeding safety limits"));
+ messages.add(new SensorMessage("Drivers seat belts are not fastened!"));
+ messages.add(new SensorMessage("Battery recharge cycles exceeded"));
+ messages.add(new SensorMessage("Unit operated outside recommended paramters"));
+
+ while (true) {
+ try {
+ Thread.sleep((long) (Math.random() * 300) + 100);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+
+ Sensor sensor = sensors.get(random.nextInt(sensors.size()));
+ SensorMessage fault = messages.get(random.nextInt(messages.size()));
+
+ Date now = new Date();
+ SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss z");
+ String nowString = sdf.format(now);
+ sensor.addMessage(fault);
+
+// System.out.println("Publishing " + sensor);
+
+ Message msg = new Message();
+ msg.putMeta("id", sensor.id);
+ msg.putMeta("lat", sensor.lat.toString());
+ msg.putMeta("lon", sensor.lon.toString());
+ msg.putMeta("html", sensor.getHTML());
+ msg.putMeta("time", nowString);
+ msg.putMeta("timeStamp", Long.toString(now.getTime()));
+ msg.putMeta("message", sensor.messages.getFirst().message);
+ msg.putMeta("severity", Integer.toString(random.nextInt(10)));
+ pub.send(msg);
+ }
+ }
+
+}
diff --git a/apps/samples/map/click.wav b/apps/samples/map/click.wav
new file mode 100644
index 0000000..e11b0b7
--- /dev/null
+++ b/apps/samples/map/click.wav
Binary files differ
diff --git a/apps/samples/map/map.html b/apps/samples/map/map.html
deleted file mode 100644
index 01dc92b..0000000
--- a/apps/samples/map/map.html
+++ /dev/null
@@ -1,30 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html>
-<head>
- <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
- <link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/dojo/1.8.3/dijit/themes/tundra/tundra.css">
- <!-- link rel="stylesheet" href="map.css" -->
- <script type="text/javascript" src="http://openlayers.org/api/OpenLayers.js"></script>
- <style type="text/css">
- </style>
-
- <script type="text/javascript">
- </script>
-
- <script src="http://ajax.googleapis.com/ajax/libs/dojo/1.8.3/dojo/dojo.js"></script>
- <script type="text/javascript" src="map.js"></script>
-
- <script type="text/javascript">
- require(["dojo/domReady!", "dojo"], function(dom, dojo) {
- var map = new Map("map");
- });
- </script>
- </head>
- <body class="tundra">
- <table>
- <tr><td>
- <div id="map" />
- </td></tr>
- </table>
- </body>
-</html>
diff --git a/apps/samples/map/map.js b/apps/samples/map/map.js
deleted file mode 100644
index 6794875..0000000
--- a/apps/samples/map/map.js
+++ /dev/null
@@ -1,158 +0,0 @@
-function Map(element) {
-
- // private attributes
- var self = this;
-
- // private instanceId
- if (!Map.instances)
- Map.instances = 0;
- var instanceId = Map.instances++;
-
- // public attributes
- this.coords = {};
-
-
- require([
- "dojo/ready",
- "dojo/dom-construct",
- "dojo/_base/window",
- "dojo/dom",
- "dojox/geo/openlayers/Map",
- "dojox/geo/openlayers/GfxLayer",
- "dojox/geo/openlayers/Layer",
- "dojox/geo/openlayers/GeometryFeature",
- "dojox/geo/openlayers/Point",
- "dojox/geo/openlayers/LineString",
- "dojox/geo/openlayers/WidgetFeature",
- "dojox/charting/widget/Chart",
- "dojox/charting/widget/Chart2D",
- "dojox/charting/plot2d/Pie",
- "dojox/charting/themes/PlotKit/blue"
- ], function(
- ready,
- domConstruct,
- win,
- dom,
- Map,
- GfxLayer,
- Layer,
- GeometryFeature,
- Point,
- LineString,
- WidgetFeature,
- Chart,
- Chart2D,
- Pie,
- blue
- ) {
- ready(function(){
-
- if (typeof(element) === 'string') {
- element = dom.byId(element);
- }
-
- element.style.width = "450px";
- element.style.height = "350px";
-
- var options = {
- baseLayerName: "WorldMap",
- baseLayerType : dojox.geo.openlayers.BaseLayerType.OSM,
- //baseLayerUrl: "http://localhost/mapserver/mapserv.cgi?map=./world.map",
- baseLayerOptions: {
- layers: ['contry','state','city','town','highway']
- },
- touchHandler: false,
- accessible: true
- };
-
- // Available base layers: http://dojotoolkit.org/reference-guide/1.7/dojox/geo/openlayers.html#id5
- self.map = new Map(element, options);
-
- // This is New York location
- var ny = {
- latitude : 49.877648,
- longitude : 8.654762
- };
-
- var people = [ {
- name : 'Dirk',
- y : 49.877848,
- x : 8.653762
- }, {
- name : 'Stefan',
- y : 49.877348,
- x : 8.655462
- } ];
-
- var div = domConstruct.create("div", {}, win.body());
- //var div = domConstruct.create("div", {});
- var chart = new Chart({
- margins : {
- l : 0,
- r : 0,
- t : 0,
- b : 0
- }
- }, div);
-
- var c = chart.chart;
- c.addPlot("default", {
- type : "Pie",
- radius : 50,
- labelOffset : 100,
- fontColor : "black",
- fontSize : 20
- });
-
- var ser = [ 2, 8, 12, 3 ];
- c.addSeries("Series", ser);
- c.setTheme(blue);
- c.render();
- c.theme.plotarea.fill = undefined;
-
- var descr = {
- longitude : ny.longitude,
- latitude : ny.latitude,
- widget : chart,
- width : 120,
- height : 120
- };
- feat3 = new WidgetFeature(descr);
-
- // create a GfxLayer
- var layer = new GfxLayer();
-
- var point = new Point({
- x:ny.longitude,
- y:ny.latitude
- });
- // create a GeometryFeature
- var feat = new GeometryFeature(point);
- // set the shape properties, fill and stroke
- feat.setFill([ 0, 128, 128 ]);
- feat.setStroke([ 0, 0, 0 ]);
- feat.setShapeProperties({
- r : 8
- });
-
- var pts = new LineString(people);
- // create a GeometryFeature
- var feat2 = new GeometryFeature(pts);
- // set the shape stroke property
- feat2.setStroke([ 0, 0, 0 ]);
-
- // add the feature to the layer
- layer.addFeature(feat);
- layer.addFeature(feat2);
- layer.addFeature(feat3);
- // add layer to the map
- self.map.addLayer(layer);
-
- // fit to New York with 0.1 degrees extent
- self.map.fitTo({
- position : [ ny.longitude, ny.latitude ],
- extent : 0.001
- });
- });
- });
-}
diff --git a/apps/samples/map/spoken-map-ticker.scxml b/apps/samples/map/spoken-map-ticker.scxml
new file mode 100644
index 0000000..147f890
--- /dev/null
+++ b/apps/samples/map/spoken-map-ticker.scxml
@@ -0,0 +1,78 @@
+<scxml datamodel="ecmascript" name="mapticker"
+ xmlns:html="http://www.w3.org/1999/xhtml"
+ xmlns:vxml="http://www.w3.org/2001/vxml"
+ xmlns="http://www.w3.org/2005/07/scxml">
+
+ <script src="http://uscxml.tk.informatik.tu-darmstadt.de/scripts/dump.js" />
+
+ <state id="start">
+ <!--
+ Invoke an external HTML browser
+ -->
+ <invoke type="xhtml" id="xhtml1">
+ <content src="spoken-map-ticker.xhtml" />
+ <finalize>
+ <!-- <script>dump(_event);</script> -->
+ </finalize>
+ </invoke>
+
+ <!--
+ Invoke a VoiceXML browser
+ -->
+ <!-- invoke type="vxml" id="vxml" / -->
+
+ <!--
+ Invoke a uMundo component for pub/sub ticker subscription
+ -->
+ <invoke type="umundo" id="umundo">
+ <param name="channel" expr="'map/tick'" />
+ <finalize>
+ <script>dump(_event);</script>
+ </finalize>
+ </invoke>
+
+ <invoke type="openal" id="audio"></invoke>
+
+ <state id="idle">
+ <!--
+ Map in XHTML invoker was moved -> update OpenAL listener position
+ -->
+ <transition event="map.center" target="idle">
+ <send event="move.listener" target="#_audio">
+ <param name="x" expr="_event.data.lon" />
+ <param name="y" expr="1" />
+ <param name="z" expr="_event.data.lat" />
+ </send>
+ </transition>
+
+ <!--
+ Ticker message was received
+ -> Send to XHTML invoker to display
+ -> Play clicking noise from respective direction
+ -> Speak content if severity exceeds a given threshold
+ -->
+ <transition target="idle" event="umundo.rcvd">
+ <send target="#_xhtml1">
+ <content>${_event.data}</content>
+ </send>
+ <send target="#_audio" event="play" delay="0ms">
+ <param name="src" expr="'click.wav'" />
+ <param name="x" expr="_event.data.lon" />
+ <param name="y" expr="0" />
+ <param name="z" expr="_event.data.lat" />
+ </send>
+
+ <if cond="_event.data.message &amp;&amp; _event.data.severity &gt; 8">
+ <send target="#_vxml">
+ <content>
+ <vxml:prompt>
+ ${_event.data.message}
+ </vxml:prompt>
+ </content>
+ </send>
+ </if>
+
+ </transition>
+ </state>
+ </state>
+</scxml> \ No newline at end of file
diff --git a/apps/samples/map/spoken-map-ticker.xhtml b/apps/samples/map/spoken-map-ticker.xhtml
new file mode 100644
index 0000000..ace8724
--- /dev/null
+++ b/apps/samples/map/spoken-map-ticker.xhtml
@@ -0,0 +1,240 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <!-- space in between script is required as <script/> is not valid HTML to most browsers -->
+ <script type="text/javascript" src="http://code.jquery.com/jquery-2.0.3.js"> </script>
+ <script type="text/javascript" src="http://www.openlayers.org/api/OpenLayers.js"> </script>
+ <script type="text/javascript" src="http://epikur.local/~sradomski/CometSession.js"> </script>
+ <script type="text/javascript" src="https://raw.github.com/jchavannes/jquery-timer/master/jquery.timer.js"> </script>
+
+ <style type="text/css">
+ html, body, #map {
+ width: 100%;
+ height: 100%;
+ margin: 0;
+ }
+ .olPopup {
+ border-radius: 8px;
+ }
+ div.olControlOverviewMapElement {
+ background-color: #666;
+ }
+ div.olMap {
+ width: 180px;
+ height: 120px;
+ margin: 0;
+ }
+ div.timeRuler {
+ font-family:Courier,Arial,Helvetica,sans-serif;
+ font-size: 1.2em;
+ font-weight: bold;
+ background-color: #eee;
+ }
+ div#message {
+ overflow: auto;
+ height: 100%;
+ font-family:Courier,Arial,Helvetica,sans-serif;
+ font-size: 0.6em;
+ }
+
+ div#message p {
+ padding: 0px;
+ margin: 4px 2px;
+ }
+
+ </style>
+
+ <!-- script type="text/javascript" src="http://localhost/~sradomski/CometSession.js"></script -->
+ <script type="text/javascript">
+//<![CDATA[
+ $(document).ready(function() {
+ var scxml = new CometSession({
+ server: document.URL,
+ onEvent: function(response, message) {
+ if (message) {
+ console.log(message);
+
+ if (!markers[message.id]) {
+ addMarker(message);
+ } else {
+ for (i = 0; i < map.popups.length; i++) {
+ if (map.popups[i].feature.id === message.id) {
+ map.popups[i].setContentHTML("<h3>" + message.id + "</h3>" + message.html);
+ }
+ }
+ markers[message.id].marker.opacity = 1.0;
+ markers[message.id].marker.setOpacity(1.0);
+
+ markers[message.id].marker.timer.play();
+ markers[message.id].feature.popupContentHTML = "<h3>" + message.id + "</h3>" + message.html;
+ }
+
+ if (message.message && message.message.length > 0) {
+ var messageDiv = $("#message")[0];
+ if (message.timeStamp > lastUpdateTime + 3000) {
+ var timeRuler = document.createElement("div");
+ timeRuler.setAttribute("class", "timeRuler");
+ timeRuler.innerHTML = message.time; // + messageDiv.innerHTML;
+ messageDiv.appendChild(timeRuler);
+ lastUpdateTime = message.timeStamp;
+ }
+
+ console.log(message.timeStamp);
+ console.log(lastUpdateTime);
+
+ var messagePara = document.createElement("p");
+ if (message.severity > 7) {
+ messagePara.setAttribute("style", "color:red; font-weight:bold;");
+ }
+ messagePara.innerHTML += message.message; // + messageDiv.innerHTML;
+
+ messageDiv.appendChild(messagePara);
+ messagePara.addEventListener("mousedown", function() {
+ var marker = markers[message.id].marker;
+ marker.events.triggerEvent("mousedown");
+ });
+ messagePara.addEventListener("mouseover", function() {
+ messagePara.style.backgroundColor = "#eee";
+ });
+ messagePara.addEventListener("mouseout", function() {
+ messagePara.style.backgroundColor = "#fff";
+ });
+
+ if (!stopScrolling) {
+ messageDiv.scrollTop = messageDiv.scrollHeight;
+ }
+ }
+ }
+ }
+ });
+
+ // var map = new OpenLayers.Map("demoMap");
+ // map.addLayer(new OpenLayers.Layer.OSM());
+ // map.zoomToMaxExtent();
+
+ var markers = {};
+ var lastUpdateTime = 0;
+ var stopScrolling = false;
+
+ var fromProjection = new OpenLayers.Projection("EPSG:4326"); // Transform from WGS 1984
+ var toProjection = new OpenLayers.Projection("EPSG:900913"); // to Spherical Mercator Projection
+
+ function onMoveEvent() {
+ var position = map.getCenter().transform(toProjection, fromProjection);
+ if (Math.random() > 0.7) { // do not publish every move event
+ scxml.send('map.center', {
+ 'zoom': map.getZoom(),
+ 'lon': position.lon,
+ 'lat': position.lat });
+ }
+ }
+
+ function onMoveEndEvent() {
+ var position = map.getCenter().transform(toProjection, fromProjection);
+ scxml.send('map.center', {
+ 'zoom': map.getZoom(),
+ 'lon': position.lon,
+ 'lat': position.lat });
+ }
+
+ function addMarker(message) {
+ var feature = new OpenLayers.Feature(
+ markerLayer,
+ new OpenLayers.LonLat(message.lon, message.lat).transform(fromProjection, toProjection));
+ feature.closeBox = true;
+ feature.popupClass =  OpenLayers.Class(OpenLayers.Popup.Anchored, {
+ 'autoSize': true,
+// 'maxSize': new OpenLayers.Size(300,200)
+ });
+ feature.data.popupContentHTML = "<h3>" + message.id + "</h3>" + message.html;
+ feature.data.overflow = "auto";
+ feature.data.id = message.id;
+ var marker = feature.createMarker();
+
+ marker.timer = $.timer(function() {
+ if (marker.opacity > 0.5) {
+ marker.opacity -= 0.02;
+ marker.setOpacity(marker.opacity);
+ } else {
+ marker.timer.stop();
+ }
+ }, 100);
+
+ marker.opacity = 1.0;
+ marker.setOpacity(marker.opacity);
+ marker.timer.play();
+
+ markerClick = function(evt) {
+ if (this.popup == null) {
+ this.popup = this.createPopup(this.closeBox);
+ map.addPopup(this.popup);
+ this.popup.show();
+ } else {
+ this.popup.toggle();
+ }
+ currentPopup = this.popup;
+ OpenLayers.Event.stop(evt);
+ };
+
+ marker.events.register("mousedown", feature, markerClick);
+ markers[message.id] = {
+ 'marker': marker,
+ 'feature': feature
+ };
+ markerLayer.addMarker(marker);
+ }
+ // see also: http://php-baustelle.de/openlayers/step-by-step/
+ var map = new OpenLayers.Map('map', {
+ eventListeners: {
+ "move": onMoveEvent,
+ "moveend": onMoveEndEvent,
+ }
+ });
+
+ var mapnik = new OpenLayers.Layer.OSM();
+ var markerLayer = new OpenLayers.Layer.Markers("Markers");
+// var attribution = new OpenLayers.Layer.Vector("Attribution", {attribution:"for Smart Vortex"});
+
+ map.addLayer(mapnik);
+// map.addLayer(attribution);
+ map.addLayer(markerLayer); // has to be the last layer to receive events!
+
+ map.addControl(new OpenLayers.Control.LayerSwitcher());
+ // see also http://dev.openlayers.org/releases/OpenLayers-2.12/examples/mousewheel-interval.html
+ map.addControl(new OpenLayers.Control.Navigation(
+ {dragPanOptions: {enableKinetic: true}}
+ ));
+
+ var overview = new OpenLayers.Control.OverviewMap({
+ maximized: true,
+ minRatio: 200,
+ maxRatio: 300,
+ });
+ map.addControl(overview);
+
+ // stockholm
+ var position = new OpenLayers.LonLat(18.08,59.32).transform(fromProjection, toProjection);
+// var position = new OpenLayers.LonLat(0,0).transform(fromProjection, toProjection);
+ var zoom = 11;
+ map.setCenter(position, zoom);
+
+ // var message = {
+ // 'id': "12",
+ // 'lat': 59.454441065280534,
+ // 'lon': 18.062356332194543,
+ // 'html': '<p>asdf</p>'
+ // };
+
+// addMarker(message);
+ });
+//]]>
+ </script>
+ </head>
+ <body>
+ <table width="100%" height="100%">
+ <tr>
+ <td width="20%" height="100%"><div id="message" onmouseover="stopScrolling = true" onmouseout="stopScrolling = false"></div></td>
+ <td width="80%" height="100%"><div id="map"></div></td>
+ </tr>
+ </table>
+ </body>
+</html> \ No newline at end of file