Mercurial > code > home > repos > homeauto
changeset 379:67cebf7a14de
frontdoor autolock. logging improvements. use simpler mqtt interface.
Ignore-this: e2bf5262a89ebb898108a634679fdec7
author | drewp@bigasterisk.com |
---|---|
date | Wed, 12 Dec 2018 01:11:54 -0800 |
parents | b90d9321d2ce |
children | f78438913bf7 |
files | service/frontDoorLock/Dockerfile service/frontDoorLock/front_door_lock.py service/frontDoorLock/index.html service/frontDoorLock/makefile service/frontDoorLock/requirements.txt |
diffstat | 5 files changed, 166 insertions(+), 16 deletions(-) [+] |
line wrap: on
line diff
--- a/service/frontDoorLock/Dockerfile Wed Dec 12 01:10:48 2018 -0800 +++ b/service/frontDoorLock/Dockerfile Wed Dec 12 01:11:54 2018 -0800 @@ -9,4 +9,4 @@ EXPOSE 10011:10011 -CMD [ "python", "./front_door_lock.py", "-v" ] +CMD [ "python", "./front_door_lock.py" ]
--- a/service/frontDoorLock/front_door_lock.py Wed Dec 12 01:10:48 2018 -0800 +++ b/service/frontDoorLock/front_door_lock.py Wed Dec 12 01:11:54 2018 -0800 @@ -2,16 +2,14 @@ from patchablegraph import PatchableGraph, CycloneGraphHandler, CycloneGraphEventsHandler from rdflib import Namespace, URIRef, Literal, Graph from rdflib.parser import StringInputSource -from twisted.internet import reactor +from twisted.internet import reactor, task import cyclone.web -import sys, logging +import sys, logging, time from mqtt_client import MqttClient +from logsetup import log, enableTwistedLog ROOM = Namespace('http://projects.bigasterisk.com/room/') -logging.basicConfig() -log = logging.getLogger() - ctx = ROOM['frontDoorControl'] def rdfGraphBody(body, headers): @@ -44,15 +42,44 @@ assert len(g) == 1, len(g) stmt = g.triples((None, None, None)).next() self._onStatement(stmt) - + post = put + def _onStatement(self, stmt): if stmt[0:2] == (ROOM['frontDoorLock'], ROOM['state']): self.settings.mqtt.publish("frontdoor/switch/strike/command", mqttMessageFromState(stmt[2])) - self.settings.masterGraph.patchObject(ctx, - stmt[0], stmt[1], stmt[2]) return log.warn("ignoring %s", stmt) + + +class AutoLock(object): + def __init__(self, masterGraph, mqtt): + self.masterGraph = masterGraph + self.mqtt = mqtt + self.timeUnlocked = None + self.autoLockSec = 5 + self.subj = ROOM['frontDoorLock'] + task.LoopingCall(self.check).start(1) + + def check(self): + now = time.time() + state = self.masterGraph._graph.value(self.subj, ROOM['state']) + if state == ROOM['unlocked']: + if self.timeUnlocked is None: + self.timeUnlocked = now + unlockedFor = now - self.timeUnlocked + self.masterGraph.patchObject(ctx, self.subj, ROOM['unlockedForSec'], + Literal(int(unlockedFor))) + self.masterGraph.patchObject(ctx, self.subj, ROOM['autoLockInSec'], + Literal(self.autoLockSec - int(unlockedFor))) + if unlockedFor > self.autoLockSec: + self.mqtt.publish("frontdoor/switch/strike/command", + mqttMessageFromState(ROOM['locked'])) + else: + self.timeUnlocked = None + self.masterGraph.patchObject(ctx, self.subj, ROOM['unlockedForSec'], None) + self.masterGraph.patchObject(ctx, self.subj, ROOM['autoLockInSec'], None) + if __name__ == '__main__': arg = docopt(""" @@ -60,23 +87,25 @@ -v Verbose """) - log.setLevel(logging.WARN) + log.setLevel(logging.INFO) if arg['-v']: - from twisted.python import log as twlog - twlog.startLogging(sys.stdout) + enableTwistedLog() log.setLevel(logging.DEBUG) masterGraph = PatchableGraph() mqtt = MqttClient(brokerPort=10010) + autoclose = AutoLock(masterGraph, mqtt) def toGraph(payload): - log.debug('toGraph %r', payload) + log.info('mqtt->graph %r', payload) masterGraph.patchObject(ctx, ROOM['frontDoorLock'], ROOM['state'], stateFromMqtt(payload)) mqtt.subscribe("frontdoor/switch/strike/state").subscribe(on_next=toGraph) port = 10011 reactor.listenTCP(port, cyclone.web.Application([ + (r"/()", cyclone.web.StaticFileHandler, + {"path": ".", "default_filename": "index.html"}), (r"/graph", CycloneGraphHandler, {'masterGraph': masterGraph}), (r"/graph/events", CycloneGraphEventsHandler, {'masterGraph': masterGraph}),
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/service/frontDoorLock/index.html Wed Dec 12 01:11:54 2018 -0800 @@ -0,0 +1,121 @@ +<!doctype html> +<html> + <head> + <title>front door lock</title> + <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> + requirejs.config({ + paths: { + "streamed-graph": "/rdf/streamed-graph", + "quadstore": "/rdf/quadstore", + "async-module": "/lib/async/80f1793/async", + "async": "/lib/async/80f1793/async", + "jsonld-module": "/lib/jsonld.js/0.4.11/js/jsonld", + "jsonld": "/lib/jsonld.js/0.4.11/js/jsonld", + "rdfstore": "/lib/rdf_store/0.9.7/dist/rdfstore", + "moment": "/lib/moment.min", + "underscore": "/lib/underscore-1.5.2.min", + } + }); + </script> + <script> + window.NS = { + dev: 'http://projects.bigasterisk.com/device/', + room: 'http://projects.bigasterisk.com/room/', + rdfs: 'http://www.w3.org/2000/01/rdf-schema#', + sensor: 'http://bigasterisk.com/homeauto/sensor/', + }; + </script> + <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> + <dom-module id="door-control"> + <style> + button { + min-width: 60px; + min-height: 40px; + } + div#form { + margin: 20px; + background: #dff5e5; + padding: 10px; + line-height: 40px; + text-align: center; + border: 2px groove white; + } + </style> + <template> + <div> + <streamed-graph url="graph/events" graph="{{graph}}"></streamed-graph> + </div> + + <div id="form"> + + <div> + Door is {{lockState}} + </div> + + <rdf-oneshot + id="unlockOneshot" + post="output" + subject="<http://projects.bigasterisk.com/room/frontDoorLock>" + predicate="<http://projects.bigasterisk.com/room/state>" + object="<http://projects.bigasterisk.com/room/unlocked>" + ></rdf-oneshot> + <button on-click="unlock">Unlock</button> + + <template is="dom-if" if="{{autoLockIsComing}}"> + <div> + Locking in {{autoLockInSec}} + </div> + </template> + </div> + </template> + <script> + HTMLImports.whenReady(function () { + Polymer({ + is: 'door-control', + properties: { + graph: { type: Object, notify: true, observer: "_onGraph" }, + lockState: { type: String }, + autoLockIsComing: { type: Boolean }, + autoLockInSec: { type: String}, + }, + behaviors: [BigastUri], + _onGraph: function(graph) { + if (!graph.graph) return; + const env = graph.graph.store.rdf; + graph.graph.quadStore.quads( + {subject: env.createNamedNode('room:frontDoorLock'), + predicate: env.createNamedNode('room:state'), + }, + (q) => { + this.lockState = q.object.toString().replace(/.*\//, ''); + }); + + this.autoLockIsComing = false; + graph.graph.quadStore.quads( + {subject: env.createNamedNode('room:frontDoorLock'), + predicate: env.createNamedNode('room:autoLockInSec'), + }, + (q) => { + this.autoLockIsComing = true; + this.autoLockInSec = parseFloat(q.object.valueOf()); + }); + }, + unlock: function() { + this.$.unlockOneshot.go(); + } + }); + }); + </script> + </dom-module> + <door-control></door-control> + </body> +</html>
--- a/service/frontDoorLock/makefile Wed Dec 12 01:10:48 2018 -0800 +++ b/service/frontDoorLock/makefile Wed Dec 12 01:11:54 2018 -0800 @@ -6,7 +6,7 @@ build_image: rm -rf tmp_ctx mkdir -p tmp_ctx - cp -a Dockerfile ../../lib/*.py *.py *.txt tmp_ctx + cp -a Dockerfile ../../lib/*.py *.py *.txt *.html tmp_ctx docker build --network=host -t ${TAG} tmp_ctx docker push ${TAG} rm -rf tmp_ctx @@ -16,4 +16,4 @@ docker run --rm -it --cap-add SYS_PTRACE --net=host bang6:5000/$(JOB)_x86:latest /bin/sh local_run: - docker run --rm -it --net=host bang6:5000/$(JOB)_x86:latest + docker run --rm -it --net=host -v `pwd`/index.html:/opt/index.html bang6:5000/$(JOB)_x86:latest python ./front_door_lock.py
--- a/service/frontDoorLock/requirements.txt Wed Dec 12 01:10:48 2018 -0800 +++ b/service/frontDoorLock/requirements.txt Wed Dec 12 01:11:54 2018 -0800 @@ -2,5 +2,5 @@ rdflib-jsonld==0.4.0 rdflib==4.2.2 twisted-mqtt==0.3.6 -https://projects.bigasterisk.com/rdfdb/rdfdb-0.3.0.tar.gz +https://projects.bigasterisk.com/rdfdb/rdfdb-0.6.0.tar.gz rx==1.6.1