Mercurial > code > home > repos > homeauto
annotate service/frontDoorLock/front_door_lock.py @ 425:d495d4382a07
comments and console layout
Ignore-this: b45fcf8177a1200c126b80bf9f43aafa
author | drewp@bigasterisk.com |
---|---|
date | Thu, 04 Apr 2019 02:14:48 -0700 |
parents | 67cebf7a14de |
children | bfe555dd0c91 |
rev | line source |
---|---|
425 | 1 """ |
2 :frontDoorLock :state :locked/:unlocked | |
3 is the true state of the lock, maintained in this process. | |
4 | |
5 put :frontDoorLock :state ?s to this /output to request a change. | |
6 | |
7 reasoning can infer :frontDoorLock :putState ?s to do that put request. | |
8 """ | |
377
5b690bfc31b2
docker/etc initial version of front door mqtt<->rdf using some rx
drewp@bigasterisk.com
parents:
diff
changeset
|
9 from docopt import docopt |
5b690bfc31b2
docker/etc initial version of front door mqtt<->rdf using some rx
drewp@bigasterisk.com
parents:
diff
changeset
|
10 from patchablegraph import PatchableGraph, CycloneGraphHandler, CycloneGraphEventsHandler |
5b690bfc31b2
docker/etc initial version of front door mqtt<->rdf using some rx
drewp@bigasterisk.com
parents:
diff
changeset
|
11 from rdflib import Namespace, URIRef, Literal, Graph |
5b690bfc31b2
docker/etc initial version of front door mqtt<->rdf using some rx
drewp@bigasterisk.com
parents:
diff
changeset
|
12 from rdflib.parser import StringInputSource |
379
67cebf7a14de
frontdoor autolock. logging improvements. use simpler mqtt interface.
drewp@bigasterisk.com
parents:
377
diff
changeset
|
13 from twisted.internet import reactor, task |
377
5b690bfc31b2
docker/etc initial version of front door mqtt<->rdf using some rx
drewp@bigasterisk.com
parents:
diff
changeset
|
14 import cyclone.web |
379
67cebf7a14de
frontdoor autolock. logging improvements. use simpler mqtt interface.
drewp@bigasterisk.com
parents:
377
diff
changeset
|
15 import sys, logging, time |
377
5b690bfc31b2
docker/etc initial version of front door mqtt<->rdf using some rx
drewp@bigasterisk.com
parents:
diff
changeset
|
16 from mqtt_client import MqttClient |
379
67cebf7a14de
frontdoor autolock. logging improvements. use simpler mqtt interface.
drewp@bigasterisk.com
parents:
377
diff
changeset
|
17 from logsetup import log, enableTwistedLog |
377
5b690bfc31b2
docker/etc initial version of front door mqtt<->rdf using some rx
drewp@bigasterisk.com
parents:
diff
changeset
|
18 |
5b690bfc31b2
docker/etc initial version of front door mqtt<->rdf using some rx
drewp@bigasterisk.com
parents:
diff
changeset
|
19 ROOM = Namespace('http://projects.bigasterisk.com/room/') |
5b690bfc31b2
docker/etc initial version of front door mqtt<->rdf using some rx
drewp@bigasterisk.com
parents:
diff
changeset
|
20 |
5b690bfc31b2
docker/etc initial version of front door mqtt<->rdf using some rx
drewp@bigasterisk.com
parents:
diff
changeset
|
21 ctx = ROOM['frontDoorControl'] |
5b690bfc31b2
docker/etc initial version of front door mqtt<->rdf using some rx
drewp@bigasterisk.com
parents:
diff
changeset
|
22 |
5b690bfc31b2
docker/etc initial version of front door mqtt<->rdf using some rx
drewp@bigasterisk.com
parents:
diff
changeset
|
23 def rdfGraphBody(body, headers): |
5b690bfc31b2
docker/etc initial version of front door mqtt<->rdf using some rx
drewp@bigasterisk.com
parents:
diff
changeset
|
24 g = Graph() |
5b690bfc31b2
docker/etc initial version of front door mqtt<->rdf using some rx
drewp@bigasterisk.com
parents:
diff
changeset
|
25 g.parse(StringInputSource(body), format='nt') |
5b690bfc31b2
docker/etc initial version of front door mqtt<->rdf using some rx
drewp@bigasterisk.com
parents:
diff
changeset
|
26 return g |
5b690bfc31b2
docker/etc initial version of front door mqtt<->rdf using some rx
drewp@bigasterisk.com
parents:
diff
changeset
|
27 |
5b690bfc31b2
docker/etc initial version of front door mqtt<->rdf using some rx
drewp@bigasterisk.com
parents:
diff
changeset
|
28 def mqttMessageFromState(state): |
5b690bfc31b2
docker/etc initial version of front door mqtt<->rdf using some rx
drewp@bigasterisk.com
parents:
diff
changeset
|
29 return { |
5b690bfc31b2
docker/etc initial version of front door mqtt<->rdf using some rx
drewp@bigasterisk.com
parents:
diff
changeset
|
30 ROOM['locked']: b'OFF', |
5b690bfc31b2
docker/etc initial version of front door mqtt<->rdf using some rx
drewp@bigasterisk.com
parents:
diff
changeset
|
31 ROOM['unlocked']: b'ON', |
5b690bfc31b2
docker/etc initial version of front door mqtt<->rdf using some rx
drewp@bigasterisk.com
parents:
diff
changeset
|
32 }[state] |
5b690bfc31b2
docker/etc initial version of front door mqtt<->rdf using some rx
drewp@bigasterisk.com
parents:
diff
changeset
|
33 |
5b690bfc31b2
docker/etc initial version of front door mqtt<->rdf using some rx
drewp@bigasterisk.com
parents:
diff
changeset
|
34 def stateFromMqtt(msg): |
5b690bfc31b2
docker/etc initial version of front door mqtt<->rdf using some rx
drewp@bigasterisk.com
parents:
diff
changeset
|
35 return { |
5b690bfc31b2
docker/etc initial version of front door mqtt<->rdf using some rx
drewp@bigasterisk.com
parents:
diff
changeset
|
36 'OFF': ROOM['locked'], |
5b690bfc31b2
docker/etc initial version of front door mqtt<->rdf using some rx
drewp@bigasterisk.com
parents:
diff
changeset
|
37 'ON': ROOM['unlocked'], |
5b690bfc31b2
docker/etc initial version of front door mqtt<->rdf using some rx
drewp@bigasterisk.com
parents:
diff
changeset
|
38 }[msg.decode('ascii')] |
5b690bfc31b2
docker/etc initial version of front door mqtt<->rdf using some rx
drewp@bigasterisk.com
parents:
diff
changeset
|
39 |
5b690bfc31b2
docker/etc initial version of front door mqtt<->rdf using some rx
drewp@bigasterisk.com
parents:
diff
changeset
|
40 class OutputPage(cyclone.web.RequestHandler): |
5b690bfc31b2
docker/etc initial version of front door mqtt<->rdf using some rx
drewp@bigasterisk.com
parents:
diff
changeset
|
41 def put(self): |
5b690bfc31b2
docker/etc initial version of front door mqtt<->rdf using some rx
drewp@bigasterisk.com
parents:
diff
changeset
|
42 arg = self.request.arguments |
5b690bfc31b2
docker/etc initial version of front door mqtt<->rdf using some rx
drewp@bigasterisk.com
parents:
diff
changeset
|
43 if arg.get('s') and arg.get('p'): |
5b690bfc31b2
docker/etc initial version of front door mqtt<->rdf using some rx
drewp@bigasterisk.com
parents:
diff
changeset
|
44 subj = URIRef(arg['s'][-1]) |
5b690bfc31b2
docker/etc initial version of front door mqtt<->rdf using some rx
drewp@bigasterisk.com
parents:
diff
changeset
|
45 pred = URIRef(arg['p'][-1]) |
5b690bfc31b2
docker/etc initial version of front door mqtt<->rdf using some rx
drewp@bigasterisk.com
parents:
diff
changeset
|
46 obj = URIRef(self.request.body) |
5b690bfc31b2
docker/etc initial version of front door mqtt<->rdf using some rx
drewp@bigasterisk.com
parents:
diff
changeset
|
47 stmt = (subj, pred, obj) |
5b690bfc31b2
docker/etc initial version of front door mqtt<->rdf using some rx
drewp@bigasterisk.com
parents:
diff
changeset
|
48 else: |
5b690bfc31b2
docker/etc initial version of front door mqtt<->rdf using some rx
drewp@bigasterisk.com
parents:
diff
changeset
|
49 g = rdfGraphBody(self.request.body, self.request.headers) |
5b690bfc31b2
docker/etc initial version of front door mqtt<->rdf using some rx
drewp@bigasterisk.com
parents:
diff
changeset
|
50 assert len(g) == 1, len(g) |
5b690bfc31b2
docker/etc initial version of front door mqtt<->rdf using some rx
drewp@bigasterisk.com
parents:
diff
changeset
|
51 stmt = g.triples((None, None, None)).next() |
5b690bfc31b2
docker/etc initial version of front door mqtt<->rdf using some rx
drewp@bigasterisk.com
parents:
diff
changeset
|
52 self._onStatement(stmt) |
379
67cebf7a14de
frontdoor autolock. logging improvements. use simpler mqtt interface.
drewp@bigasterisk.com
parents:
377
diff
changeset
|
53 post = put |
67cebf7a14de
frontdoor autolock. logging improvements. use simpler mqtt interface.
drewp@bigasterisk.com
parents:
377
diff
changeset
|
54 |
377
5b690bfc31b2
docker/etc initial version of front door mqtt<->rdf using some rx
drewp@bigasterisk.com
parents:
diff
changeset
|
55 def _onStatement(self, stmt): |
5b690bfc31b2
docker/etc initial version of front door mqtt<->rdf using some rx
drewp@bigasterisk.com
parents:
diff
changeset
|
56 if stmt[0:2] == (ROOM['frontDoorLock'], ROOM['state']): |
5b690bfc31b2
docker/etc initial version of front door mqtt<->rdf using some rx
drewp@bigasterisk.com
parents:
diff
changeset
|
57 self.settings.mqtt.publish("frontdoor/switch/strike/command", |
5b690bfc31b2
docker/etc initial version of front door mqtt<->rdf using some rx
drewp@bigasterisk.com
parents:
diff
changeset
|
58 mqttMessageFromState(stmt[2])) |
5b690bfc31b2
docker/etc initial version of front door mqtt<->rdf using some rx
drewp@bigasterisk.com
parents:
diff
changeset
|
59 return |
5b690bfc31b2
docker/etc initial version of front door mqtt<->rdf using some rx
drewp@bigasterisk.com
parents:
diff
changeset
|
60 log.warn("ignoring %s", stmt) |
379
67cebf7a14de
frontdoor autolock. logging improvements. use simpler mqtt interface.
drewp@bigasterisk.com
parents:
377
diff
changeset
|
61 |
67cebf7a14de
frontdoor autolock. logging improvements. use simpler mqtt interface.
drewp@bigasterisk.com
parents:
377
diff
changeset
|
62 |
67cebf7a14de
frontdoor autolock. logging improvements. use simpler mqtt interface.
drewp@bigasterisk.com
parents:
377
diff
changeset
|
63 class AutoLock(object): |
67cebf7a14de
frontdoor autolock. logging improvements. use simpler mqtt interface.
drewp@bigasterisk.com
parents:
377
diff
changeset
|
64 def __init__(self, masterGraph, mqtt): |
67cebf7a14de
frontdoor autolock. logging improvements. use simpler mqtt interface.
drewp@bigasterisk.com
parents:
377
diff
changeset
|
65 self.masterGraph = masterGraph |
67cebf7a14de
frontdoor autolock. logging improvements. use simpler mqtt interface.
drewp@bigasterisk.com
parents:
377
diff
changeset
|
66 self.mqtt = mqtt |
67cebf7a14de
frontdoor autolock. logging improvements. use simpler mqtt interface.
drewp@bigasterisk.com
parents:
377
diff
changeset
|
67 self.timeUnlocked = None |
67cebf7a14de
frontdoor autolock. logging improvements. use simpler mqtt interface.
drewp@bigasterisk.com
parents:
377
diff
changeset
|
68 self.autoLockSec = 5 |
67cebf7a14de
frontdoor autolock. logging improvements. use simpler mqtt interface.
drewp@bigasterisk.com
parents:
377
diff
changeset
|
69 self.subj = ROOM['frontDoorLock'] |
67cebf7a14de
frontdoor autolock. logging improvements. use simpler mqtt interface.
drewp@bigasterisk.com
parents:
377
diff
changeset
|
70 task.LoopingCall(self.check).start(1) |
67cebf7a14de
frontdoor autolock. logging improvements. use simpler mqtt interface.
drewp@bigasterisk.com
parents:
377
diff
changeset
|
71 |
67cebf7a14de
frontdoor autolock. logging improvements. use simpler mqtt interface.
drewp@bigasterisk.com
parents:
377
diff
changeset
|
72 def check(self): |
67cebf7a14de
frontdoor autolock. logging improvements. use simpler mqtt interface.
drewp@bigasterisk.com
parents:
377
diff
changeset
|
73 now = time.time() |
67cebf7a14de
frontdoor autolock. logging improvements. use simpler mqtt interface.
drewp@bigasterisk.com
parents:
377
diff
changeset
|
74 state = self.masterGraph._graph.value(self.subj, ROOM['state']) |
67cebf7a14de
frontdoor autolock. logging improvements. use simpler mqtt interface.
drewp@bigasterisk.com
parents:
377
diff
changeset
|
75 if state == ROOM['unlocked']: |
67cebf7a14de
frontdoor autolock. logging improvements. use simpler mqtt interface.
drewp@bigasterisk.com
parents:
377
diff
changeset
|
76 if self.timeUnlocked is None: |
67cebf7a14de
frontdoor autolock. logging improvements. use simpler mqtt interface.
drewp@bigasterisk.com
parents:
377
diff
changeset
|
77 self.timeUnlocked = now |
67cebf7a14de
frontdoor autolock. logging improvements. use simpler mqtt interface.
drewp@bigasterisk.com
parents:
377
diff
changeset
|
78 unlockedFor = now - self.timeUnlocked |
67cebf7a14de
frontdoor autolock. logging improvements. use simpler mqtt interface.
drewp@bigasterisk.com
parents:
377
diff
changeset
|
79 self.masterGraph.patchObject(ctx, self.subj, ROOM['unlockedForSec'], |
67cebf7a14de
frontdoor autolock. logging improvements. use simpler mqtt interface.
drewp@bigasterisk.com
parents:
377
diff
changeset
|
80 Literal(int(unlockedFor))) |
67cebf7a14de
frontdoor autolock. logging improvements. use simpler mqtt interface.
drewp@bigasterisk.com
parents:
377
diff
changeset
|
81 self.masterGraph.patchObject(ctx, self.subj, ROOM['autoLockInSec'], |
67cebf7a14de
frontdoor autolock. logging improvements. use simpler mqtt interface.
drewp@bigasterisk.com
parents:
377
diff
changeset
|
82 Literal(self.autoLockSec - int(unlockedFor))) |
67cebf7a14de
frontdoor autolock. logging improvements. use simpler mqtt interface.
drewp@bigasterisk.com
parents:
377
diff
changeset
|
83 if unlockedFor > self.autoLockSec: |
67cebf7a14de
frontdoor autolock. logging improvements. use simpler mqtt interface.
drewp@bigasterisk.com
parents:
377
diff
changeset
|
84 self.mqtt.publish("frontdoor/switch/strike/command", |
67cebf7a14de
frontdoor autolock. logging improvements. use simpler mqtt interface.
drewp@bigasterisk.com
parents:
377
diff
changeset
|
85 mqttMessageFromState(ROOM['locked'])) |
67cebf7a14de
frontdoor autolock. logging improvements. use simpler mqtt interface.
drewp@bigasterisk.com
parents:
377
diff
changeset
|
86 else: |
67cebf7a14de
frontdoor autolock. logging improvements. use simpler mqtt interface.
drewp@bigasterisk.com
parents:
377
diff
changeset
|
87 self.timeUnlocked = None |
67cebf7a14de
frontdoor autolock. logging improvements. use simpler mqtt interface.
drewp@bigasterisk.com
parents:
377
diff
changeset
|
88 self.masterGraph.patchObject(ctx, self.subj, ROOM['unlockedForSec'], None) |
67cebf7a14de
frontdoor autolock. logging improvements. use simpler mqtt interface.
drewp@bigasterisk.com
parents:
377
diff
changeset
|
89 self.masterGraph.patchObject(ctx, self.subj, ROOM['autoLockInSec'], None) |
67cebf7a14de
frontdoor autolock. logging improvements. use simpler mqtt interface.
drewp@bigasterisk.com
parents:
377
diff
changeset
|
90 |
377
5b690bfc31b2
docker/etc initial version of front door mqtt<->rdf using some rx
drewp@bigasterisk.com
parents:
diff
changeset
|
91 |
5b690bfc31b2
docker/etc initial version of front door mqtt<->rdf using some rx
drewp@bigasterisk.com
parents:
diff
changeset
|
92 if __name__ == '__main__': |
5b690bfc31b2
docker/etc initial version of front door mqtt<->rdf using some rx
drewp@bigasterisk.com
parents:
diff
changeset
|
93 arg = docopt(""" |
5b690bfc31b2
docker/etc initial version of front door mqtt<->rdf using some rx
drewp@bigasterisk.com
parents:
diff
changeset
|
94 Usage: front_door_lock.py [options] |
5b690bfc31b2
docker/etc initial version of front door mqtt<->rdf using some rx
drewp@bigasterisk.com
parents:
diff
changeset
|
95 |
5b690bfc31b2
docker/etc initial version of front door mqtt<->rdf using some rx
drewp@bigasterisk.com
parents:
diff
changeset
|
96 -v Verbose |
5b690bfc31b2
docker/etc initial version of front door mqtt<->rdf using some rx
drewp@bigasterisk.com
parents:
diff
changeset
|
97 """) |
379
67cebf7a14de
frontdoor autolock. logging improvements. use simpler mqtt interface.
drewp@bigasterisk.com
parents:
377
diff
changeset
|
98 log.setLevel(logging.INFO) |
377
5b690bfc31b2
docker/etc initial version of front door mqtt<->rdf using some rx
drewp@bigasterisk.com
parents:
diff
changeset
|
99 if arg['-v']: |
379
67cebf7a14de
frontdoor autolock. logging improvements. use simpler mqtt interface.
drewp@bigasterisk.com
parents:
377
diff
changeset
|
100 enableTwistedLog() |
377
5b690bfc31b2
docker/etc initial version of front door mqtt<->rdf using some rx
drewp@bigasterisk.com
parents:
diff
changeset
|
101 log.setLevel(logging.DEBUG) |
5b690bfc31b2
docker/etc initial version of front door mqtt<->rdf using some rx
drewp@bigasterisk.com
parents:
diff
changeset
|
102 |
5b690bfc31b2
docker/etc initial version of front door mqtt<->rdf using some rx
drewp@bigasterisk.com
parents:
diff
changeset
|
103 masterGraph = PatchableGraph() |
5b690bfc31b2
docker/etc initial version of front door mqtt<->rdf using some rx
drewp@bigasterisk.com
parents:
diff
changeset
|
104 mqtt = MqttClient(brokerPort=10010) |
379
67cebf7a14de
frontdoor autolock. logging improvements. use simpler mqtt interface.
drewp@bigasterisk.com
parents:
377
diff
changeset
|
105 autoclose = AutoLock(masterGraph, mqtt) |
377
5b690bfc31b2
docker/etc initial version of front door mqtt<->rdf using some rx
drewp@bigasterisk.com
parents:
diff
changeset
|
106 |
5b690bfc31b2
docker/etc initial version of front door mqtt<->rdf using some rx
drewp@bigasterisk.com
parents:
diff
changeset
|
107 def toGraph(payload): |
379
67cebf7a14de
frontdoor autolock. logging improvements. use simpler mqtt interface.
drewp@bigasterisk.com
parents:
377
diff
changeset
|
108 log.info('mqtt->graph %r', payload) |
377
5b690bfc31b2
docker/etc initial version of front door mqtt<->rdf using some rx
drewp@bigasterisk.com
parents:
diff
changeset
|
109 masterGraph.patchObject(ctx, ROOM['frontDoorLock'], ROOM['state'], |
5b690bfc31b2
docker/etc initial version of front door mqtt<->rdf using some rx
drewp@bigasterisk.com
parents:
diff
changeset
|
110 stateFromMqtt(payload)) |
5b690bfc31b2
docker/etc initial version of front door mqtt<->rdf using some rx
drewp@bigasterisk.com
parents:
diff
changeset
|
111 |
5b690bfc31b2
docker/etc initial version of front door mqtt<->rdf using some rx
drewp@bigasterisk.com
parents:
diff
changeset
|
112 mqtt.subscribe("frontdoor/switch/strike/state").subscribe(on_next=toGraph) |
5b690bfc31b2
docker/etc initial version of front door mqtt<->rdf using some rx
drewp@bigasterisk.com
parents:
diff
changeset
|
113 port = 10011 |
5b690bfc31b2
docker/etc initial version of front door mqtt<->rdf using some rx
drewp@bigasterisk.com
parents:
diff
changeset
|
114 reactor.listenTCP(port, cyclone.web.Application([ |
379
67cebf7a14de
frontdoor autolock. logging improvements. use simpler mqtt interface.
drewp@bigasterisk.com
parents:
377
diff
changeset
|
115 (r"/()", cyclone.web.StaticFileHandler, |
67cebf7a14de
frontdoor autolock. logging improvements. use simpler mqtt interface.
drewp@bigasterisk.com
parents:
377
diff
changeset
|
116 {"path": ".", "default_filename": "index.html"}), |
377
5b690bfc31b2
docker/etc initial version of front door mqtt<->rdf using some rx
drewp@bigasterisk.com
parents:
diff
changeset
|
117 (r"/graph", CycloneGraphHandler, {'masterGraph': masterGraph}), |
5b690bfc31b2
docker/etc initial version of front door mqtt<->rdf using some rx
drewp@bigasterisk.com
parents:
diff
changeset
|
118 (r"/graph/events", CycloneGraphEventsHandler, |
5b690bfc31b2
docker/etc initial version of front door mqtt<->rdf using some rx
drewp@bigasterisk.com
parents:
diff
changeset
|
119 {'masterGraph': masterGraph}), |
5b690bfc31b2
docker/etc initial version of front door mqtt<->rdf using some rx
drewp@bigasterisk.com
parents:
diff
changeset
|
120 (r'/output', OutputPage), |
5b690bfc31b2
docker/etc initial version of front door mqtt<->rdf using some rx
drewp@bigasterisk.com
parents:
diff
changeset
|
121 ], mqtt=mqtt, masterGraph=masterGraph, debug=arg['-v']), interface='::') |
5b690bfc31b2
docker/etc initial version of front door mqtt<->rdf using some rx
drewp@bigasterisk.com
parents:
diff
changeset
|
122 log.warn('serving on %s', port) |
5b690bfc31b2
docker/etc initial version of front door mqtt<->rdf using some rx
drewp@bigasterisk.com
parents:
diff
changeset
|
123 |
5b690bfc31b2
docker/etc initial version of front door mqtt<->rdf using some rx
drewp@bigasterisk.com
parents:
diff
changeset
|
124 reactor.run() |