Skip to content

Commit 31655a9

Browse files
authored
Merge pull request #154 from openxc/next
Next
2 parents 2054c3d + 8f1eb8b commit 31655a9

File tree

22 files changed

+531
-377
lines changed

22 files changed

+531
-377
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,4 @@ coverage.xml
1717
diffcover.html
1818
htmlcov
1919
*~
20+
.scannerwork/

CHANGELOG.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,14 @@
11
OpenXC Python Library Changelog
22
===============================
33

4+
v2.1.0
5+
----------
6+
* SonarQube integration
7+
* Fix: Modem configuration for c5 cellar build now properly sets baud rate
8+
* Fix: Protobuf general improvements
9+
* Keyboard interupt via <ctrl>c added to openxc-dump and Obd2 Scanner
10+
* Stitching Feature, large messages are now packaged and sent in smaller chunks from the vi
11+
412
v2.0.0
513
----------
614
* Known Issue: OpenXC python must be used with firmware 8.0.0 or greater.

README.rst

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ OpenXC for Python
44

55
.. image:: https://github.com/openxc/openxc-python/raw/master/docs/_static/logo.png
66

7-
:Version: 2.0.0
7+
:Version: 2.1.0
88
:Web: http://openxcplatform.com
99
:Download: http://pypi.python.org/pypi/openxc/
1010
:Documentation: http://python.openxcplatform.com
@@ -31,6 +31,7 @@ number of command-line tools for connecting to the CAN translator and
3131
manipulating previously recorded vehicle data.
3232

3333
Due to changes in signals.cpp openxc-python Version 2.0.0 must be used with vi-firmware 8.0.0 or greater.
34+
Due to changes with large diagnostic responses Version 2.1.0 must be used with vi-firmware 8.1.0 or greater.
3435

3536
To package run "setup.py sdist bdist_wheel"
3637
to push to pypi run "python -m twine upload dist/\*"
@@ -44,6 +45,6 @@ Version files:
4445
License
4546
========
4647

47-
Copyright (c) 2012-2017 Ford Motor Company
48+
Copyright (c) 2012-2020 Ford Motor Company
4849

4950
Licensed under the BSD license.

docs/_static/rtd.css

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -382,12 +382,6 @@ div.sphinxsidebar p a:hover {
382382
border: 1px solid #888;
383383
}
384384

385-
/* Tweak any link appearing in a heading */
386-
div.sphinxsidebar h3 a {
387-
}
388-
389-
390-
391385

392386
/* OTHER STUFF ------------------------------------------------------------ */
393387

docs/index.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ OpenXC for Python
44

55
.. image:: https://github.com/openxc/openxc-python/raw/master/docs/_static/logo.png
66

7-
:Version: 2.0.0
7+
:Version: 2.1.0
88
:Web: http://openxcplatform.com
99
:Download: http://pypi.python.org/pypi/openxc/
1010
:Documentation: http://python.openxcplatform.com

docs/tools/control.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ Set the host and port for the C5 Cellular device
8787

8888
.. code-block:: bash
8989
90-
$ openxc-control set --network-host www.server.com --port 80
90+
$ openxc-control set --host www.server.com --port 80
9191
9292
This will return true when successful. If network-host is supplied, but not port,
9393
port will default to 80.

openxc/controllers/base.py

Lines changed: 56 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ def __init__(self, queue, request, quit_after_first=True):
3636
queue - A multithreading queue that this receiver will pull potential responses from.
3737
request - The request we are trying to match up with a response.
3838
"""
39+
self.diag_dict = {}
3940
self.request = request
4041
self.queue = queue
4142
self.responses = []
@@ -82,12 +83,44 @@ def handle_responses(self):
8283
response = self.queue.get(
8384
timeout=self.COMMAND_RESPONSE_TIMEOUT_S)
8485
if self._response_matches_request(response):
86+
if type(self) == DiagnosticResponseReceiver:
87+
if self._response_is_multiframe(response):
88+
if response['id'] in self.diag_dict:
89+
self.diag_dict[response['id']].addFrame(response)
90+
else:
91+
self.diag_dict[response['id']] = MultiframeDiagnosticMessage(response)
92+
if self._return_final(response):
93+
self.responses.append(self.diag_dict[response['id']].getResponse())
94+
self.diag_dict.pop(response['id'])
8595
self.responses.append(response)
8696
if self.quit_after_first:
8797
self.running = False
8898
self.queue.task_done()
8999
except Empty:
90100
break
101+
102+
class MultiframeDiagnosticMessage:
103+
def __init__(self, response):
104+
self.id = response['id'] - 16
105+
self.mode = response['mode']
106+
self.bus = response['bus']
107+
self.pid = response['pid']
108+
self.payload = '0x' + response['payload'][8:]
109+
110+
def addFrame(self, response):
111+
self.payload += response['payload'][8:]
112+
113+
def getResponse(self):
114+
request = {
115+
'timestamp': 0,
116+
'bus': self.bus,
117+
'id': self.id,
118+
'mode': self.mode,
119+
'success': True,
120+
'pid': self.pid,
121+
'payload': self.payload
122+
}
123+
return request
91124

92125
class CommandResponseReceiver(ResponseReceiver):
93126
"""A receiver that matches the 'command' field in responses to the
@@ -104,7 +137,7 @@ class DiagnosticResponseReceiver(ResponseReceiver):
104137
"""A receiver that matches the bus, ID, mode and PID from a
105138
diagnostic request to an incoming response.
106139
"""
107-
140+
108141
def __init__(self, queue, request):
109142
super(DiagnosticResponseReceiver, self).__init__(queue, request,
110143
quit_after_first=False)
@@ -135,7 +168,16 @@ def _response_matches_request(self, response):
135168
return False
136169

137170
return response.get('mode', None) == self.diagnostic_request['mode']
138-
171+
172+
def _response_is_multiframe(self, response):
173+
if 'frame' in response:
174+
return True
175+
return False
176+
177+
def _return_final(self, response):
178+
if response['frame'] == -1:
179+
return True
180+
return False
139181

140182
class Controller(object):
141183
"""A Controller is a physical vehicle interface that accepts commands to be
@@ -175,17 +217,17 @@ def complex_request(self, request, wait_for_first_response=True):
175217
if wait_for_first_response:
176218
responses = receiver.wait_for_responses()
177219
return responses
178-
220+
179221
def _send_complex_request(self, request):
180222
self.write_bytes(self.streamer.serialize_for_stream(request))
181223

182224
@classmethod
183-
def _build_diagnostic_request(cls, message_id, mode, bus=None, pid=None,
225+
def _build_diagnostic_request(cls, id, mode, bus=None, pid=None,
184226
frequency=None, payload=None, decoded_type=None):
185227
request = {
186228
'command': "diagnostic_request",
187229
'request': {
188-
'id': message_id,
230+
'id': id,
189231
'mode': mode
190232
}
191233
}
@@ -205,19 +247,19 @@ def _build_diagnostic_request(cls, message_id, mode, bus=None, pid=None,
205247

206248
return request
207249

208-
def delete_diagnostic_request(self, message_id, mode, bus=None, pid=None):
209-
request = self._build_diagnostic_request(message_id, mode, bus, pid)
250+
def delete_diagnostic_request(self, id, mode, bus=None, pid=None):
251+
request = self._build_diagnostic_request(id, mode, bus, pid)
210252
request['action'] = 'cancel'
211253
return self._check_command_response_status(request)
212254

213-
def create_diagnostic_request(self, message_id, mode, bus=None, pid=None,
255+
def create_diagnostic_request(self, id, mode, bus=None, pid=None,
214256
frequency=None, payload=None, wait_for_ack=True,
215257
wait_for_first_response=False, decoded_type=None):
216258
"""Send a new diagnostic message request to the VI
217259
218260
Required:
219261
220-
message_id - The message ID (arbitration ID) for the request.
262+
id - The message ID (arbitration ID) for the request.
221263
mode - the diagnostic mode (or service).
222264
223265
Optional:
@@ -245,7 +287,7 @@ def create_diagnostic_request(self, message_id, mode, bus=None, pid=None,
245287
246288
"""
247289

248-
request = self._build_diagnostic_request(message_id, mode, bus, pid,
290+
request = self._build_diagnostic_request(id, mode, bus, pid,
249291
frequency, payload, decoded_type)
250292

251293
diag_response_receiver = None
@@ -411,15 +453,15 @@ def write_translated(self, name, value, event=None):
411453
assert bytes_written == len(message)
412454
return bytes_written
413455

414-
def write_raw(self, message_id, data, bus=None, frame_format=None):
456+
def write_raw(self, id, data, bus=None, frame_format=None):
415457
"""Send a raw write request to the VI.
416458
"""
417-
if not isinstance(message_id, numbers.Number):
459+
if not isinstance(id, numbers.Number):
418460
try:
419-
message_id = int(message_id, 0)
461+
id = int(id, 0)
420462
except ValueError:
421463
raise ValueError("ID must be numerical")
422-
data = {'id': message_id, 'data': data}
464+
data = {'id': id, 'data': data}
423465
if bus is not None:
424466
data['bus'] = bus
425467
if frame_format is not None:

openxc/controllers/usb.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ def _send_complex_request(self, request):
3333
"""Send a request via the USB control request endpoint, rather than as a
3434
bulk transfer.
3535
"""
36+
# LOG.warn("DEBUG STUFF ________________ " + str(self.streamer.serialize_for_stream(request)))
3637
self.device.ctrl_transfer(0x40, self.COMPLEX_CONTROL_COMMAND, 0, 0,
3738
self.streamer.serialize_for_stream(request))
3839

0 commit comments

Comments
 (0)