|
|
|
#!/usr/bin/env python2.7
|
|
|
|
import json
|
|
|
|
import os
|
|
|
|
import random
|
|
|
|
import time
|
|
|
|
import threading
|
|
|
|
import traceback
|
|
|
|
import zmq
|
getting ready for Python 3 (#619)
* tabs to spaces
python 2 to 3: https://portingguide.readthedocs.io/en/latest/syntax.html#tabs-and-spaces
* use the new except syntax
python 2 to 3: https://portingguide.readthedocs.io/en/latest/exceptions.html#the-new-except-syntax
* make relative imports absolute
python 2 to 3: https://portingguide.readthedocs.io/en/latest/imports.html#absolute-imports
* Queue renamed to queue in python 3
Use the six compatibility library to support both python 2 and 3: https://portingguide.readthedocs.io/en/latest/stdlib-reorg.html#renamed-modules
* replace dict.has_key() with in
python 2 to 3: https://portingguide.readthedocs.io/en/latest/dicts.html#removed-dict-has-key
* make dict views compatible with python 3
python 2 to 3: https://portingguide.readthedocs.io/en/latest/dicts.html#dict-views-and-iterators
Where needed, wrapping things that will be a view in python 3 with a list(). For example, if it's accessed with []
Python 3 has no iter*() methods, so just using the values() instead of itervalues() as long as it's not too performance intensive. Note that any minor performance hit of using a list instead of a view will go away when switching to python 3. If it is intensive, we could use the six version.
* Explicitly use truncating division
python 2 to 3: https://portingguide.readthedocs.io/en/latest/numbers.html#division
python 3 treats / as float division. When we want the result to be an integer, use //
* replace map() with list comprehension where a list result is needed.
In python 3, map() returns an iterator.
python 2 to 3: https://portingguide.readthedocs.io/en/latest/iterators.html#new-behavior-of-map-and-filter
* replace filter() with list comprehension
In python 3, filter() returns an interatoooooooooooor.
python 2 to 3: https://portingguide.readthedocs.io/en/latest/iterators.html#new-behavior-of-map-and-filter
* wrap zip() in list() where we need the result to be a list
python 2 to 3: https://portingguide.readthedocs.io/en/latest/iterators.html#new-behavior-of-zip
* clean out some lint
Removes these pylint warnings:
************* Module selfdrive.car.chrysler.chryslercan
W: 15, 0: Unnecessary semicolon (unnecessary-semicolon)
W: 16, 0: Unnecessary semicolon (unnecessary-semicolon)
W: 25, 0: Unnecessary semicolon (unnecessary-semicolon)
************* Module common.dbc
W:101, 0: Anomalous backslash in string: '\?'. String constant might be missing an r prefix. (anomalous-backslash-in-string)
************* Module selfdrive.car.gm.interface
R:102, 6: Redefinition of ret.minEnableSpeed type from float to int (redefined-variable-type)
R:103, 6: Redefinition of ret.mass type from int to float (redefined-variable-type)
************* Module selfdrive.updated
R: 20, 6: Redefinition of r type from int to str (redefined-variable-type)
old-commit-hash: 9dae0bfac4e54ec2b2e488d2b4ead1495c8f56d8
6 years ago
|
|
|
import six.moves.queue
|
|
|
|
from jsonrpc import JSONRPCResponseManager, dispatcher
|
|
|
|
from websocket import create_connection, WebSocketTimeoutException
|
|
|
|
|
|
|
|
import selfdrive.crash as crash
|
|
|
|
import selfdrive.messaging as messaging
|
|
|
|
from common.params import Params
|
|
|
|
from selfdrive.services import service_list
|
|
|
|
from selfdrive.swaglog import cloudlog
|
|
|
|
from selfdrive.version import version, dirty
|
|
|
|
|
|
|
|
ATHENA_HOST = os.getenv('ATHENA_HOST', 'wss://athena.comma.ai')
|
|
|
|
HANDLER_THREADS = os.getenv('HANDLER_THREADS', 4)
|
|
|
|
|
|
|
|
dispatcher["echo"] = lambda s: s
|
getting ready for Python 3 (#619)
* tabs to spaces
python 2 to 3: https://portingguide.readthedocs.io/en/latest/syntax.html#tabs-and-spaces
* use the new except syntax
python 2 to 3: https://portingguide.readthedocs.io/en/latest/exceptions.html#the-new-except-syntax
* make relative imports absolute
python 2 to 3: https://portingguide.readthedocs.io/en/latest/imports.html#absolute-imports
* Queue renamed to queue in python 3
Use the six compatibility library to support both python 2 and 3: https://portingguide.readthedocs.io/en/latest/stdlib-reorg.html#renamed-modules
* replace dict.has_key() with in
python 2 to 3: https://portingguide.readthedocs.io/en/latest/dicts.html#removed-dict-has-key
* make dict views compatible with python 3
python 2 to 3: https://portingguide.readthedocs.io/en/latest/dicts.html#dict-views-and-iterators
Where needed, wrapping things that will be a view in python 3 with a list(). For example, if it's accessed with []
Python 3 has no iter*() methods, so just using the values() instead of itervalues() as long as it's not too performance intensive. Note that any minor performance hit of using a list instead of a view will go away when switching to python 3. If it is intensive, we could use the six version.
* Explicitly use truncating division
python 2 to 3: https://portingguide.readthedocs.io/en/latest/numbers.html#division
python 3 treats / as float division. When we want the result to be an integer, use //
* replace map() with list comprehension where a list result is needed.
In python 3, map() returns an iterator.
python 2 to 3: https://portingguide.readthedocs.io/en/latest/iterators.html#new-behavior-of-map-and-filter
* replace filter() with list comprehension
In python 3, filter() returns an interatoooooooooooor.
python 2 to 3: https://portingguide.readthedocs.io/en/latest/iterators.html#new-behavior-of-map-and-filter
* wrap zip() in list() where we need the result to be a list
python 2 to 3: https://portingguide.readthedocs.io/en/latest/iterators.html#new-behavior-of-zip
* clean out some lint
Removes these pylint warnings:
************* Module selfdrive.car.chrysler.chryslercan
W: 15, 0: Unnecessary semicolon (unnecessary-semicolon)
W: 16, 0: Unnecessary semicolon (unnecessary-semicolon)
W: 25, 0: Unnecessary semicolon (unnecessary-semicolon)
************* Module common.dbc
W:101, 0: Anomalous backslash in string: '\?'. String constant might be missing an r prefix. (anomalous-backslash-in-string)
************* Module selfdrive.car.gm.interface
R:102, 6: Redefinition of ret.minEnableSpeed type from float to int (redefined-variable-type)
R:103, 6: Redefinition of ret.mass type from int to float (redefined-variable-type)
************* Module selfdrive.updated
R: 20, 6: Redefinition of r type from int to str (redefined-variable-type)
old-commit-hash: 9dae0bfac4e54ec2b2e488d2b4ead1495c8f56d8
6 years ago
|
|
|
payload_queue = six.moves.queue.Queue()
|
|
|
|
response_queue = six.moves.queue.Queue()
|
|
|
|
|
|
|
|
def handle_long_poll(ws):
|
|
|
|
end_event = threading.Event()
|
|
|
|
|
|
|
|
threads = [
|
|
|
|
threading.Thread(target=ws_recv, args=(ws, end_event)),
|
|
|
|
threading.Thread(target=ws_send, args=(ws, end_event))
|
|
|
|
] + [
|
|
|
|
threading.Thread(target=jsonrpc_handler, args=(end_event,))
|
|
|
|
for x in xrange(HANDLER_THREADS)
|
|
|
|
]
|
|
|
|
|
|
|
|
map(lambda thread: thread.start(), threads)
|
|
|
|
try:
|
|
|
|
while not end_event.is_set():
|
|
|
|
time.sleep(0.1)
|
|
|
|
except (KeyboardInterrupt, SystemExit):
|
|
|
|
end_event.set()
|
|
|
|
raise
|
|
|
|
finally:
|
|
|
|
for i, thread in enumerate(threads):
|
|
|
|
thread.join()
|
|
|
|
|
|
|
|
def jsonrpc_handler(end_event):
|
|
|
|
while not end_event.is_set():
|
|
|
|
try:
|
|
|
|
data = payload_queue.get(timeout=1)
|
|
|
|
response = JSONRPCResponseManager.handle(data, dispatcher)
|
|
|
|
response_queue.put_nowait(response)
|
getting ready for Python 3 (#619)
* tabs to spaces
python 2 to 3: https://portingguide.readthedocs.io/en/latest/syntax.html#tabs-and-spaces
* use the new except syntax
python 2 to 3: https://portingguide.readthedocs.io/en/latest/exceptions.html#the-new-except-syntax
* make relative imports absolute
python 2 to 3: https://portingguide.readthedocs.io/en/latest/imports.html#absolute-imports
* Queue renamed to queue in python 3
Use the six compatibility library to support both python 2 and 3: https://portingguide.readthedocs.io/en/latest/stdlib-reorg.html#renamed-modules
* replace dict.has_key() with in
python 2 to 3: https://portingguide.readthedocs.io/en/latest/dicts.html#removed-dict-has-key
* make dict views compatible with python 3
python 2 to 3: https://portingguide.readthedocs.io/en/latest/dicts.html#dict-views-and-iterators
Where needed, wrapping things that will be a view in python 3 with a list(). For example, if it's accessed with []
Python 3 has no iter*() methods, so just using the values() instead of itervalues() as long as it's not too performance intensive. Note that any minor performance hit of using a list instead of a view will go away when switching to python 3. If it is intensive, we could use the six version.
* Explicitly use truncating division
python 2 to 3: https://portingguide.readthedocs.io/en/latest/numbers.html#division
python 3 treats / as float division. When we want the result to be an integer, use //
* replace map() with list comprehension where a list result is needed.
In python 3, map() returns an iterator.
python 2 to 3: https://portingguide.readthedocs.io/en/latest/iterators.html#new-behavior-of-map-and-filter
* replace filter() with list comprehension
In python 3, filter() returns an interatoooooooooooor.
python 2 to 3: https://portingguide.readthedocs.io/en/latest/iterators.html#new-behavior-of-map-and-filter
* wrap zip() in list() where we need the result to be a list
python 2 to 3: https://portingguide.readthedocs.io/en/latest/iterators.html#new-behavior-of-zip
* clean out some lint
Removes these pylint warnings:
************* Module selfdrive.car.chrysler.chryslercan
W: 15, 0: Unnecessary semicolon (unnecessary-semicolon)
W: 16, 0: Unnecessary semicolon (unnecessary-semicolon)
W: 25, 0: Unnecessary semicolon (unnecessary-semicolon)
************* Module common.dbc
W:101, 0: Anomalous backslash in string: '\?'. String constant might be missing an r prefix. (anomalous-backslash-in-string)
************* Module selfdrive.car.gm.interface
R:102, 6: Redefinition of ret.minEnableSpeed type from float to int (redefined-variable-type)
R:103, 6: Redefinition of ret.mass type from int to float (redefined-variable-type)
************* Module selfdrive.updated
R: 20, 6: Redefinition of r type from int to str (redefined-variable-type)
old-commit-hash: 9dae0bfac4e54ec2b2e488d2b4ead1495c8f56d8
6 years ago
|
|
|
except six.moves.queue.Empty:
|
|
|
|
pass
|
|
|
|
except Exception as e:
|
|
|
|
cloudlog.exception("athena jsonrpc handler failed")
|
|
|
|
traceback.print_exc()
|
|
|
|
response_queue.put_nowait(json.dumps({"error": str(e)}))
|
|
|
|
|
|
|
|
# security: user should be able to request any message from their car
|
|
|
|
# TODO: add service to, for example, start visiond and take a picture
|
|
|
|
@dispatcher.add_method
|
|
|
|
def getMessage(service=None, timeout=1000):
|
|
|
|
context = zmq.Context()
|
|
|
|
if service is None or service not in service_list:
|
|
|
|
raise Exception("invalid service")
|
|
|
|
socket = messaging.sub_sock(context, service_list[service].port)
|
|
|
|
socket.setsockopt(zmq.RCVTIMEO, timeout)
|
|
|
|
ret = messaging.recv_one(socket)
|
|
|
|
return ret.to_dict()
|
|
|
|
|
|
|
|
def ws_recv(ws, end_event):
|
|
|
|
while not end_event.is_set():
|
|
|
|
try:
|
|
|
|
data = ws.recv()
|
|
|
|
payload_queue.put_nowait(data)
|
|
|
|
except WebSocketTimeoutException:
|
|
|
|
pass
|
|
|
|
except Exception:
|
|
|
|
traceback.print_exc()
|
|
|
|
end_event.set()
|
|
|
|
|
|
|
|
def ws_send(ws, end_event):
|
|
|
|
while not end_event.is_set():
|
|
|
|
try:
|
|
|
|
response = response_queue.get(timeout=1)
|
|
|
|
ws.send(response.json)
|
getting ready for Python 3 (#619)
* tabs to spaces
python 2 to 3: https://portingguide.readthedocs.io/en/latest/syntax.html#tabs-and-spaces
* use the new except syntax
python 2 to 3: https://portingguide.readthedocs.io/en/latest/exceptions.html#the-new-except-syntax
* make relative imports absolute
python 2 to 3: https://portingguide.readthedocs.io/en/latest/imports.html#absolute-imports
* Queue renamed to queue in python 3
Use the six compatibility library to support both python 2 and 3: https://portingguide.readthedocs.io/en/latest/stdlib-reorg.html#renamed-modules
* replace dict.has_key() with in
python 2 to 3: https://portingguide.readthedocs.io/en/latest/dicts.html#removed-dict-has-key
* make dict views compatible with python 3
python 2 to 3: https://portingguide.readthedocs.io/en/latest/dicts.html#dict-views-and-iterators
Where needed, wrapping things that will be a view in python 3 with a list(). For example, if it's accessed with []
Python 3 has no iter*() methods, so just using the values() instead of itervalues() as long as it's not too performance intensive. Note that any minor performance hit of using a list instead of a view will go away when switching to python 3. If it is intensive, we could use the six version.
* Explicitly use truncating division
python 2 to 3: https://portingguide.readthedocs.io/en/latest/numbers.html#division
python 3 treats / as float division. When we want the result to be an integer, use //
* replace map() with list comprehension where a list result is needed.
In python 3, map() returns an iterator.
python 2 to 3: https://portingguide.readthedocs.io/en/latest/iterators.html#new-behavior-of-map-and-filter
* replace filter() with list comprehension
In python 3, filter() returns an interatoooooooooooor.
python 2 to 3: https://portingguide.readthedocs.io/en/latest/iterators.html#new-behavior-of-map-and-filter
* wrap zip() in list() where we need the result to be a list
python 2 to 3: https://portingguide.readthedocs.io/en/latest/iterators.html#new-behavior-of-zip
* clean out some lint
Removes these pylint warnings:
************* Module selfdrive.car.chrysler.chryslercan
W: 15, 0: Unnecessary semicolon (unnecessary-semicolon)
W: 16, 0: Unnecessary semicolon (unnecessary-semicolon)
W: 25, 0: Unnecessary semicolon (unnecessary-semicolon)
************* Module common.dbc
W:101, 0: Anomalous backslash in string: '\?'. String constant might be missing an r prefix. (anomalous-backslash-in-string)
************* Module selfdrive.car.gm.interface
R:102, 6: Redefinition of ret.minEnableSpeed type from float to int (redefined-variable-type)
R:103, 6: Redefinition of ret.mass type from int to float (redefined-variable-type)
************* Module selfdrive.updated
R: 20, 6: Redefinition of r type from int to str (redefined-variable-type)
old-commit-hash: 9dae0bfac4e54ec2b2e488d2b4ead1495c8f56d8
6 years ago
|
|
|
except six.moves.queue.Empty:
|
|
|
|
pass
|
|
|
|
except Exception:
|
|
|
|
traceback.print_exc()
|
|
|
|
end_event.set()
|
|
|
|
|
|
|
|
def backoff(retries):
|
|
|
|
return random.randrange(0, min(128, int(2 ** retries)))
|
|
|
|
|
|
|
|
def main(gctx=None):
|
|
|
|
params = Params()
|
|
|
|
dongle_id = params.get("DongleId")
|
|
|
|
access_token = params.get("AccessToken")
|
|
|
|
ws_uri = ATHENA_HOST + "/ws/" + dongle_id
|
|
|
|
|
|
|
|
crash.bind_user(id=dongle_id)
|
|
|
|
crash.bind_extra(version=version, dirty=dirty, is_eon=True)
|
|
|
|
crash.install()
|
|
|
|
|
|
|
|
conn_retries = 0
|
|
|
|
while 1:
|
|
|
|
try:
|
|
|
|
print("connecting to %s" % ws_uri)
|
|
|
|
ws = create_connection(ws_uri,
|
|
|
|
cookie="jwt=" + access_token,
|
|
|
|
enable_multithread=True)
|
|
|
|
ws.settimeout(1)
|
|
|
|
conn_retries = 0
|
|
|
|
handle_long_poll(ws)
|
|
|
|
except (KeyboardInterrupt, SystemExit):
|
|
|
|
break
|
|
|
|
except Exception:
|
|
|
|
conn_retries += 1
|
|
|
|
traceback.print_exc()
|
|
|
|
|
|
|
|
time.sleep(backoff(conn_retries))
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
main()
|