SoC mit CANBus und ESPHome
Verfasst: Mi Feb 16, 2022 8:24 pm
Hallo,
aktuell habe ich nicht so viel Zeit aber ich wollte gerne mit Euch einmal meine Erfahrungen teilen.
Ich habe einen Kona noch ohne die Online-Anbindung und eine PV-Anlage. Damit man das gut steuern kann, brauche ich ja den Ladestand der Batterie.
Lösungen mit PI oder kommerzielle Lösungen waren mir zu teuer, da es mir ausreicht, wenn das ganze zuhause funktioniert (wenn das Auto an der OpenWB angeschlossen ist). Sehr lange Zeit habe ich nach Lösungen gesucht aber auch mit USB oder Bluetooth Dongle und Android Handy fand ich das alles viel zu umständlich und komisch.
Da ich Zuhause ESPHOME in Verbindung mit HomeAssistant einsetze, hatte ich schon oft den Gedanken, einfach ESPHome dafür zu verwenden...
Leider ist die Doku für CAN-BUS sehr gering und von ODBII wird erst gar nicht geredet. Außerdem befürchtete ich, dass die Geräte vielleicht die Autobatterie leer ziehen.
Insofern habe ich mich weiter umgesehen und folgendes gefunden:
https://github.com/MagnusThome/RejsaCAN-ESP32
Magnus habe ich dann einfach per Mail gefragt, ob er mir einen zuschicken kann und das hat auch geklappt!
Alternativ kann man auch womöglich folgendes verwenden https://www.macchina.cc/catalog/a0-boards/a0-under-dash (nicht ausprobiert, GPIO sind anzupassen)
Über https://www.savvycan.com/ und ESP32RET habe ich mich dann dran gemacht, die Kommunikation zu belauschen mit dem Ergebnis, dass es nix zu belauschen gibt...
Über https://github.com/JejuSoul/OBD-PIDs-fo ... EV_BMS.csv
habe ich dann gelernt, wie man Requests stellt. Dazu muss man immer das Gerät über eine ID ansprechen und dann ein paar Bytes abschicken. Gefolgt von einer weiteren Nachricht, die das Auto auffordern, alle weiteren Informationen zu schicken.
Für den Kona sieht das dann so aus:
Request CANID: 0x7E4 Data: 03220105AAAAAAA
Request CANID: 0x7E4 Data: 3000000000000000
Die Antwort kommt dann auf CANID 0x7EC und beinhaltet u.a. z.B. die Antwort 25 7D xx xx xx xx xx xx. Die 7D muss man nur noch in eine Dezimalzahl umrechnen und durch zwei teilen und schon hat man den Batteriestand.
Das ganze habe ich dann über ESPHOME ausgelesen und schicke es über MQTT an die OpenWB. Natürlich kann man noch viel mehr abfragen und steuern. Scheinbar kann man auch nachts das Auto abschließen, wenn NUKI die Haustüre abgeschlossen hat, aber mit so etwas habe ich mich noch nicht beschäftigt.
Das tolle ist, dass diese Lösung faktisch mit jedem Auto funktionieren müsste, wenn man die CAN-IDs und die zu sendenden Daten kennt. Dazu gibt es aber im Internet eine Menge Seiten.
Über die kommenden Wochen will ich die Lösung noch etwas ausbauen.
Für pure Anfänger ist die Lösung in dieser Form noch leider nichts...
Hier einmal meine ESPHOME YAML Konfiguration.
aktuell habe ich nicht so viel Zeit aber ich wollte gerne mit Euch einmal meine Erfahrungen teilen.
Ich habe einen Kona noch ohne die Online-Anbindung und eine PV-Anlage. Damit man das gut steuern kann, brauche ich ja den Ladestand der Batterie.
Lösungen mit PI oder kommerzielle Lösungen waren mir zu teuer, da es mir ausreicht, wenn das ganze zuhause funktioniert (wenn das Auto an der OpenWB angeschlossen ist). Sehr lange Zeit habe ich nach Lösungen gesucht aber auch mit USB oder Bluetooth Dongle und Android Handy fand ich das alles viel zu umständlich und komisch.
Da ich Zuhause ESPHOME in Verbindung mit HomeAssistant einsetze, hatte ich schon oft den Gedanken, einfach ESPHome dafür zu verwenden...
Leider ist die Doku für CAN-BUS sehr gering und von ODBII wird erst gar nicht geredet. Außerdem befürchtete ich, dass die Geräte vielleicht die Autobatterie leer ziehen.
Insofern habe ich mich weiter umgesehen und folgendes gefunden:
https://github.com/MagnusThome/RejsaCAN-ESP32
Magnus habe ich dann einfach per Mail gefragt, ob er mir einen zuschicken kann und das hat auch geklappt!
Alternativ kann man auch womöglich folgendes verwenden https://www.macchina.cc/catalog/a0-boards/a0-under-dash (nicht ausprobiert, GPIO sind anzupassen)
Über https://www.savvycan.com/ und ESP32RET habe ich mich dann dran gemacht, die Kommunikation zu belauschen mit dem Ergebnis, dass es nix zu belauschen gibt...
Über https://github.com/JejuSoul/OBD-PIDs-fo ... EV_BMS.csv
habe ich dann gelernt, wie man Requests stellt. Dazu muss man immer das Gerät über eine ID ansprechen und dann ein paar Bytes abschicken. Gefolgt von einer weiteren Nachricht, die das Auto auffordern, alle weiteren Informationen zu schicken.
Für den Kona sieht das dann so aus:
Request CANID: 0x7E4 Data: 03220105AAAAAAA
Request CANID: 0x7E4 Data: 3000000000000000
Die Antwort kommt dann auf CANID 0x7EC und beinhaltet u.a. z.B. die Antwort 25 7D xx xx xx xx xx xx. Die 7D muss man nur noch in eine Dezimalzahl umrechnen und durch zwei teilen und schon hat man den Batteriestand.
Das ganze habe ich dann über ESPHOME ausgelesen und schicke es über MQTT an die OpenWB. Natürlich kann man noch viel mehr abfragen und steuern. Scheinbar kann man auch nachts das Auto abschließen, wenn NUKI die Haustüre abgeschlossen hat, aber mit so etwas habe ich mich noch nicht beschäftigt.
Das tolle ist, dass diese Lösung faktisch mit jedem Auto funktionieren müsste, wenn man die CAN-IDs und die zu sendenden Daten kennt. Dazu gibt es aber im Internet eine Menge Seiten.
Über die kommenden Wochen will ich die Lösung noch etwas ausbauen.
Für pure Anfänger ist die Lösung in dieser Form noch leider nichts...
Hier einmal meine ESPHOME YAML Konfiguration.
Code: Alles auswählen
substitutions:
upper_devicename: Kona
devicename: kona
device_description: "Kona ODB2 Interface"
esphome:
name: $devicename
comment: "${device_description}"
esp32:
board: nodemcu-32s
framework:
type: arduino
version: recommended
web_server:
port: 80
mqtt:
broker: 192.168.175.44
port: 1883
discovery: false
id: mqtt_client
wifi:
reboot_timeout: 10min
ssid: !secret wifi_ssid
password: !secret wifi_password
power_save_mode: light
logger:
#level: VERBOSE #Change the log level as required; during testing verbose is helpful.
api:
reboot_timeout: 9999 min
encryption:
key: !secret encryption_key
ota:
password: !secret ota_password
time:
- platform: homeassistant # man kann auch alternativ die Internetzeit konfigurieren
id: homeassistant_time
timezone: "Europe/Berlin"
on_time:
- seconds: 0
minutes: /2 # every minute
then:
- canbus.send: # Batteriezustand abfragen: 0x7E4 -> 220105
data: [ 0x03, 0x22, 0x01, 0x05, 0xAA, 0xAA, 0xAA, 0xAA ]
canbus_id: odb
can_id: 0x7E4 # (BMS)
- delay: 200ms
- canbus.send:
data: [ 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ]
canbus_id: odb
can_id: 0x7E4 # (BMS)
sensor:
- platform: template
name: "${upper_devicename} Batteriestand"
id: battery
unit_of_measurement: "%"
icon: "mdi:car-battery"
device_class: "battery"
state_class: "measurement"
accuracy_decimals: 1
on_value: # openWB/set/lp/1/%Soc Ladezustand in %, int, 0-100
- lambda: |-
char text[3];
dtostrf( (double) (x),1,0,text);
id(mqtt_client).publish("openWB/set/lp/1/%Soc",text);
binary_sensor:
- platform: gpio
pin:
number: GPIO14
mode:
input: true
pullup: true
id: SENSE_V_DIG
name: "${upper_devicename} 12V Battery Status"
device_class: battery_charging
light:
- platform: binary
name: "Yellow"
output: yellow_output
internal: true
- platform: binary
name: "Blue"
output: blue_output
internal: true
switch:
- platform: output
name: "${upper_devicename} ForceOn"
output: "ForceOn_output"
output:
- platform: gpio
pin: GPIO25
id: ForceOn_output
- platform: gpio
pin: GPIO12
id: yellow_output
- platform: gpio
pin: GPIO13
id: blue_output
- platform: gpio
pin: GPIO27
id: HighDriver_output
canbus:
- platform: esp32_can
tx_pin: GPIO17
rx_pin: GPIO16
id: odb
can_id: 0x7E4 # (BMS)
use_extended_id: false
bit_rate: 500KBPS
on_frame: # A variable x of type std::vector<uint8_t>
- can_id: 0x7EC # listen to ECM answers on 7EC
use_extended_id: false
then:
- lambda: |-
int wert0 = int(x[0]);
int wert1 =int(x[1]);
int wert2 =int(x[2]);
int wert3 =int(x[3]);
int wert4 =int(x[4]);
int wert5 =int(x[5]);
int wert6 =int(x[6]);
int wert7 =int(x[7]);
ESP_LOGD("main", "Antwort Hex: %x %x %x %x %x %x %x %x", wert0, wert1, wert2, wert3, wert4, wert5, wert6, wert7);
- lambda: |-
if(x[0] == 0x25) {
float battery_value = float(float(int(x[1]))/2);
id(battery).publish_state(battery_value);
ESP_LOGD("main", "battery received over can is %f", battery_value);
}