SoC mit CANBus und ESPHome

Alles rund um SoC (Ladezustand des Fahrzeuges). Probleme, Fragen, Fehlfunktionen gehören hier hin
Antworten
SebastianLotz
Beiträge: 14
Registriert: Mo Jul 12, 2021 10:11 am

SoC mit CANBus und ESPHome

Beitrag von SebastianLotz »

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.

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);
          }
be_smarten
Beiträge: 1
Registriert: Mi Aug 10, 2022 8:37 am

Re: SoC mit CANBus und ESPHome

Beitrag von be_smarten »

Hallo,

Ich habe auch etwas ähnliches vor. Ich will den SoC (und evtl weitere Daten) meines Seat Mii Electric (vgl. E-Up oder Citigo) in meinem Home Assistant verfügbar haben, um PV-Überschussladen zu regeln.
Dafür habe ich mir den T-CAN485 besorgt und mit esphome geflashed (Hier der Link zum Gerät: https://github.com/Xinyuan-LilyGO/T-CAN485)

Eine Liste von Codes für mein Auto habe ich auch schon gefunden.
z.B. hier https://www.goingelectric.de/wiki/VW-e-up-OBD2-SG01
Header 7E0/7E8
22 16 18 (aa*2^8+bb)/100 % Hochvoltbatterie Ladezustand Absolutwert
und hier http://obd-amigos.linuxtech.net/files/amigos_PIDs.pm

Code: Alles auswählen

# data for known parameters
our %pid=(
# 01 Engine/motor control unit (J623)
       SoC_n01=>{cmd=>'22 11 64', cu=>'01', desc=>'SoC net (.01)',                unit=>'%',         d=>2,  formula=>'sprintf("%.2f", U16(V1,V2)/100)'},                                 # verified correct
Jetzt stehe ich aber bisschen auf dem Schlauch wie ich die IDs im YAML eintragen muss.

CanID = J623 oder 7E0/7E8 ??? warum sind das zwei Werte?
Data = 22 16 18 oder 22 11 64 (kann ich ausprobieren)

Kannst du mir helfen meinen Request zu bauen?

Danke!
zut
Beiträge: 591
Registriert: Di Feb 23, 2021 9:34 pm
Has thanked: 4 times
Been thanked: 8 times

Re: SoC mit CANBus und ESPHome

Beitrag von zut »

Gab es im letzten Jahr hier Fortschritte? Ich würde gerne auch bei der Rückkehr zur heimischen Wallbox den aktuellen SOC per MQTT zur Wallbox schicken. Ich bin kurz davor, einen WiCAN zu bestellen. Hat schon jemand Erfahrung damit?
zut
Beiträge: 591
Registriert: Di Feb 23, 2021 9:34 pm
Has thanked: 4 times
Been thanked: 8 times

Re: SoC mit CANBus und ESPHome

Beitrag von zut »

Ich antworte mir selbst:

Mittlerweile habe ich ein MeatPi und gehe erste Schritte. Zwischenstand der Kommunikation mit meinem e-up!:
  • Den MeatPi habe ich auf Firmware 1.80 hochgezogen. Mit 1.78 wollte er nicht in den Schlafmodus.
  • Im Hausnetz lauert ein mosquitto-Broker auf einem Raspberry Pi 3 mit Adresse 192.168.1.28
  • Wenn der MeatPi sich an dem Broker anmeldet, kommt auf dem Topic "wican/<Geräte-ID>/status" die Nachricht status= {"status":"online"}
  • Beim Schlafengehen 3 Minuten nach Rücknahme der Fahrbereitschaft entsprechend status={"status":"offline"}
  • Ich kann dem BMS via MeatPi eine Aufforderung schicken, den aktuellen SOC zu senden:

    Code: Alles auswählen

    mosquitto_pub -h 192.168.1.28 -u wican -P wican -t "wican/<ID>/can/tx" -m "{ \"bus\": \"0\", \"type\": \"tx\", \"frame\": [{ \"id\": 2021, \"dlc\": 8, \"rtr\": false, \"extd\": false, \"data\": [3, 34, 2, 140, 170, 170, 170, 170] }] }"
  • Die Antwort erscheint auf einem Terminal, auf dem ich den MeatPi-CAN abonniert habe:

    Code: Alles auswählen

    {"bus":"0","type":"rx","ts":8202,"frame":[{"id":2029,"dlc":8,"rtr":false,"extd":false,"data":[4,98,2,140,199,170,170,170]}]}
    Dies bedeutet 199/2,55=78,04% Ladestand (Rohwert, nicht Anzeigewert)
Weitere Schritte:
  • Kleines Python-Programm schreiben, daß den MeatPi abboniert und auf das Auftauchen der online-Statusmeldung wartet
  • Bei Auftreten des online-Status muß die oben genannte Botschaft abgefeuert werden und die Antwort in einen SOC umgerechnet werden.
  • Dieser muß dann an das passende Topic der openWB geschickt werden (da gibt es in einen Parallelthread gerade das Thema, daß bei Nutzung des Moduls "Manuell+Berechnet" noch Probleme bestehen, wenn der aktuelle SOC geschrieben wird.
  • Freuen, daß ich nicht für 99€/a ein Abo für weConnect bezahlen muß.
Zur Erklärung der Botschaften oben:
Unter <https://github.com/meatpiHQ/wican-fw#mqtt> ist beschrieben, wie man zum Beispiel die Umgebungstemperatur per OBD-Abfrage aus dem Fahrzeug holt.
Hier <https://www.goingelectric.de/wiki/VW-e-up-OBD2-SG8C> steht, welche Befehle man braucht, um den SOC aus dem e-up! auszulesen.
Mir war lange nicht klar, wie ich solche 3-Byte-Befehle in die CAN-Botschaft packe. Um anderen die Suche etwas zu vereinfachen, möchte ich hier meine Erkenntnis beschreiben:
Statt nur ein Byte muß man in der CAN-Botschaft einfach drei nutzen: So wird an Adresse 2021 (0x7e5) eine Botschaft mit den Bytes 3, 34, 2, 140 geschickt - das sind die ANzahl der Nutzbytes (3) und direkt folgend die in der zweiten Qelle beschriebenen 0x22 0x02 0x8C.
In der Antwort von Adresse 2029 (0x7ed) sind 4, 98, 2 140, 199 also 4 Nutzbytes, die 98 ist das OBD2-übliche erste Byte plus 64 (0x40) als Antwort, die 2 und die 140 sind die Wiederholung der folgenden beiden Bytes der Anforderung, und die 199 ist schließlich der SOC, mit 2,55 multipliziert.
zut
Beiträge: 591
Registriert: Di Feb 23, 2021 9:34 pm
Has thanked: 4 times
Been thanked: 8 times

Re: SoC mit CANBus und ESPHome

Beitrag von zut »

Ich antworte mir nochmal selber:

viewtopic.php?t=7451

Ich habe ein Projekt angefangen, um über OBD auf SOC zuzugreifen (das funktioniert schon ganz gut). Es ergeben sich mehr Möglichkeiten, z.B. für die Anbindung an Spritmonitor.
Antworten