Mercurial > code > home > repos > homeauto
annotate service/tomatoWifi/tomatoWifi.py @ 62:f8cc3d1baa85
redo wifi scraper to work with zyxel router report page too. add last connected time (from mongo) to web table
Ignore-this: 18bade72e14d40532bd019791d03fa7d
author | drewp@bigasterisk.com |
---|---|
date | Sat, 06 Apr 2013 17:08:19 -0700 |
parents | 875a37be1228 |
children | bca6d6c63bdc |
rev | line source |
---|---|
0 | 1 #!/usr/bin/python |
2 """ | |
3 scrape the tomato router status pages to see who's connected to the | |
4 wifi access points. Includes leases that aren't currently connected. | |
5 | |
6 Returns: | |
7 json listing (for magma page) | |
8 rdf graph (for reasoning) | |
9 activity stream, when we start saving history | |
10 | |
11 Todo: this should be the one polling and writing to mongo, not entrancemusic | |
12 """ | |
13 from __future__ import division | |
51
d2842eedd56d
rewrite tomatowifi from restkit to cyclone httpclient
drewp@bigasterisk.com
parents:
50
diff
changeset
|
14 import sys, cyclone.web, json, traceback, time, pystache, datetime, logging |
62
f8cc3d1baa85
redo wifi scraper to work with zyxel router report page too. add last connected time (from mongo) to web table
drewp@bigasterisk.com
parents:
52
diff
changeset
|
15 import web.utils |
51
d2842eedd56d
rewrite tomatowifi from restkit to cyclone httpclient
drewp@bigasterisk.com
parents:
50
diff
changeset
|
16 from cyclone.httpclient import fetch |
d2842eedd56d
rewrite tomatowifi from restkit to cyclone httpclient
drewp@bigasterisk.com
parents:
50
diff
changeset
|
17 sys.path.append("/home/drewp/projects/photo/lib/python2.7/site-packages") |
0 | 18 from dateutil import tz |
19 from twisted.internet import reactor, task | |
62
f8cc3d1baa85
redo wifi scraper to work with zyxel router report page too. add last connected time (from mongo) to web table
drewp@bigasterisk.com
parents:
52
diff
changeset
|
20 from twisted.internet.defer import inlineCallbacks |
0 | 21 |
22 from pymongo import Connection, DESCENDING | |
23 from rdflib import Namespace, Literal, URIRef | |
24 sys.path.append("/my/site/magma") | |
25 from stategraph import StateGraph | |
26 from wifi import Wifi | |
62
f8cc3d1baa85
redo wifi scraper to work with zyxel router report page too. add last connected time (from mongo) to web table
drewp@bigasterisk.com
parents:
52
diff
changeset
|
27 from dhcpparse import addDhcpData |
0 | 28 |
29 sys.path.append("/my/proj/homeauto/lib") | |
30 from cycloneerr import PrettyErrorHandler | |
1 | 31 from logsetup import log |
0 | 32 |
36 | 33 import rdflib |
34 from rdflib import plugin | |
35 plugin.register( | |
36 "sparql", rdflib.query.Processor, | |
37 "rdfextras.sparql.processor", "Processor") | |
38 plugin.register( | |
39 "sparql", rdflib.query.Result, | |
40 "rdfextras.sparql.query", "SPARQLQueryResult") | |
41 | |
0 | 42 DEV = Namespace("http://projects.bigasterisk.com/device/") |
43 ROOM = Namespace("http://projects.bigasterisk.com/room/") | |
51
d2842eedd56d
rewrite tomatowifi from restkit to cyclone httpclient
drewp@bigasterisk.com
parents:
50
diff
changeset
|
44 reasoning = "http://bang:9071/" |
1 | 45 |
0 | 46 class Index(PrettyErrorHandler, cyclone.web.RequestHandler): |
47 def get(self): | |
48 | |
49 age = time.time() - self.settings.poller.lastPollTime | |
50 if age > 10: | |
51 raise ValueError("poll data is stale. age=%s" % age) | |
51
d2842eedd56d
rewrite tomatowifi from restkit to cyclone httpclient
drewp@bigasterisk.com
parents:
50
diff
changeset
|
52 |
0 | 53 self.write("this is wifiusage. needs index page that embeds the table") |
54 | |
55 class Table(PrettyErrorHandler, cyclone.web.RequestHandler): | |
56 def get(self): | |
62
f8cc3d1baa85
redo wifi scraper to work with zyxel router report page too. add last connected time (from mongo) to web table
drewp@bigasterisk.com
parents:
52
diff
changeset
|
57 def rowDict(row): |
f8cc3d1baa85
redo wifi scraper to work with zyxel router report page too. add last connected time (from mongo) to web table
drewp@bigasterisk.com
parents:
52
diff
changeset
|
58 row['cls'] = "signal" if row.get('connected') else "nosignal" |
f8cc3d1baa85
redo wifi scraper to work with zyxel router report page too. add last connected time (from mongo) to web table
drewp@bigasterisk.com
parents:
52
diff
changeset
|
59 if 'name' not in row: |
f8cc3d1baa85
redo wifi scraper to work with zyxel router report page too. add last connected time (from mongo) to web table
drewp@bigasterisk.com
parents:
52
diff
changeset
|
60 row['name'] = row['clientHostname'] |
f8cc3d1baa85
redo wifi scraper to work with zyxel router report page too. add last connected time (from mongo) to web table
drewp@bigasterisk.com
parents:
52
diff
changeset
|
61 if 'signal' not in row: |
f8cc3d1baa85
redo wifi scraper to work with zyxel router report page too. add last connected time (from mongo) to web table
drewp@bigasterisk.com
parents:
52
diff
changeset
|
62 row['signal'] = 'yes' if row['connected'] else 'no' |
f8cc3d1baa85
redo wifi scraper to work with zyxel router report page too. add last connected time (from mongo) to web table
drewp@bigasterisk.com
parents:
52
diff
changeset
|
63 |
f8cc3d1baa85
redo wifi scraper to work with zyxel router report page too. add last connected time (from mongo) to web table
drewp@bigasterisk.com
parents:
52
diff
changeset
|
64 try: |
f8cc3d1baa85
redo wifi scraper to work with zyxel router report page too. add last connected time (from mongo) to web table
drewp@bigasterisk.com
parents:
52
diff
changeset
|
65 conn = self.whenConnected(row['mac']) |
f8cc3d1baa85
redo wifi scraper to work with zyxel router report page too. add last connected time (from mongo) to web table
drewp@bigasterisk.com
parents:
52
diff
changeset
|
66 row['connectedAgo'] = web.utils.datestr( |
f8cc3d1baa85
redo wifi scraper to work with zyxel router report page too. add last connected time (from mongo) to web table
drewp@bigasterisk.com
parents:
52
diff
changeset
|
67 conn.astimezone(tz.tzutc()).replace(tzinfo=None)) |
f8cc3d1baa85
redo wifi scraper to work with zyxel router report page too. add last connected time (from mongo) to web table
drewp@bigasterisk.com
parents:
52
diff
changeset
|
68 except ValueError: |
f8cc3d1baa85
redo wifi scraper to work with zyxel router report page too. add last connected time (from mongo) to web table
drewp@bigasterisk.com
parents:
52
diff
changeset
|
69 pass |
f8cc3d1baa85
redo wifi scraper to work with zyxel router report page too. add last connected time (from mongo) to web table
drewp@bigasterisk.com
parents:
52
diff
changeset
|
70 |
f8cc3d1baa85
redo wifi scraper to work with zyxel router report page too. add last connected time (from mongo) to web table
drewp@bigasterisk.com
parents:
52
diff
changeset
|
71 return row |
0 | 72 |
73 self.set_header("Content-Type", "application/xhtml+xml") | |
74 self.write(pystache.render( | |
75 open("table.mustache").read(), | |
76 dict( | |
77 rows=sorted(map(rowDict, self.settings.poller.lastAddrs), | |
62
f8cc3d1baa85
redo wifi scraper to work with zyxel router report page too. add last connected time (from mongo) to web table
drewp@bigasterisk.com
parents:
52
diff
changeset
|
78 key=lambda a: (not a.get('connected'), |
f8cc3d1baa85
redo wifi scraper to work with zyxel router report page too. add last connected time (from mongo) to web table
drewp@bigasterisk.com
parents:
52
diff
changeset
|
79 a.get('name')))))) |
0 | 80 |
62
f8cc3d1baa85
redo wifi scraper to work with zyxel router report page too. add last connected time (from mongo) to web table
drewp@bigasterisk.com
parents:
52
diff
changeset
|
81 def whenConnected(self, macThatIsNowConnected): |
f8cc3d1baa85
redo wifi scraper to work with zyxel router report page too. add last connected time (from mongo) to web table
drewp@bigasterisk.com
parents:
52
diff
changeset
|
82 lastArrive = None |
f8cc3d1baa85
redo wifi scraper to work with zyxel router report page too. add last connected time (from mongo) to web table
drewp@bigasterisk.com
parents:
52
diff
changeset
|
83 for ev in self.settings.mongo.find({'address': macThatIsNowConnected}, |
f8cc3d1baa85
redo wifi scraper to work with zyxel router report page too. add last connected time (from mongo) to web table
drewp@bigasterisk.com
parents:
52
diff
changeset
|
84 sort=[('created', -1)], |
f8cc3d1baa85
redo wifi scraper to work with zyxel router report page too. add last connected time (from mongo) to web table
drewp@bigasterisk.com
parents:
52
diff
changeset
|
85 max_scan=100000): |
f8cc3d1baa85
redo wifi scraper to work with zyxel router report page too. add last connected time (from mongo) to web table
drewp@bigasterisk.com
parents:
52
diff
changeset
|
86 if ev['action'] == 'arrive': |
f8cc3d1baa85
redo wifi scraper to work with zyxel router report page too. add last connected time (from mongo) to web table
drewp@bigasterisk.com
parents:
52
diff
changeset
|
87 lastArrive = ev |
f8cc3d1baa85
redo wifi scraper to work with zyxel router report page too. add last connected time (from mongo) to web table
drewp@bigasterisk.com
parents:
52
diff
changeset
|
88 if ev['action'] == 'leave': |
f8cc3d1baa85
redo wifi scraper to work with zyxel router report page too. add last connected time (from mongo) to web table
drewp@bigasterisk.com
parents:
52
diff
changeset
|
89 break |
f8cc3d1baa85
redo wifi scraper to work with zyxel router report page too. add last connected time (from mongo) to web table
drewp@bigasterisk.com
parents:
52
diff
changeset
|
90 if lastArrive is None: |
f8cc3d1baa85
redo wifi scraper to work with zyxel router report page too. add last connected time (from mongo) to web table
drewp@bigasterisk.com
parents:
52
diff
changeset
|
91 raise ValueError("no past arrivals") |
f8cc3d1baa85
redo wifi scraper to work with zyxel router report page too. add last connected time (from mongo) to web table
drewp@bigasterisk.com
parents:
52
diff
changeset
|
92 |
f8cc3d1baa85
redo wifi scraper to work with zyxel router report page too. add last connected time (from mongo) to web table
drewp@bigasterisk.com
parents:
52
diff
changeset
|
93 return lastArrive['created'] |
f8cc3d1baa85
redo wifi scraper to work with zyxel router report page too. add last connected time (from mongo) to web table
drewp@bigasterisk.com
parents:
52
diff
changeset
|
94 |
51
d2842eedd56d
rewrite tomatowifi from restkit to cyclone httpclient
drewp@bigasterisk.com
parents:
50
diff
changeset
|
95 |
0 | 96 class Json(PrettyErrorHandler, cyclone.web.RequestHandler): |
97 def get(self): | |
98 self.set_header("Content-Type", "application/json") | |
99 age = time.time() - self.settings.poller.lastPollTime | |
100 if age > 10: | |
101 raise ValueError("poll data is stale. age=%s" % age) | |
51
d2842eedd56d
rewrite tomatowifi from restkit to cyclone httpclient
drewp@bigasterisk.com
parents:
50
diff
changeset
|
102 self.write(json.dumps({"wifi" : self.settings.poller.lastAddrs, |
0 | 103 "dataAge" : age})) |
104 | |
105 class GraphHandler(PrettyErrorHandler, cyclone.web.RequestHandler): | |
106 def get(self): | |
107 g = StateGraph(ctx=DEV['wifi']) | |
108 | |
109 # someday i may also record specific AP and their strength, | |
110 # for positioning. But many users just want to know that the | |
111 # device is connected to some bigasterisk AP. | |
112 aps = URIRef("http://bigasterisk.com/wifiAccessPoints") | |
113 age = time.time() - self.settings.poller.lastPollTime | |
114 if age > 10: | |
115 raise ValueError("poll data is stale. age=%s" % age) | |
116 | |
117 for dev in self.settings.poller.lastAddrs: | |
62
f8cc3d1baa85
redo wifi scraper to work with zyxel router report page too. add last connected time (from mongo) to web table
drewp@bigasterisk.com
parents:
52
diff
changeset
|
118 if not dev.get('connected'): |
0 | 119 continue |
120 uri = URIRef("http://bigasterisk.com/wifiDevice/%s" % dev['mac']) | |
121 g.add((uri, ROOM['macAddress'], Literal(dev['mac']))) | |
62
f8cc3d1baa85
redo wifi scraper to work with zyxel router report page too. add last connected time (from mongo) to web table
drewp@bigasterisk.com
parents:
52
diff
changeset
|
122 |
0 | 123 g.add((uri, ROOM['connected'], aps)) |
62
f8cc3d1baa85
redo wifi scraper to work with zyxel router report page too. add last connected time (from mongo) to web table
drewp@bigasterisk.com
parents:
52
diff
changeset
|
124 if 'clientHostname' in dev: |
f8cc3d1baa85
redo wifi scraper to work with zyxel router report page too. add last connected time (from mongo) to web table
drewp@bigasterisk.com
parents:
52
diff
changeset
|
125 g.add((uri, ROOM['wifiNetworkName'], Literal(dev['clientHostname']))) |
f8cc3d1baa85
redo wifi scraper to work with zyxel router report page too. add last connected time (from mongo) to web table
drewp@bigasterisk.com
parents:
52
diff
changeset
|
126 if 'name' in dev: |
f8cc3d1baa85
redo wifi scraper to work with zyxel router report page too. add last connected time (from mongo) to web table
drewp@bigasterisk.com
parents:
52
diff
changeset
|
127 g.add((uri, ROOM['deviceName'], Literal(dev['name']))) |
f8cc3d1baa85
redo wifi scraper to work with zyxel router report page too. add last connected time (from mongo) to web table
drewp@bigasterisk.com
parents:
52
diff
changeset
|
128 if 'signal' in dev: |
f8cc3d1baa85
redo wifi scraper to work with zyxel router report page too. add last connected time (from mongo) to web table
drewp@bigasterisk.com
parents:
52
diff
changeset
|
129 g.add((uri, ROOM['signalStrength'], Literal(dev['signal']))) |
0 | 130 |
131 self.set_header('Content-type', 'application/x-trig') | |
132 self.write(g.asTrig()) | |
51
d2842eedd56d
rewrite tomatowifi from restkit to cyclone httpclient
drewp@bigasterisk.com
parents:
50
diff
changeset
|
133 |
0 | 134 class Poller(object): |
135 def __init__(self, wifi, mongo): | |
136 self.wifi = wifi | |
137 self.mongo = mongo | |
138 self.lastAddrs = [] | |
139 self.lastWithSignal = [] | |
140 self.lastPollTime = 0 | |
141 | |
142 def assertCurrent(self): | |
143 dt = time.time() - self.lastPollTime | |
144 assert dt < 10, "last poll was %s sec ago" % dt | |
51
d2842eedd56d
rewrite tomatowifi from restkit to cyclone httpclient
drewp@bigasterisk.com
parents:
50
diff
changeset
|
145 |
d2842eedd56d
rewrite tomatowifi from restkit to cyclone httpclient
drewp@bigasterisk.com
parents:
50
diff
changeset
|
146 @inlineCallbacks |
0 | 147 def poll(self): |
148 try: | |
51
d2842eedd56d
rewrite tomatowifi from restkit to cyclone httpclient
drewp@bigasterisk.com
parents:
50
diff
changeset
|
149 newAddrs = yield self.wifi.getPresentMacAddrs() |
62
f8cc3d1baa85
redo wifi scraper to work with zyxel router report page too. add last connected time (from mongo) to web table
drewp@bigasterisk.com
parents:
52
diff
changeset
|
150 addDhcpData(newAddrs) |
f8cc3d1baa85
redo wifi scraper to work with zyxel router report page too. add last connected time (from mongo) to web table
drewp@bigasterisk.com
parents:
52
diff
changeset
|
151 |
f8cc3d1baa85
redo wifi scraper to work with zyxel router report page too. add last connected time (from mongo) to web table
drewp@bigasterisk.com
parents:
52
diff
changeset
|
152 newWithSignal = [a for a in newAddrs if a.get('connected')] |
0 | 153 |
154 actions = self.computeActions(newWithSignal) | |
155 for action in actions: | |
1 | 156 log.info("action: %s", action) |
0 | 157 action['created'] = datetime.datetime.now(tz.gettz('UTC')) |
158 mongo.save(action) | |
159 try: | |
160 self.doEntranceMusic(action) | |
161 except Exception, e: | |
1 | 162 log.error("entrancemusic error: %r", e) |
51
d2842eedd56d
rewrite tomatowifi from restkit to cyclone httpclient
drewp@bigasterisk.com
parents:
50
diff
changeset
|
163 |
0 | 164 self.lastWithSignal = newWithSignal |
50 | 165 if actions: # this doesn't currently include signal strength changes |
51
d2842eedd56d
rewrite tomatowifi from restkit to cyclone httpclient
drewp@bigasterisk.com
parents:
50
diff
changeset
|
166 fetch(reasoning + "immediateUpdate", |
52 | 167 timeout=2, |
168 headers={'user-agent': ['tomatoWifi']}).addErrback(log.warn) | |
0 | 169 self.lastAddrs = newAddrs |
170 self.lastPollTime = time.time() | |
171 except Exception, e: | |
1 | 172 log.error("poll error: %s\n%s", e, traceback.format_exc()) |
0 | 173 |
174 def computeActions(self, newWithSignal): | |
175 actions = [] | |
176 | |
177 def makeAction(addr, act): | |
62
f8cc3d1baa85
redo wifi scraper to work with zyxel router report page too. add last connected time (from mongo) to web table
drewp@bigasterisk.com
parents:
52
diff
changeset
|
178 d = dict(sensor="wifi", |
0 | 179 address=addr.get('mac'), |
180 name=addr.get('name'), | |
62
f8cc3d1baa85
redo wifi scraper to work with zyxel router report page too. add last connected time (from mongo) to web table
drewp@bigasterisk.com
parents:
52
diff
changeset
|
181 networkName=addr.get('clientHostname'), |
0 | 182 action=act) |
62
f8cc3d1baa85
redo wifi scraper to work with zyxel router report page too. add last connected time (from mongo) to web table
drewp@bigasterisk.com
parents:
52
diff
changeset
|
183 if act == 'arrive' and 'ip' in addr: |
f8cc3d1baa85
redo wifi scraper to work with zyxel router report page too. add last connected time (from mongo) to web table
drewp@bigasterisk.com
parents:
52
diff
changeset
|
184 # this won't cover the possible case that you get on |
f8cc3d1baa85
redo wifi scraper to work with zyxel router report page too. add last connected time (from mongo) to web table
drewp@bigasterisk.com
parents:
52
diff
changeset
|
185 # wifi but don't have an ip yet. We'll record an |
f8cc3d1baa85
redo wifi scraper to work with zyxel router report page too. add last connected time (from mongo) to web table
drewp@bigasterisk.com
parents:
52
diff
changeset
|
186 # action with no ip and then never record your ip. |
f8cc3d1baa85
redo wifi scraper to work with zyxel router report page too. add last connected time (from mongo) to web table
drewp@bigasterisk.com
parents:
52
diff
changeset
|
187 d['ip'] = addr['ip'] |
f8cc3d1baa85
redo wifi scraper to work with zyxel router report page too. add last connected time (from mongo) to web table
drewp@bigasterisk.com
parents:
52
diff
changeset
|
188 return d |
0 | 189 |
190 for addr in newWithSignal: | |
62
f8cc3d1baa85
redo wifi scraper to work with zyxel router report page too. add last connected time (from mongo) to web table
drewp@bigasterisk.com
parents:
52
diff
changeset
|
191 if addr['mac'] not in [r['mac'] for r in self.lastWithSignal]: |
0 | 192 actions.append(makeAction(addr, 'arrive')) |
193 | |
194 for addr in self.lastWithSignal: | |
62
f8cc3d1baa85
redo wifi scraper to work with zyxel router report page too. add last connected time (from mongo) to web table
drewp@bigasterisk.com
parents:
52
diff
changeset
|
195 if addr['mac'] not in [r['mac'] for r in newWithSignal]: |
0 | 196 actions.append(makeAction(addr, 'leave')) |
197 | |
198 return actions | |
199 | |
200 | |
1 | 201 # these need to move out to their own service |
0 | 202 def doEntranceMusic(self, action): |
1 | 203 import restkit, jsonlib |
0 | 204 dt = self.deltaSinceLastArrive(action['name']) |
1 | 205 log.debug("dt=%s", dt) |
0 | 206 if dt > datetime.timedelta(hours=1): |
207 hub = restkit.Resource( | |
208 # PSHB not working yet; "http://bang:9030/" | |
209 "http://slash:9049/" | |
210 ) | |
211 action = action.copy() | |
212 del action['created'] | |
1 | 213 del action['_id'] |
214 log.info("post to %s", hub) | |
0 | 215 hub.post("visitorNet", payload=jsonlib.dumps(action)) |
216 | |
217 def deltaSinceLastArrive(self, name): | |
218 results = list(self.mongo.find({'name' : name}).sort('created', | |
219 DESCENDING).limit(1)) | |
220 if not results: | |
221 return datetime.timedelta.max | |
222 now = datetime.datetime.now(tz.gettz('UTC')) | |
223 last = results[0]['created'].replace(tzinfo=tz.gettz('UTC')) | |
224 return now - last | |
51
d2842eedd56d
rewrite tomatowifi from restkit to cyclone httpclient
drewp@bigasterisk.com
parents:
50
diff
changeset
|
225 |
0 | 226 |
227 if __name__ == '__main__': | |
228 config = { | |
229 'servePort' : 9070, | |
230 'pollFrequency' : 1/5, | |
231 } | |
1 | 232 from twisted.python import log as twlog |
0 | 233 #log.startLogging(sys.stdout) |
1 | 234 #log.setLevel(10) |
62
f8cc3d1baa85
redo wifi scraper to work with zyxel router report page too. add last connected time (from mongo) to web table
drewp@bigasterisk.com
parents:
52
diff
changeset
|
235 #log.setLevel(logging.DEBUG) |
0 | 236 |
62
f8cc3d1baa85
redo wifi scraper to work with zyxel router report page too. add last connected time (from mongo) to web table
drewp@bigasterisk.com
parents:
52
diff
changeset
|
237 mongo = Connection('bang', 27017, tz_aware=True)['visitor']['visitor'] |
0 | 238 |
239 wifi = Wifi() | |
240 poller = Poller(wifi, mongo) | |
241 task.LoopingCall(poller.poll).start(1/config['pollFrequency']) | |
242 | |
62
f8cc3d1baa85
redo wifi scraper to work with zyxel router report page too. add last connected time (from mongo) to web table
drewp@bigasterisk.com
parents:
52
diff
changeset
|
243 reactor.listenTCP(config['servePort'], |
f8cc3d1baa85
redo wifi scraper to work with zyxel router report page too. add last connected time (from mongo) to web table
drewp@bigasterisk.com
parents:
52
diff
changeset
|
244 cyclone.web.Application( |
f8cc3d1baa85
redo wifi scraper to work with zyxel router report page too. add last connected time (from mongo) to web table
drewp@bigasterisk.com
parents:
52
diff
changeset
|
245 [ |
f8cc3d1baa85
redo wifi scraper to work with zyxel router report page too. add last connected time (from mongo) to web table
drewp@bigasterisk.com
parents:
52
diff
changeset
|
246 (r"/", Index), |
f8cc3d1baa85
redo wifi scraper to work with zyxel router report page too. add last connected time (from mongo) to web table
drewp@bigasterisk.com
parents:
52
diff
changeset
|
247 (r'/json', Json), |
f8cc3d1baa85
redo wifi scraper to work with zyxel router report page too. add last connected time (from mongo) to web table
drewp@bigasterisk.com
parents:
52
diff
changeset
|
248 (r'/graph', GraphHandler), |
f8cc3d1baa85
redo wifi scraper to work with zyxel router report page too. add last connected time (from mongo) to web table
drewp@bigasterisk.com
parents:
52
diff
changeset
|
249 (r'/table', Table), |
f8cc3d1baa85
redo wifi scraper to work with zyxel router report page too. add last connected time (from mongo) to web table
drewp@bigasterisk.com
parents:
52
diff
changeset
|
250 #(r'/activity', Activity), |
f8cc3d1baa85
redo wifi scraper to work with zyxel router report page too. add last connected time (from mongo) to web table
drewp@bigasterisk.com
parents:
52
diff
changeset
|
251 ], |
f8cc3d1baa85
redo wifi scraper to work with zyxel router report page too. add last connected time (from mongo) to web table
drewp@bigasterisk.com
parents:
52
diff
changeset
|
252 wifi=wifi, |
f8cc3d1baa85
redo wifi scraper to work with zyxel router report page too. add last connected time (from mongo) to web table
drewp@bigasterisk.com
parents:
52
diff
changeset
|
253 poller=poller, |
f8cc3d1baa85
redo wifi scraper to work with zyxel router report page too. add last connected time (from mongo) to web table
drewp@bigasterisk.com
parents:
52
diff
changeset
|
254 mongo=mongo)) |
0 | 255 reactor.run() |