Skip to content

Commit a372044

Browse files
authored
Merge pull request brendan-w#125 from Ircama/headers
Add support of custom headers to OBDCommand
2 parents f9f14ee + fad0702 commit a372044

5 files changed

Lines changed: 36 additions & 5 deletions

File tree

docs/Custom Commands.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ If the command you need is not in python-OBDs tables, you can create a new `OBDC
1010
| decoder | callable | Function used for decoding messages from the OBD adapter |
1111
| ecu (optional) | ECU | ID of the ECU this command should listen to (`ECU.ALL` by default) |
1212
| fast (optional) | bool | Allows python-OBD to alter this command for efficieny (`False` by default) |
13+
| header (optional) | string | If set, use a custom header instead of the defalut one (7E0) |
1314

1415

1516
Example
@@ -95,7 +96,13 @@ The `ecu` argument is a constant used to filter incoming messages. Some commands
9596

9697
### OBDCommand.fast
9798

98-
The `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.
99+
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.
100+
101+
---
102+
103+
### OBDCommand.header
104+
105+
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.
99106

100107
---
101108

obd/OBDCommand.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
########################################################################
3232

3333
from .utils import *
34-
from .protocols import ECU
34+
from .protocols import ECU, ECU_HEADER
3535
from .OBDResponse import OBDResponse
3636

3737
import logging
@@ -47,14 +47,16 @@ def __init__(self,
4747
_bytes,
4848
decoder,
4949
ecu=ECU.ALL,
50-
fast=False):
50+
fast=False,
51+
header=ECU_HEADER.ENGINE):
5152
self.name = name # human readable name (also used as key in commands dict)
5253
self.desc = desc # human readable description
5354
self.command = command # command string
5455
self.bytes = _bytes # number of bytes expected in return
5556
self.decode = decoder # decoding function
5657
self.ecu = ecu # ECU ID from which this command expects messages from
5758
self.fast = fast # can an extra digit be added to the end of the command? (to make the ELM return early)
59+
self.header = header # ECU header used for the queries
5860

5961
def clone(self):
6062
return OBDCommand(self.name,

obd/obd.py

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
from .commands import commands
3939
from .OBDResponse import OBDResponse
4040
from .utils import scan_serial, OBDStatus
41+
from .protocols import ECU_HEADER
4142

4243
logger = logging.getLogger(__name__)
4344

@@ -55,6 +56,7 @@ def __init__(self, portstr=None, baudrate=None, protocol=None, fast=True,
5556
self.fast = fast # global switch for disabling optimizations
5657
self.timeout = timeout
5758
self.__last_command = b"" # used for running the previous command with a CR
59+
self.__last_header = ECU_HEADER.ENGINE # for comparing with the previously used header
5860
self.__frame_counts = {} # keeps track of the number of return frames for each command
5961

6062
logger.info("======================= python-OBD (v%s) =======================" % __version__)
@@ -138,6 +140,19 @@ def __load_commands(self):
138140
logger.info("finished querying with %d commands supported" % len(self.supported_commands))
139141

140142

143+
def __set_header(self, header):
144+
if header == self.__last_header:
145+
return
146+
r = self.interface.send_and_parse(b'AT SH ' + header + b' ')
147+
if not r:
148+
logger.info("Set Header ('AT SH %s') did not return data", header)
149+
return OBDResponse()
150+
if "\n".join([ m.raw() for m in r ]) != "OK":
151+
logger.info("Set Header ('AT SH %s') did not return 'OK'", header)
152+
return OBDResponse()
153+
self.__last_header = header
154+
155+
141156
def close(self):
142157
"""
143158
Closes the connection, and clears supported_commands
@@ -147,6 +162,7 @@ def close(self):
147162

148163
if self.interface is not None:
149164
logger.info("Closing connection")
165+
self.__set_header(ECU_HEADER.ENGINE)
150166
self.interface.close()
151167
self.interface = None
152168

@@ -254,7 +270,8 @@ def query(self, cmd, force=False):
254270
if not force and not self.test_cmd(cmd):
255271
return OBDResponse()
256272

257-
# send command and retrieve message
273+
self.__set_header(cmd.header)
274+
258275
logger.info("Sending command: %s" % str(cmd))
259276
cmd_string = self.__build_command_string(cmd)
260277
messages = self.interface.send_and_parse(cmd_string)

obd/protocols/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
# #
3131
########################################################################
3232

33-
from .protocol import ECU
33+
from .protocol import ECU, ECU_HEADER
3434

3535
from .protocol_unknown import UnknownProtocol
3636

obd/protocols/protocol.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,11 @@
4545
"""
4646

4747

48+
class ECU_HEADER:
49+
""" Values for the ECU headers """
50+
ENGINE = b'7E0'
51+
52+
4853
class ECU:
4954
""" constant flags used for marking and filtering messages """
5055

0 commit comments

Comments
 (0)