You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/Connections.md
+91-5Lines changed: 91 additions & 5 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,5 +1,5 @@
1
1
2
-
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 scanSerial helper retrieve a list of connected ports.
2
+
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.
3
3
4
4
```python
5
5
import obd
@@ -12,18 +12,36 @@ connection = obd.OBD("/dev/ttyUSB0") # create connection with USB 0
12
12
13
13
# OR
14
14
15
-
ports = obd.scanSerial() # return list of valid USB or RF ports
15
+
ports = obd.scan_serial() # return list of valid USB or RF ports
16
16
print ports # ['/dev/ttyUSB0', '/dev/ttyUSB1']
17
17
connection = obd.OBD(ports[0]) # connect to the first port in the list
`portstr`: The UNIX device file or Windows COM Port for your adapter. The default value (`None`) will auto select a port.
26
+
27
+
`baudrate`: The baudrate at which to set the serial connection. This can vary from adapter to adapter. Typical values are: 9600, 38400, 19200, 57600, 115200
28
+
29
+
`protocol`: Forces python-OBD to use the given protocol when communicating with the adapter. See `protocol_id()` for possible values. The default value (`None`) will auto select a protocol.
30
+
31
+
`fast`: Allows commands to be optimized before being sent to the car. Python-OBD currently makes two such optimizations:
32
+
33
+
- Sends carriage returns to repeat the previous command.
34
+
- Appends a response limit to the end of the command, telling the adapter to return after it receives *N* responses (rather than waiting and eventually timing out). This feature can be enabled and disabled for individual commands.
35
+
36
+
Disabling fast mode will guarantee that python-OBD outputs the unaltered command for every request.
37
+
20
38
<br>
21
39
22
40
---
23
41
24
42
### query(command, force=False)
25
43
26
-
Sends an `OBDCommand` to the car, and returns a `OBDResponse` object. This function will block until a response is recieved from the car. This function will also check whether the given command is supported by your car. If a command is not marked as supported, it will not be sent to the car, and an empty `Response` will be returned. To force an unsupported command to be sent, there is an optional `force` parameter for your convenience.
44
+
Sends an `OBDCommand` to the car, and returns a `OBDResponse` object. This function will block until a response is received from the car. This function will also check whether the given command is supported by your car. If a command is not marked as supported, it will not be sent to the car, and an empty `Response` will be returned. To force an unsupported command to be sent, there is an optional `force` parameter for your convenience.
27
45
28
46
*For non-blocking querying, see [Async Querying](Async Connections.md)*
29
47
@@ -36,24 +54,92 @@ r = connection.query(obd.commands.RPM) # returns the response from the car
36
54
37
55
---
38
56
57
+
### status()
58
+
59
+
Returns a string value reflecting the status of the connection. These values should be compared against the `OBDStatus` class. The fact that they are strings is for human readability only. There are currently 3 possible states:
60
+
61
+
```python
62
+
from obd import OBDStatus
63
+
64
+
# no connection is made
65
+
OBDStatus.NOT_CONNECTED# "Not Connected"
66
+
67
+
# successful communication with the ELM327 adapter
68
+
OBDStatus.ELM_CONNECTED# "ELM Connected"
69
+
70
+
# successful communication with the ELM327 and the vehicle
71
+
OBDStatus.CAR_CONNECTED# "Car Connected"
72
+
```
73
+
74
+
The middle state, `ELM_CONNECTED` is mostly for diagnosing errors. When a proper connection is established, you will never encounter this value.
75
+
76
+
---
77
+
39
78
### is_connected()
40
79
41
-
Returns a boolean for whether a connection was established.
80
+
Returns a boolean for whether a connection was established with the vehicle. It is identical to writing:
81
+
82
+
```python
83
+
connection.status() == OBDStatus.CAR_CONNECTED
84
+
```
42
85
43
86
---
44
87
45
-
### get_port_name()
88
+
### port_name()
46
89
47
90
Returns the string name for the currently connected port (`"/dev/ttyUSB0"`). If no connection was made, this function returns `"Not connected to any port"`.
48
91
49
92
---
50
93
94
+
### get_port_name()
95
+
96
+
**Deprecated:** use `port_name()` instead
97
+
98
+
---
99
+
51
100
### supports(command)
52
101
53
102
Returns a boolean for whether a command is supported by both the car and python-OBD
54
103
55
104
---
56
105
106
+
### protocol_id()
107
+
### protocol_name()
108
+
109
+
Both functions return string names for the protocol currently being used by the adapter. Protocol *ID's* are the short values used by your adapter, whereas protocol *names* are the human-readable versions. The `protocol_id()` function is a good way to lookup which value to pass in the `protocol` field of the OBD constructor (though, this is mainly for advanced usage). These functions do not make any serial requests. When no connection has been made, these functions will return empty strings. The possible values are:
110
+
111
+
|ID | Name |
112
+
|---|--------------------------|
113
+
| 1 | SAE J1850 PWM |
114
+
| 2 | SAE J1850 VPW |
115
+
| 3 | AUTO, ISO 9141-2 |
116
+
| 4 | ISO 14230-4 (KWP 5BAUD) |
117
+
| 5 | ISO 14230-4 (KWP FAST) |
118
+
| 6 | ISO 15765-4 (CAN 11/500) |
119
+
| 7 | ISO 15765-4 (CAN 29/500) |
120
+
| 8 | ISO 15765-4 (CAN 11/250) |
121
+
| 9 | ISO 15765-4 (CAN 29/250) |
122
+
| A | SAE J1939 (CAN 29/250) |
123
+
124
+
---
125
+
126
+
<!--
127
+
128
+
### ecus()
129
+
130
+
Returns a list of identified "Engine Control Units" visible to the adapter. Each value in the list is a constant representing that ECU's function. These constants are found in the `ECU` class:
131
+
132
+
```python
133
+
from obd import ECU
134
+
135
+
ECU.UNKNOWN
136
+
ECU.ENGINE
137
+
```
138
+
139
+
Python-OBD can currently only detect the engine computer, but future versions may extend this capability.
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).
| bytes | int | Number of bytes expected in response |
11
-
| decoder | callable | Function used for decoding the hex response |
12
-
| supported (optional) | bool | Flag to prevent the sending of unsupported commands (`False` by default) |
13
-
14
-
*When the command is sent, the `mode` and `pid` properties are simply concatenated. For unusual codes that don't follow the `mode + pid` structure, feel free to use just one, while setting the other to an empty string.*
| bytes | int | Number of bytes expected in response |
10
+
| decoder | callable | Function used for decoding messages from the OBD adapter |
11
+
| ecu (optional) | ECU | ID of the ECU this command should listen to (`ECU.ALL` by default) |
12
+
| fast (optional) | bool | Allows python-OBD to alter this command for efficieny (`False` by default) |
15
13
16
-
The `decoder` argument is a function of following form.
14
+
15
+
Example
16
+
-------
17
17
18
18
```python
19
-
def<name>(_hex):
20
-
...
21
-
return (<value>, <unit>)
19
+
from obd import OBDCommand
20
+
from obd.protocols importECU
21
+
from obd.utils import bytes_to_int
22
+
23
+
defrpm(messages):
24
+
d = messages[0].data
25
+
v = bytes_to_int(d) /4.0# helper function for converting byte arrays to ints
26
+
return (v, Unit.RPM)
27
+
28
+
c = OBDCommand("RPM", \ # name
29
+
"Engine RPM", \ # description
30
+
"010C", \ # command
31
+
2, \ # number of return bytes to expect
32
+
rpm, \ # decoding function
33
+
ECU.ENGINE, \ # (optional) ECU filter
34
+
True) # (optional) allow a "01" to be added for speed
22
35
```
23
36
24
-
The `_hex` argument is the data recieved from the car, and is guaranteed to be the size of the `bytes` property specified in the OBDCommand.
37
+
By default, custom commands will be treated as "unsupported by the vehicle". There are two ways to handle this:
25
38
26
-
For example:
39
+
```python
40
+
# use the `force` parameter when querying
41
+
o = obd.OBD()
42
+
o.query(c, force=True)
43
+
```
44
+
45
+
or
27
46
28
47
```python
29
-
from obd import OBDCommand
30
-
from obd.utils import unhex
48
+
# add your command to the set of supported commands
49
+
o = obd.OBD()
50
+
o.supported_commands.add(c)
51
+
o.query(c)
52
+
```
53
+
54
+
<br>
55
+
56
+
Here are some details on the less intuitive fields of an OBDCommand:
31
57
32
-
defrpm(_hex):
33
-
v = unhex(_hex) # helper function to convert hex to int
34
-
v = v /4.0
35
-
return (v, obd.Unit.RPM)
58
+
---
59
+
60
+
### OBDCommand.decoder
61
+
62
+
The `decoder` argument is a function of following form.
36
63
37
-
c = OBDCommand("RPM", "Engine RPM", "01", "0C", 2, rpm)
64
+
```python
65
+
def<name>(<list_of_messages>):
66
+
...
67
+
return (<value>, <unit>)
68
+
```
69
+
70
+
Decoders are given a list of `Message` objects as an argument. If your decoder is called, this list is garaunteed to have at least one message object. Each `Message` object has a `data` property, which holds a parsed byte array, and is also garauteed to have the number of bytes specified by the command.
71
+
72
+
*NOTE: If you are transitioning from an older version of Python-OBD (where decoders were given raw hex strings as arguments), you can use the `Message.hex()` function as a patch.*
73
+
74
+
```python
75
+
def<name>(messages):
76
+
_hex = messages[0].hex()
77
+
...
78
+
return (<value>, <unit>)
38
79
```
39
80
81
+
*You can also access the original string sent by the adapter using the `Message.raw()` function.*
82
+
83
+
---
84
+
85
+
### OBDCommand.ecu
86
+
87
+
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:
88
+
89
+
-`ECU.ALL`
90
+
-`ECU.ALL_KNOWN`
91
+
-`ECU.UNKNOWN`
92
+
-`ECU.ENGINE`
93
+
94
+
---
95
+
96
+
### OBDCommand.fast
97
+
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.
Copy file name to clipboardExpand all lines: docs/index.md
+3-1Lines changed: 3 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -12,7 +12,7 @@ Install the latest release from pypi:
12
12
$ pip install obd
13
13
```
14
14
15
-
If you are using a bluetooth adapter on Debian-based linux, you will need to install the following packages:
15
+
*Note: If you are using a Bluetooth adapter on Linux, you may also need to install and configure your Bluetooth stack. On Debian-based systems, this usually means installing the following packages:*
16
16
17
17
```shell
18
18
$ sudo apt-get install bluetooth bluez-utils blueman
@@ -35,6 +35,8 @@ print(response.value)
35
35
print(response.unit)
36
36
```
37
37
38
+
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` and `unit` properties.
0 commit comments