Mercurial > code > home > repos > homeauto
comparison service/frontDoorLock/front_door_lock.py @ 1456:a81def58ecfb
index page rewrite. mqtt subscribe update. new store/events graph uri
Ignore-this: f0e59d3487ebfc90f8f4a830a7084023
darcs-hash:45bd18fecdb41c90b786a9e5909111e4a17bfcbe
author | drewp <drewp@bigasterisk.com> |
---|---|
date | Wed, 25 Sep 2019 17:36:44 -0700 |
parents | 7229daca9c9a |
children | a93fbf0d0daa |
comparison
equal
deleted
inserted
replaced
1455:1a7cd0cff3eb | 1456:a81def58ecfb |
---|---|
42 | 42 |
43 def requestUser(req): | 43 def requestUser(req): |
44 # what happened to the case-insens dict? | 44 # what happened to the case-insens dict? |
45 h = dict((k.lower(), v) for k,v in req.headers.items()) | 45 h = dict((k.lower(), v) for k,v in req.headers.items()) |
46 return URIRef(h['x-foaf-agent']) | 46 return URIRef(h['x-foaf-agent']) |
47 | 47 |
48 | 48 |
49 class OutputPage(cyclone.web.RequestHandler): | 49 class OutputPage(cyclone.web.RequestHandler): |
50 def put(self): | 50 def put(self): |
51 try: | 51 try: |
52 user = requestUser(self.request) | 52 user = requestUser(self.request) |
64 g = rdfGraphBody(self.request.body, self.request.headers) | 64 g = rdfGraphBody(self.request.body, self.request.headers) |
65 assert len(g) == 1, len(g) | 65 assert len(g) == 1, len(g) |
66 stmt = next(g.triples((None, None, None))) | 66 stmt = next(g.triples((None, None, None))) |
67 self._onStatement(user, stmt) | 67 self._onStatement(user, stmt) |
68 post = put | 68 post = put |
69 | 69 |
70 def _onStatement(self, user, stmt): | 70 def _onStatement(self, user, stmt): |
71 log.info('put statement %r', stmt) | 71 log.info('put statement %r', stmt) |
72 if stmt[0:2] == (ROOM['frontDoorLock'], ROOM['state']): | 72 if stmt[0:2] == (ROOM['frontDoorLock'], ROOM['state']): |
73 if stmt[2] == ROOM['unlocked']: | 73 if stmt[2] == ROOM['unlocked']: |
74 log.info('unlock for %r', user) | 74 log.info('unlock for %r', user) |
86 user = requestUser(self.request) | 86 user = requestUser(self.request) |
87 except KeyError: | 87 except KeyError: |
88 log.warn('request without x-foaf-agent: %s', h) | 88 log.warn('request without x-foaf-agent: %s', h) |
89 self.set_status(403, 'need x-foaf-agent') | 89 self.set_status(403, 'need x-foaf-agent') |
90 return | 90 return |
91 | 91 |
92 state = self.request.body.strip().decode('ascii') | 92 state = self.request.body.strip().decode('ascii') |
93 if state == 'unlock': | 93 if state == 'unlock': |
94 self.settings.autoLock.onUnlockedStmt() | 94 self.settings.autoLock.onUnlockedStmt() |
95 self.settings.mqtt.publish(espName + b"/switch/strike/command", b'ON') | 95 self.settings.mqtt.publish(espName + b"/switch/strike/command", b'ON') |
96 if state == 'lock': | 96 if state == 'lock': |
97 self.settings.autoLock.onLockedStmt() | 97 self.settings.autoLock.onLockedStmt() |
98 self.settings.mqtt.publish(espName + b"/switch/strike/command", b'OFF') | 98 self.settings.mqtt.publish(espName + b"/switch/strike/command", b'OFF') |
99 | 99 |
100 | 100 |
101 class AutoLock(object): | 101 class AutoLock(object): |
102 def __init__(self, masterGraph, mqtt): | 102 def __init__(self, masterGraph, mqtt): |
103 self.masterGraph = masterGraph | 103 self.masterGraph = masterGraph |
104 self.mqtt = mqtt | 104 self.mqtt = mqtt |
105 self.timeUnlocked = None | 105 self.timeUnlocked = None |
106 self.autoLockSec = 6 | 106 self.autoLockSec = 6 |
107 self.subj = ROOM['frontDoorLock'] | 107 self.subj = ROOM['frontDoorLock'] |
108 task.LoopingCall(self.pollCheck).start(1) | 108 task.LoopingCall(self.pollCheck).start(1) |
109 | 109 |
110 def relock(self): | 110 def relock(self): |
111 log.info('autolock is up: requesting lock') | 111 log.info('autolock is up: requesting lock') |
133 def pollCheck(self): | 133 def pollCheck(self): |
134 try: | 134 try: |
135 self.check() | 135 self.check() |
136 except Exception: | 136 except Exception: |
137 log.exception('poll failed') | 137 log.exception('poll failed') |
138 | 138 |
139 def check(self): | 139 def check(self): |
140 g = self.masterGraph | 140 g = self.masterGraph |
141 now = time.time() | 141 now = time.time() |
142 state = g._graph.value(self.subj, ROOM['state']) | 142 state = g._graph.value(self.subj, ROOM['state']) |
143 if state == ROOM['unlocked']: | 143 if state == ROOM['unlocked']: |
158 else: | 158 else: |
159 self.clearReport() | 159 self.clearReport() |
160 | 160 |
161 def onUnlockedStmt(self): | 161 def onUnlockedStmt(self): |
162 self.timeUnlocked = None | 162 self.timeUnlocked = None |
163 | 163 |
164 def onLockedStmt(self): | 164 def onLockedStmt(self): |
165 pass | 165 pass |
166 | 166 |
167 class BluetoothButton(cyclone.web.RequestHandler): | 167 class BluetoothButton(cyclone.web.RequestHandler): |
168 def post(self): | 168 def post(self): |
171 if body['addr'] == 'zz:zz:zz:zz:zz:zz' and body['key'] == 'top': | 171 if body['addr'] == 'zz:zz:zz:zz:zz:zz' and body['key'] == 'top': |
172 log.info('unlock for %r', body['addr']) | 172 log.info('unlock for %r', body['addr']) |
173 self.settings.mqtt.publish( | 173 self.settings.mqtt.publish( |
174 espName + b"/switch/strike/command", b'ON') | 174 espName + b"/switch/strike/command", b'ON') |
175 | 175 |
176 | 176 |
177 if __name__ == '__main__': | 177 if __name__ == '__main__': |
178 arg = docopt(""" | 178 arg = docopt(""" |
179 Usage: front_door_lock.py [options] | 179 Usage: front_door_lock.py [options] |
180 | 180 |
181 -v Verbose | 181 -v Verbose |
183 verboseLogging(arg['-v']) | 183 verboseLogging(arg['-v']) |
184 | 184 |
185 masterGraph = PatchableGraph() | 185 masterGraph = PatchableGraph() |
186 mqtt = MqttClient(brokerPort=10010) | 186 mqtt = MqttClient(brokerPort=10010) |
187 autoclose = AutoLock(masterGraph, mqtt) | 187 autoclose = AutoLock(masterGraph, mqtt) |
188 | |
189 def toGraph(payload): | 188 def toGraph(payload): |
190 log.info('mqtt->graph %r', payload) | 189 log.info('mqtt->graph %r', payload) |
191 masterGraph.patchObject(ctx, ROOM['frontDoorLock'], ROOM['state'], | 190 masterGraph.patchObject(ctx, ROOM['frontDoorLock'], ROOM['state'], |
192 stateFromMqtt(payload)) | 191 stateFromMqtt(payload)) |
193 | 192 |
194 mqtt.subscribe(espName + b"/switch/strike/state").subscribe(on_next=toGraph) | 193 sub = mqtt.subscribe(espName + b"/switch/strike/state") |
194 sub.subscribe(on_next=toGraph) | |
195 | 195 |
196 def setEspState(payload): | 196 def setEspState(payload): |
197 log.info('esp state change %r', payload) | 197 log.info('esp state change %r', payload) |
198 masterGraph.patchObject(ctx, ROOM['frontDoorLock'], ROOM['espMqttConnection'], | 198 masterGraph.patchObject(ctx, ROOM['frontDoorLock'], ROOM['espMqttConnection'], |
199 ROOM['mqtt' + payload.decode('ascii').capitalize()]) | 199 ROOM['mqtt' + payload.decode('ascii').capitalize()]) |
200 | 200 |
201 mqtt.subscribe(espName + b"/status").subscribe(on_next=setEspState) | 201 sub = mqtt.subscribe(espName + b"/status") |
202 | 202 sub.subscribe(on_next=setEspState) |
203 | |
203 port = 10011 | 204 port = 10011 |
204 reactor.listenTCP(port, cyclone.web.Application( | 205 reactor.listenTCP(port, cyclone.web.Application( |
205 [ | 206 [ |
206 (r"/()", cyclone.web.StaticFileHandler, | 207 (r"/()", cyclone.web.StaticFileHandler, |
207 {"path": ".", "default_filename": "index.html"}), | 208 {"path": ".", "default_filename": "index.html"}), |