Skip to content
Shiny.NET

OBD-II

NuGet package Shiny.AppDeviceBridge.Obd

The OBD-II bridge talks to a vehicle through an ELM327 or OBDLink adapter: decoded PIDs, the VIN, trouble codes and live readings. It’s backed by Shiny.Obd.

Terminal window
dotnet add package Shiny.AppDeviceBridge.Obd
builder.UseAppDeviceBridge(
bridge => bridge.AddObdBridge(),
webApp => { /* … */ }
);
Client C# TypeScript
IObdBridge AddObdBridgeClient() ObdBridge
Topic Details
Adapters ELM327 and OBDLink, one at a time. scan finds Bluetooth LE adapters, or with "transport": "wifi" probes the addresses Wi-Fi adapters ship with. connection takes the peripheralUuid from a scan, or a Wi-Fi host and port. The host must be a loopback, private or link-local IP address.
Reading command takes a name from GET obd/commands (engineRpm, vehicleSpeed, coolantTemperature…) and answers the decoded value with its unit. POST obd/raw sends a read-only request: modes 01, 02, 03, 05, 06, 07, 09, 0A or 22, or an informational AT command. Commands are serialized, because ELM327 is half-duplex.
Trouble codes GET obd/dtc returns stored, pending and permanent codes. A list is null when the vehicle doesn’t support that mode. DELETE obd/dtc needs ?confirm=true, because clearing codes also resets the emissions readiness monitors.
Monitoring monitor polls up to 10 commands, every 250 ms at most often, and sends each result as obd.reading, so listen to that first; without a listener it answers 409. It stops once nothing listens to obd.reading, and the adapter stays connected. After three rounds with no answers the connection is dropped with obd.disconnected.
Platform setup Bluetooth as for the Bluetooth LE bridge. Wi-Fi adapters need NSLocalNetworkUsageDescription on iOS and Mac Catalyst. On Android, the app has to bind to the adapter’s network, which has no internet. Linux supports Wi-Fi adapters only.
import { ObdBridge } from "@shinyorg/appdevicebridge";
const obd = new ObdBridge();
const [adapter] = await obd.scan({ transport: "Ble", scanMs: 5000 });
await obd.connect({ transport: "Ble", peripheralUuid: adapter.id });
const rpm = await obd.read({ command: "engineRpm" }); // { value: 812, unit: "rpm" }
const { vin } = await obd.getVin();
// live gauges: listen, then start the monitor
await obd.onReading(r => gauges[r.command] = r.value);
await obd.startMonitor({ commands: ["engineRpm", "vehicleSpeed", "coolantTemperature"], intervalMs: 500 });

getCommands() lists the named values read and startMonitor take.

GET/_bridge/obd/status#

The connection, the adapter, Bluetooth availability, and the running monitor.

C#IObdBridge.GetStatusAsyncTSObdBridge.getStatus
Response
200 ObdStatus
ObdStatus · 11 fields
connectedboolean
transportObdTransport | null
adapterIdstring | null
adapterNamestring | null
adapterTypeObdAdapterType | null
adapterIdentifierstring | nullWhat the adapter reports about itself.
protocolstring | nullThe vehicle protocol the adapter settled on.
bluetoothSupportedbooleanWhether Bluetooth LE adapters can be used here.
bluetoothAccessAccessState | null
scanningboolean
monitorObdMonitor | nullThe running monitor.
GET/_bridge/obd/commands#

The named commands read and startMonitor accept.

C#IObdBridge.GetCommandsAsyncTSObdBridge.getCommands
Response
200 ObdCommandInfo[]
ObdCommandInfo · 3 fields
namestringSuch as engineRpm.
pidstringThe raw request it sends.
unitstring | null
POST/_bridge/obd/scan#

The adapters seen during the scan window.

C#IObdBridge.ScanAsyncTSObdBridge.scan
Body
application/json · ObdScanRequest
ObdScanRequest · 3 fields
transportObdTransport
scanMsnumber | nullUp to 30,000 ms; 5 seconds when null.
nameFilterstring | nullOnly adapters whose name contains this; at most 64 characters.
Response
200 ObdAdapter[]
ObdAdapter · 5 fields
idstringA Bluetooth peripheral id, or a Wi-Fi adapter's host and port.
namestring
transportObdTransport
hoststring | null
portnumber | null
GET/_bridge/obd/adapters#

The last scan's adapters.

C#IObdBridge.GetAdaptersAsyncTSObdBridge.getAdapters
Response
200 ObdAdapter[]
ObdAdapter · 5 fields
idstringA Bluetooth peripheral id, or a Wi-Fi adapter's host and port.
namestring
transportObdTransport
hoststring | null
portnumber | null
POST/_bridge/obd/connection#

Connects to an adapter — a Bluetooth peripheral, or a Wi-Fi host, probed when none is given.

C#IObdBridge.ConnectAsyncTSObdBridge.connect
Body
application/json · ObdConnectRequest
ObdConnectRequest · 8 fields
transportObdTransport
peripheralUuidstring | null
hoststring | null
portnumber | null
timeoutMsnumber | nullUp to 60,000 ms; 30 seconds when null.
serviceUuidstring | nullFor an adapter that does not use the usual GATT service.
readCharacteristicUuidstring | null
writeCharacteristicUuidstring | null
Response
200 ObdStatus
ObdStatus · 11 fields
connectedboolean
transportObdTransport | null
adapterIdstring | null
adapterNamestring | null
adapterTypeObdAdapterType | null
adapterIdentifierstring | nullWhat the adapter reports about itself.
protocolstring | nullThe vehicle protocol the adapter settled on.
bluetoothSupportedbooleanWhether Bluetooth LE adapters can be used here.
bluetoothAccessAccessState | null
scanningboolean
monitorObdMonitor | nullThe running monitor.
DELETE/_bridge/obd/connection#

Disconnects, stopping the monitor.

C#IObdBridge.DisconnectAsyncTSObdBridge.disconnect
Response
204 No content
POST/_bridge/obd/command#

Reads one named value. Fails with 404 for a command not in getCommands.

C#IObdBridge.ReadAsyncTSObdBridge.read
Body
application/json · ObdReadRequest
ObdReadRequest · 1 field
commandstringA name from the command list, such as engineRpm.
Response
200 ObdReading
ObdReading · 4 fields
commandstring
valuenumber | nullA numeric reading.
textstring | nullA text reading.
unitstring | null
Errors
404Not found
POST/_bridge/obd/raw#

Sends a raw request and returns the adapter's reply. Only read-only requests are accepted: OBD modes 01, 02, 03, 05, 06, 07, 09, 0A or 22 in hex, or a harmless AT command.

C#IObdBridge.SendRawAsyncTSObdBridge.sendRaw
Body
application/json · ObdRawRequest
ObdRawRequest · 1 field
rawstringSuch as 010C or AT RV.
Response
200 ObdRawResult
ObdRawResult · 2 fields
commandstring
responsestring
GET/_bridge/obd/vin#

The vehicle identification number.

C#IObdBridge.GetVinAsyncTSObdBridge.getVin
Response
200 ObdVin
ObdVin · 1 field
vinstring
GET/_bridge/obd/dtc#

Stored, pending and permanent trouble codes.

C#IObdBridge.GetTroubleCodesAsyncTSObdBridge.getTroubleCodes
Response
200 ObdTroubleCodes
ObdTroubleCodes · 3 fields
storedstring[] | null
pendingstring[] | null
permanentstring[] | null
DELETE/_bridge/obd/dtc#

Clears trouble codes. This also resets the emissions readiness monitors, which take several drive cycles to complete again, so confirm must be true.

C#IObdBridge.ClearTroubleCodesAsyncTSObdBridge.clearTroubleCodes
ParameterInType
confirmquerybooleanrequired
Response
200 ObdClearResult
ObdClearResult · 1 field
clearedboolean
POST/_bridge/obd/monitor#

Reads up to 10 named values on an interval; readings arrive through onReading, so listen first: without a listener it fails with 409. The monitor stops once that has no listener left; the adapter stays connected.

C#IObdBridge.StartMonitorAsyncTSObdBridge.startMonitor
Body
application/json · ObdMonitorRequest
ObdMonitorRequest · 2 fields
commandsstring[]
intervalMsnumber | null250–60,000 ms; one second when null.
Response
200 ObdMonitor
ObdMonitor · 2 fields
commandsstring[]
intervalMsnumber
Errors
409Conflict
DELETE/_bridge/obd/monitor#

Stops the monitor.

C#IObdBridge.StopMonitorAsyncTSObdBridge.stopMonitor
Response
204 No content
EVENTobd.reading#

A monitored reading, or the error reading it.

C#IObdBridge.OnReadingAsyncTSObdBridge.onReading
Payload
ObdMonitorReading
commandstring
valuenumber | null
textstring | null
unitstring | null
errorstring | nullWhy the reading failed; the value is null then.
timestampstring
EVENTobd.disconnected#

The adapter went away or stopped answering.

C#IObdBridge.OnDisconnectedAsyncTSObdBridge.onDisconnected
Payload
ObdDisconnected
reasonstring
transportObdTransport
adapterIdstring

JSON property names are camelCase and enums travel as their names. A ? marks a property the payload may omit;| null one that may be null.

ObdStatusobject#
connectedboolean
transportObdTransport | null
adapterIdstring | null
adapterNamestring | null
adapterTypeObdAdapterType | null
adapterIdentifierstring | nullWhat the adapter reports about itself.
protocolstring | nullThe vehicle protocol the adapter settled on.
bluetoothSupportedbooleanWhether Bluetooth LE adapters can be used here.
bluetoothAccessAccessState | null
scanningboolean
monitorObdMonitor | nullThe running monitor.
ObdTransportenum#
"Ble""Wifi"
ObdAdapterTypeenum#
"Unknown""Elm327""ObdLink"
AccessStateenum#

Where a permission stands. Reported by every bridge that needs one; the names match Shiny's own.

"Unknown""NotSupported""NotSetup""Disabled""Restricted""Denied""Available"
ObdMonitorobject#
commandsstring[]
intervalMsnumber
ObdCommandInfoobject#
namestringSuch as engineRpm.
pidstringThe raw request it sends.
unitstring | null
ObdScanRequestobject#
transport?ObdTransport
scanMs?number | nullUp to 30,000 ms; 5 seconds when null.
nameFilter?string | nullOnly adapters whose name contains this; at most 64 characters.
ObdAdapterobject#
idstringA Bluetooth peripheral id, or a Wi-Fi adapter's host and port.
namestring
transportObdTransport
hoststring | null
portnumber | null
ObdConnectRequestobject#

An adapter to connect to: peripheralUuid for Bluetooth, host and port for Wi-Fi.

transport?ObdTransport
peripheralUuid?string | null
host?string | null
port?number | null
timeoutMs?number | nullUp to 60,000 ms; 30 seconds when null.
serviceUuid?string | nullFor an adapter that does not use the usual GATT service.
readCharacteristicUuid?string | null
writeCharacteristicUuid?string | null
ObdReadRequestobject#
commandstringA name from the command list, such as engineRpm.
ObdReadingobject#
commandstring
valuenumber | nullA numeric reading.
textstring | nullA text reading.
unitstring | null
ObdRawRequestobject#
rawstringSuch as 010C or AT RV.
ObdRawResultobject#
commandstring
responsestring
ObdVinobject#
vinstring
ObdTroubleCodesobject#

Each list is null where the vehicle did not answer that request.

storedstring[] | null
pendingstring[] | null
permanentstring[] | null
ObdClearResultobject#
clearedboolean
ObdMonitorRequestobject#
commandsstring[]
intervalMs?number | null250–60,000 ms; one second when null.
ObdMonitorReadingobject#
commandstring
valuenumber | null
textstring | null
unitstring | null
errorstring | nullWhy the reading failed; the value is null then.
timestampstring
ObdDisconnectedobject#
reasonstring
transportObdTransport
adapterIdstring

These routes sit under AppDeviceBridgePolicies.Bridges like every other bridge: callers on this device by default. See Security.