Mercurial > code > home > repos > homeauto
comparison service/frontDoorLock/front_door_lock.py @ 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 | 5b690bfc31b2 |
children | d495d4382a07 |
comparison
equal
deleted
inserted
replaced
378:b90d9321d2ce | 379:67cebf7a14de |
---|---|
1 from docopt import docopt | 1 from docopt import docopt |
2 from patchablegraph import PatchableGraph, CycloneGraphHandler, CycloneGraphEventsHandler | 2 from patchablegraph import PatchableGraph, CycloneGraphHandler, CycloneGraphEventsHandler |
3 from rdflib import Namespace, URIRef, Literal, Graph | 3 from rdflib import Namespace, URIRef, Literal, Graph |
4 from rdflib.parser import StringInputSource | 4 from rdflib.parser import StringInputSource |
5 from twisted.internet import reactor | 5 from twisted.internet import reactor, task |
6 import cyclone.web | 6 import cyclone.web |
7 import sys, logging | 7 import sys, logging, time |
8 from mqtt_client import MqttClient | 8 from mqtt_client import MqttClient |
9 from logsetup import log, enableTwistedLog | |
9 | 10 |
10 ROOM = Namespace('http://projects.bigasterisk.com/room/') | 11 ROOM = Namespace('http://projects.bigasterisk.com/room/') |
11 | |
12 logging.basicConfig() | |
13 log = logging.getLogger() | |
14 | 12 |
15 ctx = ROOM['frontDoorControl'] | 13 ctx = ROOM['frontDoorControl'] |
16 | 14 |
17 def rdfGraphBody(body, headers): | 15 def rdfGraphBody(body, headers): |
18 g = Graph() | 16 g = Graph() |
42 else: | 40 else: |
43 g = rdfGraphBody(self.request.body, self.request.headers) | 41 g = rdfGraphBody(self.request.body, self.request.headers) |
44 assert len(g) == 1, len(g) | 42 assert len(g) == 1, len(g) |
45 stmt = g.triples((None, None, None)).next() | 43 stmt = g.triples((None, None, None)).next() |
46 self._onStatement(stmt) | 44 self._onStatement(stmt) |
47 | 45 post = put |
46 | |
48 def _onStatement(self, stmt): | 47 def _onStatement(self, stmt): |
49 if stmt[0:2] == (ROOM['frontDoorLock'], ROOM['state']): | 48 if stmt[0:2] == (ROOM['frontDoorLock'], ROOM['state']): |
50 self.settings.mqtt.publish("frontdoor/switch/strike/command", | 49 self.settings.mqtt.publish("frontdoor/switch/strike/command", |
51 mqttMessageFromState(stmt[2])) | 50 mqttMessageFromState(stmt[2])) |
52 self.settings.masterGraph.patchObject(ctx, | |
53 stmt[0], stmt[1], stmt[2]) | |
54 return | 51 return |
55 log.warn("ignoring %s", stmt) | 52 log.warn("ignoring %s", stmt) |
53 | |
54 | |
55 class AutoLock(object): | |
56 def __init__(self, masterGraph, mqtt): | |
57 self.masterGraph = masterGraph | |
58 self.mqtt = mqtt | |
59 self.timeUnlocked = None | |
60 self.autoLockSec = 5 | |
61 self.subj = ROOM['frontDoorLock'] | |
62 task.LoopingCall(self.check).start(1) | |
63 | |
64 def check(self): | |
65 now = time.time() | |
66 state = self.masterGraph._graph.value(self.subj, ROOM['state']) | |
67 if state == ROOM['unlocked']: | |
68 if self.timeUnlocked is None: | |
69 self.timeUnlocked = now | |
70 unlockedFor = now - self.timeUnlocked | |
71 self.masterGraph.patchObject(ctx, self.subj, ROOM['unlockedForSec'], | |
72 Literal(int(unlockedFor))) | |
73 self.masterGraph.patchObject(ctx, self.subj, ROOM['autoLockInSec'], | |
74 Literal(self.autoLockSec - int(unlockedFor))) | |
75 if unlockedFor > self.autoLockSec: | |
76 self.mqtt.publish("frontdoor/switch/strike/command", | |
77 mqttMessageFromState(ROOM['locked'])) | |
78 else: | |
79 self.timeUnlocked = None | |
80 self.masterGraph.patchObject(ctx, self.subj, ROOM['unlockedForSec'], None) | |
81 self.masterGraph.patchObject(ctx, self.subj, ROOM['autoLockInSec'], None) | |
82 | |
56 | 83 |
57 if __name__ == '__main__': | 84 if __name__ == '__main__': |
58 arg = docopt(""" | 85 arg = docopt(""" |
59 Usage: front_door_lock.py [options] | 86 Usage: front_door_lock.py [options] |
60 | 87 |
61 -v Verbose | 88 -v Verbose |
62 """) | 89 """) |
63 log.setLevel(logging.WARN) | 90 log.setLevel(logging.INFO) |
64 if arg['-v']: | 91 if arg['-v']: |
65 from twisted.python import log as twlog | 92 enableTwistedLog() |
66 twlog.startLogging(sys.stdout) | |
67 log.setLevel(logging.DEBUG) | 93 log.setLevel(logging.DEBUG) |
68 | 94 |
69 masterGraph = PatchableGraph() | 95 masterGraph = PatchableGraph() |
70 mqtt = MqttClient(brokerPort=10010) | 96 mqtt = MqttClient(brokerPort=10010) |
97 autoclose = AutoLock(masterGraph, mqtt) | |
71 | 98 |
72 def toGraph(payload): | 99 def toGraph(payload): |
73 log.debug('toGraph %r', payload) | 100 log.info('mqtt->graph %r', payload) |
74 masterGraph.patchObject(ctx, ROOM['frontDoorLock'], ROOM['state'], | 101 masterGraph.patchObject(ctx, ROOM['frontDoorLock'], ROOM['state'], |
75 stateFromMqtt(payload)) | 102 stateFromMqtt(payload)) |
76 | 103 |
77 mqtt.subscribe("frontdoor/switch/strike/state").subscribe(on_next=toGraph) | 104 mqtt.subscribe("frontdoor/switch/strike/state").subscribe(on_next=toGraph) |
78 port = 10011 | 105 port = 10011 |
79 reactor.listenTCP(port, cyclone.web.Application([ | 106 reactor.listenTCP(port, cyclone.web.Application([ |
107 (r"/()", cyclone.web.StaticFileHandler, | |
108 {"path": ".", "default_filename": "index.html"}), | |
80 (r"/graph", CycloneGraphHandler, {'masterGraph': masterGraph}), | 109 (r"/graph", CycloneGraphHandler, {'masterGraph': masterGraph}), |
81 (r"/graph/events", CycloneGraphEventsHandler, | 110 (r"/graph/events", CycloneGraphEventsHandler, |
82 {'masterGraph': masterGraph}), | 111 {'masterGraph': masterGraph}), |
83 (r'/output', OutputPage), | 112 (r'/output', OutputPage), |
84 ], mqtt=mqtt, masterGraph=masterGraph, debug=arg['-v']), interface='::') | 113 ], mqtt=mqtt, masterGraph=masterGraph, debug=arg['-v']), interface='::') |