Mercurial > code > home > repos > homeauto
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/service/frontDoorLock/front_door_lock.py Tue Dec 11 19:13:06 2018 -0800 @@ -0,0 +1,87 @@ +from docopt import docopt +from patchablegraph import PatchableGraph, CycloneGraphHandler, CycloneGraphEventsHandler +from rdflib import Namespace, URIRef, Literal, Graph +from rdflib.parser import StringInputSource +from twisted.internet import reactor +import cyclone.web +import sys, logging +from mqtt_client import MqttClient + +ROOM = Namespace('http://projects.bigasterisk.com/room/') + +logging.basicConfig() +log = logging.getLogger() + +ctx = ROOM['frontDoorControl'] + +def rdfGraphBody(body, headers): + g = Graph() + g.parse(StringInputSource(body), format='nt') + return g + +def mqttMessageFromState(state): + return { + ROOM['locked']: b'OFF', + ROOM['unlocked']: b'ON', + }[state] + +def stateFromMqtt(msg): + return { + 'OFF': ROOM['locked'], + 'ON': ROOM['unlocked'], + }[msg.decode('ascii')] + +class OutputPage(cyclone.web.RequestHandler): + def put(self): + arg = self.request.arguments + if arg.get('s') and arg.get('p'): + subj = URIRef(arg['s'][-1]) + pred = URIRef(arg['p'][-1]) + obj = URIRef(self.request.body) + stmt = (subj, pred, obj) + else: + g = rdfGraphBody(self.request.body, self.request.headers) + assert len(g) == 1, len(g) + stmt = g.triples((None, None, None)).next() + self._onStatement(stmt) + + 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) + +if __name__ == '__main__': + arg = docopt(""" + Usage: front_door_lock.py [options] + + -v Verbose + """) + log.setLevel(logging.WARN) + if arg['-v']: + from twisted.python import log as twlog + twlog.startLogging(sys.stdout) + log.setLevel(logging.DEBUG) + + masterGraph = PatchableGraph() + mqtt = MqttClient(brokerPort=10010) + + def toGraph(payload): + log.debug('toGraph %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"/graph", CycloneGraphHandler, {'masterGraph': masterGraph}), + (r"/graph/events", CycloneGraphEventsHandler, + {'masterGraph': masterGraph}), + (r'/output', OutputPage), + ], mqtt=mqtt, masterGraph=masterGraph, debug=arg['-v']), interface='::') + log.warn('serving on %s', port) + + reactor.run()