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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
1 #!/usr/bin/python
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
2 """
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
3 scrape the tomato router status pages to see who's connected to the
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
4 wifi access points. Includes leases that aren't currently connected.
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
5
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
6 Returns:
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
7 json listing (for magma page)
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
8 rdf graph (for reasoning)
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
9 activity stream, when we start saving history
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
10
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
11 Todo: this should be the one polling and writing to mongo, not entrancemusic
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
12 """
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
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
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
18 from dateutil import tz
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
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
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
21
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
22 from pymongo import Connection, DESCENDING
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
23 from rdflib import Namespace, Literal, URIRef
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
24 sys.path.append("/my/site/magma")
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
25 from stategraph import StateGraph
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
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
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
28
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
29 sys.path.append("/my/proj/homeauto/lib")
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
30 from cycloneerr import PrettyErrorHandler
1
26a6cf58743d entrancemusic improve logging
drewp@bigasterisk.com
parents: 0
diff changeset
31 from logsetup import log
0
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
32
36
0ab069867c64 rdflib and jsonlib api updates
drewp@bigasterisk.com
parents: 1
diff changeset
33 import rdflib
0ab069867c64 rdflib and jsonlib api updates
drewp@bigasterisk.com
parents: 1
diff changeset
34 from rdflib import plugin
0ab069867c64 rdflib and jsonlib api updates
drewp@bigasterisk.com
parents: 1
diff changeset
35 plugin.register(
0ab069867c64 rdflib and jsonlib api updates
drewp@bigasterisk.com
parents: 1
diff changeset
36 "sparql", rdflib.query.Processor,
0ab069867c64 rdflib and jsonlib api updates
drewp@bigasterisk.com
parents: 1
diff changeset
37 "rdfextras.sparql.processor", "Processor")
0ab069867c64 rdflib and jsonlib api updates
drewp@bigasterisk.com
parents: 1
diff changeset
38 plugin.register(
0ab069867c64 rdflib and jsonlib api updates
drewp@bigasterisk.com
parents: 1
diff changeset
39 "sparql", rdflib.query.Result,
0ab069867c64 rdflib and jsonlib api updates
drewp@bigasterisk.com
parents: 1
diff changeset
40 "rdfextras.sparql.query", "SPARQLQueryResult")
0ab069867c64 rdflib and jsonlib api updates
drewp@bigasterisk.com
parents: 1
diff changeset
41
0
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
42 DEV = Namespace("http://projects.bigasterisk.com/device/")
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
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
26a6cf58743d entrancemusic improve logging
drewp@bigasterisk.com
parents: 0
diff changeset
45
0
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
46 class Index(PrettyErrorHandler, cyclone.web.RequestHandler):
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
47 def get(self):
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
48
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
49 age = time.time() - self.settings.poller.lastPollTime
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
50 if age > 10:
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
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
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
53 self.write("this is wifiusage. needs index page that embeds the table")
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
54
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
55 class Table(PrettyErrorHandler, cyclone.web.RequestHandler):
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
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
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
72
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
73 self.set_header("Content-Type", "application/xhtml+xml")
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
74 self.write(pystache.render(
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
75 open("table.mustache").read(),
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
76 dict(
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
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
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
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
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
96 class Json(PrettyErrorHandler, cyclone.web.RequestHandler):
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
97 def get(self):
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
98 self.set_header("Content-Type", "application/json")
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
99 age = time.time() - self.settings.poller.lastPollTime
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
100 if age > 10:
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
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
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
103 "dataAge" : age}))
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
104
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
105 class GraphHandler(PrettyErrorHandler, cyclone.web.RequestHandler):
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
106 def get(self):
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
107 g = StateGraph(ctx=DEV['wifi'])
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
108
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
109 # someday i may also record specific AP and their strength,
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
110 # for positioning. But many users just want to know that the
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
111 # device is connected to some bigasterisk AP.
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
112 aps = URIRef("http://bigasterisk.com/wifiAccessPoints")
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
113 age = time.time() - self.settings.poller.lastPollTime
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
114 if age > 10:
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
115 raise ValueError("poll data is stale. age=%s" % age)
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
116
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
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
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
119 continue
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
120 uri = URIRef("http://bigasterisk.com/wifiDevice/%s" % dev['mac'])
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
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
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
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
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
130
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
131 self.set_header('Content-type', 'application/x-trig')
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
132 self.write(g.asTrig())
51
d2842eedd56d rewrite tomatowifi from restkit to cyclone httpclient
drewp@bigasterisk.com
parents: 50
diff changeset
133
0
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
134 class Poller(object):
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
135 def __init__(self, wifi, mongo):
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
136 self.wifi = wifi
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
137 self.mongo = mongo
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
138 self.lastAddrs = []
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
139 self.lastWithSignal = []
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
140 self.lastPollTime = 0
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
141
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
142 def assertCurrent(self):
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
143 dt = time.time() - self.lastPollTime
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
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
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
147 def poll(self):
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
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
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
153
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
154 actions = self.computeActions(newWithSignal)
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
155 for action in actions:
1
26a6cf58743d entrancemusic improve logging
drewp@bigasterisk.com
parents: 0
diff changeset
156 log.info("action: %s", action)
0
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
157 action['created'] = datetime.datetime.now(tz.gettz('UTC'))
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
158 mongo.save(action)
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
159 try:
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
160 self.doEntranceMusic(action)
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
161 except Exception, e:
1
26a6cf58743d entrancemusic improve logging
drewp@bigasterisk.com
parents: 0
diff changeset
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
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
164 self.lastWithSignal = newWithSignal
50
56eeda98cac5 ping reasoning
drewp@bigasterisk.com
parents: 36
diff changeset
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
875a37be1228 fix fetch calls in tomatowifi
drewp@bigasterisk.com
parents: 51
diff changeset
167 timeout=2,
875a37be1228 fix fetch calls in tomatowifi
drewp@bigasterisk.com
parents: 51
diff changeset
168 headers={'user-agent': ['tomatoWifi']}).addErrback(log.warn)
0
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
169 self.lastAddrs = newAddrs
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
170 self.lastPollTime = time.time()
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
171 except Exception, e:
1
26a6cf58743d entrancemusic improve logging
drewp@bigasterisk.com
parents: 0
diff changeset
172 log.error("poll error: %s\n%s", e, traceback.format_exc())
0
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
173
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
174 def computeActions(self, newWithSignal):
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
175 actions = []
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
176
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
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
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
179 address=addr.get('mac'),
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
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
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
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
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
189
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
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
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
192 actions.append(makeAction(addr, 'arrive'))
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
193
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
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
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
196 actions.append(makeAction(addr, 'leave'))
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
197
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
198 return actions
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
199
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
200
1
26a6cf58743d entrancemusic improve logging
drewp@bigasterisk.com
parents: 0
diff changeset
201 # these need to move out to their own service
0
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
202 def doEntranceMusic(self, action):
1
26a6cf58743d entrancemusic improve logging
drewp@bigasterisk.com
parents: 0
diff changeset
203 import restkit, jsonlib
0
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
204 dt = self.deltaSinceLastArrive(action['name'])
1
26a6cf58743d entrancemusic improve logging
drewp@bigasterisk.com
parents: 0
diff changeset
205 log.debug("dt=%s", dt)
0
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
206 if dt > datetime.timedelta(hours=1):
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
207 hub = restkit.Resource(
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
208 # PSHB not working yet; "http://bang:9030/"
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
209 "http://slash:9049/"
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
210 )
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
211 action = action.copy()
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
212 del action['created']
1
26a6cf58743d entrancemusic improve logging
drewp@bigasterisk.com
parents: 0
diff changeset
213 del action['_id']
26a6cf58743d entrancemusic improve logging
drewp@bigasterisk.com
parents: 0
diff changeset
214 log.info("post to %s", hub)
0
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
215 hub.post("visitorNet", payload=jsonlib.dumps(action))
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
216
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
217 def deltaSinceLastArrive(self, name):
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
218 results = list(self.mongo.find({'name' : name}).sort('created',
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
219 DESCENDING).limit(1))
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
220 if not results:
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
221 return datetime.timedelta.max
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
222 now = datetime.datetime.now(tz.gettz('UTC'))
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
223 last = results[0]['created'].replace(tzinfo=tz.gettz('UTC'))
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
224 return now - last
51
d2842eedd56d rewrite tomatowifi from restkit to cyclone httpclient
drewp@bigasterisk.com
parents: 50
diff changeset
225
0
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
226
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
227 if __name__ == '__main__':
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
228 config = {
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
229 'servePort' : 9070,
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
230 'pollFrequency' : 1/5,
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
231 }
1
26a6cf58743d entrancemusic improve logging
drewp@bigasterisk.com
parents: 0
diff changeset
232 from twisted.python import log as twlog
0
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
233 #log.startLogging(sys.stdout)
1
26a6cf58743d entrancemusic improve logging
drewp@bigasterisk.com
parents: 0
diff changeset
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
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
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
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
238
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
239 wifi = Wifi()
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
240 poller = Poller(wifi, mongo)
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
241 task.LoopingCall(poller.poll).start(1/config['pollFrequency'])
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
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
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
255 reactor.run()