Mercurial > code > home > repos > homeauto
comparison service/frontDoorLock/front_door_lock.py @ 1182:bd215f18e715
docker/etc initial version of front door mqtt<->rdf using some rx
Ignore-this: 87ea28bde75a5b0d35fe89d61f11090a
darcs-hash:7eb3a5f6c7b2153f118f86d0009e16f4c950b04f
author | drewp <drewp@bigasterisk.com> |
---|---|
date | Tue, 11 Dec 2018 19:13:06 -0800 |
parents | |
children | 67cebf7a14de |
comparison
equal
deleted
inserted
replaced
1181:0c366a029c49 | 1182:bd215f18e715 |
---|---|
1 from docopt import docopt | |
2 from patchablegraph import PatchableGraph, CycloneGraphHandler, CycloneGraphEventsHandler | |
3 from rdflib import Namespace, URIRef, Literal, Graph | |
4 from rdflib.parser import StringInputSource | |
5 from twisted.internet import reactor | |
6 import cyclone.web | |
7 import sys, logging | |
8 from mqtt_client import MqttClient | |
9 | |
10 ROOM = Namespace('http://projects.bigasterisk.com/room/') | |
11 | |
12 logging.basicConfig() | |
13 log = logging.getLogger() | |
14 | |
15 ctx = ROOM['frontDoorControl'] | |
16 | |
17 def rdfGraphBody(body, headers): | |
18 g = Graph() | |
19 g.parse(StringInputSource(body), format='nt') | |
20 return g | |
21 | |
22 def mqttMessageFromState(state): | |
23 return { | |
24 ROOM['locked']: b'OFF', | |
25 ROOM['unlocked']: b'ON', | |
26 }[state] | |
27 | |
28 def stateFromMqtt(msg): | |
29 return { | |
30 'OFF': ROOM['locked'], | |
31 'ON': ROOM['unlocked'], | |
32 }[msg.decode('ascii')] | |
33 | |
34 class OutputPage(cyclone.web.RequestHandler): | |
35 def put(self): | |
36 arg = self.request.arguments | |
37 if arg.get('s') and arg.get('p'): | |
38 subj = URIRef(arg['s'][-1]) | |
39 pred = URIRef(arg['p'][-1]) | |
40 obj = URIRef(self.request.body) | |
41 stmt = (subj, pred, obj) | |
42 else: | |
43 g = rdfGraphBody(self.request.body, self.request.headers) | |
44 assert len(g) == 1, len(g) | |
45 stmt = g.triples((None, None, None)).next() | |
46 self._onStatement(stmt) | |
47 | |
48 def _onStatement(self, stmt): | |
49 if stmt[0:2] == (ROOM['frontDoorLock'], ROOM['state']): | |
50 self.settings.mqtt.publish("frontdoor/switch/strike/command", | |
51 mqttMessageFromState(stmt[2])) | |
52 self.settings.masterGraph.patchObject(ctx, | |
53 stmt[0], stmt[1], stmt[2]) | |
54 return | |
55 log.warn("ignoring %s", stmt) | |
56 | |
57 if __name__ == '__main__': | |
58 arg = docopt(""" | |
59 Usage: front_door_lock.py [options] | |
60 | |
61 -v Verbose | |
62 """) | |
63 log.setLevel(logging.WARN) | |
64 if arg['-v']: | |
65 from twisted.python import log as twlog | |
66 twlog.startLogging(sys.stdout) | |
67 log.setLevel(logging.DEBUG) | |
68 | |
69 masterGraph = PatchableGraph() | |
70 mqtt = MqttClient(brokerPort=10010) | |
71 | |
72 def toGraph(payload): | |
73 log.debug('toGraph %r', payload) | |
74 masterGraph.patchObject(ctx, ROOM['frontDoorLock'], ROOM['state'], | |
75 stateFromMqtt(payload)) | |
76 | |
77 mqtt.subscribe("frontdoor/switch/strike/state").subscribe(on_next=toGraph) | |
78 port = 10011 | |
79 reactor.listenTCP(port, cyclone.web.Application([ | |
80 (r"/graph", CycloneGraphHandler, {'masterGraph': masterGraph}), | |
81 (r"/graph/events", CycloneGraphEventsHandler, | |
82 {'masterGraph': masterGraph}), | |
83 (r'/output', OutputPage), | |
84 ], mqtt=mqtt, masterGraph=masterGraph, debug=arg['-v']), interface='::') | |
85 log.warn('serving on %s', port) | |
86 | |
87 reactor.run() |