Mercurial > code > home > repos > homeauto
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>🔓<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">🔓 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"> + 🔒 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) +