MCPcopy Index your code
hub / github.com/Ircama/ELM327-emulator

github.com/Ircama/ELM327-emulator @v3.0.5

Chat with this repo
repository ↗ · DeepWiki ↗ · release v3.0.5 ↗ · + Follow
146 symbols 415 edges 18 files 65 documented · 45%
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

ELM327-emulator

PyPI Python Versions PyPI download month GitHub license

A Python emulator of the ELM327 OBD-II adapter connected to a vehicle supporting multi-ECU simulation.

ELM327-emulator connects client applications to multiple emulated ECUs via OBD-II interface through different networking systems, including serial communication (where pseudo-terminals are used if supported by the operating systems), or direct interaction with communication devices, or TCP/IP, or Bluetooth. The software simulates an ELM327 adapter connected to a vehicle, includes a command-line interface for extensive monitoring and offers a documented Python development framework to implement ECU emulation objects.

ELM327-emulator is able to support basic ELM327 commands and OBD service requests through stateless request/response method via OBD-II, but can also handle stateful UDS communication with ISO-TP Flow Control and Keyword Protocol 2000, concurrently emulating multiple ECUs. It is designed to be extended via a plugin architecture to allow easy development of specific tasks implementing workflows, including the possibility to simulate anomalies for testing purposes. Many AT commands are supported, as well as some OBDLink AT/ST commands.

ELM327-emulator supports different operating systems including Windows, macOS and UNIX/Linux; it is agnostic of the client application and has been tested with python-OBD as well as with many applications on Windows, Linux and on smartphone devices.

An internal dictionary (named ObdMessage) allows configuring the emulation, which is currently set to reproduce the message flow generated by more ECUs, including the basic communication of a Toyota Auris Hybrid car (through the scenario car option) and can be easily extended to simulate communication produced by other vehicles or ECUs. In case of more complex interactions (e.g., entering privileged diagnostic sessions and performing reset or flash upload operations), the dictionary can instance tasks, which are implemented through plugins, very simple to be developed by users extending the software. Some example of plugins is already included.

ELM327-emulator also offers a feature that compares the emulation with the direct connection of an OBD-II adapter to allow extending the dictionary by reporting unmatched requests. In addition, it provides an auxiliary scanning tool (obd_dictionary) that builds the ObdMessage dictionary of a specific vehicle by automatically querying all standard OBD service requests one by one (as well as querying additional custom PIDs specified by the user via CSV file); the dictionary can then be used to emulate stateless request/responses of a specific car or ECU.

Installation

Check that the Python version is 3.6 or higher (python3 -V), then install ELM327-emulator with the following command:

python3 -m pip install ELM327-emulator

This is enough to run the software.

Prerequisite components: pyyaml, python-daemon, obd; in addition, with Windows also pyreadline3. All needed prerequisites are automatically installed with the package.

obd (python-OBD) is needed for obd_dictionary. It is better to use an updated version of python-OBD package (e.g., the one installed from GitHub with python3 -m pip install --upgrade git+https://github.com/brendan-w/python-OBD.git).

Alternatively to the above mentioned installation method, the following steps allow installing the latest version from GitHub.

  • Optional preliminary configuration with Ubuntu (if not already done):

shell sudo apt-get update sudo apt-get -y upgrade sudo add-apt-repository universe # this is only needed if "sudo apt install python3-pip" fails sudo apt-get update sudo apt install -y python3-pip python3 -m pip install --upgrade pip sudo apt install -y git

  • Optional preliminary configuration with Windows:

  • install the latest version of Python (also available from Microsoft Store);

  • if you want to install ELM327-emulator from GitHub, install git from Git-scm or using the Git for Windows installer;
  • if the interface to use is a COM port (e.g., not TCP/IP or Bluetooth), also install com0com (no installation is needed when using TCP/IP or Bluetooth interfaces);
  • optionally, check that PIP is upgraded (python3 -m pip install --upgrade pip).

  • Run this command:

  python3 -m pip install git+https://github.com/ircama/ELM327-emulator

To uninstall:

python3 -m pip uninstall -y ELM327-emulator

Basic use

The emulator allows batch and interactive mode. The latter is the default and can be executed as follows:

python3 -m elm

or simply:

elm

After starting the program, the emulator is ready to use.

To enable the preconfigured set of OBD service requests of a Toyota Auris Hybrid car, enter scenario car (or, alternatively, run the emulator with the -s car option, i.e python3 -m elm -s car).

By default, ELM327-emulator uses serial communication. The external application interfacing the emulator just needs to connect to the virtual device shown by the emulator and interact with the vehicle as if it was accessing a real ELM327 adapter.

Alternatively to the serial communication, ELM327-emulator supports TCP/IP networking through the -n option, followed by the port number (wich in most cases is 35000). Example:

python3 -m elm -n 35000

All subsequent information is not needed for basic usage of the tool and allows mastering ELM327-emulator, exploiting it to test specific features including the simulation of communication exceptions, which are not always easy to be reproduced with a real link.

Running the pre-built executable program

The elm327-emulator.zip archive in the Releases folder incudes the elm327-emulator.exe executable asset; the ZIP archive is auto-generated by a GitHub Action. elm327-emulator.exe is a Windows application that can be directly executed.

Compatibility

ELM327-emulator has been tested with Python 3.6, 3.7, 3.8, 3.9. Previous Python versions are not supported.

When using serial communication, with UNIX/Linux OSs, this code uses pty pseudo-terminals. With Windows, you should first install com0com (a kernel-mode virtual serial port driver), or other virtual serial port software; alternatively, cygwin and Windows Subsystem for Linux (WSL) are supported.

Usage

The description of the ELM327-emulator command-line option is the following:

usage: elm [-h] [-V] [-e] [-l] [-t] [-d] [-b FILE] [-p PORT] [-P DEVICE_PORT] [-a BAUDRATE] [-v LOG] [-s SCENARIO] [-n INET_PORT]
           [-H INET_FORWARD_HOST] [-N INET_FORWARD_PORT] [-S FORWARD_SERIAL_PORT] [-B FORWARD_SERIAL_BAUDRATE] [-T FORWARD_TIMEOUT]

optional arguments:
  -h, --help            show this help message and exit
  -V, --version         Print ELM327-emulator version and exit
  -e, --no-echo         Disable echo by default
  -l, --newline         Use newline (<NL>) instead of carriage return <CR> for detecting a line separator
  -t, --terminate       Terminate the daemon process sending SIGTERM
  -d, --daemon          Run ELM327-emulator in daemon mode.
  -b FILE, --batch FILE
                        Run ELM327-emulator in batch mode. Argument is the output file. The first line in that file will be the virtual
                        serial device
  -p PORT, --port PORT  Set a serial communication port instead of using a pseudo-tty.
  -P DEVICE_PORT, --device DEVICE_PORT
                        Set the communication device to be opened instead of using a pseudo-tty port.
  -a BAUDRATE, --baudrate BAUDRATE
                        Set the serial device baud rate used by ELM327-emulator.
  -v LOG, --log LOG     Preset a log level in interactive mode.
  -s SCENARIO, --scenario SCENARIO
                        Set the scenario used by ELM327-emulator.
  -n INET_PORT, --net INET_PORT
                        Set the INET socket port used by ELM327-emulator.
  -H INET_FORWARD_HOST, --forward_host INET_FORWARD_HOST
                        Set the INET host used by ELM327-emulator.when forwarding the client interaction to a remote OBD-II port.
  -N INET_FORWARD_PORT, --forward_port INET_FORWARD_PORT
                        Set the INET socket port used by ELM327-emulator when forwarding the client interaction to a remote OBD-II port.
  -S FORWARD_SERIAL_PORT, --forward_serial_port FORWARD_SERIAL_PORT
                        Set the serial device port used by ELM327-emulator when forwarding the client interaction to a serial device.
  -B FORWARD_SERIAL_BAUDRATE, --forward_serial_baudrate FORWARD_SERIAL_BAUDRATE
                        Set the device baud rate used by ELM327-emulator when forwarding the client interaction to a serial device.
  -T FORWARD_TIMEOUT, --forward_timeout FORWARD_TIMEOUT
                        Set forward timeout as floating number (default is 5 seconds).

ELM327-emulator v3.0.0 - ELM327 OBD-II adapter emulator

Description

The communication port to be used by the application interfacing the emulator is displayed when starting the program. E.g. on UNIX/Linux:

ELM327-emulator is running on /dev/pts/0

When running on Windows, the following message is shown:

ELM327-emulator is running on com0com serial port pair reading from COM3

Embedded dictionary of AT Commands and OBD service requests

A dictionary named ObdMessage is used to define commands and PIDs. The dictionary includes more sections (named scenarios):

  • 'AT': set of default AT and ST commands
  • 'default': set of default PIDs
  • 'car': PIDs of a Toyota Auris Hybrid vehicle
  • 'mt05': basic set of PIDs of an MT05 ECU from Delphi used in many motorbikes and ATV's
  • any additional custom section can be used to define specific scenarios

Default settings include both the 'AT' and the 'default' scenarios.

The dictionary used to parse each ELM command is dynamically built as a union of three defined scenarios in the following order: 'default', 'AT', custom scenario (when applied). Each subsequent scenario redefines the commands of the previous scenarios. In principle, 'AT' scenario is added to 'default' and, if a custom scenario is used, this is also added on top, and all equal keys are replaced. Then the Priority key defines the precedence to match elements.

If a custom scenario is selected through the scenario command, any key defined in the custom scenario replaces the default settings ('AT' and 'default' scenarios).

The key used in the dictionary consists of a unique identifier for each PID. Allowed case-insensitive values for each key (PID):

  • 'Request': received data; a regular expression can be used
  • 'Descr': string describing the PID
  • 'Exec': command to be executed
  • 'Log': logging.debug argument
  • 'Info': logging.info argument
  • 'Warning': logging.warning argument
  • 'ResponseFooter': run a function and returns a footer to the response (a lambda function can be used)
  • 'ResponseHeader': run a function and returns a header to the response (a lambda function can be used)
  • 'Response': returned data; can be a string, or a list/tuple of strings; if more strings are included (e.g., if a tuple or a list is used), the emulator selects one of them each time, according to the criteria defined by the choose command, which can be either sequential (default) or random.
  • 'Action': can be set to 'skip' in order to skip the processing of the PID
  • 'Header': if set, process the command only if the corresponding header (CAN ID) matches
  • 'Priority'=number: when set, the key has higher priority than the default (highest number = 1, lowest = 10 = default)
  • 'Task': if set, the related header/request activates a specific task referring to an installed plugin.

The emulator provides a monitoring front-end, supporting commands and controlling the backend thread which executes the actual process.

Built-in keywords

At the CMD> prompt, the emulator accepts the commands described in the following table.

Command Description
help List available commands (or detailed help with "help cmd").
port Print the used TCP/IP port, or the used device,

Core symbols most depended-on inside this repo

SZ
called by 1103
elm/obd_message.py
HD
called by 1103
elm/obd_message.py
DT
called by 1103
elm/obd_message.py
ST
called by 109
elm/obd_message.py
PA
called by 98
elm/obd_message.py
NA
called by 50
elm/obd_message.py
terminate
called by 15
elm/elm.py
PA
called by 8
elm/elm.py

Shape

Method 107
Function 21
Class 18

Languages

Python100%

Modules by API surface

elm/interpreter.py58 symbols
elm/elm.py53 symbols
elm/obd_message.py11 symbols
obd_dictionary/__init__.py3 symbols
elm/plugins/task_erase_memory.py3 symbols
elm/plugins/task_ecu_11F1.py3 symbols
elm/plugins/task_request_seed.py2 symbols
elm/plugins/task_mt05_write_mem_addr.py2 symbols
elm/plugins/task_mt05_stop_routine.py2 symbols
elm/plugins/task_mt05_start_routine.py2 symbols
elm/plugins/task_mt05_read_mem_addr.py2 symbols
elm/plugins/task_hardware_reset.py2 symbols

For agents

$ claude mcp add ELM327-emulator \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact

Ask about this repo answers extend the page