changeset 866:a99b4d5afb83

use websockets for temperature update Ignore-this: 558ad53cf5b4b0c013041db555fbb458 darcs-hash:20130210214135-312f9-f69d37d4b9bce7fa6ec0e9c9889b2de90fd26a8f
author drewp <drewp@bigasterisk.com>
date Sun, 10 Feb 2013 13:41:35 -0800
parents db3e0510ab49
children d9bc9a82dcca
files service/wallscreen/gui.js service/wallscreen/index.html service/wallscreen/wallscreen.py service/wallscreen/websocket.js
diffstat 4 files changed, 110 insertions(+), 62 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/service/wallscreen/gui.js	Sun Feb 10 13:41:35 2013 -0800
@@ -0,0 +1,50 @@
+var reloadData;
+$(function () {
+    
+    setTimeout(function () {
+        window.resizeTo(702,480);
+    }, 10000);
+    
+    var model = {
+        requestedF: ko.observable(),
+        tasks: ko.observableArray([]),
+        events: ko.observableArray([]),
+        isToday: function (ev) {
+            var today = moment().format("YYYY-MM-DD");
+            return ev.date == today;
+        }
+    };
+    reloadData = function() {
+        $.getJSON("content", function (data) {
+            model.tasks(data.tasks);
+            model.events(data.events);
+        });
+    }
+    setInterval(reloadData, 30*60*1000);
+    reloadData();
+
+    function onMessage(d) {
+        if (d.tempF) {
+            model.requestedF(d.tempF);
+        }
+    }
+    reconnectingWebSocket("ws://localhost:9102/live", onMessage);
+
+    ko.applyBindings(model);
+
+    if (navigator.userAgent == "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:18.0) Gecko/18.0 Firefox/18.0") {
+        $(".rot").removeClass("rot");
+    }
+
+    function updateClock() {
+        var now = moment();
+        var s = (new Date()).toLocaleTimeString();
+        $("#clock").html(
+            "<div>"+now.format("dddd")+"</div>"+
+                "<div>"+now.format("MMM Do")+"</div>"+
+                "<div>"+now.format("HH:mm")+"</div>"
+        )
+    }
+    setInterval(updateClock, 20000)
+    updateClock();
+});
--- a/service/wallscreen/index.html	Sun Feb 10 12:06:17 2013 -0800
+++ b/service/wallscreen/index.html	Sun Feb 10 13:41:35 2013 -0800
@@ -1,6 +1,7 @@
 <!DOCTYPE html>
 <html>
   <head>
+    <meta charset='utf-8'> 
     <title>wallscreen</title>
     <link href='http://fonts.googleapis.com/css?family=Yanone+Kaffeesatz:400' rel='stylesheet' type='text/css'></link>
       <style type="text/css" media="all">
@@ -118,6 +119,12 @@
 left: 8px;
 top: 640px;
 }
+#status {
+  color: red;
+    left: 100px;
+    position: absolute;
+    top: 100px;
+}
 
 	/* ]]> */
       </style>
@@ -158,64 +165,14 @@
       <div id="thermostat">
         Thermostat at <span style="color: #FAB1FA;" data-bind="text: requestedF"></span>. Use knob to adjust.
       </div>
+      <div id="status"></div>
 
     </div>
 <script src="static/jquery-1.8.3.min.js"></script>
 <script src="static/underscore-1.4.2.min.js"></script>
 <script src="static/knockout-2.1.0.min.js"></script>
 <script src="static/moment.min.js"></script>
-<script type="text/javascript">
-var reloadData;
-  $(function () {
-  setTimeout(function () {
-  window.resizeTo(702,480);
-  }, 10000);
-
-  var model = {
-    requestedF: ko.observable(),
-    tasks: ko.observableArray([]),
-    events: ko.observableArray([]),
-    isToday: function (ev) {
-      var today = moment().format("YYYY-MM-DD");
-      return ev.date == today;
-    }
-  };
-  reloadData = function() {
-    $.getJSON("content", function (data) {
-      model.tasks(data.tasks);
-      model.events(data.events);
-    });
-  }
-  setInterval(reloadData, 30*60*1000);
-  reloadData();
-
-setInterval(function () {
-$.getJSON("/thermostat", function (data) {
-  model.requestedF(data.tempF);
-});
-}, 1000);
-
-  ko.applyBindings(model);
-
-
-  if (navigator.userAgent == "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:18.0) Gecko/18.0 Firefox/18.0") {
-    $(".rot").removeClass("rot");
-  }
-
-  function updateClock() {
-    var now = moment();
-    var s = (new Date()).toLocaleTimeString();
-    $("#clock").html(
-"<div>"+now.format("dddd")+"</div>"+
-"<div>"+now.format("MMM Do")+"</div>"+
-"<div>"+now.format("HH:mm")+"</div>"
-)
-  }
-  setInterval(updateClock, 20000)
-  updateClock();
-
-  });
-</script>
-
+<script src="websocket.js"></script>
+<script src="gui.js"></script>
   </body>
 </html>
--- a/service/wallscreen/wallscreen.py	Sun Feb 10 12:06:17 2013 -0800
+++ b/service/wallscreen/wallscreen.py	Sun Feb 10 13:41:35 2013 -0800
@@ -4,9 +4,9 @@
 and then fix the window with this:
   echo "window.resizeTo(702,480)" | nc localhost 9999
 """
-import json, sys
+import json, sys, time
 from dateutil.parser import parse
-from twisted.internet import reactor
+from twisted.internet import reactor, task
 from twisted.internet.defer import inlineCallbacks
 import cyclone.web, cyclone.httpclient, cyclone.websocket
 from rdflib import Graph, URIRef, Namespace, Literal, RDF
@@ -72,20 +72,41 @@
 
         self.write(json.dumps({'tasks':out, 'events' : events}))
 
-class Thermostat(PrettyErrorHandler, cyclone.web.RequestHandler):
-    @inlineCallbacks
-    def get(self):
-        self.write((yield cyclone.httpclient.fetch("http://bang:10001/requestedTemperature")).body)
+@inlineCallbacks
+def pushThermostat():
+    f = json.loads((yield cyclone.httpclient.fetch("http://bang:10001/requestedTemperature")).body)
+    [c.sendMessage(f) for c in liveClients]
     
-    
+class RefreshTemperature(PrettyErrorHandler, cyclone.web.RequestHandler):
+    def post(self):
+        return pushThermostat()
+
+liveClients = set()
+
+class Live(cyclone.websocket.WebSocketHandler):
+    def connectionMade(self, *args, **kwargs):
+        log.info("websocket opened")
+        liveClients.add(self)
+
+    def connectionLost(self, reason):
+        log.info("websocket closed")
+        liveClients.remove(self)
+
+    def messageReceived(self, message):
+        log.info("got message %s" % message)
+        self.sendMessage(message)
+
 if __name__ == '__main__':
     from twisted.python import log as twlog
     #twlog.startLogging(sys.stdout)
-            
+
+    task.LoopingCall(pushThermostat).start(1)
+    
     port = 9102
     reactor.listenTCP(port, cyclone.web.Application(handlers=[
         (r'/content', Content),
-        (r'/thermostat', Thermostat),        
+        (r'/live', Live),
+        (r'/refreshTemperature', RefreshTemperature),
         (r'/(.*)', cyclone.web.StaticFileHandler,
          {"path" : ".", # security hole- serves this dir too
           "default_filename" : "index.html"}),
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/service/wallscreen/websocket.js	Sun Feb 10 13:41:35 2013 -0800
@@ -0,0 +1,20 @@
+// from the light9/rdfdb one
+
+function reconnectingWebSocket(url, onMessage) {
+    var pong = 0;
+    function connect() {
+        var ws = new WebSocket(url);
+        
+        ws.onopen = function() {   $("#status").text(""); };
+        ws.onerror = function(e) { $("#status").text("error: "+e); };
+        ws.onclose = function() {  
+            pong = 1 - pong;
+            $("#status").text("disconnected (retrying "+(pong ? "😼":"😺")+")"); 
+            setTimeout(connect, 2000);
+        };
+        ws.onmessage = function (evt) {
+            onMessage(JSON.parse(evt.data));
+        };
+    }
+    connect();
+}