annotate service/wifi/wifi.py @ 1705:250f4c27d56f

less logging
author drewp@bigasterisk.com
date Sat, 23 Oct 2021 13:21:06 -0700
parents f88ff1021ee0
children 81aa0873b48d
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
1 """
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
2 scrape the tomato router status pages to see who's connected to the
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
3 wifi access points. Includes leases that aren't currently connected.
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
4
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
5 Returns:
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
6 json listing (for magma page)
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
7 rdf graph (for reasoning)
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
8 activity stream, when we start saving history
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
9
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
10 Todo: this should be the one polling and writing to mongo, not entrancemusic
162
bb70eaa45666 whitespace
drewp@bigasterisk.com
parents: 161
diff changeset
11
0
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
12 """
1679
f88ff1021ee0 checkpoint service/wifi
drewp@bigasterisk.com
parents: 722
diff changeset
13 from collections import defaultdict
f88ff1021ee0 checkpoint service/wifi
drewp@bigasterisk.com
parents: 722
diff changeset
14 import datetime
f88ff1021ee0 checkpoint service/wifi
drewp@bigasterisk.com
parents: 722
diff changeset
15 import json
f88ff1021ee0 checkpoint service/wifi
drewp@bigasterisk.com
parents: 722
diff changeset
16 import logging
f88ff1021ee0 checkpoint service/wifi
drewp@bigasterisk.com
parents: 722
diff changeset
17 import sys
f88ff1021ee0 checkpoint service/wifi
drewp@bigasterisk.com
parents: 722
diff changeset
18 import time
f88ff1021ee0 checkpoint service/wifi
drewp@bigasterisk.com
parents: 722
diff changeset
19 import traceback
423
e0703c7824e9 very big rewrite. py3; orbi-only for now; n3 config file; delete or move out dead code
drewp@bigasterisk.com
parents: 422
diff changeset
20 from typing import List
e0703c7824e9 very big rewrite. py3; orbi-only for now; n3 config file; delete or move out dead code
drewp@bigasterisk.com
parents: 422
diff changeset
21
1679
f88ff1021ee0 checkpoint service/wifi
drewp@bigasterisk.com
parents: 722
diff changeset
22 import ago
51
d2842eedd56d rewrite tomatowifi from restkit to cyclone httpclient
drewp@bigasterisk.com
parents: 50
diff changeset
23 from cyclone.httpclient import fetch
1679
f88ff1021ee0 checkpoint service/wifi
drewp@bigasterisk.com
parents: 722
diff changeset
24 import cyclone.web
f88ff1021ee0 checkpoint service/wifi
drewp@bigasterisk.com
parents: 722
diff changeset
25 from cycloneerr import PrettyErrorHandler
0
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
26 from dateutil import tz
1679
f88ff1021ee0 checkpoint service/wifi
drewp@bigasterisk.com
parents: 722
diff changeset
27 import docopt
f88ff1021ee0 checkpoint service/wifi
drewp@bigasterisk.com
parents: 722
diff changeset
28 from patchablegraph import (
f88ff1021ee0 checkpoint service/wifi
drewp@bigasterisk.com
parents: 722
diff changeset
29 CycloneGraphEventsHandler,
f88ff1021ee0 checkpoint service/wifi
drewp@bigasterisk.com
parents: 722
diff changeset
30 CycloneGraphHandler,
f88ff1021ee0 checkpoint service/wifi
drewp@bigasterisk.com
parents: 722
diff changeset
31 PatchableGraph,
f88ff1021ee0 checkpoint service/wifi
drewp@bigasterisk.com
parents: 722
diff changeset
32 )
f88ff1021ee0 checkpoint service/wifi
drewp@bigasterisk.com
parents: 722
diff changeset
33 from prometheus_client import Counter, Gauge, Summary
f88ff1021ee0 checkpoint service/wifi
drewp@bigasterisk.com
parents: 722
diff changeset
34 from prometheus_client.exposition import generate_latest
f88ff1021ee0 checkpoint service/wifi
drewp@bigasterisk.com
parents: 722
diff changeset
35 from prometheus_client.registry import REGISTRY
f88ff1021ee0 checkpoint service/wifi
drewp@bigasterisk.com
parents: 722
diff changeset
36 from pymongo import DESCENDING, MongoClient as Connection
f88ff1021ee0 checkpoint service/wifi
drewp@bigasterisk.com
parents: 722
diff changeset
37 from pymongo.collection import Collection
f88ff1021ee0 checkpoint service/wifi
drewp@bigasterisk.com
parents: 722
diff changeset
38 import pystache
f88ff1021ee0 checkpoint service/wifi
drewp@bigasterisk.com
parents: 722
diff changeset
39 from rdflib import ConjunctiveGraph, Literal, Namespace, RDF
f88ff1021ee0 checkpoint service/wifi
drewp@bigasterisk.com
parents: 722
diff changeset
40 from standardservice.logsetup import log
0
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
41 from twisted.internet import reactor, task
1679
f88ff1021ee0 checkpoint service/wifi
drewp@bigasterisk.com
parents: 722
diff changeset
42 from twisted.internet.defer import ensureDeferred, inlineCallbacks
383
8f5a16a55f64 various docker setups and build fixes
drewp@bigasterisk.com
parents: 340
diff changeset
43
1679
f88ff1021ee0 checkpoint service/wifi
drewp@bigasterisk.com
parents: 722
diff changeset
44 from scrape import SeenNode, Wifi
36
0ab069867c64 rdflib and jsonlib api updates
drewp@bigasterisk.com
parents: 1
diff changeset
45
422
19460b3f7baf factor out some URI generation
drewp@bigasterisk.com
parents: 421
diff changeset
46 AST = Namespace("http://bigasterisk.com/")
0
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
47 DEV = Namespace("http://projects.bigasterisk.com/device/")
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
48 ROOM = Namespace("http://projects.bigasterisk.com/room/")
1
26a6cf58743d entrancemusic improve logging
drewp@bigasterisk.com
parents: 0
diff changeset
49
1679
f88ff1021ee0 checkpoint service/wifi
drewp@bigasterisk.com
parents: 722
diff changeset
50
0
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
51 class Index(PrettyErrorHandler, cyclone.web.RequestHandler):
1679
f88ff1021ee0 checkpoint service/wifi
drewp@bigasterisk.com
parents: 722
diff changeset
52
0
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
53 def get(self):
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
54 age = time.time() - self.settings.poller.lastPollTime
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
55 if age > 10:
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
56 raise ValueError("poll data is stale. age=%s" % age)
659
ea9ed11598b0 remote suspend, wifi group arg
drewp@bigasterisk.com
parents: 566
diff changeset
57
175
c81a451f9b26 rewrites for better graph export, removal of dhcp reader
drewp@bigasterisk.com
parents: 162
diff changeset
58 self.set_header("Content-Type", "text/html")
c81a451f9b26 rewrites for better graph export, removal of dhcp reader
drewp@bigasterisk.com
parents: 162
diff changeset
59 self.write(open("index.html").read())
51
d2842eedd56d rewrite tomatowifi from restkit to cyclone httpclient
drewp@bigasterisk.com
parents: 50
diff changeset
60
1679
f88ff1021ee0 checkpoint service/wifi
drewp@bigasterisk.com
parents: 722
diff changeset
61
175
c81a451f9b26 rewrites for better graph export, removal of dhcp reader
drewp@bigasterisk.com
parents: 162
diff changeset
62 def whenConnected(mongo, macThatIsNowConnected):
c81a451f9b26 rewrites for better graph export, removal of dhcp reader
drewp@bigasterisk.com
parents: 162
diff changeset
63 lastArrive = None
1679
f88ff1021ee0 checkpoint service/wifi
drewp@bigasterisk.com
parents: 722
diff changeset
64 for ev in mongo.find({'address': macThatIsNowConnected.upper()}, sort=[('created', -1)], max_time_ms=5000):
175
c81a451f9b26 rewrites for better graph export, removal of dhcp reader
drewp@bigasterisk.com
parents: 162
diff changeset
65 if ev['action'] == 'arrive':
c81a451f9b26 rewrites for better graph export, removal of dhcp reader
drewp@bigasterisk.com
parents: 162
diff changeset
66 lastArrive = ev
c81a451f9b26 rewrites for better graph export, removal of dhcp reader
drewp@bigasterisk.com
parents: 162
diff changeset
67 if ev['action'] == 'leave':
c81a451f9b26 rewrites for better graph export, removal of dhcp reader
drewp@bigasterisk.com
parents: 162
diff changeset
68 break
c81a451f9b26 rewrites for better graph export, removal of dhcp reader
drewp@bigasterisk.com
parents: 162
diff changeset
69 if lastArrive is None:
c81a451f9b26 rewrites for better graph export, removal of dhcp reader
drewp@bigasterisk.com
parents: 162
diff changeset
70 raise ValueError("no past arrivals")
0
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
71
175
c81a451f9b26 rewrites for better graph export, removal of dhcp reader
drewp@bigasterisk.com
parents: 162
diff changeset
72 return lastArrive['created']
c81a451f9b26 rewrites for better graph export, removal of dhcp reader
drewp@bigasterisk.com
parents: 162
diff changeset
73
1679
f88ff1021ee0 checkpoint service/wifi
drewp@bigasterisk.com
parents: 722
diff changeset
74
175
c81a451f9b26 rewrites for better graph export, removal of dhcp reader
drewp@bigasterisk.com
parents: 162
diff changeset
75 def connectedAgoString(conn):
423
e0703c7824e9 very big rewrite. py3; orbi-only for now; n3 config file; delete or move out dead code
drewp@bigasterisk.com
parents: 422
diff changeset
76 return ago.human(conn.astimezone(tz.tzutc()).replace(tzinfo=None))
659
ea9ed11598b0 remote suspend, wifi group arg
drewp@bigasterisk.com
parents: 566
diff changeset
77
1679
f88ff1021ee0 checkpoint service/wifi
drewp@bigasterisk.com
parents: 722
diff changeset
78
0
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
79 class Table(PrettyErrorHandler, cyclone.web.RequestHandler):
1679
f88ff1021ee0 checkpoint service/wifi
drewp@bigasterisk.com
parents: 722
diff changeset
80
0
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
81 def get(self):
1679
f88ff1021ee0 checkpoint service/wifi
drewp@bigasterisk.com
parents: 722
diff changeset
82
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
83 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
84 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
85 if 'name' not in row:
74
bca6d6c63bdc handle wifi users with no clientHostname
drewp@bigasterisk.com
parents: 62
diff changeset
86 row['name'] = row.get('clientHostname', '-')
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
87 if 'signal' not in row:
175
c81a451f9b26 rewrites for better graph export, removal of dhcp reader
drewp@bigasterisk.com
parents: 162
diff changeset
88 row['signal'] = 'yes' if row.get('connected') else 'no'
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
89
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 try:
175
c81a451f9b26 rewrites for better graph export, removal of dhcp reader
drewp@bigasterisk.com
parents: 162
diff changeset
91 conn = whenConnected(self.settings.mongo, row.get('mac', '??'))
c81a451f9b26 rewrites for better graph export, removal of dhcp reader
drewp@bigasterisk.com
parents: 162
diff changeset
92 row['connectedAgo'] = connectedAgoString(conn)
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
93 except ValueError:
175
c81a451f9b26 rewrites for better graph export, removal of dhcp reader
drewp@bigasterisk.com
parents: 162
diff changeset
94 row['connectedAgo'] = 'yes' if row.get('connected') else ''
c81a451f9b26 rewrites for better graph export, removal of dhcp reader
drewp@bigasterisk.com
parents: 162
diff changeset
95 row['router'] = row.get('ssid', '')
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
96 return row
0
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
97
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
98 self.set_header("Content-Type", "application/xhtml+xml")
1679
f88ff1021ee0 checkpoint service/wifi
drewp@bigasterisk.com
parents: 722
diff changeset
99 self.write(
f88ff1021ee0 checkpoint service/wifi
drewp@bigasterisk.com
parents: 722
diff changeset
100 pystache.render(
f88ff1021ee0 checkpoint service/wifi
drewp@bigasterisk.com
parents: 722
diff changeset
101 open("table.mustache").read(),
f88ff1021ee0 checkpoint service/wifi
drewp@bigasterisk.com
parents: 722
diff changeset
102 dict(rows=sorted(map(rowDict, self.settings.poller.lastAddrs),
f88ff1021ee0 checkpoint service/wifi
drewp@bigasterisk.com
parents: 722
diff changeset
103 key=lambda a: (not a.get('connected'), a.get('name'))))))
f88ff1021ee0 checkpoint service/wifi
drewp@bigasterisk.com
parents: 722
diff changeset
104
51
d2842eedd56d rewrite tomatowifi from restkit to cyclone httpclient
drewp@bigasterisk.com
parents: 50
diff changeset
105
0
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
106 class Json(PrettyErrorHandler, cyclone.web.RequestHandler):
1679
f88ff1021ee0 checkpoint service/wifi
drewp@bigasterisk.com
parents: 722
diff changeset
107
0
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
108 def get(self):
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
109 self.set_header("Content-Type", "application/json")
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
110 age = time.time() - self.settings.poller.lastPollTime
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
111 if age > 10:
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
112 raise ValueError("poll data is stale. age=%s" % age)
1679
f88ff1021ee0 checkpoint service/wifi
drewp@bigasterisk.com
parents: 722
diff changeset
113 self.write(json.dumps({"wifi": self.settings.poller.lastAddrs, "dataAge": age}))
f88ff1021ee0 checkpoint service/wifi
drewp@bigasterisk.com
parents: 722
diff changeset
114
f88ff1021ee0 checkpoint service/wifi
drewp@bigasterisk.com
parents: 722
diff changeset
115
f88ff1021ee0 checkpoint service/wifi
drewp@bigasterisk.com
parents: 722
diff changeset
116 POLL = Summary('poll', 'Time in HTTP poll requests')
f88ff1021ee0 checkpoint service/wifi
drewp@bigasterisk.com
parents: 722
diff changeset
117 POLL_SUCCESSES = Counter('poll_successes', 'poll success count')
f88ff1021ee0 checkpoint service/wifi
drewp@bigasterisk.com
parents: 722
diff changeset
118 POLL_ERRORS = Counter('poll_errors', 'poll error count')
f88ff1021ee0 checkpoint service/wifi
drewp@bigasterisk.com
parents: 722
diff changeset
119 CURRENTLY_ON_WIFI = Gauge('currently_on_wifi', 'current nodes known to wifi router (some may be wired)')
f88ff1021ee0 checkpoint service/wifi
drewp@bigasterisk.com
parents: 722
diff changeset
120 MAC_ON_WIFI = Gauge('connected', 'mac addr is currently connected', ['mac'])
f88ff1021ee0 checkpoint service/wifi
drewp@bigasterisk.com
parents: 722
diff changeset
121
0
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
122
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
123 class Poller(object):
1679
f88ff1021ee0 checkpoint service/wifi
drewp@bigasterisk.com
parents: 722
diff changeset
124
f88ff1021ee0 checkpoint service/wifi
drewp@bigasterisk.com
parents: 722
diff changeset
125 def __init__(self, wifi: Wifi, mongo: Collection):
0
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
126 self.wifi = wifi
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
127 self.mongo = mongo
1679
f88ff1021ee0 checkpoint service/wifi
drewp@bigasterisk.com
parents: 722
diff changeset
128 self.lastAddrs = [] # List[SeenNode]
0
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
129 self.lastWithSignal = []
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
130 self.lastPollTime = 0
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
131
1679
f88ff1021ee0 checkpoint service/wifi
drewp@bigasterisk.com
parents: 722
diff changeset
132 @POLL.time()
f88ff1021ee0 checkpoint service/wifi
drewp@bigasterisk.com
parents: 722
diff changeset
133 async def poll(self):
0
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
134 try:
1679
f88ff1021ee0 checkpoint service/wifi
drewp@bigasterisk.com
parents: 722
diff changeset
135 newAddrs = await self.wifi.getPresentMacAddrs()
423
e0703c7824e9 very big rewrite. py3; orbi-only for now; n3 config file; delete or move out dead code
drewp@bigasterisk.com
parents: 422
diff changeset
136 self.onNodes(newAddrs)
1679
f88ff1021ee0 checkpoint service/wifi
drewp@bigasterisk.com
parents: 722
diff changeset
137 POLL_SUCCESSES.inc()
421
47d7dd31bb2c port to py3
drewp@bigasterisk.com
parents: 420
diff changeset
138 except Exception as e:
175
c81a451f9b26 rewrites for better graph export, removal of dhcp reader
drewp@bigasterisk.com
parents: 162
diff changeset
139 log.error("poll error: %r\n%s", e, traceback.format_exc())
1679
f88ff1021ee0 checkpoint service/wifi
drewp@bigasterisk.com
parents: 722
diff changeset
140 POLL_ERRORS.inc()
0
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
141
423
e0703c7824e9 very big rewrite. py3; orbi-only for now; n3 config file; delete or move out dead code
drewp@bigasterisk.com
parents: 422
diff changeset
142 def onNodes(self, newAddrs: List[SeenNode]):
e0703c7824e9 very big rewrite. py3; orbi-only for now; n3 config file; delete or move out dead code
drewp@bigasterisk.com
parents: 422
diff changeset
143 now = int(time.time())
e0703c7824e9 very big rewrite. py3; orbi-only for now; n3 config file; delete or move out dead code
drewp@bigasterisk.com
parents: 422
diff changeset
144 newWithSignal = [a for a in newAddrs if a.connected]
1679
f88ff1021ee0 checkpoint service/wifi
drewp@bigasterisk.com
parents: 722
diff changeset
145 CURRENTLY_ON_WIFI.set(len(newWithSignal))
423
e0703c7824e9 very big rewrite. py3; orbi-only for now; n3 config file; delete or move out dead code
drewp@bigasterisk.com
parents: 422
diff changeset
146
e0703c7824e9 very big rewrite. py3; orbi-only for now; n3 config file; delete or move out dead code
drewp@bigasterisk.com
parents: 422
diff changeset
147 actions = self.computeActions(newWithSignal)
e0703c7824e9 very big rewrite. py3; orbi-only for now; n3 config file; delete or move out dead code
drewp@bigasterisk.com
parents: 422
diff changeset
148 for action in actions:
e0703c7824e9 very big rewrite. py3; orbi-only for now; n3 config file; delete or move out dead code
drewp@bigasterisk.com
parents: 422
diff changeset
149 log.info("action: %s", action)
e0703c7824e9 very big rewrite. py3; orbi-only for now; n3 config file; delete or move out dead code
drewp@bigasterisk.com
parents: 422
diff changeset
150 action['created'] = datetime.datetime.now(tz.gettz('UTC'))
e0703c7824e9 very big rewrite. py3; orbi-only for now; n3 config file; delete or move out dead code
drewp@bigasterisk.com
parents: 422
diff changeset
151 mongo.save(action)
1679
f88ff1021ee0 checkpoint service/wifi
drewp@bigasterisk.com
parents: 722
diff changeset
152 MAC_ON_WIFI.labels(mac=action['address'].lower()).set(1 if action['action'] == 'arrive' else 0)
423
e0703c7824e9 very big rewrite. py3; orbi-only for now; n3 config file; delete or move out dead code
drewp@bigasterisk.com
parents: 422
diff changeset
153 if now // 3600 > self.lastPollTime // 3600:
e0703c7824e9 very big rewrite. py3; orbi-only for now; n3 config file; delete or move out dead code
drewp@bigasterisk.com
parents: 422
diff changeset
154 log.info('hourly writes')
e0703c7824e9 very big rewrite. py3; orbi-only for now; n3 config file; delete or move out dead code
drewp@bigasterisk.com
parents: 422
diff changeset
155 for addr in newWithSignal:
1679
f88ff1021ee0 checkpoint service/wifi
drewp@bigasterisk.com
parents: 722
diff changeset
156 MAC_ON_WIFI.labels(mac=addr.mac.lower()).set(1)
423
e0703c7824e9 very big rewrite. py3; orbi-only for now; n3 config file; delete or move out dead code
drewp@bigasterisk.com
parents: 422
diff changeset
157
e0703c7824e9 very big rewrite. py3; orbi-only for now; n3 config file; delete or move out dead code
drewp@bigasterisk.com
parents: 422
diff changeset
158 self.lastWithSignal = newWithSignal
e0703c7824e9 very big rewrite. py3; orbi-only for now; n3 config file; delete or move out dead code
drewp@bigasterisk.com
parents: 422
diff changeset
159 self.lastAddrs = newAddrs
e0703c7824e9 very big rewrite. py3; orbi-only for now; n3 config file; delete or move out dead code
drewp@bigasterisk.com
parents: 422
diff changeset
160 self.lastPollTime = now
e0703c7824e9 very big rewrite. py3; orbi-only for now; n3 config file; delete or move out dead code
drewp@bigasterisk.com
parents: 422
diff changeset
161
e0703c7824e9 very big rewrite. py3; orbi-only for now; n3 config file; delete or move out dead code
drewp@bigasterisk.com
parents: 422
diff changeset
162 self.updateGraph(masterGraph)
566
c3d06c350e24 no more immediateUpdate since we push patch events now. and the code was broken for py3 anyway
drewp@bigasterisk.com
parents: 564
diff changeset
163
0
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
164 def computeActions(self, newWithSignal):
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
165 actions = []
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
166
423
e0703c7824e9 very big rewrite. py3; orbi-only for now; n3 config file; delete or move out dead code
drewp@bigasterisk.com
parents: 422
diff changeset
167 def makeAction(addr: SeenNode, act: str):
1679
f88ff1021ee0 checkpoint service/wifi
drewp@bigasterisk.com
parents: 722
diff changeset
168 d = dict(
f88ff1021ee0 checkpoint service/wifi
drewp@bigasterisk.com
parents: 722
diff changeset
169 sensor="wifi",
f88ff1021ee0 checkpoint service/wifi
drewp@bigasterisk.com
parents: 722
diff changeset
170 address=addr.mac.upper(), # mongo data is legacy uppercase
f88ff1021ee0 checkpoint service/wifi
drewp@bigasterisk.com
parents: 722
diff changeset
171 action=act)
423
e0703c7824e9 very big rewrite. py3; orbi-only for now; n3 config file; delete or move out dead code
drewp@bigasterisk.com
parents: 422
diff changeset
172 if act == 'arrive':
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
173 # 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
174 # 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
175 # action with no ip and then never record your ip.
423
e0703c7824e9 very big rewrite. py3; orbi-only for now; n3 config file; delete or move out dead code
drewp@bigasterisk.com
parents: 422
diff changeset
176 d['ip'] = addr.ip
659
ea9ed11598b0 remote suspend, wifi group arg
drewp@bigasterisk.com
parents: 566
diff changeset
177 return d
0
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
178
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
179 for addr in newWithSignal:
423
e0703c7824e9 very big rewrite. py3; orbi-only for now; n3 config file; delete or move out dead code
drewp@bigasterisk.com
parents: 422
diff changeset
180 if addr.mac not in [r.mac for r in self.lastWithSignal]:
0
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
181 actions.append(makeAction(addr, 'arrive'))
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
182
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
183 for addr in self.lastWithSignal:
423
e0703c7824e9 very big rewrite. py3; orbi-only for now; n3 config file; delete or move out dead code
drewp@bigasterisk.com
parents: 422
diff changeset
184 if addr.mac not in [r.mac for r in newWithSignal]:
0
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
185 actions.append(makeAction(addr, 'leave'))
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
186
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
187 return actions
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
188
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
189 def deltaSinceLastArrive(self, name):
1679
f88ff1021ee0 checkpoint service/wifi
drewp@bigasterisk.com
parents: 722
diff changeset
190 results = list(self.mongo.find({'name': name}).sort('created', DESCENDING).limit(1))
0
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
191 if not results:
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
192 return datetime.timedelta.max
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
193 now = datetime.datetime.now(tz.gettz('UTC'))
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
194 last = results[0]['created'].replace(tzinfo=tz.gettz('UTC'))
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
195 return now - last
51
d2842eedd56d rewrite tomatowifi from restkit to cyclone httpclient
drewp@bigasterisk.com
parents: 50
diff changeset
196
340
70954bd426be wifi now uses PatchableGraph
drewp@bigasterisk.com
parents: 309
diff changeset
197 def updateGraph(self, masterGraph):
70954bd426be wifi now uses PatchableGraph
drewp@bigasterisk.com
parents: 309
diff changeset
198 g = ConjunctiveGraph()
70954bd426be wifi now uses PatchableGraph
drewp@bigasterisk.com
parents: 309
diff changeset
199 ctx = DEV['wifi']
70954bd426be wifi now uses PatchableGraph
drewp@bigasterisk.com
parents: 309
diff changeset
200
70954bd426be wifi now uses PatchableGraph
drewp@bigasterisk.com
parents: 309
diff changeset
201 # someday i may also record specific AP and their strength,
70954bd426be wifi now uses PatchableGraph
drewp@bigasterisk.com
parents: 309
diff changeset
202 # for positioning. But many users just want to know that the
70954bd426be wifi now uses PatchableGraph
drewp@bigasterisk.com
parents: 309
diff changeset
203 # device is connected to some bigasterisk AP.
70954bd426be wifi now uses PatchableGraph
drewp@bigasterisk.com
parents: 309
diff changeset
204 age = time.time() - self.lastPollTime
70954bd426be wifi now uses PatchableGraph
drewp@bigasterisk.com
parents: 309
diff changeset
205 if age > 10:
70954bd426be wifi now uses PatchableGraph
drewp@bigasterisk.com
parents: 309
diff changeset
206 raise ValueError("poll data is stale. age=%s" % age)
70954bd426be wifi now uses PatchableGraph
drewp@bigasterisk.com
parents: 309
diff changeset
207
70954bd426be wifi now uses PatchableGraph
drewp@bigasterisk.com
parents: 309
diff changeset
208 for dev in self.lastAddrs:
423
e0703c7824e9 very big rewrite. py3; orbi-only for now; n3 config file; delete or move out dead code
drewp@bigasterisk.com
parents: 422
diff changeset
209 if not dev.connected:
340
70954bd426be wifi now uses PatchableGraph
drewp@bigasterisk.com
parents: 309
diff changeset
210 continue
427
db031d9ec28e don't use 'connected' for time and for network. add rdf:type.
drewp@bigasterisk.com
parents: 423
diff changeset
211 g.add((dev.uri, RDF.type, ROOM['NetworkedDevice'], ctx))
423
e0703c7824e9 very big rewrite. py3; orbi-only for now; n3 config file; delete or move out dead code
drewp@bigasterisk.com
parents: 422
diff changeset
212 g.add((dev.uri, ROOM['macAddress'], Literal(dev.mac), ctx))
e0703c7824e9 very big rewrite. py3; orbi-only for now; n3 config file; delete or move out dead code
drewp@bigasterisk.com
parents: 422
diff changeset
213 g.add((dev.uri, ROOM['ipAddress'], Literal(dev.ip), ctx))
340
70954bd426be wifi now uses PatchableGraph
drewp@bigasterisk.com
parents: 309
diff changeset
214
1679
f88ff1021ee0 checkpoint service/wifi
drewp@bigasterisk.com
parents: 722
diff changeset
215 for s, p, o in dev.stmts:
423
e0703c7824e9 very big rewrite. py3; orbi-only for now; n3 config file; delete or move out dead code
drewp@bigasterisk.com
parents: 422
diff changeset
216 g.add((s, p, o, ctx))
e0703c7824e9 very big rewrite. py3; orbi-only for now; n3 config file; delete or move out dead code
drewp@bigasterisk.com
parents: 422
diff changeset
217
340
70954bd426be wifi now uses PatchableGraph
drewp@bigasterisk.com
parents: 309
diff changeset
218 try:
423
e0703c7824e9 very big rewrite. py3; orbi-only for now; n3 config file; delete or move out dead code
drewp@bigasterisk.com
parents: 422
diff changeset
219 conn = whenConnected(mongo, dev.mac)
340
70954bd426be wifi now uses PatchableGraph
drewp@bigasterisk.com
parents: 309
diff changeset
220 except ValueError:
70954bd426be wifi now uses PatchableGraph
drewp@bigasterisk.com
parents: 309
diff changeset
221 traceback.print_exc()
70954bd426be wifi now uses PatchableGraph
drewp@bigasterisk.com
parents: 309
diff changeset
222 pass
70954bd426be wifi now uses PatchableGraph
drewp@bigasterisk.com
parents: 309
diff changeset
223 else:
1679
f88ff1021ee0 checkpoint service/wifi
drewp@bigasterisk.com
parents: 722
diff changeset
224 g.add((dev.uri, ROOM['connectedAgo'], Literal(connectedAgoString(conn)), ctx))
423
e0703c7824e9 very big rewrite. py3; orbi-only for now; n3 config file; delete or move out dead code
drewp@bigasterisk.com
parents: 422
diff changeset
225 g.add((dev.uri, ROOM['connected'], Literal(conn), ctx))
340
70954bd426be wifi now uses PatchableGraph
drewp@bigasterisk.com
parents: 309
diff changeset
226 masterGraph.setToGraph(g)
70954bd426be wifi now uses PatchableGraph
drewp@bigasterisk.com
parents: 309
diff changeset
227
1679
f88ff1021ee0 checkpoint service/wifi
drewp@bigasterisk.com
parents: 722
diff changeset
228
659
ea9ed11598b0 remote suspend, wifi group arg
drewp@bigasterisk.com
parents: 566
diff changeset
229 class RemoteSuspend(PrettyErrorHandler, cyclone.web.RequestHandler):
1679
f88ff1021ee0 checkpoint service/wifi
drewp@bigasterisk.com
parents: 722
diff changeset
230
659
ea9ed11598b0 remote suspend, wifi group arg
drewp@bigasterisk.com
parents: 566
diff changeset
231 def post(self):
ea9ed11598b0 remote suspend, wifi group arg
drewp@bigasterisk.com
parents: 566
diff changeset
232 # windows is running shutter (https://www.den4b.com/products/shutter)
ea9ed11598b0 remote suspend, wifi group arg
drewp@bigasterisk.com
parents: 566
diff changeset
233 fetch('http://DESKTOP-GOU4AC4:8011/action', postdata={'id': 'Sleep'})
ea9ed11598b0 remote suspend, wifi group arg
drewp@bigasterisk.com
parents: 566
diff changeset
234
0
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
235
1679
f88ff1021ee0 checkpoint service/wifi
drewp@bigasterisk.com
parents: 722
diff changeset
236 class Metrics(cyclone.web.RequestHandler):
f88ff1021ee0 checkpoint service/wifi
drewp@bigasterisk.com
parents: 722
diff changeset
237
f88ff1021ee0 checkpoint service/wifi
drewp@bigasterisk.com
parents: 722
diff changeset
238 def get(self):
f88ff1021ee0 checkpoint service/wifi
drewp@bigasterisk.com
parents: 722
diff changeset
239 self.add_header('content-type', 'text/plain')
f88ff1021ee0 checkpoint service/wifi
drewp@bigasterisk.com
parents: 722
diff changeset
240 self.write(generate_latest(REGISTRY))
f88ff1021ee0 checkpoint service/wifi
drewp@bigasterisk.com
parents: 722
diff changeset
241
f88ff1021ee0 checkpoint service/wifi
drewp@bigasterisk.com
parents: 722
diff changeset
242
0
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
243 if __name__ == '__main__':
189
fc184ea1416d switch to docopt
drewp@bigasterisk.com
parents: 175
diff changeset
244 args = docopt.docopt('''
fc184ea1416d switch to docopt
drewp@bigasterisk.com
parents: 175
diff changeset
245 Usage:
423
e0703c7824e9 very big rewrite. py3; orbi-only for now; n3 config file; delete or move out dead code
drewp@bigasterisk.com
parents: 422
diff changeset
246 wifi.py [options]
189
fc184ea1416d switch to docopt
drewp@bigasterisk.com
parents: 175
diff changeset
247
fc184ea1416d switch to docopt
drewp@bigasterisk.com
parents: 175
diff changeset
248 Options:
fc184ea1416d switch to docopt
drewp@bigasterisk.com
parents: 175
diff changeset
249 -v, --verbose more logging
fc184ea1416d switch to docopt
drewp@bigasterisk.com
parents: 175
diff changeset
250 --port=<n> serve on port [default: 9070]
fc184ea1416d switch to docopt
drewp@bigasterisk.com
parents: 175
diff changeset
251 --poll=<freq> poll frequency [default: .2]
fc184ea1416d switch to docopt
drewp@bigasterisk.com
parents: 175
diff changeset
252 ''')
fc184ea1416d switch to docopt
drewp@bigasterisk.com
parents: 175
diff changeset
253 if args['--verbose']:
fc184ea1416d switch to docopt
drewp@bigasterisk.com
parents: 175
diff changeset
254 from twisted.python import log as twlog
fc184ea1416d switch to docopt
drewp@bigasterisk.com
parents: 175
diff changeset
255 twlog.startLogging(sys.stdout)
fc184ea1416d switch to docopt
drewp@bigasterisk.com
parents: 175
diff changeset
256 log.setLevel(10)
fc184ea1416d switch to docopt
drewp@bigasterisk.com
parents: 175
diff changeset
257 log.setLevel(logging.DEBUG)
0
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
258
1679
f88ff1021ee0 checkpoint service/wifi
drewp@bigasterisk.com
parents: 722
diff changeset
259 mongo = Connection('mongodb.default.svc.cluster.local', 27017, tz_aware=True)['visitor']['visitor']
0
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
260
423
e0703c7824e9 very big rewrite. py3; orbi-only for now; n3 config file; delete or move out dead code
drewp@bigasterisk.com
parents: 422
diff changeset
261 config = ConjunctiveGraph()
e0703c7824e9 very big rewrite. py3; orbi-only for now; n3 config file; delete or move out dead code
drewp@bigasterisk.com
parents: 422
diff changeset
262 config.parse(open('private_config.n3'), format='n3')
659
ea9ed11598b0 remote suspend, wifi group arg
drewp@bigasterisk.com
parents: 566
diff changeset
263
340
70954bd426be wifi now uses PatchableGraph
drewp@bigasterisk.com
parents: 309
diff changeset
264 masterGraph = PatchableGraph()
423
e0703c7824e9 very big rewrite. py3; orbi-only for now; n3 config file; delete or move out dead code
drewp@bigasterisk.com
parents: 422
diff changeset
265 wifi = Wifi(config)
0
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
266 poller = Poller(wifi, mongo)
1679
f88ff1021ee0 checkpoint service/wifi
drewp@bigasterisk.com
parents: 722
diff changeset
267 task.LoopingCall(lambda: ensureDeferred(poller.poll())).start(1 / float(args['--poll']))
0
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
268
422
19460b3f7baf factor out some URI generation
drewp@bigasterisk.com
parents: 421
diff changeset
269 reactor.listenTCP(
19460b3f7baf factor out some URI generation
drewp@bigasterisk.com
parents: 421
diff changeset
270 int(args['--port']),
19460b3f7baf factor out some URI generation
drewp@bigasterisk.com
parents: 421
diff changeset
271 cyclone.web.Application(
19460b3f7baf factor out some URI generation
drewp@bigasterisk.com
parents: 421
diff changeset
272 [
19460b3f7baf factor out some URI generation
drewp@bigasterisk.com
parents: 421
diff changeset
273 (r"/", Index),
1679
f88ff1021ee0 checkpoint service/wifi
drewp@bigasterisk.com
parents: 722
diff changeset
274 (r"/build/(bundle\.js)", cyclone.web.StaticFileHandler, {
f88ff1021ee0 checkpoint service/wifi
drewp@bigasterisk.com
parents: 722
diff changeset
275 "path": 'build'
f88ff1021ee0 checkpoint service/wifi
drewp@bigasterisk.com
parents: 722
diff changeset
276 }),
422
19460b3f7baf factor out some URI generation
drewp@bigasterisk.com
parents: 421
diff changeset
277 (r'/json', Json),
1679
f88ff1021ee0 checkpoint service/wifi
drewp@bigasterisk.com
parents: 722
diff changeset
278 (r'/graph/wifi', CycloneGraphHandler, {
f88ff1021ee0 checkpoint service/wifi
drewp@bigasterisk.com
parents: 722
diff changeset
279 'masterGraph': masterGraph
f88ff1021ee0 checkpoint service/wifi
drewp@bigasterisk.com
parents: 722
diff changeset
280 }),
f88ff1021ee0 checkpoint service/wifi
drewp@bigasterisk.com
parents: 722
diff changeset
281 (r'/graph/wifi/events', CycloneGraphEventsHandler, {
f88ff1021ee0 checkpoint service/wifi
drewp@bigasterisk.com
parents: 722
diff changeset
282 'masterGraph': masterGraph
f88ff1021ee0 checkpoint service/wifi
drewp@bigasterisk.com
parents: 722
diff changeset
283 }),
422
19460b3f7baf factor out some URI generation
drewp@bigasterisk.com
parents: 421
diff changeset
284 (r'/table', Table),
659
ea9ed11598b0 remote suspend, wifi group arg
drewp@bigasterisk.com
parents: 566
diff changeset
285 (r'/remoteSuspend', RemoteSuspend),
1679
f88ff1021ee0 checkpoint service/wifi
drewp@bigasterisk.com
parents: 722
diff changeset
286 (r'/metrics', Metrics),
422
19460b3f7baf factor out some URI generation
drewp@bigasterisk.com
parents: 421
diff changeset
287 #(r'/activity', Activity),
19460b3f7baf factor out some URI generation
drewp@bigasterisk.com
parents: 421
diff changeset
288 ],
19460b3f7baf factor out some URI generation
drewp@bigasterisk.com
parents: 421
diff changeset
289 wifi=wifi,
19460b3f7baf factor out some URI generation
drewp@bigasterisk.com
parents: 421
diff changeset
290 poller=poller,
19460b3f7baf factor out some URI generation
drewp@bigasterisk.com
parents: 421
diff changeset
291 mongo=mongo))
0
Drew Perttula <drewp@bigasterisk.com>
parents:
diff changeset
292 reactor.run()