Mercurial > code > home > repos > homeauto
annotate service/frontDoorLock/front_door_lock.py @ 1380:7229daca9c9a
simple api checks for (any) user too
Ignore-this: 84192f452f44ba481f77629bf065f2d1
darcs-hash:f1b3dc8be5cefd577c09268c2564645c6529c22c
author | drewp <drewp@bigasterisk.com> |
---|---|
date | Mon, 06 May 2019 21:11:00 -0700 |
parents | baf1acaa9ac9 |
children | 013e2a89b345 |
rev | line source |
---|---|
1228 | 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 """ | |
1366 | 9 import time, json |
10 | |
1182
bd215f18e715
docker/etc initial version of front door mqtt<->rdf using some rx
drewp <drewp@bigasterisk.com>
parents:
diff
changeset
|
11 from docopt import docopt |
bd215f18e715
docker/etc initial version of front door mqtt<->rdf using some rx
drewp <drewp@bigasterisk.com>
parents:
diff
changeset
|
12 from rdflib import Namespace, URIRef, Literal, Graph |
bd215f18e715
docker/etc initial version of front door mqtt<->rdf using some rx
drewp <drewp@bigasterisk.com>
parents:
diff
changeset
|
13 from rdflib.parser import StringInputSource |
1184
c87e5c8eb8ab
frontdoor autolock. logging improvements. use simpler mqtt interface.
drewp <drewp@bigasterisk.com>
parents:
1182
diff
changeset
|
14 from twisted.internet import reactor, task |
1182
bd215f18e715
docker/etc initial version of front door mqtt<->rdf using some rx
drewp <drewp@bigasterisk.com>
parents:
diff
changeset
|
15 import cyclone.web |
1366 | 16 |
1182
bd215f18e715
docker/etc initial version of front door mqtt<->rdf using some rx
drewp <drewp@bigasterisk.com>
parents:
diff
changeset
|
17 from mqtt_client import MqttClient |
1366 | 18 from patchablegraph import PatchableGraph, CycloneGraphHandler, CycloneGraphEventsHandler |
19 from standardservice.logsetup import log, verboseLogging | |
1182
bd215f18e715
docker/etc initial version of front door mqtt<->rdf using some rx
drewp <drewp@bigasterisk.com>
parents:
diff
changeset
|
20 |
bd215f18e715
docker/etc initial version of front door mqtt<->rdf using some rx
drewp <drewp@bigasterisk.com>
parents:
diff
changeset
|
21 ROOM = Namespace('http://projects.bigasterisk.com/room/') |
bd215f18e715
docker/etc initial version of front door mqtt<->rdf using some rx
drewp <drewp@bigasterisk.com>
parents:
diff
changeset
|
22 |
bd215f18e715
docker/etc initial version of front door mqtt<->rdf using some rx
drewp <drewp@bigasterisk.com>
parents:
diff
changeset
|
23 ctx = ROOM['frontDoorControl'] |
1371
293d328a55d7
match esp hostname in py code
drewp <drewp@bigasterisk.com>
parents:
1366
diff
changeset
|
24 espName = b'frontdoorlock' # from door.yaml |
1182
bd215f18e715
docker/etc initial version of front door mqtt<->rdf using some rx
drewp <drewp@bigasterisk.com>
parents:
diff
changeset
|
25 |
bd215f18e715
docker/etc initial version of front door mqtt<->rdf using some rx
drewp <drewp@bigasterisk.com>
parents:
diff
changeset
|
26 def rdfGraphBody(body, headers): |
bd215f18e715
docker/etc initial version of front door mqtt<->rdf using some rx
drewp <drewp@bigasterisk.com>
parents:
diff
changeset
|
27 g = Graph() |
bd215f18e715
docker/etc initial version of front door mqtt<->rdf using some rx
drewp <drewp@bigasterisk.com>
parents:
diff
changeset
|
28 g.parse(StringInputSource(body), format='nt') |
bd215f18e715
docker/etc initial version of front door mqtt<->rdf using some rx
drewp <drewp@bigasterisk.com>
parents:
diff
changeset
|
29 return g |
bd215f18e715
docker/etc initial version of front door mqtt<->rdf using some rx
drewp <drewp@bigasterisk.com>
parents:
diff
changeset
|
30 |
1366 | 31 def mqttMessageFromState(state: URIRef): |
1182
bd215f18e715
docker/etc initial version of front door mqtt<->rdf using some rx
drewp <drewp@bigasterisk.com>
parents:
diff
changeset
|
32 return { |
bd215f18e715
docker/etc initial version of front door mqtt<->rdf using some rx
drewp <drewp@bigasterisk.com>
parents:
diff
changeset
|
33 ROOM['locked']: b'OFF', |
bd215f18e715
docker/etc initial version of front door mqtt<->rdf using some rx
drewp <drewp@bigasterisk.com>
parents:
diff
changeset
|
34 ROOM['unlocked']: b'ON', |
bd215f18e715
docker/etc initial version of front door mqtt<->rdf using some rx
drewp <drewp@bigasterisk.com>
parents:
diff
changeset
|
35 }[state] |
bd215f18e715
docker/etc initial version of front door mqtt<->rdf using some rx
drewp <drewp@bigasterisk.com>
parents:
diff
changeset
|
36 |
1366 | 37 def stateFromMqtt(msg: bytes): |
1182
bd215f18e715
docker/etc initial version of front door mqtt<->rdf using some rx
drewp <drewp@bigasterisk.com>
parents:
diff
changeset
|
38 return { |
1366 | 39 b'OFF': ROOM['locked'], |
40 b'ON': ROOM['unlocked'], | |
41 }[bytes(msg)] | |
1380
7229daca9c9a
simple api checks for (any) user too
drewp <drewp@bigasterisk.com>
parents:
1379
diff
changeset
|
42 |
7229daca9c9a
simple api checks for (any) user too
drewp <drewp@bigasterisk.com>
parents:
1379
diff
changeset
|
43 def requestUser(req): |
7229daca9c9a
simple api checks for (any) user too
drewp <drewp@bigasterisk.com>
parents:
1379
diff
changeset
|
44 # what happened to the case-insens dict? |
7229daca9c9a
simple api checks for (any) user too
drewp <drewp@bigasterisk.com>
parents:
1379
diff
changeset
|
45 h = dict((k.lower(), v) for k,v in req.headers.items()) |
7229daca9c9a
simple api checks for (any) user too
drewp <drewp@bigasterisk.com>
parents:
1379
diff
changeset
|
46 return URIRef(h['x-foaf-agent']) |
1182
bd215f18e715
docker/etc initial version of front door mqtt<->rdf using some rx
drewp <drewp@bigasterisk.com>
parents:
diff
changeset
|
47 |
1380
7229daca9c9a
simple api checks for (any) user too
drewp <drewp@bigasterisk.com>
parents:
1379
diff
changeset
|
48 |
1182
bd215f18e715
docker/etc initial version of front door mqtt<->rdf using some rx
drewp <drewp@bigasterisk.com>
parents:
diff
changeset
|
49 class OutputPage(cyclone.web.RequestHandler): |
bd215f18e715
docker/etc initial version of front door mqtt<->rdf using some rx
drewp <drewp@bigasterisk.com>
parents:
diff
changeset
|
50 def put(self): |
1229
02e4b84821d5
talk to store graph, second button for holding unlocked, etc
drewp <drewp@bigasterisk.com>
parents:
1228
diff
changeset
|
51 try: |
1380
7229daca9c9a
simple api checks for (any) user too
drewp <drewp@bigasterisk.com>
parents:
1379
diff
changeset
|
52 user = requestUser(self.request) |
1229
02e4b84821d5
talk to store graph, second button for holding unlocked, etc
drewp <drewp@bigasterisk.com>
parents:
1228
diff
changeset
|
53 except KeyError: |
1366 | 54 log.warn('request without x-foaf-agent: %s', h) |
1229
02e4b84821d5
talk to store graph, second button for holding unlocked, etc
drewp <drewp@bigasterisk.com>
parents:
1228
diff
changeset
|
55 self.set_status(403, 'need x-foaf-agent') |
02e4b84821d5
talk to store graph, second button for holding unlocked, etc
drewp <drewp@bigasterisk.com>
parents:
1228
diff
changeset
|
56 return |
1182
bd215f18e715
docker/etc initial version of front door mqtt<->rdf using some rx
drewp <drewp@bigasterisk.com>
parents:
diff
changeset
|
57 arg = self.request.arguments |
bd215f18e715
docker/etc initial version of front door mqtt<->rdf using some rx
drewp <drewp@bigasterisk.com>
parents:
diff
changeset
|
58 if arg.get('s') and arg.get('p'): |
bd215f18e715
docker/etc initial version of front door mqtt<->rdf using some rx
drewp <drewp@bigasterisk.com>
parents:
diff
changeset
|
59 subj = URIRef(arg['s'][-1]) |
bd215f18e715
docker/etc initial version of front door mqtt<->rdf using some rx
drewp <drewp@bigasterisk.com>
parents:
diff
changeset
|
60 pred = URIRef(arg['p'][-1]) |
1366 | 61 obj = URIRef(self.request.body.strip().decode('ascii')) |
1182
bd215f18e715
docker/etc initial version of front door mqtt<->rdf using some rx
drewp <drewp@bigasterisk.com>
parents:
diff
changeset
|
62 stmt = (subj, pred, obj) |
bd215f18e715
docker/etc initial version of front door mqtt<->rdf using some rx
drewp <drewp@bigasterisk.com>
parents:
diff
changeset
|
63 else: |
bd215f18e715
docker/etc initial version of front door mqtt<->rdf using some rx
drewp <drewp@bigasterisk.com>
parents:
diff
changeset
|
64 g = rdfGraphBody(self.request.body, self.request.headers) |
bd215f18e715
docker/etc initial version of front door mqtt<->rdf using some rx
drewp <drewp@bigasterisk.com>
parents:
diff
changeset
|
65 assert len(g) == 1, len(g) |
1366 | 66 stmt = next(g.triples((None, None, None))) |
1229
02e4b84821d5
talk to store graph, second button for holding unlocked, etc
drewp <drewp@bigasterisk.com>
parents:
1228
diff
changeset
|
67 self._onStatement(user, stmt) |
1184
c87e5c8eb8ab
frontdoor autolock. logging improvements. use simpler mqtt interface.
drewp <drewp@bigasterisk.com>
parents:
1182
diff
changeset
|
68 post = put |
c87e5c8eb8ab
frontdoor autolock. logging improvements. use simpler mqtt interface.
drewp <drewp@bigasterisk.com>
parents:
1182
diff
changeset
|
69 |
1229
02e4b84821d5
talk to store graph, second button for holding unlocked, etc
drewp <drewp@bigasterisk.com>
parents:
1228
diff
changeset
|
70 def _onStatement(self, user, stmt): |
02e4b84821d5
talk to store graph, second button for holding unlocked, etc
drewp <drewp@bigasterisk.com>
parents:
1228
diff
changeset
|
71 log.info('put statement %r', stmt) |
1182
bd215f18e715
docker/etc initial version of front door mqtt<->rdf using some rx
drewp <drewp@bigasterisk.com>
parents:
diff
changeset
|
72 if stmt[0:2] == (ROOM['frontDoorLock'], ROOM['state']): |
1229
02e4b84821d5
talk to store graph, second button for holding unlocked, etc
drewp <drewp@bigasterisk.com>
parents:
1228
diff
changeset
|
73 if stmt[2] == ROOM['unlocked']: |
02e4b84821d5
talk to store graph, second button for holding unlocked, etc
drewp <drewp@bigasterisk.com>
parents:
1228
diff
changeset
|
74 log.info('unlock for %r', user) |
02e4b84821d5
talk to store graph, second button for holding unlocked, etc
drewp <drewp@bigasterisk.com>
parents:
1228
diff
changeset
|
75 self.settings.autoLock.onUnlockedStmt() |
02e4b84821d5
talk to store graph, second button for holding unlocked, etc
drewp <drewp@bigasterisk.com>
parents:
1228
diff
changeset
|
76 if stmt[2] == ROOM['locked']: |
02e4b84821d5
talk to store graph, second button for holding unlocked, etc
drewp <drewp@bigasterisk.com>
parents:
1228
diff
changeset
|
77 self.settings.autoLock.onLockedStmt() |
1371
293d328a55d7
match esp hostname in py code
drewp <drewp@bigasterisk.com>
parents:
1366
diff
changeset
|
78 self.settings.mqtt.publish(espName + b"/switch/strike/command", |
1182
bd215f18e715
docker/etc initial version of front door mqtt<->rdf using some rx
drewp <drewp@bigasterisk.com>
parents:
diff
changeset
|
79 mqttMessageFromState(stmt[2])) |
bd215f18e715
docker/etc initial version of front door mqtt<->rdf using some rx
drewp <drewp@bigasterisk.com>
parents:
diff
changeset
|
80 return |
bd215f18e715
docker/etc initial version of front door mqtt<->rdf using some rx
drewp <drewp@bigasterisk.com>
parents:
diff
changeset
|
81 log.warn("ignoring %s", stmt) |
1184
c87e5c8eb8ab
frontdoor autolock. logging improvements. use simpler mqtt interface.
drewp <drewp@bigasterisk.com>
parents:
1182
diff
changeset
|
82 |
1379
baf1acaa9ac9
new simple mode that can set the door without rdf
drewp <drewp@bigasterisk.com>
parents:
1378
diff
changeset
|
83 class SimpleState(cyclone.web.RequestHandler): |
baf1acaa9ac9
new simple mode that can set the door without rdf
drewp <drewp@bigasterisk.com>
parents:
1378
diff
changeset
|
84 def post(self): |
1380
7229daca9c9a
simple api checks for (any) user too
drewp <drewp@bigasterisk.com>
parents:
1379
diff
changeset
|
85 try: |
7229daca9c9a
simple api checks for (any) user too
drewp <drewp@bigasterisk.com>
parents:
1379
diff
changeset
|
86 user = requestUser(self.request) |
7229daca9c9a
simple api checks for (any) user too
drewp <drewp@bigasterisk.com>
parents:
1379
diff
changeset
|
87 except KeyError: |
7229daca9c9a
simple api checks for (any) user too
drewp <drewp@bigasterisk.com>
parents:
1379
diff
changeset
|
88 log.warn('request without x-foaf-agent: %s', h) |
7229daca9c9a
simple api checks for (any) user too
drewp <drewp@bigasterisk.com>
parents:
1379
diff
changeset
|
89 self.set_status(403, 'need x-foaf-agent') |
7229daca9c9a
simple api checks for (any) user too
drewp <drewp@bigasterisk.com>
parents:
1379
diff
changeset
|
90 return |
7229daca9c9a
simple api checks for (any) user too
drewp <drewp@bigasterisk.com>
parents:
1379
diff
changeset
|
91 |
1379
baf1acaa9ac9
new simple mode that can set the door without rdf
drewp <drewp@bigasterisk.com>
parents:
1378
diff
changeset
|
92 state = self.request.body.strip().decode('ascii') |
baf1acaa9ac9
new simple mode that can set the door without rdf
drewp <drewp@bigasterisk.com>
parents:
1378
diff
changeset
|
93 if state == 'unlock': |
baf1acaa9ac9
new simple mode that can set the door without rdf
drewp <drewp@bigasterisk.com>
parents:
1378
diff
changeset
|
94 self.settings.autoLock.onUnlockedStmt() |
baf1acaa9ac9
new simple mode that can set the door without rdf
drewp <drewp@bigasterisk.com>
parents:
1378
diff
changeset
|
95 self.settings.mqtt.publish(espName + b"/switch/strike/command", b'ON') |
baf1acaa9ac9
new simple mode that can set the door without rdf
drewp <drewp@bigasterisk.com>
parents:
1378
diff
changeset
|
96 if state == 'lock': |
baf1acaa9ac9
new simple mode that can set the door without rdf
drewp <drewp@bigasterisk.com>
parents:
1378
diff
changeset
|
97 self.settings.autoLock.onLockedStmt() |
baf1acaa9ac9
new simple mode that can set the door without rdf
drewp <drewp@bigasterisk.com>
parents:
1378
diff
changeset
|
98 self.settings.mqtt.publish(espName + b"/switch/strike/command", b'OFF') |
baf1acaa9ac9
new simple mode that can set the door without rdf
drewp <drewp@bigasterisk.com>
parents:
1378
diff
changeset
|
99 |
1184
c87e5c8eb8ab
frontdoor autolock. logging improvements. use simpler mqtt interface.
drewp <drewp@bigasterisk.com>
parents:
1182
diff
changeset
|
100 |
c87e5c8eb8ab
frontdoor autolock. logging improvements. use simpler mqtt interface.
drewp <drewp@bigasterisk.com>
parents:
1182
diff
changeset
|
101 class AutoLock(object): |
c87e5c8eb8ab
frontdoor autolock. logging improvements. use simpler mqtt interface.
drewp <drewp@bigasterisk.com>
parents:
1182
diff
changeset
|
102 def __init__(self, masterGraph, mqtt): |
c87e5c8eb8ab
frontdoor autolock. logging improvements. use simpler mqtt interface.
drewp <drewp@bigasterisk.com>
parents:
1182
diff
changeset
|
103 self.masterGraph = masterGraph |
c87e5c8eb8ab
frontdoor autolock. logging improvements. use simpler mqtt interface.
drewp <drewp@bigasterisk.com>
parents:
1182
diff
changeset
|
104 self.mqtt = mqtt |
c87e5c8eb8ab
frontdoor autolock. logging improvements. use simpler mqtt interface.
drewp <drewp@bigasterisk.com>
parents:
1182
diff
changeset
|
105 self.timeUnlocked = None |
1229
02e4b84821d5
talk to store graph, second button for holding unlocked, etc
drewp <drewp@bigasterisk.com>
parents:
1228
diff
changeset
|
106 self.autoLockSec = 6 |
1184
c87e5c8eb8ab
frontdoor autolock. logging improvements. use simpler mqtt interface.
drewp <drewp@bigasterisk.com>
parents:
1182
diff
changeset
|
107 self.subj = ROOM['frontDoorLock'] |
1365
e6c6574f3d24
fix a hang bug where polling stopped
drewp <drewp@bigasterisk.com>
parents:
1271
diff
changeset
|
108 task.LoopingCall(self.pollCheck).start(1) |
1184
c87e5c8eb8ab
frontdoor autolock. logging improvements. use simpler mqtt interface.
drewp <drewp@bigasterisk.com>
parents:
1182
diff
changeset
|
109 |
1229
02e4b84821d5
talk to store graph, second button for holding unlocked, etc
drewp <drewp@bigasterisk.com>
parents:
1228
diff
changeset
|
110 def relock(self): |
02e4b84821d5
talk to store graph, second button for holding unlocked, etc
drewp <drewp@bigasterisk.com>
parents:
1228
diff
changeset
|
111 log.info('autolock is up: requesting lock') |
1371
293d328a55d7
match esp hostname in py code
drewp <drewp@bigasterisk.com>
parents:
1366
diff
changeset
|
112 self.mqtt.publish(espName + b"/switch/strike/command", |
1229
02e4b84821d5
talk to store graph, second button for holding unlocked, etc
drewp <drewp@bigasterisk.com>
parents:
1228
diff
changeset
|
113 mqttMessageFromState(ROOM['locked'])) |
02e4b84821d5
talk to store graph, second button for holding unlocked, etc
drewp <drewp@bigasterisk.com>
parents:
1228
diff
changeset
|
114 |
02e4b84821d5
talk to store graph, second button for holding unlocked, etc
drewp <drewp@bigasterisk.com>
parents:
1228
diff
changeset
|
115 def reportTimes(self, unlockedFor): |
02e4b84821d5
talk to store graph, second button for holding unlocked, etc
drewp <drewp@bigasterisk.com>
parents:
1228
diff
changeset
|
116 g = self.masterGraph |
02e4b84821d5
talk to store graph, second button for holding unlocked, etc
drewp <drewp@bigasterisk.com>
parents:
1228
diff
changeset
|
117 lockIn = self.autoLockSec - int(unlockedFor) |
02e4b84821d5
talk to store graph, second button for holding unlocked, etc
drewp <drewp@bigasterisk.com>
parents:
1228
diff
changeset
|
118 if lockIn < 0: |
1365
e6c6574f3d24
fix a hang bug where polling stopped
drewp <drewp@bigasterisk.com>
parents:
1271
diff
changeset
|
119 state = g._graph.value(self.subj, ROOM['state']) |
e6c6574f3d24
fix a hang bug where polling stopped
drewp <drewp@bigasterisk.com>
parents:
1271
diff
changeset
|
120 log.warn(f"timeUnlocked {self.timeUnlocked}, state {state}, " |
1379
baf1acaa9ac9
new simple mode that can set the door without rdf
drewp <drewp@bigasterisk.com>
parents:
1378
diff
changeset
|
121 f"unlockedFor {unlockedFor}, lockIn {lockIn}") |
1229
02e4b84821d5
talk to store graph, second button for holding unlocked, etc
drewp <drewp@bigasterisk.com>
parents:
1228
diff
changeset
|
122 lockIn = 0 |
02e4b84821d5
talk to store graph, second button for holding unlocked, etc
drewp <drewp@bigasterisk.com>
parents:
1228
diff
changeset
|
123 g.patchObject(ctx, self.subj, ROOM['unlockedForSec'], |
02e4b84821d5
talk to store graph, second button for holding unlocked, etc
drewp <drewp@bigasterisk.com>
parents:
1228
diff
changeset
|
124 Literal(int(unlockedFor))) |
02e4b84821d5
talk to store graph, second button for holding unlocked, etc
drewp <drewp@bigasterisk.com>
parents:
1228
diff
changeset
|
125 g.patchObject(ctx, self.subj, ROOM['autoLockInSec'], |
02e4b84821d5
talk to store graph, second button for holding unlocked, etc
drewp <drewp@bigasterisk.com>
parents:
1228
diff
changeset
|
126 Literal(lockIn)) |
02e4b84821d5
talk to store graph, second button for holding unlocked, etc
drewp <drewp@bigasterisk.com>
parents:
1228
diff
changeset
|
127 |
02e4b84821d5
talk to store graph, second button for holding unlocked, etc
drewp <drewp@bigasterisk.com>
parents:
1228
diff
changeset
|
128 def clearReport(self): |
02e4b84821d5
talk to store graph, second button for holding unlocked, etc
drewp <drewp@bigasterisk.com>
parents:
1228
diff
changeset
|
129 g = self.masterGraph |
02e4b84821d5
talk to store graph, second button for holding unlocked, etc
drewp <drewp@bigasterisk.com>
parents:
1228
diff
changeset
|
130 g.patchObject(ctx, self.subj, ROOM['unlockedForSec'], None) |
02e4b84821d5
talk to store graph, second button for holding unlocked, etc
drewp <drewp@bigasterisk.com>
parents:
1228
diff
changeset
|
131 g.patchObject(ctx, self.subj, ROOM['autoLockInSec'], None) |
1365
e6c6574f3d24
fix a hang bug where polling stopped
drewp <drewp@bigasterisk.com>
parents:
1271
diff
changeset
|
132 |
e6c6574f3d24
fix a hang bug where polling stopped
drewp <drewp@bigasterisk.com>
parents:
1271
diff
changeset
|
133 def pollCheck(self): |
e6c6574f3d24
fix a hang bug where polling stopped
drewp <drewp@bigasterisk.com>
parents:
1271
diff
changeset
|
134 try: |
e6c6574f3d24
fix a hang bug where polling stopped
drewp <drewp@bigasterisk.com>
parents:
1271
diff
changeset
|
135 self.check() |
e6c6574f3d24
fix a hang bug where polling stopped
drewp <drewp@bigasterisk.com>
parents:
1271
diff
changeset
|
136 except Exception: |
e6c6574f3d24
fix a hang bug where polling stopped
drewp <drewp@bigasterisk.com>
parents:
1271
diff
changeset
|
137 log.exception('poll failed') |
1229
02e4b84821d5
talk to store graph, second button for holding unlocked, etc
drewp <drewp@bigasterisk.com>
parents:
1228
diff
changeset
|
138 |
1184
c87e5c8eb8ab
frontdoor autolock. logging improvements. use simpler mqtt interface.
drewp <drewp@bigasterisk.com>
parents:
1182
diff
changeset
|
139 def check(self): |
1229
02e4b84821d5
talk to store graph, second button for holding unlocked, etc
drewp <drewp@bigasterisk.com>
parents:
1228
diff
changeset
|
140 g = self.masterGraph |
1184
c87e5c8eb8ab
frontdoor autolock. logging improvements. use simpler mqtt interface.
drewp <drewp@bigasterisk.com>
parents:
1182
diff
changeset
|
141 now = time.time() |
1229
02e4b84821d5
talk to store graph, second button for holding unlocked, etc
drewp <drewp@bigasterisk.com>
parents:
1228
diff
changeset
|
142 state = g._graph.value(self.subj, ROOM['state']) |
1184
c87e5c8eb8ab
frontdoor autolock. logging improvements. use simpler mqtt interface.
drewp <drewp@bigasterisk.com>
parents:
1182
diff
changeset
|
143 if state == ROOM['unlocked']: |
c87e5c8eb8ab
frontdoor autolock. logging improvements. use simpler mqtt interface.
drewp <drewp@bigasterisk.com>
parents:
1182
diff
changeset
|
144 if self.timeUnlocked is None: |
c87e5c8eb8ab
frontdoor autolock. logging improvements. use simpler mqtt interface.
drewp <drewp@bigasterisk.com>
parents:
1182
diff
changeset
|
145 self.timeUnlocked = now |
1229
02e4b84821d5
talk to store graph, second button for holding unlocked, etc
drewp <drewp@bigasterisk.com>
parents:
1228
diff
changeset
|
146 # *newly* unlocked- this resets on every input stmt |
1184
c87e5c8eb8ab
frontdoor autolock. logging improvements. use simpler mqtt interface.
drewp <drewp@bigasterisk.com>
parents:
1182
diff
changeset
|
147 unlockedFor = now - self.timeUnlocked |
c87e5c8eb8ab
frontdoor autolock. logging improvements. use simpler mqtt interface.
drewp <drewp@bigasterisk.com>
parents:
1182
diff
changeset
|
148 if unlockedFor > self.autoLockSec: |
1229
02e4b84821d5
talk to store graph, second button for holding unlocked, etc
drewp <drewp@bigasterisk.com>
parents:
1228
diff
changeset
|
149 self.relock() |
1184
c87e5c8eb8ab
frontdoor autolock. logging improvements. use simpler mqtt interface.
drewp <drewp@bigasterisk.com>
parents:
1182
diff
changeset
|
150 else: |
c87e5c8eb8ab
frontdoor autolock. logging improvements. use simpler mqtt interface.
drewp <drewp@bigasterisk.com>
parents:
1182
diff
changeset
|
151 self.timeUnlocked = None |
1271
398bd2b2490c
new graph view. some autolock and BT code
drewp <drewp@bigasterisk.com>
parents:
1229
diff
changeset
|
152 unlockedFor = 0 |
398bd2b2490c
new graph view. some autolock and BT code
drewp <drewp@bigasterisk.com>
parents:
1229
diff
changeset
|
153 if unlockedFor > 3: |
398bd2b2490c
new graph view. some autolock and BT code
drewp <drewp@bigasterisk.com>
parents:
1229
diff
changeset
|
154 # only start showing the count if it looks like we're not |
398bd2b2490c
new graph view. some autolock and BT code
drewp <drewp@bigasterisk.com>
parents:
1229
diff
changeset
|
155 # being repeatedly held open. Time is hopefully more than |
398bd2b2490c
new graph view. some autolock and BT code
drewp <drewp@bigasterisk.com>
parents:
1229
diff
changeset
|
156 # the refresh rate of "reasoning.actions". |
398bd2b2490c
new graph view. some autolock and BT code
drewp <drewp@bigasterisk.com>
parents:
1229
diff
changeset
|
157 self.reportTimes(unlockedFor) |
398bd2b2490c
new graph view. some autolock and BT code
drewp <drewp@bigasterisk.com>
parents:
1229
diff
changeset
|
158 else: |
398bd2b2490c
new graph view. some autolock and BT code
drewp <drewp@bigasterisk.com>
parents:
1229
diff
changeset
|
159 self.clearReport() |
398bd2b2490c
new graph view. some autolock and BT code
drewp <drewp@bigasterisk.com>
parents:
1229
diff
changeset
|
160 |
398bd2b2490c
new graph view. some autolock and BT code
drewp <drewp@bigasterisk.com>
parents:
1229
diff
changeset
|
161 def onUnlockedStmt(self): |
398bd2b2490c
new graph view. some autolock and BT code
drewp <drewp@bigasterisk.com>
parents:
1229
diff
changeset
|
162 self.timeUnlocked = None |
398bd2b2490c
new graph view. some autolock and BT code
drewp <drewp@bigasterisk.com>
parents:
1229
diff
changeset
|
163 |
398bd2b2490c
new graph view. some autolock and BT code
drewp <drewp@bigasterisk.com>
parents:
1229
diff
changeset
|
164 def onLockedStmt(self): |
398bd2b2490c
new graph view. some autolock and BT code
drewp <drewp@bigasterisk.com>
parents:
1229
diff
changeset
|
165 pass |
398bd2b2490c
new graph view. some autolock and BT code
drewp <drewp@bigasterisk.com>
parents:
1229
diff
changeset
|
166 |
398bd2b2490c
new graph view. some autolock and BT code
drewp <drewp@bigasterisk.com>
parents:
1229
diff
changeset
|
167 class BluetoothButton(cyclone.web.RequestHandler): |
398bd2b2490c
new graph view. some autolock and BT code
drewp <drewp@bigasterisk.com>
parents:
1229
diff
changeset
|
168 def post(self): |
398bd2b2490c
new graph view. some autolock and BT code
drewp <drewp@bigasterisk.com>
parents:
1229
diff
changeset
|
169 body = json.loads(self.request.body) |
398bd2b2490c
new graph view. some autolock and BT code
drewp <drewp@bigasterisk.com>
parents:
1229
diff
changeset
|
170 log.info('POST bluetoothButton %r', body) |
398bd2b2490c
new graph view. some autolock and BT code
drewp <drewp@bigasterisk.com>
parents:
1229
diff
changeset
|
171 if body['addr'] == 'zz:zz:zz:zz:zz:zz' and body['key'] == 'top': |
398bd2b2490c
new graph view. some autolock and BT code
drewp <drewp@bigasterisk.com>
parents:
1229
diff
changeset
|
172 log.info('unlock for %r', body['addr']) |
1366 | 173 self.settings.mqtt.publish( |
1371
293d328a55d7
match esp hostname in py code
drewp <drewp@bigasterisk.com>
parents:
1366
diff
changeset
|
174 espName + b"/switch/strike/command", b'ON') |
1184
c87e5c8eb8ab
frontdoor autolock. logging improvements. use simpler mqtt interface.
drewp <drewp@bigasterisk.com>
parents:
1182
diff
changeset
|
175 |
1182
bd215f18e715
docker/etc initial version of front door mqtt<->rdf using some rx
drewp <drewp@bigasterisk.com>
parents:
diff
changeset
|
176 |
bd215f18e715
docker/etc initial version of front door mqtt<->rdf using some rx
drewp <drewp@bigasterisk.com>
parents:
diff
changeset
|
177 if __name__ == '__main__': |
bd215f18e715
docker/etc initial version of front door mqtt<->rdf using some rx
drewp <drewp@bigasterisk.com>
parents:
diff
changeset
|
178 arg = docopt(""" |
bd215f18e715
docker/etc initial version of front door mqtt<->rdf using some rx
drewp <drewp@bigasterisk.com>
parents:
diff
changeset
|
179 Usage: front_door_lock.py [options] |
bd215f18e715
docker/etc initial version of front door mqtt<->rdf using some rx
drewp <drewp@bigasterisk.com>
parents:
diff
changeset
|
180 |
bd215f18e715
docker/etc initial version of front door mqtt<->rdf using some rx
drewp <drewp@bigasterisk.com>
parents:
diff
changeset
|
181 -v Verbose |
bd215f18e715
docker/etc initial version of front door mqtt<->rdf using some rx
drewp <drewp@bigasterisk.com>
parents:
diff
changeset
|
182 """) |
1366 | 183 verboseLogging(arg['-v']) |
1182
bd215f18e715
docker/etc initial version of front door mqtt<->rdf using some rx
drewp <drewp@bigasterisk.com>
parents:
diff
changeset
|
184 |
bd215f18e715
docker/etc initial version of front door mqtt<->rdf using some rx
drewp <drewp@bigasterisk.com>
parents:
diff
changeset
|
185 masterGraph = PatchableGraph() |
bd215f18e715
docker/etc initial version of front door mqtt<->rdf using some rx
drewp <drewp@bigasterisk.com>
parents:
diff
changeset
|
186 mqtt = MqttClient(brokerPort=10010) |
1184
c87e5c8eb8ab
frontdoor autolock. logging improvements. use simpler mqtt interface.
drewp <drewp@bigasterisk.com>
parents:
1182
diff
changeset
|
187 autoclose = AutoLock(masterGraph, mqtt) |
1182
bd215f18e715
docker/etc initial version of front door mqtt<->rdf using some rx
drewp <drewp@bigasterisk.com>
parents:
diff
changeset
|
188 |
bd215f18e715
docker/etc initial version of front door mqtt<->rdf using some rx
drewp <drewp@bigasterisk.com>
parents:
diff
changeset
|
189 def toGraph(payload): |
1184
c87e5c8eb8ab
frontdoor autolock. logging improvements. use simpler mqtt interface.
drewp <drewp@bigasterisk.com>
parents:
1182
diff
changeset
|
190 log.info('mqtt->graph %r', payload) |
1182
bd215f18e715
docker/etc initial version of front door mqtt<->rdf using some rx
drewp <drewp@bigasterisk.com>
parents:
diff
changeset
|
191 masterGraph.patchObject(ctx, ROOM['frontDoorLock'], ROOM['state'], |
bd215f18e715
docker/etc initial version of front door mqtt<->rdf using some rx
drewp <drewp@bigasterisk.com>
parents:
diff
changeset
|
192 stateFromMqtt(payload)) |
bd215f18e715
docker/etc initial version of front door mqtt<->rdf using some rx
drewp <drewp@bigasterisk.com>
parents:
diff
changeset
|
193 |
1371
293d328a55d7
match esp hostname in py code
drewp <drewp@bigasterisk.com>
parents:
1366
diff
changeset
|
194 mqtt.subscribe(espName + b"/switch/strike/state").subscribe(on_next=toGraph) |
1378
fecbac537f63
faster keepalive from esp chip. report aliveness into the graph. more programming tasks in tasks.py
drewp <drewp@bigasterisk.com>
parents:
1371
diff
changeset
|
195 |
fecbac537f63
faster keepalive from esp chip. report aliveness into the graph. more programming tasks in tasks.py
drewp <drewp@bigasterisk.com>
parents:
1371
diff
changeset
|
196 def setEspState(payload): |
fecbac537f63
faster keepalive from esp chip. report aliveness into the graph. more programming tasks in tasks.py
drewp <drewp@bigasterisk.com>
parents:
1371
diff
changeset
|
197 log.info('esp state change %r', payload) |
fecbac537f63
faster keepalive from esp chip. report aliveness into the graph. more programming tasks in tasks.py
drewp <drewp@bigasterisk.com>
parents:
1371
diff
changeset
|
198 masterGraph.patchObject(ctx, ROOM['frontDoorLock'], ROOM['espMqttConnection'], |
fecbac537f63
faster keepalive from esp chip. report aliveness into the graph. more programming tasks in tasks.py
drewp <drewp@bigasterisk.com>
parents:
1371
diff
changeset
|
199 ROOM['mqtt' + payload.decode('ascii').capitalize()]) |
fecbac537f63
faster keepalive from esp chip. report aliveness into the graph. more programming tasks in tasks.py
drewp <drewp@bigasterisk.com>
parents:
1371
diff
changeset
|
200 |
fecbac537f63
faster keepalive from esp chip. report aliveness into the graph. more programming tasks in tasks.py
drewp <drewp@bigasterisk.com>
parents:
1371
diff
changeset
|
201 mqtt.subscribe(espName + b"/status").subscribe(on_next=setEspState) |
fecbac537f63
faster keepalive from esp chip. report aliveness into the graph. more programming tasks in tasks.py
drewp <drewp@bigasterisk.com>
parents:
1371
diff
changeset
|
202 |
1182
bd215f18e715
docker/etc initial version of front door mqtt<->rdf using some rx
drewp <drewp@bigasterisk.com>
parents:
diff
changeset
|
203 port = 10011 |
1229
02e4b84821d5
talk to store graph, second button for holding unlocked, etc
drewp <drewp@bigasterisk.com>
parents:
1228
diff
changeset
|
204 reactor.listenTCP(port, cyclone.web.Application( |
02e4b84821d5
talk to store graph, second button for holding unlocked, etc
drewp <drewp@bigasterisk.com>
parents:
1228
diff
changeset
|
205 [ |
02e4b84821d5
talk to store graph, second button for holding unlocked, etc
drewp <drewp@bigasterisk.com>
parents:
1228
diff
changeset
|
206 (r"/()", cyclone.web.StaticFileHandler, |
02e4b84821d5
talk to store graph, second button for holding unlocked, etc
drewp <drewp@bigasterisk.com>
parents:
1228
diff
changeset
|
207 {"path": ".", "default_filename": "index.html"}), |
1379
baf1acaa9ac9
new simple mode that can set the door without rdf
drewp <drewp@bigasterisk.com>
parents:
1378
diff
changeset
|
208 (r"/simple/()", cyclone.web.StaticFileHandler, |
baf1acaa9ac9
new simple mode that can set the door without rdf
drewp <drewp@bigasterisk.com>
parents:
1378
diff
changeset
|
209 {"path": ".", "default_filename": "simple.html"}), |
1229
02e4b84821d5
talk to store graph, second button for holding unlocked, etc
drewp <drewp@bigasterisk.com>
parents:
1228
diff
changeset
|
210 (r"/graph", CycloneGraphHandler, {'masterGraph': masterGraph}), |
02e4b84821d5
talk to store graph, second button for holding unlocked, etc
drewp <drewp@bigasterisk.com>
parents:
1228
diff
changeset
|
211 (r"/graph/events", CycloneGraphEventsHandler, |
02e4b84821d5
talk to store graph, second button for holding unlocked, etc
drewp <drewp@bigasterisk.com>
parents:
1228
diff
changeset
|
212 {'masterGraph': masterGraph}), |
02e4b84821d5
talk to store graph, second button for holding unlocked, etc
drewp <drewp@bigasterisk.com>
parents:
1228
diff
changeset
|
213 (r'/output', OutputPage), |
02e4b84821d5
talk to store graph, second button for holding unlocked, etc
drewp <drewp@bigasterisk.com>
parents:
1228
diff
changeset
|
214 (r'/bluetoothButton', BluetoothButton), |
1379
baf1acaa9ac9
new simple mode that can set the door without rdf
drewp <drewp@bigasterisk.com>
parents:
1378
diff
changeset
|
215 (r'/simpleState', SimpleState), |
1229
02e4b84821d5
talk to store graph, second button for holding unlocked, etc
drewp <drewp@bigasterisk.com>
parents:
1228
diff
changeset
|
216 ], |
02e4b84821d5
talk to store graph, second button for holding unlocked, etc
drewp <drewp@bigasterisk.com>
parents:
1228
diff
changeset
|
217 mqtt=mqtt, |
02e4b84821d5
talk to store graph, second button for holding unlocked, etc
drewp <drewp@bigasterisk.com>
parents:
1228
diff
changeset
|
218 masterGraph=masterGraph, |
02e4b84821d5
talk to store graph, second button for holding unlocked, etc
drewp <drewp@bigasterisk.com>
parents:
1228
diff
changeset
|
219 autoLock=autoclose, |
02e4b84821d5
talk to store graph, second button for holding unlocked, etc
drewp <drewp@bigasterisk.com>
parents:
1228
diff
changeset
|
220 debug=arg['-v']), |
02e4b84821d5
talk to store graph, second button for holding unlocked, etc
drewp <drewp@bigasterisk.com>
parents:
1228
diff
changeset
|
221 interface='::') |
1182
bd215f18e715
docker/etc initial version of front door mqtt<->rdf using some rx
drewp <drewp@bigasterisk.com>
parents:
diff
changeset
|
222 log.warn('serving on %s', port) |
bd215f18e715
docker/etc initial version of front door mqtt<->rdf using some rx
drewp <drewp@bigasterisk.com>
parents:
diff
changeset
|
223 |
bd215f18e715
docker/etc initial version of front door mqtt<->rdf using some rx
drewp <drewp@bigasterisk.com>
parents:
diff
changeset
|
224 reactor.run() |