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()