-
Notifications
You must be signed in to change notification settings - Fork 11
/
DashboardServer.py
140 lines (107 loc) · 4.36 KB
/
DashboardServer.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
#!/usr/bin/env python
# here python should be python3 variant...
'''
This is our dashboard server application, using the tornado handlers,
that you can use to connect your HTML/Javascript dashboard code to
your robot via NetworkTables.
Run this application with python, then you can open your browser to
http://localhost:5080/ to view the index.html page.
Notes on upgrading networktables:
- make sure to update both pynetworktables and pynetworktables2js
to the same support level
- make sure that a pip install produces the right version string.
'''
from os.path import abspath, dirname, exists, join
from optparse import OptionParser
import sys
import mimetypes
import tornado.web
from tornado.ioloop import IOLoop
from tornado.web import RequestHandler
import networktables
from networktables import NetworkTables
import pynetworktables2js
import pylib.Robotlog as Robotlog
import pylib.WebAPI as WebAPI
import pylib.ApiHandler as ApiHandler
import functools
import logging
logger = logging.getLogger('dashboard')
import asyncio
mimetypes.add_type("text/javascript", ".js")
if sys.platform == 'win32':
# python-3.8
asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
def initNetworktables(options):
if options.dashboard:
# connects to driver station on localhost to obtain server IPaddress.
# (don't often run in this mode).
logger.info("Connecting to networktables in DSClient mode")
NetworkTables.initialize();
NetworkTables.startDSClient(options.port);
else:
logger.info("Connecting to networktables at %s", options.robot)
NetworkTables.initialize(options.robot)
logger.info("Networktables Initialized %s, %s" %
(networktables.__version__ , pynetworktables2js.__version__))
if __name__ == '__main__':
# Setup options here
parser = OptionParser()
parser.add_option('-p', '--port', default=5080,
help='Port to run web server on')
parser.add_option('-v', '--verbose', default=False, action='store_true',
help='Enable verbose logging')
parser.add_option('--robot', default='10.49.15.2',
help="Robot's IP address")
parser.add_option('--dashboard', default=False, action='store_true',
help='Use this instead of --robot to receive the IP '
'from the driver station. WARNING: It will not work '
'if you are not on the same host as the DS!')
options, args = parser.parse_args()
# Setup logging
log_datefmt = "%H:%M:%S"
log_format = "%(asctime)s %(levelname)-6s: %(name)-8s: %(message)s"
logging.basicConfig(datefmt=log_datefmt,
format=log_format,
level=logging.DEBUG if options.verbose else logging.INFO)
if options.dashboard and options.robot != '10.49.15.2':
parser.error("Cannot specify --robot and --dashboard")
initNetworktables(options)
robotlog = Robotlog.Robotlog()
# setup tornado application with static handler + networktables support
www_dir = abspath(join(dirname(__file__), 'www'))
index_html = join(www_dir, 'index.html')
if not exists(www_dir):
logger.error("Directory '%s' does not exist!", www_dir)
exit(1)
if not exists(index_html):
logger.warn("%s not found" % index_html)
class My404Handler(RequestHandler):
# Override prepare() instead of get() to cover all possible HTTP methods.
def prepare(self):
self.set_status(404)
self.render("404.html")
app = tornado.web.Application(
pynetworktables2js.get_handlers() +
robotlog.getHandlers() +
ApiHandler.getHandlers() +
WebAPI.getHandlers() +
[
(r"/()", pynetworktables2js.NonCachingStaticFileHandler,
{"path": index_html}),
(r"/(.*)", pynetworktables2js.NonCachingStaticFileHandler,
{"path": www_dir})
],
default_handler_class=My404Handler
)
# Start the app
logger.info("Listening on http://localhost:%s/", options.port)
app.listen(options.port)
ioLoop = IOLoop.current()
robotlog.initConnection(ioLoop)
try:
ioLoop.start()
except KeyboardInterrupt:
logger.info("interrupted")
ioLoop.stop()
exit()