From a61b3de3b3dd689fc9478954c4ccc14d70dbd215 Mon Sep 17 00:00:00 2001 From: Roman Nyukhalov Date: Thu, 14 Apr 2022 19:04:15 +1000 Subject: [PATCH 01/22] Define CI pipeline using Github Actions --- .github/workflows/ci.yml | 28 ++++++++++++++++++++++++++++ .travis.yml | 29 ----------------------------- tox.ini | 9 ++++++++- 3 files changed, 36 insertions(+), 30 deletions(-) create mode 100644 .github/workflows/ci.yml delete mode 100644 .travis.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000..e9e764ca --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,28 @@ +name: CI Pipeline + +on: + push: + branches: 'master' + pull_request: + branches: '*' + +jobs: + build: + runs-on: ubuntu-18.04 + strategy: + max-parallel: 4 + fail-fast: false + matrix: + python-version: ['3.5', '3.6', '3.7', '3.8'] + steps: + - uses: actions/checkout@v1 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + - name: Install dependencies + run: | + python -m pip install --upgrade pip + python -m pip install tox tox-gh-actions + - name: Test with tox + run: tox \ No newline at end of file diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 57c84096..00000000 --- a/.travis.yml +++ /dev/null @@ -1,29 +0,0 @@ -language: python -dist: xenial -sudo: false - -install: - - pip install tox - -matrix: - include: - - python: '3.6' - env: TOXENV=check36 - - python: '3.8' - env: TOXENV=check38 - - python: '3.4' - env: TOXENV=py34 - - python: '3.5' - env: TOXENV=py35 - - python: '3.6' - env: TOXENV=py36 - - python: '3.7' - env: TOXENV=py37 - - python: '3.8' - env: TOXENV=py38 - -script: - - tox - -cache: - pip: true diff --git a/tox.ini b/tox.ini index 2de0b4a1..ab6217bb 100644 --- a/tox.ini +++ b/tox.ini @@ -1,9 +1,16 @@ [tox] envlist = check{36,38}, - py{34,35,36,37,38}, + py{35,36,37,38}, coverage +[gh-actions] +python = + 3.5: py35 + 3.6: py36 + 3.7: py37 + 3.8: py38 + [testenv] usedevelop = true setenv = From a08424da2f61f64a123cf9dbabe351bd90348d94 Mon Sep 17 00:00:00 2001 From: Roman Nyukhalov Date: Wed, 27 Apr 2022 19:42:05 +1000 Subject: [PATCH 02/22] Fix test_populate_ecu_map test --- tests/test_protocol.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_protocol.py b/tests/test_protocol.py index b2757276..0c6ccc75 100644 --- a/tests/test_protocol.py +++ b/tests/test_protocol.py @@ -74,4 +74,4 @@ def test_populate_ecu_map(): # if no messages were received, then the map is empty p = SAE_J1850_PWM([]) - assert len(p.ecu_map) == 0 + assert p.ecu_map[p.TX_ID_ENGINE] == ECU.ENGINE From dbfd379d0b5f5b65dec9d96986e8c045dd4e8f59 Mon Sep 17 00:00:00 2001 From: Adam Novak Date: Fri, 20 May 2022 09:51:12 -0400 Subject: [PATCH 03/22] Only treat "OK" as a response terminator when appropriate Right now __read() will stop reading at "OK" even if a ">" is still coming. This can cause the ">" to be seen as the response to the next command, which confuses the initialization sequence, since the initialization sequence expects a very specific set of responses to its commands. This changes __read() so that by default it only treats ">" as the response terminator. When we issue the "ATLP" command to enter low-power mode, we will use "OK" as the response terminator instead, since that's the only time we don't expect to see a prompt. This should fix #226 and should also fix #227. --- obd/elm327.py | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/obd/elm327.py b/obd/elm327.py index db11355c..b543effc 100644 --- a/obd/elm327.py +++ b/obd/elm327.py @@ -55,7 +55,9 @@ class ELM327: ecus() """ + # chevron (ELM prompt character) ELM_PROMPT = b'>' + # an 'OK' which indicates we are entering low power state ELM_LP_ACTIVE = b'OK' _SUPPORTED_PROTOCOLS = { @@ -391,7 +393,7 @@ def low_power(self): logger.info("cannot enter low power when unconnected") return None - lines = self.__send(b"ATLP", delay=1) + lines = self.__send(b"ATLP", delay=1, end_marker=self.ELM_LP_ACTIVE) if 'OK' in lines: logger.debug("Successfully entered low power mode") @@ -466,13 +468,14 @@ def send_and_parse(self, cmd): messages = self.__protocol(lines) return messages - def __send(self, cmd, delay=None): + def __send(self, cmd, delay=None, end_marker=ELM_PROMPT): """ unprotected send() function will __write() the given string, no questions asked. returns result of __read() (a list of line strings) - after an optional delay. + after an optional delay, until the end marker (by + default, the prompt) is seen """ self.__write(cmd) @@ -482,13 +485,13 @@ def __send(self, cmd, delay=None): time.sleep(delay) delayed += delay - r = self.__read() + r = self.__read(end_marker=end_marker) while delayed < 1.0 and len(r) <= 0: d = 0.1 logger.debug("no response; wait: %f seconds" % d) time.sleep(d) delayed += d - r = self.__read() + r = self.__read(end_marker=end_marker) return r def __write(self, cmd): @@ -512,11 +515,12 @@ def __write(self, cmd): else: logger.info("cannot perform __write() when unconnected") - def __read(self): + def __read(self, end_marker=ELM_PROMPT): """ "low-level" read function - accumulates characters until the prompt character is seen + accumulates characters until the end marker (by + default, the prompt character) is seen returns a list of [/r/n] delimited strings """ if not self.__port: @@ -543,9 +547,8 @@ def __read(self): buffer.extend(data) - # end on chevron (ELM prompt character) or an 'OK' which - # indicates we are entering low power state - if self.ELM_PROMPT in buffer or self.ELM_LP_ACTIVE in buffer: + # end on specified end-marker sequence + if end_marker in buffer: break # log, and remove the "bytearray( ... )" part From d64064d64a1fa05393d9055c92065333b91bfd58 Mon Sep 17 00:00:00 2001 From: Roman Niukhalov Date: Mon, 11 Apr 2022 19:08:09 +0800 Subject: [PATCH 04/22] Update pint version to 0.19.* --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 17a9c7e8..2e542b81 100644 --- a/setup.py +++ b/setup.py @@ -30,5 +30,5 @@ packages=find_packages(), include_package_data=True, zip_safe=False, - install_requires=["pyserial==3.*", "pint==0.7.*"], + install_requires=["pyserial==3.*", "pint==0.19.*"], ) From c7be924a21c5d0be87cce51e3087e8fb21a0ecf2 Mon Sep 17 00:00:00 2001 From: Roman Niukhalov Date: Fri, 3 Jun 2022 09:12:14 +1000 Subject: [PATCH 05/22] Update the python version range to 3.8-3.10 --- .github/workflows/ci.yml | 4 ++-- tox.ini | 17 +++++------------ 2 files changed, 7 insertions(+), 14 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e9e764ca..0bc5b768 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,7 +13,7 @@ jobs: max-parallel: 4 fail-fast: false matrix: - python-version: ['3.5', '3.6', '3.7', '3.8'] + python-version: ['3.8', '3.9', '3.10'] steps: - uses: actions/checkout@v1 - name: Set up Python ${{ matrix.python-version }} @@ -25,4 +25,4 @@ jobs: python -m pip install --upgrade pip python -m pip install tox tox-gh-actions - name: Test with tox - run: tox \ No newline at end of file + run: tox diff --git a/tox.ini b/tox.ini index ab6217bb..ffee2943 100644 --- a/tox.ini +++ b/tox.ini @@ -1,15 +1,13 @@ [tox] envlist = - check{36,38}, - py{35,36,37,38}, + py{38,39,310}, coverage [gh-actions] python = - 3.5: py35 - 3.6: py36 - 3.7: py37 3.8: py38 + 3.9: py39 + 3.10: py310 [testenv] usedevelop = true @@ -17,19 +15,14 @@ setenv = COVERAGE_FILE={toxinidir}/.coverage_{envname} deps = pdbpp==0.9.6 - pytest==3.10.1 - pytest-cov==2.6.1 + pytest==7.1.2 + pytest-cov==3.0.0 whitelist_externals = rm commands = rm -vf {toxinidir}/.coverage_{envname} pytest --cov-report= --cov=obd {posargs} -[testenv:check36] -basepython = python3.6 -skipsdist = true - - [testenv:coverage] skipsdist = true deps = From c55a7a98f29c427365a35491bee328762bf38a9b Mon Sep 17 00:00:00 2001 From: Alistair Francis Date: Tue, 24 Jan 2023 22:28:43 +1000 Subject: [PATCH 06/22] tox.ini: Bump the python and pypi versions Signed-off-by: Alistair Francis --- tox.ini | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/tox.ini b/tox.ini index ffee2943..20476082 100644 --- a/tox.ini +++ b/tox.ini @@ -1,6 +1,6 @@ [tox] envlist = - py{38,39,310}, + py{38,39,310,311}, coverage [gh-actions] @@ -8,19 +8,17 @@ python = 3.8: py38 3.9: py39 3.10: py310 + 3.11: py311 [testenv] usedevelop = true setenv = COVERAGE_FILE={toxinidir}/.coverage_{envname} deps = - pdbpp==0.9.6 - pytest==7.1.2 - pytest-cov==3.0.0 -whitelist_externals = - rm + pdbpp==0.10.3 + pytest==7.2.1 + pytest-cov==4.0.0 commands = - rm -vf {toxinidir}/.coverage_{envname} pytest --cov-report= --cov=obd {posargs} [testenv:coverage] @@ -29,7 +27,6 @@ deps = coverage whitelist_externals = /bin/bash - rm commands = /bin/bash -c 'coverage combine {toxinidir}/.coverage_*' coverage html -i @@ -38,7 +35,6 @@ commands = [flake8] max-line-length = 120 - [coverage:run] omit = .tox/* From 7642ad61da237a79b8fc43bdf39debcdfbde330c Mon Sep 17 00:00:00 2001 From: Alistair Francis Date: Tue, 24 Jan 2023 22:33:41 +1000 Subject: [PATCH 07/22] setup.py: Bump pint version Signed-off-by: Alistair Francis --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 2e542b81..c0936440 100644 --- a/setup.py +++ b/setup.py @@ -30,5 +30,5 @@ packages=find_packages(), include_package_data=True, zip_safe=False, - install_requires=["pyserial==3.*", "pint==0.19.*"], + install_requires=["pyserial==3.*", "pint==0.20.*"], ) From e952b9172d43c21f5507b08220ec04408ec95a9f Mon Sep 17 00:00:00 2001 From: Mario Niedermeyer <61496163+Mario2407@users.noreply.github.com> Date: Tue, 7 Mar 2023 12:45:49 +0100 Subject: [PATCH 08/22] Fixed printing with brackets --- docs/Async Connections.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Async Connections.md b/docs/Async Connections.md index b4074be1..8250ab04 100644 --- a/docs/Async Connections.md +++ b/docs/Async Connections.md @@ -32,7 +32,7 @@ connection = obd.Async() # a callback that prints every new value to the console def new_rpm(r): - print r.value + print (r.value) connection.watch(obd.commands.RPM, callback=new_rpm) connection.start() From d95554a0f970647b56c4f0563698c087a5866db4 Mon Sep 17 00:00:00 2001 From: Brendan Whitfield Date: Sun, 9 Jul 2023 20:08:02 -0700 Subject: [PATCH 09/22] bumped to v0.7.2 --- obd/__version__.py | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/obd/__version__.py b/obd/__version__.py index f0788a87..fb9b668f 100644 --- a/obd/__version__.py +++ b/obd/__version__.py @@ -1 +1 @@ -__version__ = '0.7.1' +__version__ = '0.7.2' diff --git a/setup.py b/setup.py index c0936440..a5e30300 100644 --- a/setup.py +++ b/setup.py @@ -8,7 +8,7 @@ setup( name="obd", - version="0.7.1", + version="0.7.2", description=("Serial module for handling live sensor data from a vehicle's OBD-II port"), long_description=long_description, long_description_content_type="text/markdown", From 7d5cd0559f1ecedf4107484aa66107bc7bbde32a Mon Sep 17 00:00:00 2001 From: green-green-avk <45503261+green-green-avk@users.noreply.github.com> Date: Sun, 9 Jul 2023 15:28:38 -0700 Subject: [PATCH 10/22] Proper `obd.Unit.percent` --- obd/UnitsAndScaling.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/obd/UnitsAndScaling.py b/obd/UnitsAndScaling.py index b49650b1..fe0fae4d 100644 --- a/obd/UnitsAndScaling.py +++ b/obd/UnitsAndScaling.py @@ -36,8 +36,8 @@ # export the unit registry Unit = pint.UnitRegistry() -Unit.define("percent = [] = %") Unit.define("ratio = []") +Unit.define("percent = 1e-2 ratio = %") Unit.define("gps = gram / second = GPS = grams_per_second") Unit.define("lph = liter / hour = LPH = liters_per_hour") Unit.define("ppm = count / 1000000 = PPM = parts_per_million") From eb8679eb9a9e7b744a17acfee3cf38a1c80516aa Mon Sep 17 00:00:00 2001 From: Brendan Whitfield Date: Sun, 13 Aug 2023 18:43:43 -0700 Subject: [PATCH 11/22] Added readthedocs yaml config file before config files are enforced --- .readthedocs.yaml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .readthedocs.yaml diff --git a/.readthedocs.yaml b/.readthedocs.yaml new file mode 100644 index 00000000..ae5ae2ee --- /dev/null +++ b/.readthedocs.yaml @@ -0,0 +1,5 @@ +version: 2 + +mkdocs: + configuration: mkdocs.yml + fail_on_warning: false From 3ecbf6fd19d91690e3ae32162c0b58ec9667396b Mon Sep 17 00:00:00 2001 From: Brendan Whitfield Date: Sun, 13 Aug 2023 18:51:07 -0700 Subject: [PATCH 12/22] Fixed mkdocs pages -> nav config --- mkdocs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mkdocs.yml b/mkdocs.yml index bec2ac65..ad9086bb 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -3,7 +3,7 @@ repo_url: https://github.com/brendan-w/python-OBD repo_name: GitHub extra_javascript: - assets/extra.js -pages: +nav: - 'Getting Started': 'index.md' - 'OBD Connections': 'Connections.md' - 'Command Lookup': 'Command Lookup.md' From d7aad00c270598cf464741bd100c71f54bc52c63 Mon Sep 17 00:00:00 2001 From: Brendan Whitfield Date: Sun, 13 Aug 2023 18:56:18 -0700 Subject: [PATCH 13/22] Revert docs updates: This is more finicky than I anticipated Moving to a feature branch This reverts commit 3ecbf6fd19d91690e3ae32162c0b58ec9667396b. This reverts commit eb8679eb9a9e7b744a17acfee3cf38a1c80516aa. --- .readthedocs.yaml | 5 ----- mkdocs.yml | 2 +- 2 files changed, 1 insertion(+), 6 deletions(-) delete mode 100644 .readthedocs.yaml diff --git a/.readthedocs.yaml b/.readthedocs.yaml deleted file mode 100644 index ae5ae2ee..00000000 --- a/.readthedocs.yaml +++ /dev/null @@ -1,5 +0,0 @@ -version: 2 - -mkdocs: - configuration: mkdocs.yml - fail_on_warning: false diff --git a/mkdocs.yml b/mkdocs.yml index ad9086bb..bec2ac65 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -3,7 +3,7 @@ repo_url: https://github.com/brendan-w/python-OBD repo_name: GitHub extra_javascript: - assets/extra.js -nav: +pages: - 'Getting Started': 'index.md' - 'OBD Connections': 'Connections.md' - 'Command Lookup': 'Command Lookup.md' From d7c781a595e10316084454b16adccff6ee183935 Mon Sep 17 00:00:00 2001 From: Brendan Whitfield Date: Sun, 13 Aug 2023 18:43:43 -0700 Subject: [PATCH 14/22] Added readthedocs yaml config file before config files are enforced Also fixed some of the doc headers for more modern versions of mkdocs --- .readthedocs.yaml | 14 ++++++++++++++ docs/Async Connections.md | 2 ++ docs/Command Lookup.md | 2 ++ docs/Command Tables.md | 18 ++++++++++-------- docs/Connections.md | 1 + docs/Custom Commands.md | 12 ++++++------ docs/Debug.md | 2 ++ docs/Responses.md | 18 ++++++++++-------- docs/Troubleshooting.md | 5 ++--- docs/index.md | 8 ++++---- docs/requirements.txt | 1 + mkdocs.yml | 2 +- 12 files changed, 55 insertions(+), 30 deletions(-) create mode 100644 .readthedocs.yaml create mode 100644 docs/requirements.txt diff --git a/.readthedocs.yaml b/.readthedocs.yaml new file mode 100644 index 00000000..9c6dea9a --- /dev/null +++ b/.readthedocs.yaml @@ -0,0 +1,14 @@ +version: 2 + +build: + os: ubuntu-22.04 + tools: + python: "3.11" + +python: + install: + - requirements: docs/requirements.txt + +mkdocs: + configuration: mkdocs.yml + fail_on_warning: false diff --git a/docs/Async Connections.md b/docs/Async Connections.md index 8250ab04..d655faff 100644 --- a/docs/Async Connections.md +++ b/docs/Async Connections.md @@ -1,3 +1,5 @@ +# Async Connections + Since the standard `query()` function is blocking, it can be a hazard for UI event loops. To deal with this, python-OBD has an `Async` connection object that can be used in place of the standard `OBD` object. `Async` is a subclass of `OBD`, and therefore inherits all of the standard methods. However, `Async` adds a few in order to control a threaded update loop. This loop will keep the values of your commands up to date with the vehicle. This way, when the user `query`s the car, the latest response is returned immediately. The update loop is controlled by calling `start()` and `stop()`. To subscribe a command for updating, call `watch()` with your requested OBDCommand. Because the update loop is threaded, commands can only be `watch`ed while the loop is `stop`ed. diff --git a/docs/Command Lookup.md b/docs/Command Lookup.md index 43e9ace7..1610657d 100644 --- a/docs/Command Lookup.md +++ b/docs/Command Lookup.md @@ -1,3 +1,5 @@ +# Command Lookup + `OBDCommand`s are objects used to query information from the vehicle. They contain all of the information neccessary to perform the query, and decode the cars response. Python-OBD has [built in tables](Command Tables.md) for the most common commands. They can be looked up by name, or by mode & PID. ```python diff --git a/docs/Command Tables.md b/docs/Command Tables.md index 9b8d6e45..aebaf85d 100644 --- a/docs/Command Tables.md +++ b/docs/Command Tables.md @@ -1,4 +1,6 @@ -# OBD-II adapter (ELM327 commands) +# Commands + +## OBD-II adapter (ELM327 commands) |PID | Name | Description | Response Value | |-----|-------------|-----------------------------------------|-----------------------| @@ -7,7 +9,7 @@
-# Mode 01 +## Mode 01 |PID | Name | Description | Response Value | |----|---------------------------|-----------------------------------------|-----------------------| @@ -110,7 +112,7 @@
-# Mode 02 +## Mode 02 Mode 02 commands are the same as mode 01, but are metrics from when the last DTC occurred (the freeze frame). To access them by name, simple prepend `DTC_` to the Mode 01 command name. @@ -124,7 +126,7 @@ obd.commands.DTC_RPM # the Mode 02 command
-# Mode 03 +## Mode 03 Mode 03 contains a single command `GET_DTC` which requests all diagnostic trouble codes from the vehicle. The response will contain the codes themselves, as well as a description (if python-OBD has one). See the [DTC Responses](Responses.md#diagnostic-trouble-codes-dtcs) section for more details. @@ -135,7 +137,7 @@ Mode 03 contains a single command `GET_DTC` which requests all diagnostic troubl
-# Mode 04 +## Mode 04 |PID | Name | Description | Response Value | |-----|-----------|-----------------------------------------|-----------------------| @@ -143,7 +145,7 @@ Mode 03 contains a single command `GET_DTC` which requests all diagnostic troubl
-# Mode 06 +## Mode 06 *WARNING: mode 06 is experimental. While it passes software tests, it has not been tested on a real vehicle. Any debug output for this mode would be greatly appreciated.* @@ -252,7 +254,7 @@ Mode 06 commands are used to monitor various test results from the vehicle. All
-# Mode 07 +## Mode 07 The return value will be encoded in the same structure as the Mode 03 `GET_DTC` command. @@ -262,7 +264,7 @@ The return value will be encoded in the same structure as the Mode 03 `GET_DTC`
-# Mode 09 +## Mode 09 *WARNING: mode 09 is experimental. While it has been tested on a hardware simulator, only a subset of the supported commands have (00-06) been tested. Any debug output for this mode, especially for the untested PIDs, would be greatly appreciated.* diff --git a/docs/Connections.md b/docs/Connections.md index fe314cdf..1df861fd 100644 --- a/docs/Connections.md +++ b/docs/Connections.md @@ -1,3 +1,4 @@ +# Connections After installing the library, simply `import obd`, and create a new OBD connection object. By default, python-OBD will scan for Bluetooth and USB serial ports (in that order), and will pick the first connection it finds. The port can also be specified manually by passing a connection string to the OBD constructor. You can also use the `scan_serial` helper retrieve a list of connected ports. diff --git a/docs/Custom Commands.md b/docs/Custom Commands.md index 466deb29..e726030d 100644 --- a/docs/Custom Commands.md +++ b/docs/Custom Commands.md @@ -1,3 +1,4 @@ +# Custom Commands If the command you need is not in python-OBDs tables, you can create a new `OBDCommand` object. The constructor accepts the following arguments (each will become a property). @@ -13,8 +14,7 @@ If the command you need is not in python-OBDs tables, you can create a new `OBDC | header (optional) | string | If set, use a custom header instead of the default one (7E0) | -Example -------- +## Example ```python from obd import OBDCommand, Unit @@ -58,7 +58,7 @@ Here are some details on the less intuitive fields of an OBDCommand: --- -### OBDCommand.decoder +## OBDCommand.decoder The `decoder` argument is a function of following form. @@ -83,7 +83,7 @@ def (messages): --- -### OBDCommand.ecu +## OBDCommand.ecu The `ecu` argument is a constant used to filter incoming messages. Some commands may listen to multiple ECUs (such as DTC decoders), where others may only be concerned with the engine (such as RPM). Currently, python-OBD can only distinguish the engine, but this list may be expanded over time: @@ -94,13 +94,13 @@ The `ecu` argument is a constant used to filter incoming messages. Some commands --- -### OBDCommand.fast +## OBDCommand.fast The optional `fast` argument tells python-OBD whether it is safe to append a `"01"` to the end of the command. This will instruct the adapter to return the first response it recieves, rather than waiting for more (and eventually reaching a timeout). This can speed up requests significantly, and is enabled for most of python-OBDs internal commands. However, for unusual commands, it is safest to leave this disabled. --- -### OBDCommand.header +## OBDCommand.header The optional `header` argument tells python-OBD to use a custom header when querying the command. If not set, python-OBD assumes that the default 7E0 header is needed for querying the command. The switch between default and custom header (and vice versa) is automatically done by python-OBD. diff --git a/docs/Debug.md b/docs/Debug.md index 0f929826..5e1df610 100644 --- a/docs/Debug.md +++ b/docs/Debug.md @@ -1,3 +1,5 @@ +# Debug + python-OBD uses python's builtin logging system. By default, it is setup to send output to `stderr` with a level of WARNING. The module's logger can be accessed via the `logger` variable at the root of the module. For instance, to enable console printing of all debug messages, use the following snippet: ```python diff --git a/docs/Responses.md b/docs/Responses.md index 30b992e6..0eef78f9 100644 --- a/docs/Responses.md +++ b/docs/Responses.md @@ -1,3 +1,5 @@ +# Responses + The `query()` function returns `OBDResponse` objects. These objects have the following properties: | Property | Description | @@ -11,7 +13,7 @@ The `query()` function returns `OBDResponse` objects. These objects have the fol --- -### is_null() +## is_null() Use this function to check if a response is empty. Python-OBD will emit empty responses when it is unable to retrieve data from the car. @@ -25,7 +27,7 @@ if not r.is_null(): --- -# Pint Values +## Pint Values The `value` property typically contains a [Pint](http://pint.readthedocs.io/en/latest/) `Quantity` object, but can also hold complex structures (depending on the request). Pint quantities combine a value and unit into a single class, and are used to represent physical values such as "4 seconds", and "88 mph". This allows for consistency when doing math and unit conversions. Pint maintains a registry of units, which is exposed in python-OBD as `obd.Unit`. @@ -71,7 +73,7 @@ import obd --- -# Status +## Status The status command returns information about the Malfunction Indicator Light (check-engine light), the number of trouble codes being thrown, and the type of engine. @@ -111,7 +113,7 @@ Here are all of the tests names that python-OBD reports: --- -# Diagnostic Trouble Codes (DTCs) +## Diagnostic Trouble Codes (DTCs) Each DTC is represented by a tuple containing the DTC code, and a description (if python-OBD has one). For commands that return multiple DTCs, a list is used. @@ -129,7 +131,7 @@ response.value = ("P0104", "Mass or Volume Air Flow Circuit Intermittent") --- -# Fuel Status +## Fuel Status The fuel status is a tuple of two strings, telling the status of the first and second fuel systems. Most cars only have one system, so the second element will likely be an empty string. The possible fuel statuses are: @@ -144,7 +146,7 @@ The fuel status is a tuple of two strings, telling the status of the first and s --- -# Air Status +## Air Status The air status will be one of these strings: @@ -157,7 +159,7 @@ The air status will be one of these strings: --- -# Oxygen Sensors Present +## Oxygen Sensors Present Returns a 2D structure of tuples (representing bank and sensor number), that holds boolean values for sensor presence. @@ -183,7 +185,7 @@ response.value[1][2] == True # Bank 1, Sensor 2 is present ``` --- -# Monitors (Mode 06 Responses) +## Monitors (Mode 06 Responses) All mode 06 commands return `Monitor` objects holding various test results for the requested sensor. A single monitor response can hold multiple tests, in the form of `MonitorTest` objects. The OBD standard defines some tests, but vehicles can always implement custom tests beyond the standard. Here are the standard Test IDs (TIDs) that python-OBD will recognize: diff --git a/docs/Troubleshooting.md b/docs/Troubleshooting.md index f2b9baca..7889e251 100644 --- a/docs/Troubleshooting.md +++ b/docs/Troubleshooting.md @@ -1,4 +1,3 @@ - # Debug Output If python-OBD is not working properly, the first thing you should do is enable debug output. Add the following line before your connection code to print all of the debug information to your console: @@ -52,7 +51,7 @@ Here are some common logs from python-OBD, and their meanings: ### Unresponsive ELM -``` +```none [obd] ========================== python-OBD (v0.4.0) ========================== [obd] Explicit port defined [obd] Opening serial port '/dev/pts/2' @@ -93,7 +92,7 @@ print ports # ['/dev/ttyUSB0', '/dev/ttyUSB1'] ### Unresponsive Vehicle -``` +```none [obd] ========================== python-OBD (v0.4.0) ========================== [obd] Explicit port defined [obd] Opening serial port '/dev/pts/2' diff --git a/docs/index.md b/docs/index.md index 7688edea..3d2c1e69 100644 --- a/docs/index.md +++ b/docs/index.md @@ -6,7 +6,7 @@ Python-OBD is a library for handling data from a car's [**O**n-**B**oard **D**ia
-# Installation +## Installation Install the latest release from pypi: @@ -22,7 +22,7 @@ $ sudo apt-get install bluetooth bluez-utils blueman
-# Basic Usage +## Basic Usage ```python import obd @@ -41,7 +41,7 @@ OBD connections operate in a request-reply fashion. To retrieve data from the ca
-# Module Layout +## Module Layout ```python import obd @@ -59,7 +59,7 @@ obd.logger # the OBD module's root logger (for debug)
-# License +## License GNU General Public License V2 diff --git a/docs/requirements.txt b/docs/requirements.txt new file mode 100644 index 00000000..49ec98c5 --- /dev/null +++ b/docs/requirements.txt @@ -0,0 +1 @@ +mkdocs==1.5.2 diff --git a/mkdocs.yml b/mkdocs.yml index bec2ac65..ad9086bb 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -3,7 +3,7 @@ repo_url: https://github.com/brendan-w/python-OBD repo_name: GitHub extra_javascript: - assets/extra.js -pages: +nav: - 'Getting Started': 'index.md' - 'OBD Connections': 'Connections.md' - 'Command Lookup': 'Command Lookup.md' From e0304c3209ac8eb3e75cf0ad5f7afdd6612d28e3 Mon Sep 17 00:00:00 2001 From: Ion Mironov <97184530+ion-mironov@users.noreply.github.com> Date: Tue, 20 Feb 2024 17:47:27 -0500 Subject: [PATCH 15/22] Several spelling and grammatical fixes. --- docs/Command Lookup.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Command Lookup.md b/docs/Command Lookup.md index 1610657d..f87ea39a 100644 --- a/docs/Command Lookup.md +++ b/docs/Command Lookup.md @@ -1,6 +1,6 @@ # Command Lookup -`OBDCommand`s are objects used to query information from the vehicle. They contain all of the information neccessary to perform the query, and decode the cars response. Python-OBD has [built in tables](Command Tables.md) for the most common commands. They can be looked up by name, or by mode & PID. +`OBDCommand`s are objects used to query information from the vehicle. They contain all of the information necessary to perform the query and decode the car's response. Python-OBD has [built in tables](Command Tables.md) for the most common commands. They can be looked up by name or by mode & PID. ```python import obd From 0c9abbc4ca9c2aa685e324b383400f47bcf11b34 Mon Sep 17 00:00:00 2001 From: Daniel Kahn Gillmor Date: Wed, 5 Feb 2025 22:07:37 -0500 Subject: [PATCH 16/22] Fix escaped serial port label string MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Without this fix, Python 3.13.1 yields this warning during "import odb": …/obd/utils.py:177: SyntaxWarning: invalid escape sequence '\C' I'm not a Windows expert, but the correct naming convention seems to be described here: https://support.microsoft.com/en-us/topic/howto-specify-serial-ports-larger-than-com9-db9078a5-b7b6-bf00-240f-f749ebfd913e --- obd/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/obd/utils.py b/obd/utils.py index 77cb36e2..221d3e9c 100644 --- a/obd/utils.py +++ b/obd/utils.py @@ -174,7 +174,7 @@ def scan_serial(): possible_ports += glob.glob("/dev/ttyUSB[0-9]*") elif sys.platform.startswith('win'): - possible_ports += ["\\.\COM%d" % i for i in range(256)] + possible_ports += [r"\\.\COM%d" % i for i in range(256)] elif sys.platform.startswith('darwin'): exclude = [ From a47d791de1884da167a4bb51f6c576dc07019a9a Mon Sep 17 00:00:00 2001 From: Ion Mironov <97184530+ion-mironov@users.noreply.github.com> Date: Tue, 20 Feb 2024 18:02:27 -0500 Subject: [PATCH 17/22] Included note mentioning which OBD it will work with. --- docs/index.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/docs/index.md b/docs/index.md index 3d2c1e69..890ffd1a 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,6 +1,8 @@ # Welcome -Python-OBD is a library for handling data from a car's [**O**n-**B**oard **D**iagnostics port](https://en.wikipedia.org/wiki/On-board_diagnostics) (OBD-II). It can stream real time sensor data, perform diagnostics (such as reading check-engine codes), and is fit for the Raspberry Pi. This library is designed to work with standard [ELM327 OBD-II adapters](http://www.amazon.com/s/ref=nb_sb_noss?field-keywords=elm327). +Python-OBD is a library for handling data from a car's [**O**n-**B**oard **D**iagnostics](https://en.wikipedia.org/wiki/On-board_diagnostics) port. Please keep in mind that the car **must** have OBD-II (any car made in 1996 and up); this will _**not**_ work with OBD-I. + +Python-OBD can stream real time sensor data, perform diagnostics (such as reading check-engine codes), and is fit for the Raspberry Pi. This library is designed to work with standard [ELM327 OBD-II adapters](http://www.amazon.com/s/ref=nb_sb_noss?field-keywords=elm327). *NOTE: Python-OBD is below 1.0.0, meaning the API may change between minor versions. Consult the [GitHub release page](https://github.com/brendan-w/python-OBD/releases) for changelogs before updating.* @@ -31,13 +33,13 @@ connection = obd.OBD() # auto-connects to USB or RF port cmd = obd.commands.SPEED # select an OBD command (sensor) -response = connection.query(cmd) # send the command, and parse the response +response = connection.query(cmd) # send the command and parse the response print(response.value) # returns unit-bearing values thanks to Pint print(response.value.to("mph")) # user-friendly unit conversions ``` -OBD connections operate in a request-reply fashion. To retrieve data from the car, you must send commands that query for the data you want (e.g. RPM, Vehicle speed, etc). In python-OBD, this is done with the `query()` function. The commands themselves are represented as objects, and can be looked up by name or value in `obd.commands`. The `query()` function will return a response object with parsed data in its `value` property. +OBD connections operate in a request-reply fashion. To retrieve data from the car, you must send commands that query for the data you want (e.g. RPM, Vehicle speed, etc). In python-OBD this is done with the `query()` function. The commands themselves are represented as objects and can be looked up by name or value in `obd.commands`. The `query()` function will return a response object with parsed data in its `value` property.
From 0c019019fddfae2435209fbf8b3d2c53483647a6 Mon Sep 17 00:00:00 2001 From: Brendan Whitfield Date: Sun, 6 Apr 2025 20:24:33 -0700 Subject: [PATCH 18/22] Uprev pint to 0.24.* for python 3.13+ support --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index a5e30300..ac3274c0 100644 --- a/setup.py +++ b/setup.py @@ -30,5 +30,5 @@ packages=find_packages(), include_package_data=True, zip_safe=False, - install_requires=["pyserial==3.*", "pint==0.20.*"], + install_requires=["pyserial==3.*", "pint==0.24.*"], ) From c30cfc3511122f7519582559805d2e87c677dba5 Mon Sep 17 00:00:00 2001 From: Brendan Whitfield Date: Sun, 6 Apr 2025 21:00:20 -0700 Subject: [PATCH 19/22] Uprev tox.ini to test python 3.13 Also corrected some of the package classifiers to indicate that this python library no longer supports python 2. It didn't even with the older 0.20.* Pint, though Pint itself now only supports python 3.9+ --- setup.py | 6 +++++- tox.ini | 5 +++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/setup.py b/setup.py index ac3274c0..f16a0232 100644 --- a/setup.py +++ b/setup.py @@ -16,8 +16,12 @@ "Operating System :: POSIX :: Linux", "License :: OSI Approved :: GNU General Public License v2 (GPLv2)", "Topic :: System :: Monitoring", - "Programming Language :: Python :: 2", "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", "Development Status :: 3 - Alpha", "Topic :: System :: Logging", "Intended Audience :: Developers", diff --git a/tox.ini b/tox.ini index 20476082..6fe55f43 100644 --- a/tox.ini +++ b/tox.ini @@ -1,14 +1,15 @@ [tox] envlist = - py{38,39,310,311}, + py{39,310,311,312,313}, coverage [gh-actions] python = - 3.8: py38 3.9: py39 3.10: py310 3.11: py311 + 3.12: py312 + 3.13: py313 [testenv] usedevelop = true From 630f0be2709d6ddba6c2a215d05f9b4024db4a21 Mon Sep 17 00:00:00 2001 From: Brendan Whitfield Date: Sun, 6 Apr 2025 21:20:42 -0700 Subject: [PATCH 20/22] setup.py -> pyproject.toml --- pyproject.toml | 36 ++++++++++++++++++++++++++++++++++++ setup.py | 38 -------------------------------------- 2 files changed, 36 insertions(+), 38 deletions(-) create mode 100644 pyproject.toml delete mode 100644 setup.py diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 00000000..2a89a0a7 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,36 @@ +[project] +name = "obd" +version = "0.7.2" +authors = [ + { name="Brendan Whitfield", email="me@brendan-w.com" }, + { name="Alistair Francis", email="alistair@alistair23.me" }, + { name="Paul Bartek" }, + { name="Peter Harris" }, +] +description = "Serial module for handling live sensor data from a vehicle's OBD-II port" +readme = "README.md" +requires-python = ">=3.9" +classifiers = [ + "Operating System :: POSIX :: Linux", + "Topic :: System :: Monitoring", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", + "Development Status :: 3 - Alpha", + "Topic :: System :: Logging", + "Intended Audience :: Developers", +] +keywords = ["obd", "obdii", "obd-ii", "obd2", "car", "serial", "vehicle", "diagnostic"] +dependencies = [ + "pyserial==3.*", + "pint==0.24.*", +] +license = "GPL-2.0-only" +license-files = ["LICENSE"] + +[project.urls] +Homepage = "https://github.com/brendan-w/python-OBD" +Issues = "https://github.com/brendan-w/python-OBD/issues" diff --git a/setup.py b/setup.py deleted file mode 100644 index f16a0232..00000000 --- a/setup.py +++ /dev/null @@ -1,38 +0,0 @@ -#!/bin/env python -# -*- coding: utf-8 -*- - -from setuptools import setup, find_packages - -with open("README.md", "r") as readme: - long_description = readme.read() - -setup( - name="obd", - version="0.7.2", - description=("Serial module for handling live sensor data from a vehicle's OBD-II port"), - long_description=long_description, - long_description_content_type="text/markdown", - classifiers=[ - "Operating System :: POSIX :: Linux", - "License :: OSI Approved :: GNU General Public License v2 (GPLv2)", - "Topic :: System :: Monitoring", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.11", - "Programming Language :: Python :: 3.12", - "Programming Language :: Python :: 3.13", - "Development Status :: 3 - Alpha", - "Topic :: System :: Logging", - "Intended Audience :: Developers", - ], - keywords="obd obdii obd-ii obd2 car serial vehicle diagnostic", - author="Brendan Whitfield", - author_email="brendanw@windworksdesign.com", - url="http://github.com/brendan-w/python-OBD", - license="GNU GPLv2", - packages=find_packages(), - include_package_data=True, - zip_safe=False, - install_requires=["pyserial==3.*", "pint==0.24.*"], -) From 3d1beba44f7202f1bd3c6dd7a2deaf3dcd21cee6 Mon Sep 17 00:00:00 2001 From: Brendan Whitfield Date: Sun, 6 Apr 2025 21:44:37 -0700 Subject: [PATCH 21/22] Updated the testing docs with modern build commands --- tests/README.md | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/tests/README.md b/tests/README.md index 2ecfa72e..5f9c4573 100644 --- a/tests/README.md +++ b/tests/README.md @@ -1,10 +1,34 @@ Testing ======= -To test python-OBD, you will need to `pip install pytest` and install the module (preferably in a virtualenv) by running `python setup.py install`. The end-to-end tests will also require [obdsim](http://icculus.org/obdgpslogger/obdsim.html) to be running in the background. When starting obdsim, note the "SimPort name" that it creates, and pass it as an argument to py.test. +To test python-OBD, you will need to install `pytest` and the `obd` module from your local tree (preferably in a virtualenv) by running: -To run all tests, run the following command: +```bash +pip install pytest +pip install build +python -m build +pip install ./dist/obd-0.7.2.tar.gz +``` - $ py.test --port=/dev/pts/ +To run all basic python-only unit tests, run: + +```bash +py.test +``` + +This directory also contains a set of end-to-end tests that require [obdsim](http://icculus.org/obdgpslogger/obdsim.html) to be running in the background. These tests are skipped by default, but can be activated by passing the `--port` flag. + +- Download `obdgpslogger`: https://icculus.org/obdgpslogger/downloads/obdgpslogger-0.16.tar.gz +- Run the following build commands: + ```bash + mkdir build + cd build + cmake .. + make obdsim + ``` +- Start `./bin/obdsim`, note the `SimPort name: /dev/pts/` that it creates. Pass this pseudoterminal path as an argument to py.test: + ```bash + py.test --port=/dev/pts/ + ``` For more information on pytest with virtualenvs, [read more here](https://pytest.org/dev/goodpractises.html) \ No newline at end of file From b53cbcbf9e6252461e276d73a7ff75adb714dc53 Mon Sep 17 00:00:00 2001 From: Brendan Whitfield Date: Sun, 6 Apr 2025 22:12:25 -0700 Subject: [PATCH 22/22] bumped to 0.7.3 --- obd/__version__.py | 2 +- pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/obd/__version__.py b/obd/__version__.py index fb9b668f..1ef13195 100644 --- a/obd/__version__.py +++ b/obd/__version__.py @@ -1 +1 @@ -__version__ = '0.7.2' +__version__ = '0.7.3' diff --git a/pyproject.toml b/pyproject.toml index 2a89a0a7..f91d6e3f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "obd" -version = "0.7.2" +version = "0.7.3" authors = [ { name="Brendan Whitfield", email="me@brendan-w.com" }, { name="Alistair Francis", email="alistair@alistair23.me" },