meatpiHQ / wican-fw

GNU General Public License v3.0
288 stars 54 forks source link

MQTT not getting any can/rx messages. #17

Open Brakelmann opened 1 year ago

Brakelmann commented 1 year ago

I am trying to get MQTT working to integrate wican into ioBroker using Node Red. After upgrading to the latest firmware V1.64 I receive the status (online / offline) as MQTT message. I impoprted your NodeRed example for HomeAssistant as iobroker also implements NodeRed.

The Node red flow gets triggered when status changes to online and sets the paylod to: "msg.payload = { "bus": "0", "type": "tx", "frame": [{ "id": 2015, "dlc": 8, "rtr": false, "extd": false, "data": [2, 1, 70, 170, 170, 170, 170, 170] }] };" The payload is published via MQTT to the topic "wican/mydev_id/can/tx"

Using MQTT FX I suscribed everything under "wican/mydev_id/#" and I receive the message as follows. "{"bus":"0","type":"tx","frame":[{"id":2015,"dlc":8,"rtr":false,"extd":false,"data":[2,1,70,170,170,170,170,170]}]}"

I was expecting to get a new MQTT message from the wican under the topic "wican/mydev_id/con/rx" But nothing happens.

Any idea how to get values via MQTT?

My car is VW e-UP and my goal was to read the State of Charge from the battery.

Many thanks in advance. Stefan.

meatpiHQ commented 1 year ago

@Brakelmann There are 2 possibilities, it's either the you have the wrong bitrate set, or your car doesn't support this PID.

First try different CAN bitrates see if that helps.

You can also check if that PID is supported, install car scanner app from play store and set the protocol in the WiCAN configuration page to ELM327. Connect to WiCAN then in the APP click on "All sensors" see if that PID supported.

image

Brakelmann commented 1 year ago

@meatpiHQ I enabled changed the protocol to LEM327 and switched on BLE trying to connect with car scanner app. The connection with car scanner app fails with the error message not compatible with ELM327 protocol.

I pulled of the wican from the OBD port and plugged it in back expecting Access point would be enabled after next boot. But wican is alway enabling BTLE and not the Access point (AP). How can I get the AP enabled again?

Thank, Stefan.

meatpiHQ commented 1 year ago

@Brakelmann Turn off the BLE on your phone, then unplug wican and plug it back again.

The car scanner app should definitely work I've tested on WiFi and BLE, can you try on WiFi?

Are you using iPhone?

Brakelmann commented 1 year ago

@meatpiHQ , I already disabled BLE on my phone but wican wont come up with wifi. I am using an android phone.

I will give it another try! How long would it take that wifi will come up after plugging wican in with BLE diasbled on my phone?

meatpiHQ commented 1 year ago

@Brakelmann It should come up immediately, what's the status of the LEDs?

Brakelmann commented 1 year ago

@meatpiHQ It's not comming up with WIFI, I waited 5 minutes without success.

The LEDs are blinking yellow (maybe green), I attached a video from the backside unfotuanetly but maybe it helps.

https://user-images.githubusercontent.com/32041481/222897756-83d2c9c0-e915-431c-a84e-9a2a1d2d3201.mp4

Is there a way to revert back to factory settings?

meatpiHQ commented 1 year ago

@Brakelmann I just found a bug, enabling MQTT and enable BLE at the same time will brick it.

Please follow the instructions to recover. Unplug from the OBD2 port and use a USB cable.

https://github.com/meatpiHQ/wican-fw#2-usb-flash

I'm fixing the bug now to disable the MQTT if the BLE is enabled.

Edit: Just added a note in the documentation about this.

meatpiHQ commented 1 year ago

@Brakelmann Make sure to erase the flash first.

Brakelmann commented 1 year ago

@meatpiHQ , after erasing the flash it is coming up with WIFI. So now I need to investiagte further...

Brakelmann commented 1 year ago

@meatpiHQ , I think I found the reason for not getting any values over MQTT. When I open the car the wican wakes up and connects to my WIFI Station and sends out the Status "online". The NodeRed Workflow is triggered from the "online" status und sends out the MQTT message to request e.g. the temperature.

But as the cars key is not yet turned and the car in not in "operating" mode it is not yet possible to request the temperature via can bus.

So I plugged of the Wican, turned the key to bring the car is in operating mode and plugged in the Wican. And here we go, sending the online status via MQTT the NodeRed Workflow is triggered and the request for the temperature is answered.

So I do not know how to solve this, but if it possible to recognize if the can bus is ready to get requests it might an option to add another status like "offline, online, online_canready" ro something like this.

With this status the NodeRed Workflow is triggered when the can bus operational.

meatpiHQ commented 1 year ago

@Brakelmann How would you know if CAN bus is ready?

Maybe try adding a delay before sending the get Temp request.

Please post more updates on your project if you managed to get the battery SoC.

Brakelmann commented 1 year ago

@meatpiHQ I am not familiar with can bus if it is not possible to recognize if can bus ready I will give it try with a delay, send the request multiple times after getting the "online" message.

Yes I will report about the SoC.

But one more question, how can I get CarScanner to connect to WiCan? I set the Protocol to ELM327. Configured Car Scanner to Connect via WIFI with the IP 192.168.80.1 and the port 3333 which is configured for TCP/UDP, but Car Scanner won't connect.

meatpiHQ commented 1 year ago

@Brakelmann Can you post a screenshot of WiCAN configuration page and Car scanner settings?

Brakelmann commented 1 year ago

@meatpiHQ here we go... WiCan_Config_1 WiCan_Config_2 CarScanner_config

meatpiHQ commented 1 year ago

@Brakelmann Try with MQTT disabled, also turn off your mobile network data.

meatpiHQ commented 1 year ago

@Brakelmann try setting the ECU protocol in advanced settings.

Screenshot_20230305-024609566 (1)

Brakelmann commented 1 year ago

@meatpiHQ with the above settings car scanner connects and works. One more question: Whilest connected to the WIFI station is a ping answered by the device? And should the config page of the Wican also be available under the IP Address given form DHCP of the Wifi Station?

Thanks, Stefan.

meatpiHQ commented 1 year ago

@Brakelmann Yes you should be able to ping it. And the configuration page is available on your network under IP Address given form DHCP.

Brakelmann commented 1 year ago

@meatpiHQ , thanks. I can confirm it is working now as expected, I had some trouble with my WIFI Access point which was not reliable.

Shall I proceed here while figuring out how to get the SoC, or close this issue and create a new one?

Thanks for your support and BR, Stefan.

marten-lucas commented 1 year ago

Hi @Brakelmann, I am working on the same project. In case you have not found the PIDs for the SoC, here are some links I found:

http://obd-amigos.linuxtech.net/files/amigos_PIDs.pm https://www.goingelectric.de/wiki/VW-e-up-OBD2-SG01#Header-7E0-7E8 https://openwb.de/forum/viewtopic.php?t=4820

What I found is, that car scanner is able to connect when the car is locked but MQTT need the car to be "drive-ready". @meatpiHQ : Do you have an idea how I could emulate the car scanner behavior to "wake up" the OBD?

Brakelmann commented 1 year ago

@marten-lucas ,thanks for pointing me into this direction.

I found a carscanner log on git hub which also has the PID for the SoC: https://github.com/sharkcow/VW-e-UP-OBD-CAN-logs/

But first I need to order a new WIFI Access point as the current one is not stable.

What I found is, that car scanner is able to connect when the car is locked but MQTT need the car to be "drive-ready". @meatpiHQ : Do you have an idea how I could emulate the car scanner behavior to "wake up" the OBD?

That would be great to check the SoC during the battery is charging.

meatpiHQ commented 1 year ago

@Brakelmann @marten-lucas

Try this pid request, it should initialize the bus, let me know if it works.

{"bus":"0","type":"tx","frame":[{"id":2015,"dlc":8,"rtr":false,"extd":false,"data":[2,1,0,170,170,170,170,170]}]}

marten-lucas commented 1 year ago

thank you for the hint. do I need eml327 protocol or slcan for this?

Brakelmann commented 1 year ago

@meatpiHQ , I will give it a try ASAP. @marten-lucas

thank you for the hint. do I need eml327 protocol or slcan for this?

I guess you can send this request directly with MQTT, and see if there is response via MQTT.

Brakelmann commented 1 year ago

@meatpiHQ I gave it a try sending the following request: {"bus":"0","type":"tx","frame":[{"id":2015,"dlc":8,"rtr":false,"extd":false,"data":[2,1,0,170,170,170,170,170]}]} And I got this answer via MQTT even as the car was sleeping: {"bus":"0","type":"rx","ts":52551,"frame":[{"id":2029,"dlc":8,"rtr":false,"extd":false,"data":[6,65,0,152,24,0,1,170]}]}

Is there a syntax description on how to create a request over MQTT to get a value for certain Can PID? Could you help me or guide me through how to get the State of Charge for my car. What I understood so far is that the SoC can be read form the motor controls unit (J623) with the command 22 11 64.

But how do I translate this into the MQTT request?

Bildschirm­foto 2023-03-07 um 18 21 02 Bildschirm­foto 2023-03-07 um 18 18 21
marten-lucas commented 1 year ago

at the OBD2 interface you need to send to requests to recieve data. First the PID then a trigger.

Here is an esphome example:

` - canbus.send: # SoC net : 0x7E0 -> '22 11 64' data: [ 0x03, 0x22, 0x11, 0x64, 0xAA, 0xAA, 0xAA, 0xAA ] canbus_id: odb_bms can_id: 0x7E0 # (Motor) use_extended_id: false

Then you can receive on the response PID and calculate the value: `

you need to put this into mqtt. Explained here:

https://github.com/meatpiHQ/wican-fw#--transmit-message-json

Brakelmann commented 1 year ago

@marten-lucas, thanks for pointing me into this direction. I will try and report here as soon as I got a stable WIFI connection to the WiCan device.

Brakelmann commented 1 year ago

@marten-lucas, @meatpiHQ,

I am still struggling with building the mqtt request to get the SoC. To request the SoC would this be correct mqtt request? {"bus":"0","type":"tx","frame":[{"id":221164,"dlc":8,"rtr":false,"extd":false,"data":[2,1,0,170,170,170,170,170]}]}

I guess the bus is default and will always be "0". Type is "tx" for transmit. Then the frame array with the first parameter the "id" which should be the pid?! Is this correct? If so, its going to be 221164. But what about the dlc, rtr, extd, and the data? Which data do I need to put in here for the request?

Thanks for you help, I am still struggling here.

marten-lucas commented 1 year ago

from my understanding dlc is the length of the data package -> 8 bit rtr is the mqtt option to retain a message extd is the option to use the extended canbus id (11bit vs 8 bit or something)

I think you need to look out if your numbers are decimal or hex. most of the documented numbers are hex (often indicated by 0x prefix).

My try for the request would on tx would be

  1. to tell the ECU which value you want

{"bus":"0","type":"tx","frame":[{"id":0x7E0,"dlc":8,"rtr":false,"extd":false,"data":[0x03, 0x22, 0x11, 0x64, 0xAA, 0xAA, 0xAA, 0xAA]}]}

  1. to trigger a response: {"bus":"0","type":"tx","frame":[{"id":0x7E0,"dlc":8,"rtr":false,"extd":false,"data":[ 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ]}]}
  2. monitor canid 0x7E8 for a resonse and calc the vaue from it first byte of the response * 2^8 is the numbers before the comma value2 = second byte of the response /100 -> is the numbers after the comma
meatpiHQ commented 1 year ago

@Brakelmann @marten-lucas

You should not send all number in decimal. Here's the correct way send a PID request over MQTT.

bus: Is always 0. Thats reserved for future application
dlc: Always 8
rtr: false
extd: false, if the car obd2 protocol is 11bit ID, 500 kbaud or 250 kbaud
extd: true, if the car obd2 protocol is 29bit ID, 500 kbaud or 250 kbaud

id: 11 bit OBD2 request ECU ID should be 2015 (that's 0x7DF in HEX)
id: 29 bit OBD2 request ECU ID should be 417018865 (that's 0x18DB33F1 in HEX)

Here's a list of standard PIDs: https://en.wikipedia.org/wiki/OBD-II_PIDs A good reference: https://www.csselectronics.com/pages/obd2-pid-table-on-board-diagnostics-j1979

Example: Get ambient temp request, PID is 70

{ "bus": "0", "type": "tx", "frame": [{ "id": 2015, "dlc": 8, "rtr": false, "extd": false, "data": [2, 1, 70, 170, 170, 170, 170, 170] }] };

image

Brakelmann commented 1 year ago

@meatpiHQ , thanks for the above explanation. With this information I am able to create valid requests and get answers, but still not the correct one for the SoC.

Looking at the different ECU and the PID I was able to send the following request and got the corresponding response: {"bus":"0","type":"tx","frame":[{"id":2021,"dlc":8,"rtr":false,"extd":false,"data":[2,1,140,170,170,170,170,170]}]} {"bus":"0","type":"rx","ts":27828,"frame":[{"id":2029,"dlc":8,"rtr":false,"extd":false,"data":[3,127,1,49,170,170,170,170]}]}

But the value for the soc in incorrect.

Using the carscanner app and sniffing via mqtt I got the following response while watching the SoC in carsanner app, which is correct: {"bus":"0","type":"rx","ts":25963,"frame":[{"id":2024,"dlc":8,"rtr":false,"extd":false,"data":[3,65,91,187,0,0,0,0]}]}

The value 187 / 2,55 = 73.3 % for the SoC which is correct.

Is there any chance to also sniff the request which is used by carscanner to find out which ECU and which PID is used?

meatpiHQ commented 1 year ago

@Brakelmann we can infer the ODB request from the SoC response.

Here's the correct request, the SoC pid is 91

{"bus":"0","type":"tx","frame":[{"id":2015,"dlc":8,"rtr":false,"extd":false,"data":[2,1,91,170,170,170,170,170]}]}

Brakelmann commented 1 year ago

@meatpiHQ , thats excellent news. I will give it a try tomorrow. Is there an explanation how to get form the rx telegram to tx request? So I will be able create future request by myself.

Thanks, Stefan.

Brakelmann commented 1 year ago

@meatpiHQ , yep its working

marten-lucas commented 1 year ago

@Brakelmann would you bei so Kind and Post the conplete solution (including wakeup)

Brakelmann commented 1 year ago

@marten-lucas, the wakeup is not working when the car is locked. I used the can wakeup in the past while sitting in the open car. I will double check tomorrow if it is still working when the car is open. It is for sure not working while the car is locked.

Currently I am using the following requests via Node Red: Get Temperature: { "bus": "0", "type": "tx", "frame": [{ "id": 2015, "dlc": 8, "rtr": false, "extd": false, "data": [2, 1, 70, 170, 170, 170, 170, 170] }] }; Get SoC: { "bus": "0", "type": "tx", "frame": [{ "id": 2015, "dlc": 8, "rtr": false, "extd": false, "data": [2, 1, 91, 170, 170, 170, 170, 170] }] } Get Kilometers after after last Error Reset: { "bus": "0", "type": "tx", "frame": [{ "id": 2015, "dlc": 8, "rtr": false, "extd": false, "data": [2, 1, 49, 170, 170, 170, 170, 170] }] }

I am requesting the values when the WiCan connects to the WLAN and send the Online status via MQTT. With this I get the values every time the car comes home and connect to WIFI. This is all I need.

Brakelmann commented 1 year ago

Done so far works for me.

marten-lucas commented 1 year ago

Hi @Brakelmann, I finally to spend some time on the wican and found out something interesting.

the PID 91 (in Hex 5B) is the SoC (gross). According to the http://obd-amigos.linuxtech.net/files/amigos_PIDs.pm SoC_g39=>{cmd=>'22 F4 5B', cu=>'01', desc=>'SoC gross (.39)', unit=>'%', d=>1, formula=>'sprintf("%.2f", V1/2.55)'}, # verified correct This means it is the total capacity not only the usable. Hence you will never read 100% b/C charging stops before.

The correct pid would be SoC (,net): https://github.com/sharkcow/VW-e-UP-OBD-CAN-logs/blob/master/carscanner.csv Restlaufzeit der Fahrbatterie;SoC 01;22F45B;A/2.55;;;%;7E0

This request have me good results so far:

{
  "bus": "0",
  "type": "tx",
  "frame": [
    {
      "id": 2016,
      "dlc": 8,
      "rtr": false,
      "extd": false,
      "data": [
        3,
        34,
        244,
        91,
        170,
        170,
        170,
        170
      ]
    }
  ]
}

Explaination: 3 b/c the pid is 4 byte long. mode 0x22 (34) is custom. 0xF4 (244) 0x5B (91) is the pid. The custom mode is also well explained here under canbus format: https://obdcon.sourceforge.net/2010/06/obd-ii-pids

@meatpiHQ: Is this correct?

@Brakelmann : How was your experience with the SoC gross? did you ever see 100%?

MrSaiclops commented 8 months ago

The correct pid would be SoC (,net): https://github.com/sharkcow/VW-e-UP-OBD-CAN-logs/blob/master/carscanner.csv Restlaufzeit der Fahrbatterie;SoC 01;22F45B;A/2.55;;;%;7E0

@marten-lucas: How are you parsing this response? I've tried:

var obj = Object();

for (let i = 0; i < msg.payload.frame.length; i++) {
    //check frame id
    if (msg.payload.frame[0].id == 2024 && msg.payload.frame[0].data[2] == 244) {
        obj.soc = msg.payload.frame[0].data[3] / 2.55;
        msg.payload = obj;
        return msg;
    }
}

but I'm only getting one response over and over again:

{"bus":"0","type":"rx","ts":27971,"frame":[{"id":401604624,"dlc":8,"rtr":false,"extd":true,"data":[32,16,0,0,0,0,0,0]}]}

For the record I have a 2019 Volkswagen e-Golf, which appears to use the same OBD codes as the e-Up.

marten-lucas commented 8 months ago

I parse the response with a home assistant automation. which trys to validate the data as well: `alias: Read Seat SoC per WiCan Mqtt (evcc) description: "" trigger:

This parses the response to this request which also queries range and temperature: `alias: Seat OBD2 Request sequence:

your response looks like a "no-response". The "extd":true looks suspicous to me. Make also sure that the ignition is on. I only trigger the request when the device comes online (assuming this is when i arrives at the drive way). Querrying during charge did not work for me. But I use evcc to the charge management and it estimates the current soc.

Brakelmann commented 8 months ago

@Brakelmann : How was your experience with the SoC gross? did you ever see 100%?

@marten-lucas I never checked this, but what I recognized is that the SoC was always 1-2% behind what the Mobile App showed. This could be very much the reason for this.

I will give it try with the pid you mentioned above and report back. Thanks for the hint.

Brakelmann commented 8 months ago

@marten-lucas I just double checked both requests. Request 1: { "bus": "0", "type": "tx", "frame": [{ "id": 2015, "dlc": 8, "rtr": false, "extd": false, "data": [2, 1, 91, 170, 170, 170, 170, 170] }] } Request 1 returns: "{"bus":"0","type":"rx","ts":5743,"frame":[{"id":2024,"dlc":8,"rtr":false,"extd":false,"data":[3,65,91,177,0,0,0,0]}]}" Request 2: { "bus": "0", "type": "tx", "frame": [{ "id": 2016, "dlc": 8, "rtr": false, "extd": false, "data": [3, 34, 244, 91, 170, 170, 170, 170] }] } Request 2 return: "{"bus":"0","type":"rx","ts":6983,"frame":[{"id":2024,"dlc":8,"rtr":false,"extd":false,"data":[4,98,244,91,177,85,85,85]}]}"

Both reuqest return 177/2.55 = 69% for the SoC. At least in the lower percentages there is no differences, but I will check with higher SoS and report back.

typxxi commented 1 month ago

any updates about what is right or wrong for the e-GOLF ?

I would need SOC and range but right now I can not figure it out properly. At least I was able to get gross SoC from the BMS like you did, but no range or so and only while ignition is turned on and car scanner app is open and showing my SOC dashboard on the phone. Otherwise (without the app and dashboard being open) it would be silent, no mqtt message would arrive.

typxxi commented 1 month ago

For the record I have a 2019 Volkswagen e-Golf, which appears to use the same OBD codes as the e-Up.

I would doubt that the e-GOLF has the SAME OBD codes as the e-Up. Quite different - maybe some in models in the beginning could been similiar or the same but not for the latest models afaik cause I have a lot of trouble at this point to get the SOC in % from the car for EVCC surplus charging.