summaryrefslogtreecommitdiffstats
path: root/test/uscxml/applications
diff options
context:
space:
mode:
Diffstat (limited to 'test/uscxml/applications')
-rw-r--r--test/uscxml/applications/SpatialMapTicker.java153
-rw-r--r--test/uscxml/applications/click.wavbin0 -> 5058 bytes
-rw-r--r--test/uscxml/applications/spoken-map-ticker.scxml78
-rw-r--r--test/uscxml/applications/spoken-map-ticker.xhtml240
4 files changed, 471 insertions, 0 deletions
diff --git a/test/uscxml/applications/SpatialMapTicker.java b/test/uscxml/applications/SpatialMapTicker.java
new file mode 100644
index 0000000..8d2a5f1
--- /dev/null
+++ b/test/uscxml/applications/SpatialMapTicker.java
@@ -0,0 +1,153 @@
+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/test/uscxml/applications/click.wav b/test/uscxml/applications/click.wav
new file mode 100644
index 0000000..e11b0b7
--- /dev/null
+++ b/test/uscxml/applications/click.wav
Binary files differ
diff --git a/test/uscxml/applications/spoken-map-ticker.scxml b/test/uscxml/applications/spoken-map-ticker.scxml
new file mode 100644
index 0000000..5a1c0b2
--- /dev/null
+++ b/test/uscxml/applications/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/test/uscxml/applications/spoken-map-ticker.xhtml b/test/uscxml/applications/spoken-map-ticker.xhtml
new file mode 100644
index 0000000..ace8724
--- /dev/null
+++ b/test/uscxml/applications/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