Skip to content

Commit

Permalink
Merge pull request #166 from openxc/next
Browse files Browse the repository at this point in the history
Next into master for 2.2.0 Python release and 8.2.0 vi-firmware release
  • Loading branch information
GenoJAFord authored Aug 11, 2021
2 parents 31655a9 + 08f7647 commit 5341180
Show file tree
Hide file tree
Showing 17 changed files with 665 additions and 445 deletions.
31 changes: 31 additions & 0 deletions .github/workflows/python-publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# This workflow will upload a Python Package using Twine when a release is created
# For more information see: https://help.github.com/en/actions/language-and-framework-guides/using-python-with-github-actions#publishing-to-package-registries

name: Upload Python Package

on:
release:
types: [created]

jobs:
deploy:

runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: '3.x'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install setuptools wheel twine
- name: Build and publish
env:
TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }}
TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }}
run: |
python setup.py sdist bdist_wheel
twine upload dist/*
33 changes: 33 additions & 0 deletions .github/workflows/python-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# This workflow will install Python dependencies, run tests and lint with a variety of Python versions
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions

name: Test Open XC Pyton

on: [ pull_request ]

jobs:
build:

runs-on: ubuntu-latest
strategy:
matrix:
python-version: [3.6.7]

steps:
- uses: actions/checkout@v2
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install python-bluetooth -qq -y
python -m pip install --upgrade pip
python -m pip install pytest pyserial==3.1.1 coveralls
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
- name: Test
run: |
python setup.py test
20 changes: 0 additions & 20 deletions .travis.yml

This file was deleted.

10 changes: 10 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
OpenXC Python Library Changelog
===============================

v2.2.0
----------
* Improvements to usb traffic handling
* Updated message format based upton the protobuf file
* Improved memory management for protobuf
* SonarQube updates
* Github actions updated,travis decommissioned
* Support for the new get_vin command
openxc-control get_vin

v2.1.0
----------
* SonarQube integration
Expand Down
8 changes: 5 additions & 3 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ OpenXC for Python

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

:Version: 2.1.0
:Version: 2.2.0
:Web: http://openxcplatform.com
:Download: http://pypi.python.org/pypi/openxc/
:Documentation: http://python.openxcplatform.com
:Source: http://github.com/openxc/openxc-python/
:Keywords: vehicle, openxc, python

.. image:: https://travis-ci.org/openxc/openxc-python.svg?branch=master
:target: https://travis-ci.org/openxc/openxc-python
.. image:: https://github.com/openxc/openxc-python/workflows/Test%20Open%20XC%20Pyton/badge.svg
:target: https://github.com/openxc/openxc-python/actions?query=workflow%3A%22Test+Open+XC+Pyton%22

.. image:: https://coveralls.io/repos/openxc/openxc-python/badge.png?branch=master
:target: https://coveralls.io/r/openxc/openxc-python?branch=master
Expand All @@ -30,6 +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.

If you are getting the error "ValueError: No backend available" on windows please reinstall your libusb0 driver using https://github.com/openxc/vi-windows-driver if you are in a envirment where you can not use an unsigned driver please use https://zadig.akeo.ie/

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.

Expand Down
2 changes: 1 addition & 1 deletion docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ OpenXC for Python

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

:Version: 2.1.0
:Version: 2.2.0
:Web: http://openxcplatform.com
:Download: http://pypi.python.org/pypi/openxc/
:Documentation: http://python.openxcplatform.com
Expand Down
25 changes: 18 additions & 7 deletions openxc/controllers/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,14 +83,16 @@ 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 type(self) == DiagnosticResponseReceiver and self._response_is_multiframe(response):
if response['id'] in self.diag_dict:
self.diag_dict[response['id']].addFrame(response)
else:
self.diag_dict[response['id']] = MultiframeDiagnosticMessage(response)
if self._return_final(response):
self.responses.append(self.diag_dict[response['id']].getResponse())
save = self.responses.pop()
dentry = self.diag_dict[response['id']].getResponse() # DO NOT REMOVE This MUST be saved to a local variable to prevent deallocation
self.responses.append(dentry) # DO NOT REMOVE This MUST be saved to a local variable to prevent deallocation
self.responses.append(save)
self.diag_dict.pop(response['id'])
self.responses.append(response)
if self.quit_after_first:
Expand All @@ -101,14 +103,14 @@ def handle_responses(self):

class MultiframeDiagnosticMessage:
def __init__(self, response):
self.id = response['id'] - 16
self.id = response['id']
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:]
self.payload += response['payload'][2:]

def getResponse(self):
request = {
Expand Down Expand Up @@ -170,8 +172,9 @@ def _response_matches_request(self, response):
return response.get('mode', None) == self.diagnostic_request['mode']

def _response_is_multiframe(self, response):
if 'frame' in response:
return True
print(response)
if 'total_size' in response.keys() and response["total_size"] > 0:
return True
return False

def _return_final(self, response):
Expand Down Expand Up @@ -427,6 +430,14 @@ def device_id(self):
}
return self._check_command_response_message(request)

def get_vin(self):
"""Request vehicle VIN
"""
request = {
"command": "get_vin"
}
return self._check_command_response_message(request)

def write(self, **kwargs):
"""Serialize a raw or translated write request and send it to the VI,
following the OpenXC message format.
Expand Down
2 changes: 0 additions & 2 deletions openxc/formats/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ class VehicleMessageStreamer(object):
bytes_received = 0

def receive(self, payload):
if not isinstance(payload, bytes):
payload = payload.encode("utf-8")
if len(payload) > 0:
self.message_buffer += payload
self.bytes_received += len(payload)
95 changes: 47 additions & 48 deletions openxc/formats/binary.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,8 @@ def _handle_diagnostic_cc_message(cls, data, message):
request_command.action = openxc_pb2.DiagnosticControlCommand.CANCEL
request = request_command.request
request_data = data['request']
request.bus = request_data['bus']
if 'bus' in request_data:
request.bus = request_data['bus']
request.message_id = request_data['id']
request.mode = request_data['mode']
if 'frequency' in request_data:
Expand Down Expand Up @@ -184,6 +185,10 @@ def _build_diagnostic_message(cls, data, message):
response.bus = data['bus']
response.message_id = data['id']
response.mode = data['mode']
if 'total_size' in data:
response.total_size = data['total_size']
if 'frame' in data:
response.frame = data['frame']
if 'pid' in data:
response.pid = data['pid']
if 'success' in data:
Expand Down Expand Up @@ -243,63 +248,57 @@ def _dict_to_protobuf(cls, data):
@classmethod
def _build_can_parsed_message(cls, message, parsed_message):
can_message = message.can_message
if can_message.HasField('bus'):
if can_message.bus != 0:
parsed_message['bus'] = can_message.bus
if can_message.HasField('id'):
if can_message.id != 0:
parsed_message['id'] = can_message.id
if can_message.HasField('data'):
if len(binascii.hexlify(can_message.data).decode("ascii")) > 0:
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"
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'):
if diagnostic_message.bus != 0:
parsed_message['bus'] = diagnostic_message.bus
if diagnostic_message.HasField('message_id'):
if diagnostic_message.message_id != 0:
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['mode'] = diagnostic_message.mode
parsed_message['pid'] = diagnostic_message.pid
if diagnostic_message.total_size != 0:
parsed_message['total_size'] = diagnostic_message.total_size
parsed_message['frame'] = diagnostic_message.frame
parsed_message['success'] = diagnostic_message.success
if diagnostic_message.value.type != openxc_pb2.DynamicField.UNUSED: ##GJA
parsed_message['value'] = diagnostic_message.value
if diagnostic_message.HasField('negative_response_code'):
if diagnostic_message.negative_response_code !=0:
parsed_message['negative_response_code'] = diagnostic_message.negative_response_code
if diagnostic_message.HasField('payload'):
if len(binascii.hexlify(diagnostic_message.payload).decode("ascii")) > 0:
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
event = simple_message.event
if (len(event.string_value) > 0):
parsed_message['event'] = event.string_value
elif event.numeric_value != 0:
parsed_message['event'] = event.numeric_value
else:
parsed_message = None
parsed_message['event'] = event.boolean_value

value = simple_message.value
if (len(value.string_value) > 0):
parsed_message['value'] = value.string_value
elif value.numeric_value != 0:
parsed_message['value'] = value.numeric_value
else:
parsed_message['value'] = value.boolean_value


@classmethod
def _handle_diagnostic_cc_parsed_message(cls, command, parsed_message):
Expand All @@ -316,16 +315,16 @@ def _handle_diagnostic_cc_parsed_message(cls, command, parsed_message):
parsed_message['request']['bus'] = request.bus
parsed_message['request']['mode'] = request.mode

if request.HasField('frequency'):
if request.frequency != 0:
parsed_message['request']['frequency'] = request.frequency
if request.HasField('name'):
if len(request.name) > 0:
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']['multiple_responses'] = request.multiple_responses
if request.pid != 0:
parsed_message['request']['pid'] = request.pid
if request.HasField('payload'):
if len(binascii.hexlify(request.payload).decode("ascii")) > 0:
parsed_message['request']['payload'] = "0x%s" % binascii.hexlify(request.payload).decode("ascii")
print("Finished _handle_diagnostic_cc_parsed_message")

@classmethod
def _handle_passthrough_cc_parsed_message(cls, command, parsed_message):
Expand Down Expand Up @@ -393,14 +392,14 @@ def _build_command_response_parsed_message(cls, message, parsed_message):
raise UnrecognizedBinaryCommandError(response.type)

parsed_message['status'] = response.status
if response.HasField('message'):
if len(response.message) > 0:
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'):
if message.type == message.CAN:
cls._build_can_parsed_message(message, parsed_message)
elif message.type == message.DIAGNOSTIC:
cls._build_diagnostic_parsed_message(message, parsed_message)
Expand Down
Loading

0 comments on commit 5341180

Please sign in to comment.