feature-requests
feature-requests copied to clipboard
ESP32 support ELM (ELM327) OBD2
Describe the problem you have/What new integration you would like
ESP32 has bluetooth which can be used for requests to the car CAN bus via OBD2 adapter. Also, such requests can be sent through the UART port.
Please describe your use case for this integration and alternatives you've tried:
The main application case is the collection of vehicle data and transmission over Wi-Fi. For example, through a MikroTik LTAP (mini) access point. There are alternatives not for this application. Example: https://github.com/PowerBroker2/ArduHUD/blob/master/src/ESP32_HUD/ESP32_HUD.ino https://github.com/PowerBroker2/ELMduino #include "ELMduino.h"
Additional context
ELM327 Device: https://www.amazon.com/ELM327/s?k=ELM327 ESP32 OBD-II Emulator: https://github.com/limiter121/esp32-obd2-emulator https://hackaday.com/2018/04/11/emulating-obd-ii-on-the-esp32/
I am looking for a canbus implementation as well to use in my campervan project! There is already work being done on canbus in this PR but I think they're aiming at interconnecting esphome nodes using canbus, not for pulling car diagnostics.
The ELM327 already supports lot's of car diagnostics protocols which a published on UART over Bluetooth. I recently ordered a ELM327 and have a ESP32 available so I will definitely give it a try in a bit.
I am looking for a canbus implementation as well to use in my campervan project! There is already work being done on canbus in this PR but I think they're aiming at interconnecting esphome nodes using canbus, not for pulling car diagnostics.
The ELM327 already supports lot's of car diagnostics protocols which a published on UART over Bluetooth. I recently ordered a ELM327 and have a ESP32 available so I will definitely give it a try in a bit.
I also ordered a CAN converter. Also I have an ESP32 and many other devices.
Is there any progress? I am looking for a solution, too.
I'd also like to see support for ELM327 over Bluetooth. This could be a non-cloud way to monitor charging status and SoC for electric vehicles.
@samuelmcconnell A Bluetooth serial component in esphome is needed (that replaces the direct connection/UART). That is a different feature request in my opinion, isn‘t it…
This would be a great feature! This would be a perferct addon for a electric vehicle.
I've just bought vLinker MC+ OBD2 dongle which is BLE capable and I'm wondering how can I transfer data thru esphome to my homeassstant DB + visualisation/graphs. An ESP32 as BLE-OBD2 to IP bridge to push data thru wifi (local or via smartphones hotspot for instance) to MQTT/Influx or Hass in general would be awesome. But I assume I would need to write/manage this as there is virtually no other one interested?
Hi, There is a device on crowdsupply which is a ESP connected directly to CAN / OBD2 called meatPi WICAN . This device publishes CAN Messages over MQTT
I think this is the way to go, if you don't have existing hardware.
I have some sample code that "kind-of" works (but not completely) on an ESP32 using BLE to a LiLink ELM327, using "native" ESPHome.
ble_client:
- mac_address: B4:99:4C:XX:XX:XX
id: lelink
name: LELink Leafspy
on_connect:
then:
- lambda: |-
ESP_LOGI("ble_client on_connect", "Connected to lelink");
- logger.log:
level: INFO
format: "Sending ATZ"
- ble_client.ble_write:
id: lelink
service_uuid: 0000ffe0-0000-1000-8000-00805f9b34fb
characteristic_uuid: ffe1
value: [0x41, 0x54, 0x5A, 0x0D, 0x0A, # ATZ\r\n
0x41, 0x54, 0x45, 0x30, 0x0D, 0x0A, # ATE0\r\n
]
on_disconnect:
then:
- lambda: |-
ESP_LOGI("ble_client_lambda", "Disconnected from lelink");
text_sensor:
- platform: ble_client
ble_client_id: lelink
internal: True
update_interval: never
notify: True
name: "lelink response"
id: lelink_response_text
service_uuid: "0000ffe0-0000-1000-8000-00805f9b34fb"
characteristic_uuid: "ffe1"
on_notify:
then:
- lambda: |-
//std::string sampleString("A TEST 1\r\n");
//std::vector<unsigned char> sampleBytes (sampleString.begin(), sampleString.end());
//ESP_LOGD("lelink_response_text on_notify", "sampleString '%s'", format_hex_pretty(sampleBytes.c_str(), sampleBytes.size()).c_str());
ESP_LOGD("lelink_response_text on_notify", "notify text from lelink");
auto tempvar = format_hex_pretty((uint8_t *) x.c_str(), x.size());
std::string string2(x.begin(),x.end());
std::vector<std::string> strings;
std::string del("\r");
int end = string2.find(del);
std::string s(string2);
while (end != -1) { // Loop until no delimiter is left in the string.
ESP_LOGD("lelink_response_text on_notify (split)", "x='%s'", s.substr(0, end).c_str());
strings.push_back(s.substr(0, end));
s.erase(s.begin(), s.begin() + end + 1);
end = s.find(del);
}
if (s.length() > 0) {
ESP_LOGD("lelink_response_text on_notify (split)", "x='%s'", s.c_str());
strings.push_back(s);
}
std::string toSearch ("\r");
std::string replaceStr(" cr ");
size_t pos = string2.find(toSearch);
// Repeat till end is reached
while( pos != std::string::npos)
{
// Replace this occurrence of Sub String
string2.replace(pos, toSearch.size(), replaceStr);
// Get the next occurrence from the current position
pos = string2.find(toSearch, pos + replaceStr.size());
}
ESP_LOGD("lelink_response_text on_notify", "x='%s'", string2.c_str());
ESP_LOGD("lelink_response_text on_notify", "b=%s", format_hex_pretty((uint8_t *) x.c_str(), x.size()).c_str());
interval:
- interval: 30s
# https://leaf-obd.readthedocs.io/en/latest/tutorial/elm327.html
then:
# - logger.log:
# level: INFO
# format: "Sending ATZ"
# - ble_client.ble_write:
# id: lelink
# service_uuid: 0000ffe0-0000-1000-8000-00805f9b34fb
# characteristic_uuid: ffe1
# value: [0x41, 0x54, 0x5A, 0x0D, 0x0A, # ATZ\r\n
# 0x41, 0x54, 0x45, 0x30, 0x0D, 0x0A, # ATE0\r\n
# ]
# - logger.log:
# level: INFO
# format: "Sending ATZ (again)"
# - ble_client.ble_write:
# id: lelink
# service_uuid: 0000ffe0-0000-1000-8000-00805f9b34fb
# characteristic_uuid: ffe1
# value: [0x41, 0x54, 0x5A, 0x0D, 0x0A, # ATZ\r\n
# ]
#ATWS
- logger.log:
level: INFO
format: "Sending ATE1 (turn echo on)"
- ble_client.ble_write:
id: lelink
service_uuid: 0000ffe0-0000-1000-8000-00805f9b34fb
characteristic_uuid: ffe1
value: [0x41, 0x54, 0x45, 0x31, 0x0D, 0x0A, # ATE1\r\n ATE0 to turn echo off
]
- logger.log:
level: INFO
format: "Sending ATI"
- ble_client.ble_write:
id: lelink
service_uuid: 0000ffe0-0000-1000-8000-00805f9b34fb
characteristic_uuid: ffe1
value: [0x41, 0x54, 0x49, 0x0D, 0x0A, # ATI\r\n
]
- logger.log:
level: INFO
format: "Sending ATL1 (line feed on)"
- ble_client.ble_write:
id: lelink
service_uuid: 0000ffe0-0000-1000-8000-00805f9b34fb
characteristic_uuid: ffe1
# List of bytes to write.
value: [0x41, 0x54, 0x4C, 0x30, 0x0D, 0x0A, # ATL1
]
- logger.log:
level: INFO
format: "Sending ATH1 (header control on)"
- ble_client.ble_write:
id: lelink
service_uuid: 0000ffe0-0000-1000-8000-00805f9b34fb
characteristic_uuid: ffe1
# List of bytes to write.
value: [0x41, 0x54, 0x48, 0x31, 0x0D, 0x0A, # ATH1
]
- logger.log:
level: INFO
format: "Sending ATS1 (print spaces on)"
- ble_client.ble_write:
id: lelink
service_uuid: 0000ffe0-0000-1000-8000-00805f9b34fb
characteristic_uuid: ffe1
# List of bytes to write.
value: [0x41, 0x54, 0x53, 0x31, 0x0D, 0x0A, # ATS1
]
- logger.log:
level: INFO
format: "Sending ATAL (allow long messages)"
- ble_client.ble_write:
id: lelink
service_uuid: 0000ffe0-0000-1000-8000-00805f9b34fb
characteristic_uuid: ffe1
# List of bytes to write.
value: [0x41, 0x54, 0x41, 0x4C, 0x0D, 0x0A, # ATAL
]
- logger.log:
level: INFO
format: "Sending ATDP"
- ble_client.ble_write:
id: lelink
service_uuid: 0000ffe0-0000-1000-8000-00805f9b34fb
characteristic_uuid: ffe1
# List of bytes to write.
value: [0x41, 0x54, 0x44, 0x50, 0x0D, 0x0A,#ATDP to return the protocol (its always ISO 15765-4 (CAN 11/500) but this is just a good sanity check)
]
- logger.log:
level: INFO
format: "Sending ATCRA 5B3"
- ble_client.ble_write:
id: lelink
service_uuid: 0000ffe0-0000-1000-8000-00805f9b34fb
characteristic_uuid: ffe1
# List of bytes to write.
value: [0x41, 0x54, 0x43, 0x52, 0x41, 0x20, 0x35, 0x42, 0x33, 0x0D, 0x0A,#ATCRA 5B3 https://leaf-obd.readthedocs.io/en/latest/pid/5b3.html
]
But I think to have a more synchronous communication I will need a native c++ component ?
@linkedupbits This code looks interesting. I have already a sequence of request/response AT codes for my Zoe. I've implemented it into direct arduino code and it sort of works, but is a bit unstable - if the car is away from garage, I often get reboots of the ESP32 or in some cases it just gets stuck on start boot loop. It would be great to have this implemented in basic ESPhome, where I can send request/response/error code from ESP BT proxy back to HA, or at least publish MQTT message. Any chance you had some progress with the code?
Hi, has anyone managed to make this code work? My idea is to connect my Twizy car to HA and control the charging. Any updates?