diff options
Diffstat (limited to 'test/uscxml/applications')
-rw-r--r-- | test/uscxml/applications/SpatialMapTicker.java | 153 | ||||
-rw-r--r-- | test/uscxml/applications/click.wav | bin | 0 -> 5058 bytes | |||
-rw-r--r-- | test/uscxml/applications/spoken-map-ticker.scxml | 78 | ||||
-rw-r--r-- | test/uscxml/applications/spoken-map-ticker.xhtml | 240 |
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 Binary files differnew file mode 100644 index 0000000..e11b0b7 --- /dev/null +++ b/test/uscxml/applications/click.wav 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 && _event.data.severity > 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 |