From b233323aeaeada75b0e60a4db2603a8f1ca51f0a Mon Sep 17 00:00:00 2001 From: Ja'mez Stokes <49651248+jstoke53@users.noreply.github.com> Date: Tue, 4 Feb 2020 15:05:32 -0500 Subject: [PATCH 01/25] Edit obd2scanner to filter all PID's scanned that has a success response and notifies when PID's did not respond. --- openxc/tools/obd2scanner.py | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/openxc/tools/obd2scanner.py b/openxc/tools/obd2scanner.py index 90f2110b..e6d9e1aa 100644 --- a/openxc/tools/obd2scanner.py +++ b/openxc/tools/obd2scanner.py @@ -10,6 +10,7 @@ import argparse from .common import device_options, configure_logging, select_device +import json def scan(controller, bus=None): @@ -20,9 +21,23 @@ def scan(controller, bus=None): response = controller.create_diagnostic_request(0x7df, mode=0x1, bus=bus, wait_for_first_response=True, pid=pid) if response is not None: - print(("PID 0x%x responded with: %s" % (pid, response))) - else: - print(("PID 0x%x did not respond" % pid)) + no_response = True + for item in response[1]: + if 'success' in item: + no_response = False + print(("PID 0x%x responded with: %s" % (pid, item))) + # if item['success']: + # if 'name' in item: + # print('found success true response at ' + item['name']) + # elif 'id' in item: + # print('found success true response at id ' + str(item['id'])) + # else: + # # print('idk') + # print(("PID 0x%x responded with: %s" % (pid, response))) + if (no_response == True): + print(("PID 0x%x did not respond" % pid)) + # else: + # print(("PID 0x%x did not respond" % pid)) def parse_options(): parser = argparse.ArgumentParser(description="Send requests for all " From f577ff84c7231dff4fe01e7e9b73f1b497993b41 Mon Sep 17 00:00:00 2001 From: Ja'mez Stokes <49651248+jstoke53@users.noreply.github.com> Date: Tue, 4 Feb 2020 16:00:39 -0500 Subject: [PATCH 02/25] remove commented out code and debug statements. --- openxc/tools/obd2scanner.py | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/openxc/tools/obd2scanner.py b/openxc/tools/obd2scanner.py index e6d9e1aa..6c69d58c 100644 --- a/openxc/tools/obd2scanner.py +++ b/openxc/tools/obd2scanner.py @@ -17,8 +17,8 @@ def scan(controller, bus=None): # TODO could read the response from the "PIDs supported" requests to see # what the vehicle reports that it *should* support. print("Beginning sequential scan of all OBD-II PIDs") - for pid in range(0, 0x88): - response = controller.create_diagnostic_request(0x7df, mode=0x1, bus=bus, + for pid in range(0xd0ff, 0xd101): + response = controller.create_diagnostic_request(0x7d0, mode=0x22, bus=bus, wait_for_first_response=True, pid=pid) if response is not None: no_response = True @@ -26,18 +26,10 @@ def scan(controller, bus=None): if 'success' in item: no_response = False print(("PID 0x%x responded with: %s" % (pid, item))) - # if item['success']: - # if 'name' in item: - # print('found success true response at ' + item['name']) - # elif 'id' in item: - # print('found success true response at id ' + str(item['id'])) - # else: - # # print('idk') - # print(("PID 0x%x responded with: %s" % (pid, response))) + if (no_response == True): print(("PID 0x%x did not respond" % pid)) - # else: - # print(("PID 0x%x did not respond" % pid)) + def parse_options(): parser = argparse.ArgumentParser(description="Send requests for all " From baf23edb8e577e36e92eb48a9d2c82f40ebeec5f Mon Sep 17 00:00:00 2001 From: Ja'mez Stokes <49651248+jstoke53@users.noreply.github.com> Date: Tue, 4 Feb 2020 16:05:11 -0500 Subject: [PATCH 03/25] fix for loop for obd2scanner. --- openxc/tools/obd2scanner.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/openxc/tools/obd2scanner.py b/openxc/tools/obd2scanner.py index 6c69d58c..565b3fc3 100644 --- a/openxc/tools/obd2scanner.py +++ b/openxc/tools/obd2scanner.py @@ -17,9 +17,9 @@ def scan(controller, bus=None): # TODO could read the response from the "PIDs supported" requests to see # what the vehicle reports that it *should* support. print("Beginning sequential scan of all OBD-II PIDs") - for pid in range(0xd0ff, 0xd101): - response = controller.create_diagnostic_request(0x7d0, mode=0x22, bus=bus, - wait_for_first_response=True, pid=pid) + for pid in range(0, 0x88): + response = controller.create_diagnostic_request(0x7df, mode=0x1, bus=bus, + wait_for_first_response=True, pid=pid) if response is not None: no_response = True for item in response[1]: From f6f84d38fdbddf5a5c28109f822979b01571bb57 Mon Sep 17 00:00:00 2001 From: Prateek Prakash <59665714+PPRAKA30@users.noreply.github.com> Date: Mon, 17 Feb 2020 10:49:32 -0500 Subject: [PATCH 04/25] Add platform command for protobuf format --- openxc/formats/binary.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/openxc/formats/binary.py b/openxc/formats/binary.py index 3797ea43..8c05d5b9 100644 --- a/openxc/formats/binary.py +++ b/openxc/formats/binary.py @@ -91,6 +91,8 @@ def _command_string_to_protobuf(self, command_name): return openxc_pb2.ControlCommand.PAYLOAD_FORMAT elif command_name == "predefined_obd2": return openxc_pb2.ControlCommand.PREDEFINED_OBD2_REQUESTS + elif command_name == "platform": + return openxc_pb2.ControlCommand.PLATFORM else: raise UnrecognizedBinaryCommandError(command_name) @@ -321,6 +323,8 @@ def _protobuf_to_dict(cls, message): parsed_message['command_response'] = "af_bypass" elif response.type == openxc_pb2.ControlCommand.PREDEFINED_OBD2_REQUESTS: parsed_message['command_response'] = "predefined_obd2" + elif response.type == openxc_pb2.ControlCommand.PLATFORM: + parsed_message['command_response'] = "platform" else: raise UnrecognizedBinaryCommandError(response.type) From 5bc2f028a5272fe26bc6f31c1505632967cdbfe0 Mon Sep 17 00:00:00 2001 From: Prateek Prakash <59665714+PPRAKA30@users.noreply.github.com> Date: Mon, 17 Feb 2020 11:36:54 -0500 Subject: [PATCH 05/25] Fix format variable not being set properly --- openxc/sources/base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openxc/sources/base.py b/openxc/sources/base.py index 7e5a3f46..80dc9f2d 100644 --- a/openxc/sources/base.py +++ b/openxc/sources/base.py @@ -39,7 +39,7 @@ def __init__(self, callback=None, log_mode=None, payload_format=None): self.running = True self._streamer = None self._formatter = None - self.format = payload_format + self._format = payload_format self.logger = SourceLogger(self, log_mode) From e28f2fe4666cb8618c7d7266b9bd54926bbef12c Mon Sep 17 00:00:00 2001 From: PPRAKA30 <59665714+PPRAKA30@users.noreply.github.com> Date: Tue, 25 Feb 2020 09:23:53 -0500 Subject: [PATCH 06/25] Update .gitignore for SonarQube --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 2819189f..82b905cb 100644 --- a/.gitignore +++ b/.gitignore @@ -17,3 +17,4 @@ coverage.xml diffcover.html htmlcov *~ +.scannerwork/ From 6206981cffe068e338cdb80a6fdfc6ebf7a6b404 Mon Sep 17 00:00:00 2001 From: Prateek Prakash <59665714+PPRAKA30@users.noreply.github.com> Date: Thu, 27 Feb 2020 11:21:16 -0500 Subject: [PATCH 07/25] Fix script indentation --- openxc/tools/obd2scanner.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/openxc/tools/obd2scanner.py b/openxc/tools/obd2scanner.py index 565b3fc3..1f34af76 100644 --- a/openxc/tools/obd2scanner.py +++ b/openxc/tools/obd2scanner.py @@ -18,8 +18,7 @@ def scan(controller, bus=None): # what the vehicle reports that it *should* support. print("Beginning sequential scan of all OBD-II PIDs") for pid in range(0, 0x88): - response = controller.create_diagnostic_request(0x7df, mode=0x1, bus=bus, - wait_for_first_response=True, pid=pid) + response = controller.create_diagnostic_request(0x7df, mode=0x1, bus=bus, wait_for_first_response=True, pid=pid) if response is not None: no_response = True for item in response[1]: From 78622d687b694ac61e75a2c08a41d336b4503f8c Mon Sep 17 00:00:00 2001 From: Prateek Prakash <59665714+PPRAKA30@users.noreply.github.com> Date: Thu, 27 Feb 2020 13:25:58 -0500 Subject: [PATCH 08/25] Flush standard output for MinTTY --- openxc/tools/obd2scanner.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/openxc/tools/obd2scanner.py b/openxc/tools/obd2scanner.py index 1f34af76..a2fc0cf3 100644 --- a/openxc/tools/obd2scanner.py +++ b/openxc/tools/obd2scanner.py @@ -6,7 +6,7 @@ module are internal only. """ - +import sys import argparse from .common import device_options, configure_logging, select_device @@ -24,11 +24,11 @@ def scan(controller, bus=None): for item in response[1]: if 'success' in item: no_response = False - print(("PID 0x%x responded with: %s" % (pid, item))) + print("PID 0x%x responded with: %s" % (pid, item)) if (no_response == True): - print(("PID 0x%x did not respond" % pid)) - + print("PID 0x%x did not respond" % pid) + sys.stdout.flush() def parse_options(): parser = argparse.ArgumentParser(description="Send requests for all " From c283b1d357bdc177f313660582a0e6494b893032 Mon Sep 17 00:00:00 2001 From: vinodsama Date: Thu, 27 Feb 2020 16:10:23 -0500 Subject: [PATCH 09/25] removed nettwork host and port --- docs/tools/control.rst | 2 +- openxc/interface.py | 7 ------- openxc/tools/common.py | 12 ------------ 3 files changed, 1 insertion(+), 20 deletions(-) diff --git a/docs/tools/control.rst b/docs/tools/control.rst index b2658d79..62acd862 100644 --- a/docs/tools/control.rst +++ b/docs/tools/control.rst @@ -87,7 +87,7 @@ Set the host and port for the C5 Cellular device .. code-block:: bash - $ openxc-control set --network-host www.server.com --port 80 + $ openxc-control set --host www.server.com --port 80 This will return true when successful. If network-host is supplied, but not port, port will default to 80. diff --git a/openxc/interface.py b/openxc/interface.py index 5782ae30..e94031b2 100644 --- a/openxc/interface.py +++ b/openxc/interface.py @@ -17,10 +17,3 @@ class SerialVehicleInterface(SerialDataSource, SerialControllerMixin): read support and limited write support (no control commands are supported). """ pass - -class NetworkVehicleInterface(NetworkDataSource, Controller): - """This class is compatibile with an OpenXC vehicle interface vehicle interface - connected via the network (e.g. Ethernet or Wi-Fi). It has full - read support and limited write support (no control commands are supported). - """ - pass diff --git a/openxc/tools/common.py b/openxc/tools/common.py index fc8e40e1..76855cbe 100644 --- a/openxc/tools/common.py +++ b/openxc/tools/common.py @@ -48,14 +48,6 @@ def device_options(): action="store", dest="baudrate", help="baudrate for serial-connected VI") - parser.add_argument("--network-host", - action="store", - dest="network_host", - help="host for networked VI") - parser.add_argument("--network-port", - action="store", - dest="network_port", - help="network port for networked VI") parser.add_argument("--log-mode", action="store", default="off", @@ -82,10 +74,6 @@ def select_device(arguments): elif arguments.trace_file: source_class = TraceDataSource source_kwargs = dict(filename=arguments.trace_file) - elif arguments.use_network: - source_class = NetworkVehicleInterface - source_kwargs = dict(host=arguments.network_host, - port=arguments.network_port) elif arguments.use_bluetooth: source_class = BluetoothVehicleInterface source_kwargs = dict(address=arguments.bluetooth_address) From 4d0c6390a5e5dc6f428217d307486ecbfa5a58e4 Mon Sep 17 00:00:00 2001 From: vinodsama Date: Fri, 28 Feb 2020 14:08:28 -0500 Subject: [PATCH 10/25] Host and port --- openxc/interface.py | 4 ++++ openxc/tools/common.py | 2 +- openxc/tools/control.py | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/openxc/interface.py b/openxc/interface.py index e94031b2..25b28b9e 100644 --- a/openxc/interface.py +++ b/openxc/interface.py @@ -17,3 +17,7 @@ class SerialVehicleInterface(SerialDataSource, SerialControllerMixin): read support and limited write support (no control commands are supported). """ pass +<<<<<<< Updated upstream +======= + +>>>>>>> Stashed changes diff --git a/openxc/tools/common.py b/openxc/tools/common.py index 76855cbe..322fc186 100644 --- a/openxc/tools/common.py +++ b/openxc/tools/common.py @@ -6,7 +6,7 @@ from openxc.sources.trace import TraceDataSource from openxc.interface import SerialVehicleInterface, UsbVehicleInterface, \ - NetworkVehicleInterface, BluetoothVehicleInterface + BluetoothVehicleInterface def device_options(): diff --git a/openxc/tools/control.py b/openxc/tools/control.py index 40d5bacb..75ebf505 100644 --- a/openxc/tools/control.py +++ b/openxc/tools/control.py @@ -161,7 +161,7 @@ def main(): if arguments.unix_time is not None: set_rtc_time(interface, int(arguments.unix_time)) if arguments.host is not None: - modem_configuration(interface, host, port) + modem_configuration(interface, arguments.host, arguments.port) elif arguments.command.startswith("write"): if arguments.command == "write": if arguments.write_name: From 919f6165fa6ebfd2b7552003680ed8477bde97b7 Mon Sep 17 00:00:00 2001 From: SamaVinod <44871626+SamaVinod@users.noreply.github.com> Date: Fri, 28 Feb 2020 14:14:04 -0500 Subject: [PATCH 11/25] Update interface.py --- openxc/interface.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/openxc/interface.py b/openxc/interface.py index 25b28b9e..6209098d 100644 --- a/openxc/interface.py +++ b/openxc/interface.py @@ -17,7 +17,5 @@ class SerialVehicleInterface(SerialDataSource, SerialControllerMixin): read support and limited write support (no control commands are supported). """ pass -<<<<<<< Updated upstream -======= ->>>>>>> Stashed changes + From 99afd78323bbe3106d2beb08049420f661092e8d Mon Sep 17 00:00:00 2001 From: Prateek Prakash <59665714+PPRAKA30@users.noreply.github.com> Date: Mon, 2 Mar 2020 10:59:03 -0500 Subject: [PATCH 12/25] Address SonarQube "blocker" flags --- docs/_static/rtd.css | 6 ------ openxc/formats/binary.py | 1 - openxc/tools/static/css/dashboard.css | 5 +---- openxc/tools/static/js/dashboard.js | 16 ++++++++-------- 4 files changed, 9 insertions(+), 19 deletions(-) diff --git a/docs/_static/rtd.css b/docs/_static/rtd.css index 5e7d693d..170064cd 100644 --- a/docs/_static/rtd.css +++ b/docs/_static/rtd.css @@ -382,12 +382,6 @@ div.sphinxsidebar p a:hover { border: 1px solid #888; } -/* Tweak any link appearing in a heading */ -div.sphinxsidebar h3 a { -} - - - /* OTHER STUFF ------------------------------------------------------------ */ diff --git a/openxc/formats/binary.py b/openxc/formats/binary.py index 8c05d5b9..55b32ceb 100644 --- a/openxc/formats/binary.py +++ b/openxc/formats/binary.py @@ -68,7 +68,6 @@ def deserialize(cls, data): except UnicodeDecodeError as e: LOG.warn("Unable to parse protobuf: %s", e) else: - #return type(cls._protobuf_to_dict(message)['payload']) return cls._protobuf_to_dict(message) @classmethod diff --git a/openxc/tools/static/css/dashboard.css b/openxc/tools/static/css/dashboard.css index b42ddaa9..520bfddc 100644 --- a/openxc/tools/static/css/dashboard.css +++ b/openxc/tools/static/css/dashboard.css @@ -37,6 +37,7 @@ caption { table, th, td { text-align: left; border-spacing: 8px 1px; + border: 1px solid black; } .metric { @@ -48,10 +49,6 @@ th:hover { background-color: #AAA; } -table, th, td { - border: 1px solid black; -} - table { padding-top: 2%; padding-bottom: 2%; diff --git a/openxc/tools/static/js/dashboard.js b/openxc/tools/static/js/dashboard.js index 9bbda308..e3d9b4ca 100644 --- a/openxc/tools/static/js/dashboard.js +++ b/openxc/tools/static/js/dashboard.js @@ -6,6 +6,9 @@ let recentlyChangedHighlightDuration; let diagnosticCount = 0; /* --- End dashboard parameters --- */ +var valueChangedTimer; +var valueRecentlyChangedTimer; + $(document).ready(function() { updateDashboardParameters(); searchTable() @@ -34,7 +37,7 @@ $(document).ready(function() { }); - namespace = ''; + var namespace = ''; var socket = io(namespace); socket.on('vehicle data', function(msg, cb) { // console.log(msg); @@ -90,12 +93,9 @@ function saveSettings(e) { } function addToDisplay(msgName) { - var added = false; - if (!added) { - $('', { - id: msgName - }).appendTo('#log'); - } + $('', { + id: msgName + }).appendTo('#log'); $('', { id: msgName + '_label', @@ -118,7 +118,7 @@ function addToDisplay(msgName) { } function updateDisplay(dataPoint) { - msg = dataPoint.current_data + var msg = dataPoint.current_data if (!($('#' + msg.name).length > 0)) { addToDisplay(msg.name); From f85c07a0f097004239f482644b71988941c1aa6d Mon Sep 17 00:00:00 2001 From: Prateek Prakash <59665714+PPRAKA30@users.noreply.github.com> Date: Mon, 2 Mar 2020 11:49:11 -0500 Subject: [PATCH 13/25] Fix some minor SonarQube flags --- openxc/tools/diagnostics.py | 4 ++-- openxc/tools/static/js/dashboard.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/openxc/tools/diagnostics.py b/openxc/tools/diagnostics.py index 7bdfde4f..022bedfa 100644 --- a/openxc/tools/diagnostics.py +++ b/openxc/tools/diagnostics.py @@ -49,8 +49,8 @@ def diagnostic_request(arguments, controller): # Stripping all of the unnesseary data we get after sending a diag request in python # Just like in enabler, it's a diag response if it contains the keys "mode", "bus", # "id", and "success". - diagMsgReqKeys = ['mode', 'bus', 'id', 'success'] - indices = [i for i, s in enumerate(response) if all(x in s for x in diagMsgReqKeys)] + diag_mgs_req_keys = ['mode', 'bus', 'id', 'success'] + indices = [i for i, s in enumerate(response) if all(x in s for x in diag_mgs_req_keys)] if indices: print(("Response: %s" % response[indices[0]])) else: diff --git a/openxc/tools/static/js/dashboard.js b/openxc/tools/static/js/dashboard.js index e3d9b4ca..aca80e2a 100644 --- a/openxc/tools/static/js/dashboard.js +++ b/openxc/tools/static/js/dashboard.js @@ -120,7 +120,7 @@ function addToDisplay(msgName) { function updateDisplay(dataPoint) { var msg = dataPoint.current_data - if (!($('#' + msg.name).length > 0)) { + if ($('#' + msg.name).length <= 0) { addToDisplay(msg.name); } From c960b76f38814ce8e17ee1a3e6ec4985d5f13481 Mon Sep 17 00:00:00 2001 From: PPRAKA30 <59665714+PPRAKA30@users.noreply.github.com> Date: Tue, 10 Mar 2020 09:53:57 -0400 Subject: [PATCH 14/25] SonarQube - Reduce Complexity (#143) * Refactor binary.py/_dict_to_protobuf() * Replace RawMessage which is deprecated * Refactor binary.py/_build_control_command_message * Refactor binary.py/_protobuf_to_dict() * Renamed methods for consistency * Update method names to match previous renaming * Refactor _build_control_command_parsed_message() * Extract printing diagnostic response * Remove unnecessary conditional statement * Refactor control.py/main() * Minimal refactor of scanner.py/scan() * Refactor structures.py/merge_message() * Refactor base.py/run() --- openxc/formats/binary.py | 512 +++++++++++++++++++-------------- openxc/generator/structures.py | 25 +- openxc/sources/base.py | 27 +- openxc/tools/control.py | 64 +++-- openxc/tools/diagnostics.py | 33 ++- openxc/tools/scanner.py | 30 +- 6 files changed, 396 insertions(+), 295 deletions(-) diff --git a/openxc/formats/binary.py b/openxc/formats/binary.py index 55b32ceb..e6433c15 100644 --- a/openxc/formats/binary.py +++ b/openxc/formats/binary.py @@ -95,241 +95,321 @@ def _command_string_to_protobuf(self, command_name): else: raise UnrecognizedBinaryCommandError(command_name) + @classmethod + def _handle_passthrough_cc_message(cls, data, message): + message.control_command.passthrough_mode_request.bus = data['bus'] + message.control_command.passthrough_mode_request.enabled = data['enabled'] + + @classmethod + def _handle_acceptance_filter_bypass_cc_message(cls, data, message): + message.control_command.acceptance_filter_bypass_command.bus = data['bus'] + message.control_command.acceptance_filter_bypass_command.bypass = data['bypass'] + + @classmethod + def _handle_predefined_obd2_requests_cc_message(cls, data, message): + message.control_command.predefined_obd2_requests_command.enabled = data['enabled'] + + @classmethod + def _handle_payload_format_cc_message(cls, data, message): + if data['format'] == "json": + message.control_command.payload_format_command.format = openxc_pb2.PayloadFormatCommand.JSON + elif data['format'] == "protobuf": + message.control_command.payload_format_command.format = openxc_pb2.PayloadFormatCommand.PROTOBUF + + @classmethod + def _handle_diagnostic_cc_message(cls, data, message): + request_command = message.control_command.diagnostic_request + action = data['action'] + if action == "add": + request_command.action = openxc_pb2.DiagnosticControlCommand.ADD + elif action == "cancel": + request_command.action = openxc_pb2.DiagnosticControlCommand.CANCEL + request = request_command.request + request_data = data['request'] + request.bus = request_data['bus'] + request.message_id = request_data['id'] + request.mode = request_data['mode'] + if 'frequency' in request_data: + request.frequency = request_data['frequency'] + if 'name' in request_data: + request.name = request_data['name'] + if 'multiple_responses' in request_data: + request.multiple_responses = request_data['multiple_responses'] + if 'pid' in request_data: + request.pid = request_data['pid'] + if 'payload' in request_data: + request.payload = binascii.unhexlify(request_data['payload'].split('0x')[1]) + + @classmethod + def _build_control_command_message(cls, data, message): + command_name = data['command'] + message.type = openxc_pb2.VehicleMessage.CONTROL_COMMAND + message.control_command.type = cls._command_string_to_protobuf(command_name) + if message.control_command.type == openxc_pb2.ControlCommand.PASSTHROUGH: + cls._handle_passthrough_cc_message(data, message) + elif message.control_command.type == openxc_pb2.ControlCommand.ACCEPTANCE_FILTER_BYPASS: + cls._handle_acceptance_filter_bypass_cc_message(data, message) + elif message.control_command.type == openxc_pb2.ControlCommand.PREDEFINED_OBD2_REQUESTS: + cls._handle_predefined_obd2_requests_cc_message(data, message) + elif message.control_command.type == openxc_pb2.ControlCommand.PAYLOAD_FORMAT: + cls._handle_payload_format_cc_message(data, message) + elif message.control_command.type == openxc_pb2.ControlCommand.DIAGNOSTIC: + cls._handle_diagnostic_cc_message(data, message) + + @classmethod + def _build_command_response_message(cls, data, message): + message.type = openxc_pb2.VehicleMessage.COMMAND_RESPONSE + message.command_response.type = cls._command_string_to_protobuf(data['command_response']) + if 'message' in data: + message.command_response.message = data['message'] + message.command_response.status = data['status'] + + @classmethod + def _build_can_message(cls, data, message): + message.type = openxc_pb2.VehicleMessage.CAN + if 'bus' in data: + message.can_message.bus = data['bus'] + if 'frame_format' in data: + if data['frame_format'] == "standard": + message.can_message.frame_format = openxc_pb2.CanMessage.STANDARD + elif data['frame_format'] == "extended": + message.can_message.frame_format = openxc_pb2.CanMessage.EXTENDED + message.can_message.id = data['id'] + message.can_message.data = binascii.unhexlify(data['data'].split('0x')[1]) + + @classmethod + def _build_diagnostic_message(cls, data, message): + message.type = openxc_pb2.VehicleMessage.DIAGNOSTIC + response = message.diagnostic_response + response.bus = data['bus'] + response.message_id = data['id'] + response.mode = data['mode'] + if 'pid' in data: + response.pid = data['pid'] + if 'success' in data: + response.success = data['success'] + if 'negative_response_code' in data: + response.negative_response_code = data['negative_response_code'] + if 'value' in data: + response.value = data['value'] + if 'payload' in data: + response.payload = binascii.unhexlify(data['payload'].split('0x')[1]) + + @classmethod + def _build_simple_message(cls, data, message): + message.type = openxc_pb2.VehicleMessage.SIMPLE + message.simple_message.name = data['name'] + value = data['value'] + if isinstance(value, bool): + message.simple_message.value.type = openxc_pb2.DynamicField.BOOL + message.simple_message.value.boolean_value = value + elif isinstance(value, str): + message.simple_message.value.type = openxc_pb2.DynamicField.STRING + message.simple_message.value.string_value = value + elif isinstance(value, numbers.Number): + message.simple_message.value.type = openxc_pb2.DynamicField.NUM + message.simple_message.value.numeric_value = value + + if 'event' in data: + event = data['event'] + # TODO holy repeated code, batman. this will be easier to DRY + # when https://github.com/openxc/openxc-message-format/issues/19 + # is resolved + if isinstance(event, bool): + message.simple_message.event.type = openxc_pb2.DynamicField.BOOL + message.simple_message.event.boolean_value = event + elif isinstance(event, str): + message.simple_message.event.type = openxc_pb2.DynamicField.STRING + message.simple_message.event.string_value = event + elif isinstance(event, numbers.Number): + message.simple_message.event.type = openxc_pb2.DynamicField.NUM + message.simple_message.event.numeric_value = event + @classmethod def _dict_to_protobuf(cls, data): message = openxc_pb2.VehicleMessage() if 'command' in data: - command_name = data['command'] - message.type = openxc_pb2.VehicleMessage.CONTROL_COMMAND - message.control_command.type = cls._command_string_to_protobuf(command_name) - if message.control_command.type == openxc_pb2.ControlCommand.PASSTHROUGH: - message.control_command.passthrough_mode_request.bus = data['bus'] - message.control_command.passthrough_mode_request.enabled = data['enabled'] - elif message.control_command.type == openxc_pb2.ControlCommand.ACCEPTANCE_FILTER_BYPASS: - message.control_command.acceptance_filter_bypass_command.bus = data['bus'] - message.control_command.acceptance_filter_bypass_command.bypass = data['bypass'] - elif message.control_command.type == openxc_pb2.ControlCommand.PREDEFINED_OBD2_REQUESTS: - message.control_command.predefined_obd2_requests_command.enabled = data['enabled'] - elif message.control_command.type == openxc_pb2.ControlCommand.PAYLOAD_FORMAT: - if data['format'] == "json": - message.control_command.payload_format_command.format = openxc_pb2.PayloadFormatCommand.JSON - elif data['format'] == "protobuf": - message.control_command.payload_format_command.format = openxc_pb2.PayloadFormatCommand.PROTOBUF - elif message.control_command.type == openxc_pb2.ControlCommand.DIAGNOSTIC: - request_command = message.control_command.diagnostic_request - action = data['action'] - if action == "add": - request_command.action = openxc_pb2.DiagnosticControlCommand.ADD - elif action == "cancel": - request_command.action = openxc_pb2.DiagnosticControlCommand.CANCEL - request = request_command.request - request_data = data['request'] - request.bus = request_data['bus'] - request.message_id = request_data['id'] - request.mode = request_data['mode'] - if 'frequency' in request_data: - request.frequency = request_data['frequency'] - if 'name' in request_data: - request.name = request_data['name'] - if 'multiple_responses' in request_data: - request.multiple_responses = request_data['multiple_responses'] - if 'pid' in request_data: - request.pid = request_data['pid'] - if 'payload' in request_data: - request.payload = binascii.unhexlify(request_data['payload'].split('0x')[1]) + cls._build_control_command_message(data, message) elif 'command_response' in data: - message.type = openxc_pb2.VehicleMessage.COMMAND_RESPONSE - message.command_response.type = cls._command_string_to_protobuf(data['command_response']) - if 'message' in data: - message.command_response.message = data['message'] - message.command_response.status = data['status'] + cls._build_command_response_message(data, message) elif 'id' in data and 'data' in data: - message.type = openxc_pb2.VehicleMessage.CAN - if 'bus' in data: - message.can_message.bus = data['bus'] - if 'frame_format' in data: - if data['frame_format'] == "standard": - message.can_message.frame_format = openxc_pb2.RawMessage.STANDARD - elif data['frame_format'] == "extended": - message.can_message.frame_format = openxc_pb2.RawMessage.EXTENDED - message.can_message.id = data['id'] - message.can_message.data = binascii.unhexlify(data['data'].split('0x')[1]) + cls._build_can_message(data, message) elif 'id' in data and 'bus' in data and 'mode' in data: - message.type = openxc_pb2.VehicleMessage.DIAGNOSTIC - response = message.diagnostic_response - response.bus = data['bus'] - response.message_id = data['id'] - response.mode = data['mode'] - if 'pid' in data: - response.pid = data['pid'] - if 'success' in data: - response.success = data['success'] - if 'negative_response_code' in data: - response.negative_response_code = data['negative_response_code'] - if 'value' in data: - response.value = data['value'] - if 'payload' in data: - response.payload = binascii.unhexlify(data['payload'].split('0x')[1]) + cls._build_diagnostic_message(data, message) elif 'name' in data and 'value' in data: - message.type = openxc_pb2.VehicleMessage.SIMPLE - message.simple_message.name = data['name'] - value = data['value'] - if isinstance(value, bool): - message.simple_message.value.type = openxc_pb2.DynamicField.BOOL - message.simple_message.value.boolean_value = value - elif isinstance(value, str): - message.simple_message.value.type = openxc_pb2.DynamicField.STRING - message.simple_message.value.string_value = value - elif isinstance(value, numbers.Number): - message.simple_message.value.type = openxc_pb2.DynamicField.NUM - message.simple_message.value.numeric_value = value - - if 'event' in data: - event = data['event'] - # TODO holy repeated code, batman. this will be easier to DRY - # when https://github.com/openxc/openxc-message-format/issues/19 - # is resolved - if isinstance(event, bool): - message.simple_message.event.type = openxc_pb2.DynamicField.BOOL - message.simple_message.event.boolean_value = event - elif isinstance(event, str): - message.simple_message.event.type = openxc_pb2.DynamicField.STRING - message.simple_message.event.string_value = event - elif isinstance(event, numbers.Number): - message.simple_message.event.type = openxc_pb2.DynamicField.NUM - message.simple_message.event.numeric_value = event + cls._build_simple_message(data, message) return message + @classmethod + def _build_can_parsed_message(cls, message, parsed_message): + can_message = message.can_message + if can_message.HasField('bus'): + parsed_message['bus'] = can_message.bus + if can_message.HasField('id'): + parsed_message['id'] = can_message.id + if can_message.HasField('data'): + parsed_message['data'] = "0x%s" % binascii.hexlify(can_message.data).decode("ascii") + if can_message.HasField('frame_format'): + if can_message.frame_format == openxc_pb2.CanMessage.STANDARD: + parsed_message['frame_format'] = "standard" + elif can_message.frame_format == openxc_pb2.CanMessage.EXTENDED: + parsed_message['frame_format'] = "extended" + + @classmethod + def _build_diagnostic_parsed_message(cls, message, parsed_message): + diagnostic_message = message.diagnostic_response + if diagnostic_message.HasField('bus'): + parsed_message['bus'] = diagnostic_message.bus + if diagnostic_message.HasField('message_id'): + parsed_message['id'] = diagnostic_message.message_id + if diagnostic_message.HasField('mode'): + parsed_message['mode'] = diagnostic_message.mode + if diagnostic_message.HasField('pid'): + parsed_message['pid'] = diagnostic_message.pid + if diagnostic_message.HasField('success'): + parsed_message['success'] = diagnostic_message.success + if diagnostic_message.HasField('value'): + parsed_message['value'] = diagnostic_message.value + if diagnostic_message.HasField('negative_response_code'): + parsed_message['negative_response_code'] = diagnostic_message.negative_response_code + if diagnostic_message.HasField('payload'): + parsed_message['payload'] = "0x%s" % binascii.hexlify(diagnostic_message.payload).decode("ascii") + + @classmethod + def _build_simple_parsed_message(cls, message, parsed_message): + simple_message = message.simple_message + parsed_message['name'] = simple_message.name + if simple_message.HasField('event'): + event = simple_message.event + if event.HasField('numeric_value'): + parsed_message['event'] = event.numeric_value + elif event.HasField('boolean_value'): + parsed_message['event'] = event.boolean_value + elif event.HasField('string_value'): + parsed_message['event'] = event.string_value + + if simple_message.HasField('value'): + value = simple_message.value + if value.HasField('numeric_value'): + parsed_message['value'] = value.numeric_value + elif value.HasField('boolean_value'): + parsed_message['value'] = value.boolean_value + elif value.HasField('string_value'): + parsed_message['value'] = value.string_value + else: + parsed_message = None + else: + parsed_message = None + + @classmethod + def _handle_diagnostic_cc_parsed_message(cls, command, parsed_message): + parsed_message['command'] = "diagnostic_request" + parsed_message['request'] = {} + action = command.diagnostic_request.action + if action == openxc_pb2.DiagnosticControlCommand.ADD: + parsed_message['action'] = "add" + elif action == openxc_pb2.DiagnosticControlCommand.CANCEL: + parsed_message['action'] = "cancel" + + request = command.diagnostic_request.request + parsed_message['request']['id'] = request.message_id + parsed_message['request']['bus'] = request.bus + parsed_message['request']['mode'] = request.mode + + if request.HasField('frequency'): + parsed_message['request']['frequency'] = request.frequency + if request.HasField('name'): + parsed_message['request']['name'] = request.name + if request.HasField('multiple_responses'): + parsed_message['request']['multiple_responses'] = request.multiple_responses + if request.HasField('pid'): + parsed_message['request']['pid'] = request.pid + if request.HasField('payload'): + parsed_message['request']['payload'] = "0x%s" % binascii.hexlify(request.payload).decode("ascii") + + @classmethod + def _handle_passthrough_cc_parsed_message(cls, command, parsed_message): + parsed_message['command'] = "passthrough" + parsed_message['bus'] = command.passthrough_mode_request.bus + parsed_message['enabled'] = command.passthrough_mode_request.enabled + + @classmethod + def _handle_predefined_obd2_requests_cc_parsed_message(cls, command, parsed_message): + parsed_message['command'] = "predefined_obd2" + parsed_message['enabled'] = command.predefined_obd2_requests_command.enabled + + @classmethod + def _handle_acceptance_filter_bypass_cc_parsed_message(cls, command, parsed_message): + parsed_message['command'] = "af_bypass" + parsed_message['bus'] = command.acceptance_filter_bypass_command.bus + parsed_message['bypass'] = command.acceptance_filter_bypass_command.bypass + + @classmethod + def _handle_payload_format_cc_parsed_message(cls, command, parsed_message): + parsed_message['command'] = "payload_format" + if command.payload_format_command.format == openxc_pb2.PayloadFormatCommand.JSON: + parsed_message['format'] = "json" + elif command.payload_format_command.format == openxc_pb2.PayloadFormatCommand.PROTOBUF: + parsed_message['format'] = "protobuf" + + @classmethod + def _build_control_command_parsed_message(cls, message, parsed_message): + command = message.control_command + if command.type == openxc_pb2.ControlCommand.VERSION: + parsed_message['command'] = "version" + elif command.type == openxc_pb2.ControlCommand.DEVICE_ID: + parsed_message['command'] = "device_id" + elif command.type == openxc_pb2.ControlCommand.DIAGNOSTIC: + cls._handle_diagnostic_cc_parsed_message(command, parsed_message) + elif command.type == openxc_pb2.ControlCommand.PASSTHROUGH: + cls._handle_passthrough_cc_parsed_message(command, parsed_message) + elif command.type == openxc_pb2.ControlCommand.PREDEFINED_OBD2_REQUESTS: + cls._handle_passthrough_cc_parsed_message(command, parsed_message) + elif command.type == openxc_pb2.ControlCommand.ACCEPTANCE_FILTER_BYPASS: + cls._handle_acceptance_filter_bypass_cc_parsed_message(command, parsed_message) + elif command.type == openxc_pb2.ControlCommand.PAYLOAD_FORMAT: + cls._handle_payload_format_cc_parsed_message(command, parsed_message) + + @classmethod + def _build_command_response_parsed_message(cls, message, parsed_message): + response = message.command_response + if response.type == openxc_pb2.ControlCommand.VERSION: + parsed_message['command_response'] = "version" + elif response.type == openxc_pb2.ControlCommand.DEVICE_ID: + parsed_message['command_response'] = "device_id" + elif response.type == openxc_pb2.ControlCommand.DIAGNOSTIC: + parsed_message['command_response'] = "diagnostic_request" + elif response.type == openxc_pb2.ControlCommand.PASSTHROUGH: + parsed_message['command_response'] = "passthrough" + elif response.type == openxc_pb2.ControlCommand.PAYLOAD_FORMAT: + parsed_message['command_response'] = "payload_format" + elif response.type == openxc_pb2.ControlCommand.ACCEPTANCE_FILTER_BYPASS: + parsed_message['command_response'] = "af_bypass" + elif response.type == openxc_pb2.ControlCommand.PREDEFINED_OBD2_REQUESTS: + parsed_message['command_response'] = "predefined_obd2" + elif response.type == openxc_pb2.ControlCommand.PLATFORM: + parsed_message['command_response'] = "platform" + else: + raise UnrecognizedBinaryCommandError(response.type) + + parsed_message['status'] = response.status + if response.HasField('message'): + parsed_message['message'] = response.message + @classmethod def _protobuf_to_dict(cls, message): parsed_message = {} if message is not None: if message.type == message.CAN and message.HasField('can_message'): - can_message = message.can_message - if can_message.HasField('bus'): - parsed_message['bus'] = can_message.bus - if can_message.HasField('id'): - parsed_message['id'] = can_message.id - if can_message.HasField('data'): - parsed_message['data'] = "0x%s" % binascii.hexlify(can_message.data).decode("ascii") - if can_message.HasField('frame_format'): - if can_message.frame_format == openxc_pb2.RawMessage.STANDARD: - parsed_message['frame_format'] = "standard" - elif can_message.frame_format == openxc_pb2.RawMessage.EXTENDED: - parsed_message['frame_format'] = "extended" + cls._build_can_parsed_message(message, parsed_message) elif message.type == message.DIAGNOSTIC: - diagnostic_message = message.diagnostic_response - if diagnostic_message.HasField('bus'): - parsed_message['bus'] = diagnostic_message.bus - if diagnostic_message.HasField('message_id'): - parsed_message['id'] = diagnostic_message.message_id - if diagnostic_message.HasField('mode'): - parsed_message['mode'] = diagnostic_message.mode - if diagnostic_message.HasField('pid'): - parsed_message['pid'] = diagnostic_message.pid - if diagnostic_message.HasField('success'): - parsed_message['success'] = diagnostic_message.success - if diagnostic_message.HasField('value'): - parsed_message['value'] = diagnostic_message.value - if diagnostic_message.HasField('negative_response_code'): - parsed_message['negative_response_code'] = diagnostic_message.negative_response_code - if diagnostic_message.HasField('payload'): - parsed_message['payload'] = "0x%s" % binascii.hexlify(diagnostic_message.payload).decode("ascii") + cls._build_diagnostic_parsed_message(message, parsed_message) elif message.type == message.SIMPLE: - simple_message = message.simple_message - parsed_message['name'] = simple_message.name - if simple_message.HasField('event'): - event = simple_message.event - if event.HasField('numeric_value'): - parsed_message['event'] = event.numeric_value - elif event.HasField('boolean_value'): - parsed_message['event'] = event.boolean_value - elif event.HasField('string_value'): - parsed_message['event'] = event.string_value - - if simple_message.HasField('value'): - value = simple_message.value - if value.HasField('numeric_value'): - parsed_message['value'] = value.numeric_value - elif value.HasField('boolean_value'): - parsed_message['value'] = value.boolean_value - elif value.HasField('string_value'): - parsed_message['value'] = value.string_value - else: - parsed_message = None - else: - parsed_message = None + cls._build_simple_parsed_message(message, parsed_message) elif message.type == message.CONTROL_COMMAND: - command = message.control_command - if command.type == openxc_pb2.ControlCommand.VERSION: - parsed_message['command'] = "version" - elif command.type == openxc_pb2.ControlCommand.DEVICE_ID: - parsed_message['command'] = "device_id" - elif command.type == openxc_pb2.ControlCommand.DIAGNOSTIC: - parsed_message['command'] = "diagnostic_request" - parsed_message['request'] = {} - action = command.diagnostic_request.action - if action == openxc_pb2.DiagnosticControlCommand.ADD: - parsed_message['action'] = "add" - elif action == openxc_pb2.DiagnosticControlCommand.CANCEL: - parsed_message['action'] = "cancel" - - request = command.diagnostic_request.request - parsed_message['request']['id'] = request.message_id - parsed_message['request']['bus'] = request.bus - parsed_message['request']['mode'] = request.mode - - if request.HasField('frequency'): - parsed_message['request']['frequency'] = request.frequency - if request.HasField('name'): - parsed_message['request']['name'] = request.name - if request.HasField('multiple_responses'): - parsed_message['request']['multiple_responses'] = request.multiple_responses - if request.HasField('pid'): - parsed_message['request']['pid'] = request.pid - if request.HasField('payload'): - parsed_message['request']['payload'] = "0x%s" % binascii.hexlify(request.payload).decode("ascii") - elif command.type == openxc_pb2.ControlCommand.PASSTHROUGH: - parsed_message['command'] = "passthrough" - parsed_message['bus'] = command.passthrough_mode_request.bus - parsed_message['enabled'] = command.passthrough_mode_request.enabled - elif command.type == openxc_pb2.ControlCommand.PREDEFINED_OBD2_REQUESTS: - parsed_message['command'] = "predefined_obd2" - parsed_message['enabled'] = command.predefined_obd2_requests_command.enabled - elif command.type == openxc_pb2.ControlCommand.ACCEPTANCE_FILTER_BYPASS: - parsed_message['command'] = "af_bypass" - parsed_message['bus'] = command.acceptance_filter_bypass_command.bus - parsed_message['bypass'] = command.acceptance_filter_bypass_command.bypass - elif command.type == openxc_pb2.ControlCommand.PAYLOAD_FORMAT: - parsed_message['command'] = "payload_format" - if command.payload_format_command.format == openxc_pb2.PayloadFormatCommand.JSON: - parsed_message['format'] = "json" - elif command.payload_format_command.format == openxc_pb2.PayloadFormatCommand.PROTOBUF: - parsed_message['format'] = "protobuf" + cls._build_control_command_parsed_message(message, parsed_message) elif message.type == message.COMMAND_RESPONSE: - response = message.command_response - if response.type == openxc_pb2.ControlCommand.VERSION: - parsed_message['command_response'] = "version" - elif response.type == openxc_pb2.ControlCommand.DEVICE_ID: - parsed_message['command_response'] = "device_id" - elif response.type == openxc_pb2.ControlCommand.DIAGNOSTIC: - parsed_message['command_response'] = "diagnostic_request" - elif response.type == openxc_pb2.ControlCommand.PASSTHROUGH: - parsed_message['command_response'] = "passthrough" - elif response.type == openxc_pb2.ControlCommand.PAYLOAD_FORMAT: - parsed_message['command_response'] = "payload_format" - elif response.type == openxc_pb2.ControlCommand.ACCEPTANCE_FILTER_BYPASS: - parsed_message['command_response'] = "af_bypass" - elif response.type == openxc_pb2.ControlCommand.PREDEFINED_OBD2_REQUESTS: - parsed_message['command_response'] = "predefined_obd2" - elif response.type == openxc_pb2.ControlCommand.PLATFORM: - parsed_message['command_response'] = "platform" - else: - raise UnrecognizedBinaryCommandError(response.type) - - parsed_message['status'] = response.status - if response.HasField('message'): - parsed_message['message'] = response.message + cls._build_command_response_parsed_message(message, parsed_message) else: parsed_message = None return parsed_message diff --git a/openxc/generator/structures.py b/openxc/generator/structures.py index 5145ffbb..9493d158 100644 --- a/openxc/generator/structures.py +++ b/openxc/generator/structures.py @@ -100,17 +100,7 @@ def id(self, value): value = int(value, 0) self._id = value - def merge_message(self, data): - self.bus_name = self.bus_name or data.get('bus', None) - - message_attributes = dir(self) - message_attributes = [a.replace('bus_name', 'bus') for a in message_attributes] - data_attributes = list(data.keys()) - extra_attributes = set(data_attributes) - set(message_attributes) - - if extra_attributes: - fatal_error('ERROR: Message %s has unrecognized attributes: %s' % (data.get('id'), ', '.join(extra_attributes))) - + def validate_bus(self): if getattr(self, 'message_set'): self.bus = self.message_set.lookup_bus(name=self.bus_name) if not self.bus.valid(): @@ -123,6 +113,19 @@ def merge_message(self, data): msg = "Bus '%s' is disabled" % self.bus_name LOG.warning("%s - message 0x%x will be disabled" % (msg, self.id)) + def merge_message(self, data): + self.bus_name = self.bus_name or data.get('bus', None) + + message_attributes = dir(self) + message_attributes = [a.replace('bus_name', 'bus') for a in message_attributes] + data_attributes = list(data.keys()) + extra_attributes = set(data_attributes) - set(message_attributes) + + if extra_attributes: + fatal_error('ERROR: Message %s has unrecognized attributes: %s' % (data.get('id'), ', '.join(extra_attributes))) + + self.validate_bus() + self.id = self.id or data.get('id') self.name = self.name or data.get('name', None) self.bit_numbering_inverted = (self.bit_numbering_inverted or diff --git a/openxc/sources/base.py b/openxc/sources/base.py index 80dc9f2d..5afe1adf 100644 --- a/openxc/sources/base.py +++ b/openxc/sources/base.py @@ -185,6 +185,20 @@ def _message_valid(self, message): return False return True + def parse_messages(self): + while True: + message = self.streamer.parse_next_message() + if message is None: + break + + if not self._message_valid(message): + self.corrupted_messages += 1 + break + + if self.callback is not None: + self.callback(message) + self._receive_command_response(message) + def run(self): """Continuously read data from the source and attempt to parse a valid message from the buffer of bytes. When a message is parsed, passes it @@ -210,18 +224,7 @@ def run(self): self.format = "protobuf" self.streamer.receive(payload) - while True: - message = self.streamer.parse_next_message() - if message is None: - break - - if not self._message_valid(message): - self.corrupted_messages += 1 - break - - if self.callback is not None: - self.callback(message) - self._receive_command_response(message) + self.parse_messages() def _receive_command_response(self, message): # TODO the controller/source are getting a little mixed up since the diff --git a/openxc/tools/control.py b/openxc/tools/control.py index 75ebf505..9945084e 100644 --- a/openxc/tools/control.py +++ b/openxc/tools/control.py @@ -134,6 +134,37 @@ def parse_options(): parser.set_defaults(format="json") return parser.parse_args() +def handle_set_command(arguments, interface): + if arguments.passthrough_enabled is not None: + passthrough(interface, int(arguments.bus), arguments.passthrough_enabled) + if arguments.af_bypass is not None: + af_bypass(interface, int(arguments.bus), arguments.af_bypass) + if arguments.new_payload_format is not None: + set_payload_format(interface, arguments.new_payload_format) + if arguments.unix_time is not None: + set_rtc_time(interface, int(arguments.unix_time)) + if arguments.host is not None: + modem_configuration(interface, arguments.host, arguments.port) + +def handle_write_command(arguments, interface): + if arguments.write_name: + interface.write(name=arguments.write_name, + value=arguments.write_value, + event=arguments.write_event) + elif arguments.write_id: + if not arguments.write_data: + sys.exit("%s requires an id and data" % arguments.command) + # TODO we should use unhexlify as with the diagnostic command + # payloads so we can standardize the API and not deal with hex + # strings in code + interface.write(bus=int(arguments.bus), + id=arguments.write_id, + data=arguments.write_data, + frame_format=arguments.write_frame_format) + elif arguments.write_input_file: + write_file(interface, arguments.write_input_file) + else: + sys.exit("%s requires a signal name, message ID or filename" % arguments.command) def main(): configure_logging() @@ -152,35 +183,8 @@ def main(): elif arguments.command == "id": device_id(interface) elif arguments.command == "set": - if arguments.passthrough_enabled is not None: - passthrough(interface, int(arguments.bus), arguments.passthrough_enabled) - if arguments.af_bypass is not None: - af_bypass(interface, int(arguments.bus), arguments.af_bypass) - if arguments.new_payload_format is not None: - set_payload_format(interface, arguments.new_payload_format) - if arguments.unix_time is not None: - set_rtc_time(interface, int(arguments.unix_time)) - if arguments.host is not None: - modem_configuration(interface, arguments.host, arguments.port) - elif arguments.command.startswith("write"): - if arguments.command == "write": - if arguments.write_name: - interface.write(name=arguments.write_name, - value=arguments.write_value, - event=arguments.write_event) - elif arguments.write_id: - if not arguments.write_data: - sys.exit("%s requires an id and data" % arguments.command) - # TODO we should use unhexlify as with the diagnostic command - # payloads so we can standardize the API and not deal with hex - # strings in code - interface.write(bus=int(arguments.bus), - id=arguments.write_id, - data=arguments.write_data, - frame_format=arguments.write_frame_format) - elif arguments.write_input_file: - write_file(interface, arguments.write_input_file) - else: - sys.exit("%s requires a signal name, message ID or filename" % arguments.command) + handle_set_command(arguments, interface) + elif arguments.command == "write": + handle_write_command(arguments, interface) else: print(("Unrecognized command \"%s\"" % arguments.command)) \ No newline at end of file diff --git a/openxc/tools/diagnostics.py b/openxc/tools/diagnostics.py index 022bedfa..c67ec1b4 100644 --- a/openxc/tools/diagnostics.py +++ b/openxc/tools/diagnostics.py @@ -13,6 +13,23 @@ from .common import device_options, configure_logging, select_device +def print_diagnostic_response(responses): + for response in responses: + # After sending a diagnostic request, it will return with a signal message saying if the + # request was recieved. After that it used to show about 30 vehicle messages (rpm, speed, etc) + # with the actual diagnostic response mixed in. So, if the response length is more than + # 1, it's the response, if its less (only 1) it's the recieved message. + if len(response) > 1: + # Stripping all of the unnesseary data we get after sending a diag request in python + # Just like in enabler, it's a diag response if it contains the keys "mode", "bus", + # "id", and "success". + diag_mgs_req_keys = ['mode', 'bus', 'id', 'success'] + indices = [i for i, s in enumerate(response) if all(x in s for x in diag_mgs_req_keys)] + if indices: + print(("Response: %s" % response[indices[0]])) + else: + print(("Response: %s" % response)) + def diagnostic_request(arguments, controller): message = int(arguments.message, 0) mode = int(arguments.mode, 0) @@ -40,21 +57,7 @@ def diagnostic_request(arguments, controller): if len(responses) == 0: print("No response received before timeout") else: - for response in responses: - # After sending a diagnostic request, it will return with a signal message saying if the - # request was recieved. After that it used to show about 30 vehicle messages (rpm, speed, etc) - # with the actual diagnostic response mixed in. So, if the response length is more than - # 1, it's the response, if its less (only 1) it's the recieved message. - if len(response) > 1: - # Stripping all of the unnesseary data we get after sending a diag request in python - # Just like in enabler, it's a diag response if it contains the keys "mode", "bus", - # "id", and "success". - diag_mgs_req_keys = ['mode', 'bus', 'id', 'success'] - indices = [i for i, s in enumerate(response) if all(x in s for x in diag_mgs_req_keys)] - if indices: - print(("Response: %s" % response[indices[0]])) - else: - print(("Response: %s" % response)) + print_diagnostic_response(responses) elif arguments.command == "cancel": if controller.delete_diagnostic_request(message, mode, bus=bus, pid=pid): diff --git a/openxc/tools/scanner.py b/openxc/tools/scanner.py index 3b284a42..576cc97e 100644 --- a/openxc/tools/scanner.py +++ b/openxc/tools/scanner.py @@ -15,15 +15,7 @@ TESTER_PRESENT_MODE = 0x3e TESTER_PRESENT_PAYLOAD = bytearray([0]) -def scan(controller, bus=None, message_id=None): - message_ids = [] - if message_id is not None: - message_ids.append(message_id) - else: - # using 11-bit IDs - message_ids = list(range(0, 0x7ff + 1)) - - print("Sending tester present message to find valid modules arb IDs") +def find_active_modules(controller, bus, message_ids): active_modules = set() for arb_id in message_ids: response = controller.create_diagnostic_request(arb_id, TESTER_PRESENT_MODE, @@ -32,9 +24,9 @@ def scan(controller, bus=None, message_id=None): if response is not None: print(("0x%x responded to tester present: %s" % (arb_id, response))) active_modules.add(arb_id) + return active_modules - # Scan for active services on each active module by sending blank requests - print("Scanning for services on active modules") +def find_active_modes(controller, bus, active_modules): active_modes = defaultdict(list) for active_module in active_modules: controller.create_diagnostic_request(active_module, TESTER_PRESENT_MODE, @@ -56,6 +48,22 @@ def scan(controller, bus=None, message_id=None): controller.create_diagnostic_request(active_module, TESTER_PRESENT_MODE, bus=bus, frequency=0) + return active_modes + +def scan(controller, bus=None, message_id=None): + message_ids = [] + if message_id is not None: + message_ids.append(message_id) + else: + # using 11-bit IDs + message_ids = list(range(0, 0x7ff + 1)) + + print("Sending tester present message to find valid modules arb IDs") + active_modules = find_active_modules(controller, bus, message_ids) + + # Scan for active services on each active module by sending blank requests + print("Scanning for services on active modules") + active_modes = find_active_modes(controller, bus, active_modules) # Scan for what each mode can do and what data it can return by fuzzing the # payloads From 437be38153d0fc36a0747ff1413b8bb467f70a99 Mon Sep 17 00:00:00 2001 From: Prateek Prakash <59665714+PPRAKA30@users.noreply.github.com> Date: Mon, 16 Mar 2020 12:15:19 -0400 Subject: [PATCH 15/25] Add Print function with flushing set to true --- openxc/tools/dump.py | 3 +++ openxc/tools/obd2scanner.py | 4 +++- openxc/tools/scanner.py | 3 +++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/openxc/tools/dump.py b/openxc/tools/dump.py index e35239b0..21c35ef0 100644 --- a/openxc/tools/dump.py +++ b/openxc/tools/dump.py @@ -13,6 +13,9 @@ from openxc.formats.json import JsonFormatter from .common import device_options, configure_logging, select_device +import functools +print = functools.partial(print, flush=True) + def receive(message, **kwargs): message['timestamp'] = time.time() print((JsonFormatter.serialize(message))) diff --git a/openxc/tools/obd2scanner.py b/openxc/tools/obd2scanner.py index a2fc0cf3..34dc3f35 100644 --- a/openxc/tools/obd2scanner.py +++ b/openxc/tools/obd2scanner.py @@ -12,6 +12,9 @@ from .common import device_options, configure_logging, select_device import json +import functools +print = functools.partial(print, flush=True) + def scan(controller, bus=None): # TODO could read the response from the "PIDs supported" requests to see @@ -28,7 +31,6 @@ def scan(controller, bus=None): if (no_response == True): print("PID 0x%x did not respond" % pid) - sys.stdout.flush() def parse_options(): parser = argparse.ArgumentParser(description="Send requests for all " diff --git a/openxc/tools/scanner.py b/openxc/tools/scanner.py index 576cc97e..2e08984e 100644 --- a/openxc/tools/scanner.py +++ b/openxc/tools/scanner.py @@ -12,6 +12,9 @@ from .common import device_options, configure_logging, select_device +import functools +print = functools.partial(print, flush=True) + TESTER_PRESENT_MODE = 0x3e TESTER_PRESENT_PAYLOAD = bytearray([0]) From d0928b85bded3b8109300c5023763681aa609f82 Mon Sep 17 00:00:00 2001 From: Ja'mez Stokes <49651248+jstoke53@users.noreply.github.com> Date: Wed, 18 Mar 2020 13:03:23 -0400 Subject: [PATCH 16/25] Change arguments to correctly seen command for modem_configuration. --- openxc/controllers/usb.py | 1 + openxc/tools/control.py | 6 ++++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/openxc/controllers/usb.py b/openxc/controllers/usb.py index 5ce8ccd3..663a8baf 100644 --- a/openxc/controllers/usb.py +++ b/openxc/controllers/usb.py @@ -33,6 +33,7 @@ def _send_complex_request(self, request): """Send a request via the USB control request endpoint, rather than as a bulk transfer. """ + # LOG.warn("DEBUG STUFF ________________ " + str(self.streamer.serialize_for_stream(request))) self.device.ctrl_transfer(0x40, self.COMPLEX_CONTROL_COMMAND, 0, 0, self.streamer.serialize_for_stream(request)) diff --git a/openxc/tools/control.py b/openxc/tools/control.py index 9945084e..98e52024 100644 --- a/openxc/tools/control.py +++ b/openxc/tools/control.py @@ -129,6 +129,8 @@ def parse_options(): dest="unix_time") parser.add_argument("--host", action="store", default=None, dest="host") + parser.add_argument("--network-host", action="store", default=None, + dest="network_host") parser.add_argument("--port", action="store", default=80, dest="port") parser.set_defaults(format="json") @@ -143,8 +145,8 @@ def handle_set_command(arguments, interface): set_payload_format(interface, arguments.new_payload_format) if arguments.unix_time is not None: set_rtc_time(interface, int(arguments.unix_time)) - if arguments.host is not None: - modem_configuration(interface, arguments.host, arguments.port) + if arguments.network_host is not None: + modem_configuration(interface, arguments.network_host, arguments.port) def handle_write_command(arguments, interface): if arguments.write_name: From a777e0710ebb3f4ca4ef5ee64279138e471d17ef Mon Sep 17 00:00:00 2001 From: garindae Date: Tue, 24 Mar 2020 13:47:35 -0400 Subject: [PATCH 17/25] Fixed Binary translation for Protobuf response (as well as other messages) --- openxc/sources/usb.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openxc/sources/usb.py b/openxc/sources/usb.py index ca4754b1..4e85680b 100644 --- a/openxc/sources/usb.py +++ b/openxc/sources/usb.py @@ -85,8 +85,8 @@ def _read(self, endpoint_address, timeout=None, read_size=DEFAULT_READ_REQUEST_SIZE): timeout = timeout or self.DEFAULT_READ_TIMEOUT try: - return str(self.device.read(0x80 + endpoint_address, - read_size, self.DEFAULT_INTERFACE_NUMBER, timeout), 'ISO-8859-1') + temp = self.device.read(0x80 + endpoint_address,read_size, self.DEFAULT_INTERFACE_NUMBER, timeout) + return str(temp, 'utf-8', 'ignore') # Formerly - Causes byte tranlation str(temp, 'ISO-8859-1') except (usb.core.USBError, AttributeError) as e: if e.backend_error_code in [self.LIBUSB0_TIMEOUT_CODE, self.LIBUSB1_TIMEOUT_CODE, self.OPENUSB_TIMEOUT_CODE]: # Timeout, it may just not be sending From 079c580e7292f8e76004963e32cf92bcd2322bbf Mon Sep 17 00:00:00 2001 From: garindae Date: Tue, 24 Mar 2020 14:20:43 -0400 Subject: [PATCH 18/25] renamed temp variable to something more appropriate --- openxc/sources/usb.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openxc/sources/usb.py b/openxc/sources/usb.py index 4e85680b..aed7aac4 100644 --- a/openxc/sources/usb.py +++ b/openxc/sources/usb.py @@ -85,8 +85,8 @@ def _read(self, endpoint_address, timeout=None, read_size=DEFAULT_READ_REQUEST_SIZE): timeout = timeout or self.DEFAULT_READ_TIMEOUT try: - temp = self.device.read(0x80 + endpoint_address,read_size, self.DEFAULT_INTERFACE_NUMBER, timeout) - return str(temp, 'utf-8', 'ignore') # Formerly - Causes byte tranlation str(temp, 'ISO-8859-1') + raw_binary = self.device.read(0x80 + endpoint_address,read_size, self.DEFAULT_INTERFACE_NUMBER, timeout) + return str(raw_binary, 'utf-8', 'ignore') # Formerly - Causes byte tranlation str(temp, 'ISO-8859-1') except (usb.core.USBError, AttributeError) as e: if e.backend_error_code in [self.LIBUSB0_TIMEOUT_CODE, self.LIBUSB1_TIMEOUT_CODE, self.OPENUSB_TIMEOUT_CODE]: # Timeout, it may just not be sending From c43dd630eb19d29651ec0c5f0ffbeed49e327c52 Mon Sep 17 00:00:00 2001 From: Ja'mez Stokes <49651248+jstoke53@users.noreply.github.com> Date: Tue, 7 Apr 2020 14:04:29 -0400 Subject: [PATCH 19/25] Add a try catch for keyboardinterupt for both openxc-dump and scanner tools. --- openxc/tools/dump.py | 20 ++++++++++++-------- openxc/tools/scanner.py | 21 ++++++++++++--------- 2 files changed, 24 insertions(+), 17 deletions(-) diff --git a/openxc/tools/dump.py b/openxc/tools/dump.py index 21c35ef0..8a90b558 100644 --- a/openxc/tools/dump.py +++ b/openxc/tools/dump.py @@ -9,6 +9,7 @@ import argparse import time import logging +import sys from openxc.formats.json import JsonFormatter from .common import device_options, configure_logging, select_device @@ -31,11 +32,14 @@ def parse_options(): def main(): - configure_logging(logging.DEBUG) - arguments = parse_options() - - source_class, source_kwargs = select_device(arguments) - source = source_class(callback=receive, **source_kwargs) - source.start() - # TODO test this, I'd prefer it to the sleep loop - source.join() + try: + configure_logging(logging.DEBUG) + arguments = parse_options() + source_class, source_kwargs = select_device(arguments) + source = source_class(callback=receive, **source_kwargs) + source.start() + # TODO test this, I'd prefer it to the sleep loop + while(True): + source.join(0.1) + except KeyboardInterrupt: + sys.exit(0) diff --git a/openxc/tools/scanner.py b/openxc/tools/scanner.py index 2e08984e..7ee4c868 100644 --- a/openxc/tools/scanner.py +++ b/openxc/tools/scanner.py @@ -6,7 +6,7 @@ module are internal only. """ - +import sys import argparse from collections import defaultdict @@ -98,11 +98,14 @@ def parse_options(): def main(): - configure_logging() - arguments = parse_options() - - controller_class, controller_kwargs = select_device(arguments) - controller = controller_class(**controller_kwargs) - controller.start() - - scan(controller, arguments.bus, arguments.message_id) + try: + configure_logging() + arguments = parse_options() + + controller_class, controller_kwargs = select_device(arguments) + controller = controller_class(**controller_kwargs) + controller.start() + while(True): + scan(controller, arguments.bus, arguments.message_id) + except KeyboardInterrupt: + sys.exit(0) From d85d434ea3d5ef157737b38137ec2b32bd260742 Mon Sep 17 00:00:00 2001 From: ptreman Date: Tue, 26 May 2020 18:44:19 -0400 Subject: [PATCH 20/25] Added new multiframe code --- openxc/controllers/base.py | 51 +++++++++++++++++++++++++++++++++++--- 1 file changed, 48 insertions(+), 3 deletions(-) diff --git a/openxc/controllers/base.py b/openxc/controllers/base.py index cc6a2450..28ad9216 100644 --- a/openxc/controllers/base.py +++ b/openxc/controllers/base.py @@ -36,6 +36,7 @@ def __init__(self, queue, request, quit_after_first=True): queue - A multithreading queue that this receiver will pull potential responses from. request - The request we are trying to match up with a response. """ + self.diag_dict = {} self.request = request self.queue = queue self.responses = [] @@ -82,12 +83,44 @@ def handle_responses(self): response = self.queue.get( timeout=self.COMMAND_RESPONSE_TIMEOUT_S) if self._response_matches_request(response): + if type(self) == DiagnosticResponseReceiver: + if self._response_is_multiframe(response): + if response['message_id'] in self.diag_dict: + self.diag_dict[response['message_id']].addFrame(response) + else: + self.diag_dict[response['message_id']] = MultiframeDiagnosticMessage(response) + if self._return_final(response): + self.responses.append(self.diag_dict[response['message_id']].getResponse()) + self.diag_dict.pop(response['message_id']) self.responses.append(response) if self.quit_after_first: self.running = False self.queue.task_done() except Empty: break + +class MultiframeDiagnosticMessage: + def __init__(self, response): + self.message_id = response['message_id'] - 16 + self.mode = response['mode'] + self.bus = response['bus'] + self.pid = response['pid'] + self.payload = '0x' + response['payload'][8:] + + def addFrame(self, response): + self.payload += response['payload'][8:] + + def getResponse(self): + request = { + 'timestamp': 0, + 'bus': self.bus, + 'id': self.message_id, + 'mode': self.mode, + 'success': True, + 'pid': self.pid, + 'payload': self.payload + } + return request class CommandResponseReceiver(ResponseReceiver): """A receiver that matches the 'command' field in responses to the @@ -104,7 +137,7 @@ class DiagnosticResponseReceiver(ResponseReceiver): """A receiver that matches the bus, ID, mode and PID from a diagnostic request to an incoming response. """ - + def __init__(self, queue, request): super(DiagnosticResponseReceiver, self).__init__(queue, request, quit_after_first=False) @@ -135,7 +168,19 @@ def _response_matches_request(self, response): return False return response.get('mode', None) == self.diagnostic_request['mode'] - + + def _response_is_multiframe(self, response): + if 'frame' in response: + return True + return False + + def _return_frame(self, response): + return response['payload'][8:] + + def _return_final(self, response): + if response['frame'] == -1: + return True + return False class Controller(object): """A Controller is a physical vehicle interface that accepts commands to be @@ -175,7 +220,7 @@ def complex_request(self, request, wait_for_first_response=True): if wait_for_first_response: responses = receiver.wait_for_responses() return responses - + def _send_complex_request(self, request): self.write_bytes(self.streamer.serialize_for_stream(request)) From 1116e457b7033b66992c2a854ce265ee0c5b15e9 Mon Sep 17 00:00:00 2001 From: ptreman Date: Tue, 26 May 2020 18:49:58 -0400 Subject: [PATCH 21/25] Remove unused code --- openxc/controllers/base.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/openxc/controllers/base.py b/openxc/controllers/base.py index 28ad9216..23b81615 100644 --- a/openxc/controllers/base.py +++ b/openxc/controllers/base.py @@ -174,9 +174,6 @@ def _response_is_multiframe(self, response): return True return False - def _return_frame(self, response): - return response['payload'][8:] - def _return_final(self, response): if response['frame'] == -1: return True From 9dc75655d5541a621d8c82d4dba03c1d4a65f86b Mon Sep 17 00:00:00 2001 From: pjt0620 Date: Wed, 22 Jul 2020 16:00:08 -0400 Subject: [PATCH 22/25] Update base.py --- openxc/controllers/base.py | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/openxc/controllers/base.py b/openxc/controllers/base.py index 23b81615..4eb0ddeb 100644 --- a/openxc/controllers/base.py +++ b/openxc/controllers/base.py @@ -85,13 +85,13 @@ def handle_responses(self): if self._response_matches_request(response): if type(self) == DiagnosticResponseReceiver: if self._response_is_multiframe(response): - if response['message_id'] in self.diag_dict: - self.diag_dict[response['message_id']].addFrame(response) + if response['id'] in self.diag_dict: + self.diag_dict[response['id']].addFrame(response) else: - self.diag_dict[response['message_id']] = MultiframeDiagnosticMessage(response) + self.diag_dict[response['id']] = MultiframeDiagnosticMessage(response) if self._return_final(response): - self.responses.append(self.diag_dict[response['message_id']].getResponse()) - self.diag_dict.pop(response['message_id']) + self.responses.append(self.diag_dict[response['id']].getResponse()) + self.diag_dict.pop(response['id']) self.responses.append(response) if self.quit_after_first: self.running = False @@ -101,7 +101,7 @@ def handle_responses(self): class MultiframeDiagnosticMessage: def __init__(self, response): - self.message_id = response['message_id'] - 16 + self.id = response['id'] - 16 self.mode = response['mode'] self.bus = response['bus'] self.pid = response['pid'] @@ -114,7 +114,7 @@ def getResponse(self): request = { 'timestamp': 0, 'bus': self.bus, - 'id': self.message_id, + 'id': self.id, 'mode': self.mode, 'success': True, 'pid': self.pid, @@ -222,12 +222,12 @@ def _send_complex_request(self, request): self.write_bytes(self.streamer.serialize_for_stream(request)) @classmethod - def _build_diagnostic_request(cls, message_id, mode, bus=None, pid=None, + def _build_diagnostic_request(cls, id, mode, bus=None, pid=None, frequency=None, payload=None, decoded_type=None): request = { 'command': "diagnostic_request", 'request': { - 'id': message_id, + 'id': id, 'mode': mode } } @@ -247,19 +247,19 @@ def _build_diagnostic_request(cls, message_id, mode, bus=None, pid=None, return request - def delete_diagnostic_request(self, message_id, mode, bus=None, pid=None): - request = self._build_diagnostic_request(message_id, mode, bus, pid) + def delete_diagnostic_request(self, id, mode, bus=None, pid=None): + request = self._build_diagnostic_request(id, mode, bus, pid) request['action'] = 'cancel' return self._check_command_response_status(request) - def create_diagnostic_request(self, message_id, mode, bus=None, pid=None, + def create_diagnostic_request(self, id, mode, bus=None, pid=None, frequency=None, payload=None, wait_for_ack=True, wait_for_first_response=False, decoded_type=None): """Send a new diagnostic message request to the VI Required: - message_id - The message ID (arbitration ID) for the request. + id - The message ID (arbitration ID) for the request. mode - the diagnostic mode (or service). Optional: @@ -287,7 +287,7 @@ def create_diagnostic_request(self, message_id, mode, bus=None, pid=None, """ - request = self._build_diagnostic_request(message_id, mode, bus, pid, + request = self._build_diagnostic_request(id, mode, bus, pid, frequency, payload, decoded_type) diag_response_receiver = None @@ -453,15 +453,15 @@ def write_translated(self, name, value, event=None): assert bytes_written == len(message) return bytes_written - def write_raw(self, message_id, data, bus=None, frame_format=None): + def write_raw(self, id, data, bus=None, frame_format=None): """Send a raw write request to the VI. """ - if not isinstance(message_id, numbers.Number): + if not isinstance(id, numbers.Number): try: - message_id = int(message_id, 0) + id = int(id, 0) except ValueError: raise ValueError("ID must be numerical") - data = {'id': message_id, 'data': data} + data = {'id': id, 'data': data} if bus is not None: data['bus'] = bus if frame_format is not None: From 6522e1cb9d1696ee9f2164cc6a52adb0e1fa00bf Mon Sep 17 00:00:00 2001 From: GenoJAFord Date: Fri, 11 Sep 2020 20:55:35 +0000 Subject: [PATCH 23/25] Release 2.1.0 versioning --- CHANGELOG.rst | 8 ++++++++ README.rst | 2 +- docs/index.rst | 2 +- openxc/version.py | 2 +- 4 files changed, 11 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 23da6d07..9d78a4b6 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,6 +1,14 @@ OpenXC Python Library Changelog =============================== +v2.1.0 +---------- +* SonarQube integration +* Fix: Modem configuration for c5 cellar build now properly sets baud rate +* Fix: Protobuf general improvements +* Keyboard interupt via c added to openxc-dump and Obd2 Scanner +* Stitching Feature, large messages are now packaged and sent in smaller chunks from the vi + v2.0.0 ---------- * Known Issue: OpenXC python must be used with firmware 8.0.0 or greater. diff --git a/README.rst b/README.rst index 3c472385..b6c83928 100644 --- a/README.rst +++ b/README.rst @@ -4,7 +4,7 @@ OpenXC for Python .. image:: https://github.com/openxc/openxc-python/raw/master/docs/_static/logo.png -:Version: 2.0.0 +:Version: 2.1.0 :Web: http://openxcplatform.com :Download: http://pypi.python.org/pypi/openxc/ :Documentation: http://python.openxcplatform.com diff --git a/docs/index.rst b/docs/index.rst index e5f36e7f..c9efc4a7 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -4,7 +4,7 @@ OpenXC for Python .. image:: https://github.com/openxc/openxc-python/raw/master/docs/_static/logo.png -:Version: 2.0.0 +:Version: 2.1.0 :Web: http://openxcplatform.com :Download: http://pypi.python.org/pypi/openxc/ :Documentation: http://python.openxcplatform.com diff --git a/openxc/version.py b/openxc/version.py index 37af0b65..b122ea39 100644 --- a/openxc/version.py +++ b/openxc/version.py @@ -6,7 +6,7 @@ which in turn needs access to this version information.) """ -VERSION = (2, 0, 0) +VERSION = (2, 1, 0) __version__ = '.'.join(map(str, VERSION)) From 083a31e62acf233ff7c62daf07a0e47ae51c94e4 Mon Sep 17 00:00:00 2001 From: GenoJAFord Date: Mon, 14 Sep 2020 17:50:51 +0000 Subject: [PATCH 24/25] Updated readme notes for dependence on vi-firmware 8.1.0 --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index b6c83928..0dcdeea4 100644 --- a/README.rst +++ b/README.rst @@ -30,7 +30,7 @@ In addition to a port of the Android library API, the package also contains a number of command-line tools for connecting to the CAN translator and manipulating previously recorded vehicle data. -Due to changes in signals.cpp openxc-python Version 2.0.0 must be used with vi-firmware 8.0.0 or greater. +Due to changes in signals.cpp openxc-python Version 2.1.0 must be used with vi-firmware 8.1.0 or greater. To package run "setup.py sdist bdist_wheel" to push to pypi run "python -m twine upload dist/\*" From f98ae4f18cf9d97920d690717de817f8b265e2be Mon Sep 17 00:00:00 2001 From: GenoJAFord Date: Mon, 14 Sep 2020 18:29:33 +0000 Subject: [PATCH 25/25] Updated readme with compatibility reason --- README.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.rst b/README.rst index 0dcdeea4..ef42bca1 100644 --- a/README.rst +++ b/README.rst @@ -30,7 +30,8 @@ In addition to a port of the Android library API, the package also contains a number of command-line tools for connecting to the CAN translator and manipulating previously recorded vehicle data. -Due to changes in signals.cpp openxc-python Version 2.1.0 must be used with vi-firmware 8.1.0 or greater. +Due to changes in signals.cpp openxc-python Version 2.0.0 must be used with vi-firmware 8.0.0 or greater. +Due to changes with large diagnostic responses Version 2.1.0 must be used with vi-firmware 8.1.0 or greater. To package run "setup.py sdist bdist_wheel" to push to pypi run "python -m twine upload dist/\*" @@ -44,6 +45,6 @@ Version files: License ======== -Copyright (c) 2012-2017 Ford Motor Company +Copyright (c) 2012-2020 Ford Motor Company Licensed under the BSD license.