Skip to content

Commit

Permalink
Merge pull request #6 from MacFJA/documentation-issue-1
Browse files Browse the repository at this point in the history
#1 - Add documentations
  • Loading branch information
MacFJA authored Jan 13, 2019
2 parents 2dd675a + 76d4ada commit f65be30
Show file tree
Hide file tree
Showing 7 changed files with 295 additions and 0 deletions.
50 changes: 50 additions & 0 deletions docs/Command.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Command

## Structure of a Command

A command is a fairly simple object, it contains 2 things:

- What to send
- How to transform the raw result of the request into a Response

### What to send

To communicate with the OBD2 (and therefor your vehicle) you need to send data that can be easily understand and don't cost to much to transfers and interpret.
With that in mind the OBD2 standard define a list of code (hexadecimal number) to send to the OBD2 that represent an action (in most of case, the state of a part of your vehicle)

The command wrap this code into a class that is easier to manipulate and read for humans.

The EML327 (the most common chip use to communicate with an OBD2) add other codes (all prefixed by `AT`, and so, not numbers) to communicate with the chip.
This allow to change some behaviors or to get other data that doesn't involve the OBD (and you vehicle).

### Result transformation

The result of a OBD command is a number, but behind it there are a lots of different meaning:

- It can be a numeric data, with ou without an unit
- It can be a string data
- It can be a list of flag
- _and so on..._

As each request can have a different type of data in the result, the command know how to transform the raw result into a usable object (a Response).

## Behavior of a command

You can change how a command will be handled by the commander

There are 2 annotations that can change how the commander behave with a command:

- `io.github.macfja.obd2.PersistentCommand`
- `io.github.macfja.obd2.elm327.DontFilterResponse`

### PersistentCommand

This annotation inform the Commander that the result won't change in the future.

When the commander receive the result of the command, if the command is successful, it store the result in its internal memory.
The next time the command is executed, the result is directly return, avoid any unnecessary communication with the OBD.

### DontFilterResponse

This annotation inform the ELM Commander (`io.github.macfja.obd2.elm327.Commander`) to not remove space from the result whatever the state of `ATSP(0/1)` is.
This is useful for `AT` command that return a string
88 changes: 88 additions & 0 deletions docs/Commander.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
# Commander

The principe of the commander is: You give it a Command, and you receive a Response.
Nothing more, nothing less.

The Commander hide all communication part between you and the OBD2.

## Different Commander

There are currently 5 commanders:

- The OBD commander (`io.github.macfja.obd2.Commander`)
- The ELM commander (`io.github.macfja.obd2.elm327.Commander`)
- The ObdSim commander (`io.github.macfja.obd2.commander.ObdSimCommander`)
- The OBD Supported commander (`io.github.macfja.obd2.command.SupportedCommander`)
- The ELM Supported commander (`io.github.macfja.obd2.elm327.SupportedCommander`)

The supported commanders are decorators that add a custom logic to check if a command is supported or not.

### OBD commander

This is the base commander, it set all the needed part to send and receive data.
But it doesn't know anything particular about command except if they are persistent or not.

### ELM commander

This commander all the compatibility layer with the ELM327 chip. The ELM327 chip is the most used chip for communicating with a vehicle through OBD2 standard.

This commander add the need logic to handle response of ELM327 (headers, spaces, custom text response, _etc._).
It also provide a method to reduce the quantity of data in both sending and receiving.
It handle the case of repetitive command.

### ObdSim commander

This commander is a simple override of the ELM327 commander to use with the program [ObdSim](https://icculus.org/obdgpslogger/obdsim.html).
The program ObdSim simulate the behavior of an ELM, but some difference in how output is generated.

### OBD Supported commander

This decorator add the ability to use OBD Supported PID commands (0100, 0120, 0140, 0160, 0180, 01A0, 01C0)
to check is an OBD command is supported by the vehicle before trying to send it.

### ELM Supported commander

This decorator add the ability to check if an ELMCommand is supported by the ELM327 chip.

## Examples

### A full featured commander

```java
io.github.macfja.obd2.commander.CommanderInterface commander = new io.github.macfja.obd2.elm327.SupportedCommander(
new io.github.macfja.obd2.command.SupportedCommander(
new io.github.macfja.obd2.elm327.Commander()
)
);
commander.setCommunicationInterface(..., ...);
Response response = commander.sendCommand(CatalystTemperature.Bank1Sensor1);
// Will first call SupportedPid.Range01To20
// Then call SupportedPid.Range21To40 if it's supported
// Then call CatalystTemperature.Bank1Sensor1 if it's supported
if (response instanceof TemperaturResponse) {
System.out.println(response.getFormattedString());
} else if (response instanceof UnsupportedResponse) {
System.err.println("The command is not supported by your vehicle");
} else {
System.err.println(response.getFormattedString());
}

// The next time you send the command CatalystTemperature.Bank1Sensor1,
// not additionnal call to SupportedPid.Range01To20 and SupportedPid.Range21To40 will be made.
```

### A ObdSim commander

```java
io.github.macfja.obd2.commander.CommanderInterface commander = io.github.macfja.obd2.commander.ObdSimCommander();
commander.setCommunicationInterface(
new FileOutputStream("/dev/pts/7"), // if ObdSim is connected on /dev/pts/7
new FileInputStream("/dev/pts/7") // if ObdSim is connected on /dev/pts/7
);
Response response = commander.sendCommand(new EngineRPM());
if (response instanceof CalculatedResponse) {
System.out.println(response.getFormattedString());
} else {
System.err.println(response.getFormattedString());
}
```
56 changes: 56 additions & 0 deletions docs/Concept.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Concept

The idea of this library is help anyone that want to interact with a vehicle through the OBD2 standard (available on every consumer vehicles since 1996 in USA, 2003 in Europe).

The goal is to have an Object Oriented way of interaction between your application and the vehicle.

## Main components

The library is based on 3 things:

- A [commander](Commander.md): The _proxy_ between you and the OBD
- A [command](Command.md): The data to send
- A [response](Response.md): The received data

### Command

A command is composed by:

- The request to send to the OBD
- How to transform the raw result into a usable response

The idea is to have a Command for every request that an OBD can understand,
because it's easier to understand `IntakeAirTemperature` than `010F`, and the result is just some numbers that don't mean anything.

### Response

The main goal of a Response is to hold data from the request result and provide a nicer access of it.
It can perform some operation to easier to manipulate (ex: transformation into a Number) and to display.

The response also contains information about the Unit of the value (Temperature, Pressure, Distance, _etc._).
The Unit can be used to transform from metric unit (used in all the OBD standard) to imperial unit.

### Commander

The idea of the Commander is to handle all the communications between the program and the OBD.

It abstract the sending of the request, and the reading/transformation of the response.

#### Different Commander

The base commander (`io.github.macfja.obd2.Commander`) implement the interaction with an OBD as we directly talk to it.

The ELM327 commander (`io.github.macfja.obd2.elm327.Commander`) extends the base commander to integrate interaction with an ELM327 chip,
which is the most common chip used to communicate with OBD2.

The ObdSim commander (`io.github.macfja.obd2.commander.ObdSimCommander`) is a simple override of the ELM327 commander to use with the program [ObdSim](https://icculus.org/obdgpslogger/obdsim.html),
as the ObdSim have some difference in how output is generated

## The code

The code is written with developer in mind, all classes have a minimal Javadoc that explain what the class do.

The code also contains comment when the logic can't be understand just by reading the code.

The library is compatible with Java 7.

8 changes: 8 additions & 0 deletions docs/Inspiration.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Inspiration

This library is inspired by the Python library [**python-OBD**](https://github.com/brendan-w/python-OBD) by [Brendan Whitfield](https://github.com/brendan-w).

It also use some idea found in [**OBD-II Java API**](https://github.com/pires/obd-java-api) by [Paulo Pires](https://github.com/pires).

Some calculation, handling have been inspired/based on others open source (community driven) project like [Wikipedia](https://en.wikipedia.org/wiki/OBD-II_PIDs),
[AndrOBD](https://github.com/fr3ts0n/AndrOBD),
14 changes: 14 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Documentations

Welcome to **OBD for JAVA**.

This documentation is here to help you to understand what this library is for, and what it can do.

## Table of Content

- [Concept](Concept.md)
- [Commander](Commander.md)
- [Command](Command.md)
- [Response](Response.md)
- [Unit](Unit.md)
- [Inspiration](Inspiration.md)
40 changes: 40 additions & 0 deletions docs/Response.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Response

A response is the representation of the result of a Command.

## Structure of a Response

A response is a object that hold the result of a command.
The idea is to have an object know what the data is, and how to render it.

## Type of response

The most of the OBD2 is reading value from sensor.
A sensor is a device that transform physic data into an electric signal.

The OBD2 only return the value of the signal.
It's the job of the Response to transform this value into the physic data that have been catch by the sensor.
So the response know what physic data have been catch (via the unit of the physic data) and how to transform the signal value into number to put in front of the unit.
With is two information, the Response object is capable to transform a raw result into a human readable information.

The number of type of sensor is fairly small, and to avoid to write several times the same logic to transform data, there an a number of predefined Response:

- `io.github.macfja.obd2.response.TemperatureResponse`: Transform raw data into a temperature data (most of sensor measure data between -40°C and 215°C, so it's the default calculation)
- `io.github.macfja.obd2.response.PressureResponse`: Transform raw data into a pressure data
- `io.github.macfja.obd2.response.Percent`: Transform raw data into a variation/percentage

There are others responses that are binary data (<=> Yes or No):

- `io.github.macfja.obd2.response.AuxilaryInputResponse`
- `io.github.macfja.obd2.response.AvailableOxygenSensorMonitorResponse`
- `io.github.macfja.obd2.response.AvailablePidResponse`
- `io.github.macfja.obd2.response.SensorPresentResponse`

Some responses contains multiple data in one request:

- `io.github.macfja.obd2.response.SecondaryOxygenSensorTrimResponse`
- `io.github.macfja.obd2.response.OxygenSensorFuelTrimResponse`
- `io.github.macfja.obd2.response.OxygenSensorFuelAirVoltageResponse`
- `io.github.macfja.obd2.response.OxygenSensorFuelAirCurrentResponse`
- `io.github.macfja.obd2.response.MaximumValuesResponse`
- `io.github.macfja.obd2.response.FuelSystemStatusResponse`
39 changes: 39 additions & 0 deletions docs/Unit.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Unit

Every Response have an information about the unit of the data.

The Unit class offer a way to what kind of data the response is, and how to display it.
The OBD2 standard use only **SI** unit (metric system), so the Unit class provide a way to convert any receive data from metric system to imperial system.

## List of all units

Type of data | Metric Unit | Imperial Unit | Conversion rate | Java Enum
------------------|-------------|---------------|------------------------|-----------
Any | - | - | - | `Unit.NoUnit`, `Unit.Unknown`, `Unit.Multiple`
Percentage | **%** | - | - | `Unit.Percent`
Temperature | **°C** | **°F** | `1°F = 1.8°C + 32` | `Unit.DegreeCelsius`
Pressure | **kPa** | **psi** | `1psi = 0.145038kPa` | `Unit.KiloPascal`
Rotational speed | **rpm** | - | - | `Unit.RoundPerMinute`
Linear speed | **km/h** | **mph** | `1mph = 0.621371km/h` | `Unit.KilometrePerHour`
Angle | **°** | - | - | `Unit.Degree`
Volumetric speed | **g/s** | - | - | `Unit.GramPerSecond`
Voltage | **V** | - | - | `Unit.Volt`
Time | **s** | - | - | `Unit.Second`
Distance | **km** | **mi** | `1mi = 0.621371km` | `Unit.Kilometre`
Pressure | **Pa** | **psi** | `1psi = 0.000145Pa` | `Unit.Pascal`
Intensity | **mA** | - | - | `Unit.Milliampere`
Time | **min** | - | - | `Unit.Minute`
Volumetric speed | **L/h** | **gal/h** | `1gal/h = 0.264172L/h` | `Unit.LitrePerHour`
Force | **Nm** | **lb-ft** | `1lb-ft = 0.737562Nm` | `Unit.NewtonMetre`

(Conversion are rounded, for the sake of readability)

## Example

```java
double vehicleSpeed = 120d;
Unit speedUnit = io.github.macfja.obd2.Unit.KilometrePerHour;

System.out.println(String.format("Metric: %d %s", vehicleSpeed, speedUnit.getSymbol());
System.out.println(String.format("Imperial: %.2f %s", speedUnit.toImperial(vehicleSpeed), speedUnit.getImperialSymbol());
```

0 comments on commit f65be30

Please sign in to comment.