changeset 1456:a81def58ecfb

index page rewrite. mqtt subscribe update. new store/events graph uri Ignore-this: f0e59d3487ebfc90f8f4a830a7084023 darcs-hash:45bd18fecdb41c90b786a9e5909111e4a17bfcbe
author drewp <drewp@bigasterisk.com>
date Wed, 25 Sep 2019 17:36:44 -0700
parents 1a7cd0cff3eb
children 2ba144b7ede0
files service/frontDoorLock/front_door_lock.py service/frontDoorLock/index.html service/frontDoorLock/requirements.txt service/frontDoorLock/tasks.py
diffstat 4 files changed, 59 insertions(+), 44 deletions(-) [+]
line wrap: on
line diff
--- a/service/frontDoorLock/front_door_lock.py	Wed Sep 25 17:33:32 2019 -0700
+++ b/service/frontDoorLock/front_door_lock.py	Wed Sep 25 17:36:44 2019 -0700
@@ -44,7 +44,7 @@
     # what happened to the case-insens dict?
     h = dict((k.lower(), v) for k,v in req.headers.items())
     return URIRef(h['x-foaf-agent'])
-    
+
 
 class OutputPage(cyclone.web.RequestHandler):
     def put(self):
@@ -66,7 +66,7 @@
             stmt = next(g.triples((None, None, None)))
         self._onStatement(user, stmt)
     post = put
-    
+
     def _onStatement(self, user, stmt):
         log.info('put statement %r', stmt)
         if stmt[0:2] == (ROOM['frontDoorLock'], ROOM['state']):
@@ -88,7 +88,7 @@
             log.warn('request without x-foaf-agent: %s', h)
             self.set_status(403, 'need x-foaf-agent')
             return
-        
+
         state = self.request.body.strip().decode('ascii')
         if state == 'unlock':
             self.settings.autoLock.onUnlockedStmt()
@@ -96,14 +96,14 @@
         if state == 'lock':
             self.settings.autoLock.onLockedStmt()
             self.settings.mqtt.publish(espName + b"/switch/strike/command", b'OFF')
-        
+
 
 class AutoLock(object):
     def __init__(self, masterGraph, mqtt):
         self.masterGraph = masterGraph
         self.mqtt = mqtt
         self.timeUnlocked = None
-        self.autoLockSec = 6 
+        self.autoLockSec = 6
         self.subj = ROOM['frontDoorLock']
         task.LoopingCall(self.pollCheck).start(1)
 
@@ -135,7 +135,7 @@
             self.check()
         except Exception:
             log.exception('poll failed')
-        
+
     def check(self):
         g = self.masterGraph
         now = time.time()
@@ -160,7 +160,7 @@
 
     def onUnlockedStmt(self):
         self.timeUnlocked = None
-        
+
     def onLockedStmt(self):
         pass
 
@@ -173,7 +173,7 @@
             self.settings.mqtt.publish(
                 espName + b"/switch/strike/command", b'ON')
 
-            
+
 if __name__ == '__main__':
     arg = docopt("""
     Usage: front_door_lock.py [options]
@@ -185,21 +185,22 @@
     masterGraph = PatchableGraph()
     mqtt = MqttClient(brokerPort=10010)
     autoclose = AutoLock(masterGraph, mqtt)
-
     def toGraph(payload):
         log.info('mqtt->graph %r', payload)
         masterGraph.patchObject(ctx, ROOM['frontDoorLock'], ROOM['state'],
                                 stateFromMqtt(payload))
 
-    mqtt.subscribe(espName + b"/switch/strike/state").subscribe(on_next=toGraph)
+    sub = mqtt.subscribe(espName + b"/switch/strike/state")
+    sub.subscribe(on_next=toGraph)
 
     def setEspState(payload):
         log.info('esp state change %r', payload)
         masterGraph.patchObject(ctx, ROOM['frontDoorLock'], ROOM['espMqttConnection'],
                                 ROOM['mqtt' + payload.decode('ascii').capitalize()])
-    
-    mqtt.subscribe(espName + b"/status").subscribe(on_next=setEspState)
-    
+
+    sub = mqtt.subscribe(espName + b"/status")
+    sub.subscribe(on_next=setEspState)
+
     port = 10011
     reactor.listenTCP(port, cyclone.web.Application(
         [
--- a/service/frontDoorLock/index.html	Wed Sep 25 17:33:32 2019 -0700
+++ b/service/frontDoorLock/index.html	Wed Sep 25 17:36:44 2019 -0700
@@ -2,36 +2,44 @@
 <html>
   <head>
     <title>front door lock</title>
-    <meta charset="utf-8" />
-    <meta name="mobile-web-app-capable" content="yes">
+    <meta charset="utf-8">
     <meta name="viewport" content="width=device-width, initial-scale=1">
+
     <script src="/lib/polymer/1.0.9/webcomponentsjs/webcomponents.min.js"></script>
     <script src="/lib/require/require-2.3.3.js"></script>
     <script src="/rdf/common_paths_and_ns.js"></script>
+
+    <link rel="stylesheet" href="/rdf/browse/style.css">
+
     <link rel="import" href="/rdf/streamed-graph.html">
     <link rel="import" href="/lib/polymer/1.0.9/polymer/polymer.html">
     <link rel="import" href="/rdf/rdf-oneshot.html">
     <link rel="import" href="/rdf/rdf-uri.html">
   </head>
-  <body>
+  <body class="rdfBrowsePage">
     <dom-module id="door-control">
       <style>
        button {
-           min-width: 60px;
-           min-height: 40px;
+           min-width: 12em;
+           min-height: 4em;
+       }
+       .fade {
+           color: #0000002b;
        }
        div#form {
            margin: 2px;
-           background: #dff5e5;
+           background: #454a47;
            padding: 10px;
            line-height: 30px;
            text-align: center;
            border: 2px groove white;
+           width: 20em;
+           margin-bottom: 6em;
        }
        .invis-true {
            visibility: hidden;
        }
-       
+
       </style>
       <template>
         <h1>Front door lock</h1>
@@ -49,11 +57,13 @@
             object="room:unlocked"
           ></rdf-oneshot>
           <button on-click="unlock"
-                  disabled$="[[!isLocked]]">Unlock 10 seconds</button>
-          
-            <div class$="invis-[[!autoLockIsComing]]">
-              Locking in {{autoLockInSec}}
-            </div>
+                  disabled$="[[!isLocked]]">
+            <span class="fade">⟪</span>&#128275;<span class="fade">⟫</span> Unlock 6 seconds
+          </button>
+
+          <div class$="invis-[[!autoLockIsComing]]">
+            Locking in {{autoLockInSec}}
+          </div>
 
           <div>
             <rdf-oneshot
@@ -64,7 +74,7 @@
               object="room:unlocked"
             ></rdf-oneshot>
             <template is="dom-if" if="{{!isHeld}}">
-              <button on-click="hold">Hold unlocked</button>
+              <button on-click="hold">&#128275; Hold unlocked</button>
             </template>
             <rdf-oneshot
               id="releaseHold"
@@ -81,7 +91,8 @@
               object="room:locked"
             ></rdf-oneshot>
             <template is="dom-if" if="{{isHeld}}">
-              <button on-click="releaseHold">Release hold; lock door</button>
+              <button on-click="releaseHold">
+                &#128274; Release hold; lock door</button>
             </template>
           </div>
         </div>
@@ -118,7 +129,7 @@
                  this.lockState = q.object.toString().replace(/.*\//, '');
                  this.isLocked = q.object.equals(locked) ? true : (q.object.equals(unlocked) ? false : null);
                });
-             
+
              this.autoLockIsComing = false;
              graph.graph.quadStore.quads(
                {subject: env.createNamedNode('room:frontDoorLock'),
@@ -127,7 +138,7 @@
                (q) => {
                  this.autoLockIsComing = true;
                  this.autoLockInSec = parseFloat(q.object.valueOf());
-               });          
+               });
            },
            _onStoreGraph: function(graph) {
              if (!graph.graph) return;
@@ -147,7 +158,7 @@
              this.$.unlockOneshot.go();
            },
            hold: function () {
-             this.$.hold.go(); 
+             this.$.hold.go();
            },
            releaseHold: function() {
              this.$.releaseHold.go();
@@ -165,16 +176,6 @@
       <script type="module" src="/rdf/streamed_graph_view.js"></script>
     </template>
 
-    <style>
-     .served-resources {
-         margin-top: 4em;
-         border-top: 1px solid gray;
-         padding-top: 1em;
-     }
-     .served-resources a {
-         padding-right: 2em;
-     }
-    </style>
 
     <div class="served-resources">
       <a href=".">root</a>
--- a/service/frontDoorLock/requirements.txt	Wed Sep 25 17:33:32 2019 -0700
+++ b/service/frontDoorLock/requirements.txt	Wed Sep 25 17:36:44 2019 -0700
@@ -1,12 +1,13 @@
 cyclone
+mypy
 rdflib-jsonld==0.4.0
 rdflib==4.2.2
+rx==1.6.1
 twisted-mqtt==0.3.6
-rx==1.6.1
-git+http://github.com/drewp/scales.git@448d59fb491b7631877528e7695a93553bfaaa93#egg=scales
 
 cycloneerr
+git+http://github.com/drewp/scales.git@448d59fb491b7631877528e7695a93553bfaaa93#egg=scales
+mqtt_client==0.5.0
 patchablegraph==0.6.0
 rdfdb==0.8.0
 standardservice==0.5.0
-mqtt_client==0.4.0
--- a/service/frontDoorLock/tasks.py	Wed Sep 25 17:33:32 2019 -0700
+++ b/service/frontDoorLock/tasks.py	Wed Sep 25 17:36:44 2019 -0700
@@ -15,7 +15,9 @@
 
 @task(pre=[build_image])
 def shell(ctx):
-    ctx.run(f'docker run --name={JOB}_shell --rm -it --cap-add SYS_PTRACE --net=host {TAG} /bin/bash', pty=True)
+    ctx.run(f'docker run --name={JOB}_shell --rm -it --cap-add SYS_PTRACE --net=host '
+            f' -v `pwd`/../../stubs:/opt/stubs'
+            f' {TAG} /bin/bash', pty=True)
 
 @task(pre=[build_image])
 def local_run(ctx):
@@ -49,3 +51,13 @@
 def mqtt_force_lock(ctx):
     ctx.run(f'mosquitto_pub -h bang -p 10010 -t frontdoorlock/switch/strike/command -m OFF')
     
+
+@task(pre=[build_image])
+def mypy(ctx):
+    ctx.run(f'docker run --rm -it --name={JOB}_mypy --net=host'
+            f' -v `pwd`/.mypy_cache:/opt/.mypy_cache'
+            f' -v `pwd`/../../stubs:/opt/stubs'
+            f' -e MYPYPATH=/opt/stubs'
+            f' {TAG}'
+            f' /usr/local/bin/mypy -m front_door_lock', pty=True)
+