dracoventions / TWCManager

Control power delivered by a Tesla Wall Charger using two wires screwed into its RS-485 terminals.
The Unlicense
182 stars 110 forks source link

Tesla Gen 3 Wall Connector (WiFi) #20

Open darkmatter08 opened 4 years ago

darkmatter08 commented 4 years ago

Is there anyone interested in adding support for the Tesla Gen 3 Wall Connector (WiFi), released in Jan 2020? I see two steps: First, the API would have to be reversed -- possibly some kind of web endpoint accessible via simple GET/POST requests, given the browser based breaker/amp selection. Or perhaps there is telnet/ssh access. Currently, there is no power sharing logic enabled, so there is no device to device traffic to watch over the network with Wireshark. Second, the core logic for green charging from this repo should be ported over to use the new API.

Currently I don't have access to the Gen3, otherwise I'd give this a shot.

darkmatter08 commented 4 years ago

Looking at the TeslaMotorsClub forum, the author of this repo (WinterDragoness) has a Gen 3 unit and is investigating. However, there's no obvious solution so far...

I will confirm the rs485 ports on gen3 do not output anything during normal operation or respond to anything I've tried sending. I don't know why the ports are even there though I theorize they want the option to do something with them in the future, if they ever get around to it.

The manual does not say anything about the rs485 ports but it does say there will be wifi power sharing available "in a future firmware update". No idea when.

Since you can change circuit breaker size over wifi, I tried doing that while it was charging in order to get some control over charge rate, but it seems to turn the wifi off after it's been on for 5+ mins. So wifi config can only be used for provisioning, not during operation.

Internal components of gen2 TWCs were made by Delta, but gen3 internals are all stamped Tesla. CPU is different, there is no obvious JTAG connector, and so the firmware must be a complete rewrite for the new hardware. My best guess is that Tesla is trying to build a walled garden where their products talk to each other over Wifi but they don't want anyone else intruding on the conversation. I'm not sure how difficult that might be to break into but I can tell you that I won't be able to help with the process due to agreements I have with the company I now work for. I'm also concerned that even if someone breaks into the conversation, Tesla may release firmware updates that lock people out again.

Bottom line, TWCManager will likely not get updated to support gen 3 TWCs unless someone else can figure out how to do it. Until Tesla releases a firmware update, even power sharing between two stock gen3 TWCs is not currently possible.

Copied from the TMC forum.

ms100austria commented 3 years ago

Please add V3 Support.

You can access the data via the API:

http://"ipaddress"/api/1/vitals

{„contactor_closed“:false „vehicle_connected“:false „session_s“:0 „grid_v“:230.1 „grid_hz“:49.928 „vehicle_current_a“:0.1 „currentA_a“:0.0 „currentB_a“:0.1 „currentC_a“:0.0 „currentN_a“:0.0 „voltageA_v“:0.0 „voltageB_v“:0.0 „voltageC_v“:0.0 „relay_coil_v“:11.8 „pcba_temp_c“:19.2 „handle_temp_c“:15.3 „mcu_temp_c“:25.1 „uptime_s“:831580 „input_thermopile_uv“:-233 „prox_v“:0.0 „pilot_high_v“:11.9 „pilot_low_v“:11.9 „session_energy_wh“:22864.699 „config_status“:5 „evse_state“:1 „current_alerts“:[]}

http://"ipaddress"/api/1/wifi_status

{„wifi_ssid“:„RlJJVFoh4565464IEZvbiBXTE456IDczOTA=“ „wifi_signal_strength“:100 „wifi_rssi“:-35 „wifi_snr“:62 „wifi_connected“:true „wifi_infra_ip“:„192.168.178.149“ „internet“:true „wifi_mac“:"98:ED:5C:8C:77:21“}

http://"ipaddress"/api/1/lifetime

{"contactor_cycles":32 "contactor_cycles_loaded":0 "alert_count":5 "thermal_foldbacks":0 "avg_startup_temp":5199147.0 "charge_starts":32 "energy_wh":89012 "connector_cycles":5 "uptime_s":1297280 "charging_time_s":33152}

http://"ipaddress"/api/1/version

{„firmware_version“:„21.8.5+g51eba2369815d7“ „part_number“:„1529455-02-D“ „serial_number“:"PGT21106012345“}

Sure will be your first beta tester.

deece commented 3 years ago

I'm not convinced there's a big value add to support logging data without being able to control the charging.

Since you already have a nice REST interface, I'd just push that directly into OpenEnergyMonitor/HomeAssistant/whatever and call it job done, at least until we have some way to control the charging.

joriws commented 3 years ago

At least a new firmware upgrade to 21.29.1 has power sharing api calls. So maybe twc manager could use that to control gene live.

But first api should be traced for handshakes and messages and then twc gen3 emulator could be build.

Darosnl commented 3 years ago

Just got an gen3. Looks like it got 2 wifi bands, it can connect to your home network and still send out the Tesla network. So looks like the dedicated tesla "network" is for load balacing.

Also i would like to mange the gen3 you must connect to the "private" tesla network. In your own network you see an /public page (and can access the api).

bgrigoriu commented 3 years ago

@Darosnl Can you give more details on what is accesible on each chanel ?

Darosnl commented 3 years ago

Could you explain what you need or what i can do?

bgrigoriu commented 3 years ago

Hi,
For the need , as most of us, I would like to be able to modulate the charging curent intensity depending on an external parameter ( for me is the output of my enphase solar system) . But this can be extended and used for load shedding. For the moment I could not found any doc on how to communicate with the Gen 3TWC. Only some reading is documented. Did you found anything else ?

Darosnl commented 3 years ago

I'm happy to help but if you can point me to some tooling i can use. Or maybe we can do it together?

bgrigoriu commented 3 years ago

Hi, I am happy to work with you but I really dont have the expertise to look/search what a gen3 is sending/expecting in order to modulate the charging curent. I think it will need that someone has two Gen3 TWC configured as "master" and "slave" and see what is transmited over the wifi connection between the two ( I do not know even if that is possible or the degree of security involved here). My Gen3 TWC connects as a station over the wifi to the house network and then to ionternet (TESLA server I suppose). The trafic is rather important: 56Mb uplink and "é MB downlink in two days including here a firmware upgrade. The four requests Vitals, Wifi Status, lifetilme and version work very well but I am not aware of any other way to interact with the TWC. The TWC also broadcasts an Wifi AccesPoint . You can change here the charge setiings. But I saw no doc over internet about it on how to interfere with this. If you have infos or ideas how to get it I am open

r151809 commented 2 years ago

Would the TWC access point stay up, if you connected and kept the connection alive forever? I.e. connect to TWC SSID, and send a get request for the config page once per minute or so. Of course the api would be better, but it's still a mystery..

mjkapkan commented 2 years ago

Hi, Good discussion you have going on here. I recently bought gen3 as well. My initial idea was to use an openwrt wifi router with 2 bands that would forward the requests to the dedicated wifi network, that way the public part of API would be always accessible. Of course, one needs to first reverse engineer the load balancing protocol to control the charger ;).

petekelly commented 2 years ago

This is really interesting. I have a gen3 and we’re looking to have an enphase solar system installed. Ideally I’d monitor the enphase via API calls and enable 6A charging to the car if the correct amount of excess solar is detected.

@bgrigoriu did you have any luck or success with anything? My initial train of thought is a device which is connected to the wall charger Wi-Fi hotspot and just posts charging rate updates as the solar capacity becomes available.

I guess there is also the issue of telling the car to stop/start charging too but 1 hurdle at a time!

bgrigoriu commented 2 years ago

@petekelly Hi, the short answer is no, I could not do anything more. It is so far to my job today and i had no time to spar for this project. My enphase system is running and I managed to write the routine to get all the data from the Envoy metered. It is rather simple. I did it on a ESP8266 in C++. I had no time and experience to access the Tesla API to see if I can modulate charge intensity. The API comands for starting charging and modifyng the charging current have been published but since I am a newbee everything takes an enourmous time.

mattiasottosson commented 2 years ago

@petekelly, if you have a tesla only, you can set the amperage via the vehicle api. I installed a twc3 in my cabin yesterday and made a really ugly python test script in home assistant in order to set the charging rate based on whats available on each phase. Tends to work fairly well, but don't know the rate limits on the api. Would be better to do it to the twc directly though since it would work with all vehicles and less things that could break along the way.

https://gist.github.com/mattiasottosson/7deb5db74d561dcaee7ec331679922e7

Screen Shot 2022-03-16 at 12 55 03
bgrigoriu commented 2 years ago

Hi,
These is very good news. I read about the api commands but never never used them. What is the minimal hardware that can log onto the tesla site and then send the commands ? (for which the suitable libraries exists/are published) .
I implemented the read of the excess solar production on a ESP8266 ( ESP32 also works). So i would like to put all this people in a small din unit that can be integrated in the electrical distribution panel. Do you know if an ESP8266.ESP32 can connect or we nees a respberu pi ? à à zero or a zero 2 would work ?)

mjkapkan commented 2 years ago

I use a cheap wifi router with custom OpenWrt firmware.

petekelly commented 2 years ago

@petekelly, if you have a tesla only, you can set the amperage via the vehicle api. I installed a twc3 in my cabin yesterday and made a really ugly python test script in home assistant in order to set the charging rate based on whats available on each phase. Tends to work fairly well, but don't know the rate limits on the api. Would be better to do it to the twc directly though since it would work with all vehicles and less things that could break along the way.

https://gist.github.com/mattiasottosson/7deb5db74d561dcaee7ec331679922e7

Screen Shot 2022-03-16 at 12 55 03

Yes Tesla only (albeit it's not arriving until Saturday...). This was my plan actually, to

  1. Connect to the solar Enphase API to determine the current excess generation
  2. If excess >6 amps (1.4KW @ 240V), instruct the car to begin charging at 6amps
  3. If excess <6 amps, instruct the car to stop charging.
robot256 commented 2 years ago

Yes Tesla only (albeit it's not arriving until Saturday...). This was my plan actually, to

  1. Connect to the solar Enphase API to determine the current excess generation
  2. If excess >6 amps (1.4KW @ 240V), instruct the car to begin charging at 6amps
  3. If excess <6 amps, instruct the car to stop charging.

I tried this a few years ago. I found that the car stopped responding to on-off commands after only a handful per day. It might be different now, and I don't know if the same limit is applied to the new API for setting Tesla charge current. If I were to do it over again I would use the car's schedule to enable charging during typical solar hours and modulate the charge current with the TWC signal (I still have Gen2).

bgrigoriu commented 2 years ago

@mjkapkan: that is a lot in term of size. I would like to put it on avery small hardware so this can be included in an distribution panel. However I am not able to find a tesla V3 authorisazation library. @robot256 could you describe your hard/software more in detail

robot256 commented 2 years ago

I forget exactly what my setup was. I think it was OpenHab using the Tesla API to control the car's on-off, and TWCManager on a Pi Zero controlling the Gen2 TWC amps setting, and OpenHab using HTTP calls to TWCManager. I have a Brultech GEM power monitor feeding OpenHab with the solar and house consumption data, which is why OpenHab needed to be the center of the system.

mattiasottosson commented 2 years ago

Yes Tesla only (albeit it's not arriving until Saturday...). This was my plan actually, to

  1. Connect to the solar Enphase API to determine the current excess generation
  2. If excess >6 amps (1.4KW @ 240V), instruct the car to begin charging at 6amps
  3. If excess <6 amps, instruct the car to stop charging.

I ran it for one night now and it seemed to be working just fine. You can actually set the amps to lower than 6 through the api. It even seems to accept 0 as a value and pauses the charging (but the actual charging session is still active).

KastB commented 2 years ago

@petekelly It looks like you would use homeassistant. I had pv excess charging (hopefully it is called that way in English) running for ~3 months with a python script that controls the charge speed via the tesla api and gets its information via mqtt (teslamate streaming api to reduce the api calls, vzlogger for the grid consumption from the smart-meter). Maybe you want to have a look at here: https://github.com/KastB/addon-tesla-pv-charging

Nevertheless I would like on "offline" version with limit imposed by the TWC better: we could have a higher rate of control and easier support of multiple cars or other brands. However, the minimal charge rate will probably be limited to 6A.

realdadfish commented 2 years ago

@KastB Based on your work I hacked together a version without MQTT / HomeAssistant support (neither of which I have in my setup) here: https://github.com/realdadfish/addon-tesla-pv-charging - it's not final yet and not tested, just work-in-progress.

The plan is to have this running standalone on my home server. The problematic part will probably be that the vehicle is woken up each time I need to query the state of charge to determine whether or not to charge it and if so at what amperage. At night the whole process can be stopped (when plugged in) because solar_power is zero, but at day time this means the car never really gets to sleep, especially when it's not charging, and this will likely draw power.

I don't know how Teslamate gathers the current data, but I'd guess it uses the Tesla API internally as well to query it, so I don't actually know how big of a problem this becomes.

KastB commented 2 years ago

@realdafish Probably there is a difference. There is some logic which decides when to stop polling/use the streaming api so that as little data as possible is lost while sleep mode is not prevented. Simply polling is probably not the best solution (probably ~300W higher consumption during the times sleep is prevented) https://docs.teslamate.org/docs/faq/

jonasman commented 4 months ago

Btw gen3 also supports rs485 power sharing . Maybe this could be adapted for that bus?

KastB commented 4 months ago

@jonasman are you sure there is full rs485 support for v3? I only read about V2 - do you have a link to detailed information?

My solution to control the charge current on the vehicle side broke due to restrictions on the API for Tesla cars.

Does anybody have any experience with this API and it's capabilities/limitations? https://github.com/jeremyvisser/wc3magic Cheers

jonasman commented 4 months ago

@KastB that’s how neurio is connected to the wc3:

https://service.tesla.com/docs/Public/Energy/Charging/Wall-Connector-Device-Setup-in-Tesla-Pros-EN/GUID-8CD32F0F-C5BA-43D9-951A-EB3E17043427.html

deece commented 4 months ago

Nice, if someone can track down the meter model, that should lead to the protocol specs (probably Modbus), and then the meter can be faked.

Looks like this is the unit: https://www.ebay.com.au/itm/296252870455 Part number is W1-MODBUS-TESLA

frizzby commented 1 month ago

Has there been any further progress? I do have a neurio w2 meter talking to WC3 for power management. However I'm trying to solve the opposite problem: I want to intercept the CT readings data. I've got a rs485 dongle and I'm going to capture some data from the modbus line for analysis.

KastB commented 1 month ago

Hi, to my knowledge, there was no further progress by now. But a capture file would be a big step. If you could record one, it would be really great. Any additional information would ease decoding it: 1) What is your electrical setup e.g. How many phases, which voltage do we expect, which currents are set. Probably the serial of the meter is communicated as well (maybe you want to share privatly) 2) What were the readings during your recording e.g. min/max currents 3) Timing of induced events e.g. maybe you could turn on/turn off load after x seconds, one on each phase, so that we see a step response in the data and can more easily correlate the data with the values we see.

Cheers

frizzby commented 1 month ago

Hi, I have captured some data with a python script. I'm using pyserial and reading bytes into a buffer one by one until there's a delay greater than 0.8s. In this case I print the collected data in binary format from the buffer and reset the buffer. I'm in North America (split phase) and I have two neurio CTs connected to two live wires (L1, L2). Each wire to N is 120V and there's 240V between the live wires.

As you suggested, I ran several tests:

  1. L1 load on, L2 off
  2. L1 load off, L1 on
  3. L1 on, L2 on
  4. Disconnected neurio from power and after a short delay reconnected.

I'll attach the results below.

A few observations, in no particular order:

  1. I can connect to my WC3 with Tesla One app and see meter readings (attached).
  2. Neurio meter has 4 ports for CT sensors and I see 4 readings in the app. Since I use only 2 CTs the two unused are floating and show small values that fluctuate around zero (~±0.070W). This means at least 4 values should be transmitted from the meter to WC3.
  3. It doesn't appear that neurio transmits its serial number (SN) after I power cycle it. From the captured data I don't see anything that looks like the SN. Also, I have a spare neurio meter and when I swap one for another Tesla One app still shows the old SN.
  4. Unless I'm missing something obvious I'm pretty sure it's not just modbus. I've tried interpreting the captured data as modbus protocol (RTU mode) as described here. I didn't get good results. The data seems to be changing too randomly. A change in load doesn't correlate with the changes I see in the captured data (small change in load -- big change in the data).
  5. A message is transmitted every ~1s.
  6. Precision. The app shows power with up to 3 digits after the decimal point (e.g. 1254.984W).
  7. Values in the app are updated every ~2s.
  8. If I disconnect the WC3 end of the rs485 line and keep the neurio meter connected all communication stops. Which means there's a two-way communication. Or the meter somehow else knows it was disconnected.
  9. The value for power is signed. If I flip a CT the power is displayed as a negative number.
  10. The app also shows current (in A), however it appears to be always displayed as a whole number and rounded up (e.g. 272W (3.0A)). I'm not sure if this value is transmitted or is just calculated by the app.
  11. I looked at the Tesla One iOs app. It's made using React Native and most of the code is in plain text. I was able to capture wi-fi packets between my phone and the WC3 while looking at the neuri meter readings in Tesla One app. They use protocol buffers for communication between the app and WC3. I'll attach an example of the decoded protobuf below.
  12. I have a hunch IEEE 754 could be used for float encoding.
  13. Despite the fact that the data doesn't look as modbus to me, everything else suggests it should be modbus: tesla documentation, manuals, also Tesla One app has multiple mentions of modbus in the context of Neurio and WC3.

The python script I'm using https://gist.github.com/frizzby/5582fc761e614c0c494c11f71e4e19eb

2024-08-13 00 22 18 2024-08-13 00 24 52

An excerpt from the protobufs communication between WC3 and Tesla One app.

    4 { // WCMeterInterface                                                                         
      1 { // NeurioMeterInterface meterInterface                                                                       
        1 { // NeurioMeterConfig config                                                                     
          1 {                                                                    
            6: 0x36303532                                                        
          }                                                                      
          2: "VAH4770AB5642"                                                     
          3 {                                                                    
            1: 7 // int32 location                                                                 
            2: 0x3f800000 // float realPowerScaleFactor                                                      
          }                                                                      
          3 {                                                                    
            1: 7 // int32 location                                                                
            2: 0x3f800000 // float realPowerScaleFactor                                                       
          }                                                                      
          3: ""                                                                  
          3: ""                                                                  
        }                                                                        
        2 { // NeurioMeterConnection connection                                                                       
          1: 3 // connectionStatus                                                                  
          2: 1 // connectionError                                                                   
          3 { // Rssi                                                                   
            1: 200                                                               
          }                                                                      
          4: "1.6.1-Tesla"  // firmwareVersion                                                      
          5 {  // NeurioMeterReadings                                                                    
            1 { // NeurioCTReading                                                                 
              1: 0x42c9e26e  // float realPowerW                                                      
              2: 0x42c9e26e  // float scaledRealPowerW                                                    
              3: 0x40000000  // float currentAmps                                                    
            }
            1 {                                                                  
              1: 0x438d956e  // float realPowerW                                                               
              2: 0x438d956e  // float scaledRealPowerW                                                     
              3: 0x40800000  // float currentAmps                                                    
            }                                                                    
            1 {                                                                  
              1: 0x40057a9e  // float realPowerW                                                          
            }                                                                    
            1 {                                                                  
              1: 0xbe81c3bf  // float realPowerW                                                         
            }                                                                    
          }                                                                      
        }                                                                        
      }                                                                          
    }            

L1 load on (27A-28A), L2 load off (1.1A-1.3A)

27A-28A / 1.1A-1.3A / (L3, L4 ~±0.070W)
001010001100001011111110001100000100010011111111
111000000001100011111000001010000100000110101100
001000000110111011111100001000001110010011111110
011010001001111111111111011010000001000010100100
001000001110110011111111011010000010001011100000
001000000001101011111101011010000011001010001100
0010000010011101001100001010011011100011
0010000001100111001010000000000010100100
001000001010101111111101001000001000011011111001
0010000001000011001000100100011011111110
0010000011101101111000001001001011101100
00100000010111000010001010100001
0010000000110110001000000101000011111110
001010000111000011111000011010000011000111111111
0010000011111110011010000000001111001101
0010000000010000111111100010100010010000
00100000111101010011000100100100
0010100011111101001000000101001011111110
001010001001111011111101001000001000000011010101
0010000001000011011010001110011011101100
00100000111110100010000011011010
001010001110100111111001001000000001000011111111
111010001000100010010000001000100110000011111110
001000001010001011111110001000000001000011100011
011010001001110111111110011010000011000011111100
0010000011100001001000101100110111111111
0010000010110110001010000110001011110111
011010001000010011111111011010000011000010101100
001000001010101111111101011010000010100011111100
0010000100011100001000101010000111111111
001000001110000011111111001000001000011011111111
0011001000110100001000000001000011111111
001010000110100111111110001010001101110111111100
001010001101011011111110011000100001101010000100
0010000000111101001000001010011011100011
001010001101011011111100011010000011000011000000
001000000001110011111100011010001111000001001000
001000001011101011111111001000100110000011111100
0110100010011101001000001011100011111100
00100000000011000010000000010010
0010100011100000001010001000110011111110
001000001101100011110000
0010110111010100001000001111011011111110001000000010000011111110
0010000010001101001100001001000011111111
001000001110111011111111001000100000110111111101
001000000110111011111111001000101000100111111001
0010000011111110111111110010000000100000
0010000010011111111111110010000010101000
001000001110000111111111001100000001000011111100
001000001001110011111111011010001011000111101100
0010000001011110001000100000111111101101

L1 load off (3A-4A), L2 load on (25A-27A)

3A-4A / 25A-27A / (L3, L4 ~±0.070W)
001010000101100011111111001010001111100011001100
001010001010011011111111001000101010001111111111
0010000001111010001000100010000011111111
0010100001011000111111110010001000110101
111010001100010011111011001000100000001011110111
001100000101100011111111011000101101111111111110
0010100001001010111111110010000011000001
001000001010010011111101001000100001101011111101
011010001000011011111110001000101100100011111110
0010100011111011001000000100000011110101
001000001000011011111101001000100000101010011000
001010001101101011111110001010000000100111110110
0010000011100100111111100010000010100101
001010001101101011111001001100000001000011111111
0110000010001100001000100000101010111000
0010000001001100011010001100001011111110
111100001001010010001101001000100001100011000001
00100000100111000110100000001001
001000000110101111111110001000000100100111111110
001000001110010111111111001000001101111011111101
001010000101100011111000001000100000101011010011
00100000100000110011000010000110
001010000101101011111110001000100000101011100001
001000000110111011111111001100000000010011111001
001010001100100011111100001000100001101011000001
001010000100101011111110001010001111101010100100
00100000011001100010000011000000
001010000100100011111111001000101000000011111111
01101000010011100010001000110001
1010000011100110011010000001001011111111
001000100101101011111100011010001011110111111101
0010000010111100001010001011110111110100
001000000100010011111111001010000111101011110100
0010100001001000111111000010000001000100
0010000010111110001100000000100011100100
0010000000101100001000100001101011011101

L1 load on (51A-52A), L2 load on (49A-50A)

51A-52A / 49A-50A / (L3, L4 ~±0.070W)
00100000111011000010100001001010
00100000111001011111111111110000
1001011010001100001000001100001111111111001000000100011011111111
001000001000011111111111001000101000001011101001
0010000011001000001000001010010011111111
001000001011100011111111001000000000110011111011
001000000000110111111111001000101000001011001001
001010001100111001101000
01101100001010000010110111111111001000101000110011111111
0010000000111101001010001111111110001100
0010000000001101001000101000000011001100
0010000000001001001000000111010011111101
001100000000110111111111001010001110000011010100
100110010001100111111111001010000110101111110110
001000000010100011111111001000101110001010011100
0010000011101000001000100100011011111001
001010001110111011111111001000000000011011111011
00101000100010010010001010011010
001010001111110011111100001000001010111011111100
0010000010111000111111110110100001101010
001010000111111111111110001000001010101011111101
0010100000010000111111110110100011110000
00100000100010001111111100100010
11110011001000000101111011111110001000000100011011111101
001000001100001111111111001000000000011011111100
00100000110001000010000000000110
0010000001000011001000101000110011111110
1110000010010000001010001111110110100100
0010000000001110111111010010000000101010
001010000110110111111111001000001110010111100100
0010000000001110111111010010000001000110
001000001110100111111100001000101001100010010011
00101000001111001111110011100000
1010010011101010001000001110110011111101011010001000110111111110
0010100001101111001000101101101011010100
001000101100010111111111001010001101101011100100
0011001000100010001000100110100011111110
001000001011010011111110001000101000100011111111
0010000010111101001000001110010111101110
0010100011100100011010001001101011111111
0010100010100110001000000000011011111111
011010000000100011111111001000100100110011111110
001010000001100011111111011010000010001011110101
0010000011011110001000101111001011111111
001000000111111011111100001000000000110011111110
00100000100000000110100000101111
001000000100001111111110011010000010011111111111
0010100011111100111111010110100001101010
001000000010000011111110001000101010101011100110
001000001101111011100010

Disconnected and Reconnected Neurio

Disconnected Neurio
11100010
11100010
11101000
11100000
11100010
11100000
11101000
11110000
11100000
11100010
11100000
11101000
11101000
11110001
11100010
11100000
11101000
11101000
11100000
11101000
11100010
11100000
11100010
11100000
11110001
11101000
11100010
11100000
11110000
11100010
11101000
11100010
11100010
11101000
11100000
11100000
11101000
11100000
11101000
11101000
11100000
Reconnected Neurio
011010000010100111110100
0010000011001110001000101010110011100101
0110001010111101011010000111100111011100
001000001110111111111101011010000101000111000100
001010001000010111111100001000100101110011111110
001000001010111111111110011010000100000111001100
001000001001010011111111001010000011111011110101
00100010111101001001100000110101
001100101111111011111111001000001110110011111011
001000001000110011111101001000000000100011111100
00100000001010000010001010111010
0010000011110110011010000110100111100101
001000001001100011111111001100101011111011100101
001000001100010011111111001000000110000111111111
00100000100011100010001001010000
0010100011110111001000101000110111111110
001000011111110111111101011000001001011011001100
001000000111011111111111001100101011100111111111
001000001000011011111101001000101011111110010011
0110100010101000001000000001100111101101
1010000011001011001000101000110011111110
001010000111110011111111001000101010111111111111
0010000000010000001000001000110011111101
00100000000101100010000011101100
0010100000100001001000101010111111101101
1110000011000110001000101110010111111011
001000001010011011111111001000100101110011111111
001000001111011011111101001000101100001011111111
0010000011111110001000000000110011111111
0010100000111000001000101011111011111100
001010000111001111111011011010000011000011100100
001010001011101011111111001010000111110011111110
001010000110000111111111011010000011000111100100
001000000001001111111111001000000011101011111011
001010000010110011111111001000101100010011111001
011000101010011111111110001000101011111110011000
00101000111000100011000000010010
0011000011101100111111110010000010011100
001010000110000111111101001010001010110111111101
001100000110001111111111001000001001000111111111
frizzby commented 1 month ago

I would appreciate it if someone else could take a look at the data. Clearly, the load values are being transmitted. There must be at least 4 floats or ints (if milliwatts are used). And I don't think the data is encrypted – it wouldn't make sense.

r151809 commented 1 month ago

Exellent job @frizzby :)

Serial number and such are probably read by WC3 when provisioned. So we should record the data from the installaion phase. I assume that the WC3 will not just blindly ask the data - it first reads the model and serial to verify it really is Neurio.

Not really done decoding yet, but the first hunch is that it could be RTU Framing. Three ones at the begining looks like 3.5 character start, the rest would be missing from capture.. Some documentation here: https://www.modbustools.com/modbus.html

KastB commented 1 month ago

I didn't have time to dig into it today. The sequences without meter are interesting. I would guess those are requests to the meter and we see the response data from the meter in the "normal" data. Thus we might be able factorize and only deal with those smaller chunks between those requests.

KastB commented 1 month ago

@frizzby Great work, thank you! I had a second look into it and wondered if we really can expect so little data: There is about 48bit, sometimes only 40bit of data. If I'm not wrong, the 7 digits of power from your screenshot need 32bits twice already. I'm wondering if the baudrate was higher / changed during your recording. Did you try other baudrates / how did you determine it?

frizzby commented 4 weeks ago

Thanks everyone for taking time to look at it!

@KastB, aaah, yes, I think you're right – I'm not using the right baud rate.

For some reason I assumed (incorrectly) that since I'm getting any data it means the baud rate is right. Now that I think about it that assumption makes no sense.

I don't have an oscilloscope, but I do have a logic analyzer. Can it be used to determine the baud rate? In my understanding it should be possible if used with rs485-TTL converter, not directly from rs485 line. Can someone confirm?

Meanwhile, I'm going to just try different baudrates to see what results it will give.

frizzby commented 4 weeks ago

Disconnected and reconnected the meter. 115200 baud rate.

0000000100000011000000001000100000000000000010100100010111100111
0000000100000011000000001000100000000000000010100100010111100111
0000000100000011000000001000100000000000000010100100010111100111
0000000100000011000000001000100000000000000010100100010111100111
0000000100000011000000001000100000000000000010100100010111100111
0000000100000011000000001000100000000000000010100100010111100111
0000000100000011000000001000100000000000000010100100010111100111
0000000100000011000000001000100000000000000010100100010111100111
0000000100000011000000001000100000000000000010100100010111100111
0000000100000011000000001000100000000000000010100100010111100111
0000000100000011000000001000100000000000000010100100010111100111
0000000100000011000000001000100000000000000010100100010111100111
0000000100000011000000001000100000000000000010100100010111100111
0000000100000011000000001000100000000000000010100100010111100111
0000000100000011000000001000100000000000000010100100010111100111
0000000100000011000000001000100000000000000010100100010111100111
0000000100000011000000001000100000000000000010100100010111100111
0000000100000011000000001000100000000000000010100100010111100111
0000000100000011000000001000100000000000000010100100010111100111
0000000100000011000000001000100000000000000010100100010111100111
0000000100000011000000001000100000000000000010100100010111100111
0000000100000011000000001000100000000000000010100100010111100111
0000000100000011000000001000100000000000000010100100010111100111
0000000100000011000000001000100000000000000010100100010111100111
0000000100000011000000001000100000000000000010100100010111100111
0000000100000011000000001000100000000000000010100100010111100111
0000000100000011000000001000100000000000000010100100010111100111
0000000100000011000000001000100000000000000010100100010111100111
0000000100000011000000001000100000000000000010100100010111100111
0000000100000011000000001000100000000000000010100100010111100111
0000000100000011000000001000100000000000000010100100010111100111
0000000100000011000000001000100000000000000010100100010111100111
0000000100000011000000001000100000000000000010100100010111100111
0000000100000011000000001000100000000000000010100100010111100111000000010000001100010100010001000100001010001110011001100100010010001000100111001101111010111101000000010110111100100101101111100010001000110100101011111100001101110010111000110100100000001101111100000000000100000011000000001111010000000000000010000000010111111110000000010000001100010000010000001101110100000101000010100100000100011011110111111110110000111100110000110101001111111000001111001100101110100011000001100010100000011100
0000000100000011000000001000100000000000000010100100010111100111000000010000001100010100010001000100001100010001000000000100010010001010001010110110010110111101000000010110111100100101101111010000000111000011101111111100001101110011000100111110000100100111011010000000000100000011000000001111010000000000000010000000010111111110000000010000001100010000010000001101101110111000100011010100000100011100100001001011001100111100101110110101011100110010001111001110001011110011100001011111111111111100
0000000100000011000000001000100000000000000010100100010111100111000000010000001100010100010001000100010010101001000001000100010010001000110110100010010010111101000000010110111100100101001111010000000111000011101111111100001101110011000000111010111101111111101111010000000100000011000000001111010000000000000010000000010111111110000000010000001100010000010000001101111011011011011001000100000100011100100111000111000000111100110011100011100001001011001111001100101110100011000001101110001010000101
0000000100000011000000001000100000000000000010100100010111100111000000010000001100010100010001000100001001100001110110100100010010001000101100110010011010111101000000010110111100100101101111011000000111000011101111111100001101110010110100110001010100011010110000010000000100000011000000001111010000000000000010000000010111111110000000010000001100010000010000001101110001000000110010100100000100011011101010001111111000111100110001111010111101001101001111001011110111001011001111011001100000100110
frizzby commented 4 weeks ago

This is how it looks with 115200 with low vs high load https://docs.google.com/spreadsheets/d/1KzO4i0zNmd9PlaaSO53OKI9kKUAVvXDLb3r9rOAyFCA/edit?usp=sharing

frankenbubble commented 4 weeks ago

looks like modbus RTU, but all the responses have an extra 107 bytes after the frame

convert to hex and use a tool like https://npulse.net/en/online-modbus (enter hex into Hexadecimal Translate, hit enter etc)

request as hex 01030088000A45E7 a response as hex (first 25 bytes, removing the 107 extra bytes) 010314444261DA4488B326BD016F25BD81C3BFC372D3151AC1

CRCs seem to check out , not sure what the extra 107 bytes are, not timestamps that I can see

First few bytes of each extra data portion: Response 1: 01006f25be2234afc372 Response 2: 01006f25be4038efc373 Response 3: 01006f254f4038efc373 Response 4: 01006f25be6038efc372

frankenbubble commented 4 weeks ago

here is some python that reads your binary and decodes it. seems they are 32bit floats, and match your readings ?

https://gist.github.com/frankenbubble/33d14a01c65c80f42e0f92a09127a888

using the raw data in your sheet, putting it data.txt for the script I get this output

Line 1: Request: Raw Hex: 01030088000a45e7 Address: 1 Function Code: 03 Data: 0088000a

CRC (received): E745 CRC (calculated): E745 CRC Match: True

Response: Raw Hex: 01031442ab3a1643c200c9bd016f253d81c3bfc233b4bcef3a Address: 1 Function Code: 03 Number of bytes: 20 Register Data: 42ab3a1643c200c9bd016f253d81c3bfc233b4bc Interpreted Data: 16-bit Registers: [17067, 14870, 17346, 201, 48385, 28453, 15745, 50111, 49715, 46268] 32-bit Floats: [85.61344909667969, 388.0061340332031, -0.03160013630986214, 0.06336163729429245, -44.92649841308594] CRC (received): 3AEF CRC (calculated): 3AEF CRC Match: True


your sheet indicates its for reading 86W and 380W, which looks like a close match to the first 2 32-bit floats in the response

for the page indicating 2000KW , script says

32-bit Floats: [1985.830322265625, 2206.439697265625, -0.03160013630986214, -0.1267232745885849, -52.32987594604492]

KastB commented 4 weeks ago

Nice script. I just made a small extension to parse the second request/response for each timeslot So now we have the power as well as the current readings: https://github.com/KastB/twc_meter_communication/blob/master/modbus_test.py

The current guess is: the 32-bit floats are Power/Current with clamp 1,2,3,4. I don't know what the 5th value is for.

KastB commented 4 weeks ago

This script give as csv to show the Power/Current values: https://github.com/KastB/twc_meter_communication/blob/master/modbus_read_data.py My guess would be, that the 5th Power value is not a flat, but some other data

KastB commented 4 weeks ago

@frizzby I guess your goal should already be achieved. For us/me there are still 2 or 3 open points: 1) What are the last 32-bits in the power message for (maybe frequency/crc/voltage?) 2) How does the initial commissioning look like so that we can emulate a meter. (Could you maybe do a recording of that as well?) 3) Does the TWC completely shut off, if the reported currents limits are reached?

frankenbubble commented 4 weeks ago

re 1. The doc for the meter say it has measurements for Real Power, Reactive Power, Energy, Imported/Exported, RMS Current, RMS Voltage, Line Frequency , so maybe it's one of those , I would assume voltage must be there somewhere for it to know amps from the watts readings. re 2. this for me is important as it means we could try fake a meter to control charge current re 3. my understanding from https://teslamotorsclub.com/tmc/posts/8124883/ that it fails to 6A if it loses connectivity.

KastB commented 3 weeks ago

1) For information ab to each clamp, there probably is too little information. Additionally: when we calculate voltage from power and current, for the low power recording, the voltage seems to be too low. So either there is pretty bad fluctuation on the grid, or a scaling factor involved. Maybe a longer recording could help there. 2) Thats my motivation as well. 3) This would be bad news for me. I would like to do PV charging, and thus need the ability to completely stop charging by setting a high current, so that the limit seems reached for the charger.

@frizzby It would be great if you could 3 more tests: 1) A long recording, where different load scenarios happen, without interrupting the recording (I think we can find the transitions now), so that we maybe can decode the 5th power value, which might be a scaling factor 2) Do a recording of the initial setup, so that we could create a virtual meter 3) It would be great if you could verify the behavior of the charger, when the limit of the cabinet is reached => maybe configure a small current limit for the cabinet, create load so that the limit is reached, and check if charging stops, or if it is only reduced to 6A

frizzby commented 3 weeks ago

Thanks everyone for the help! Nicely done decoding it!

  1. I'm not sure what are the last 32-bits in the power message. It usually sits at around -50. When I start EV charging it drops to -240 and doesn't react much when I increase the load even more (by turning on the oven). However, it jumps to 1200 when I start my AC. What could it be? Reactive power? See https://snapshots.raintank.io/dashboard/snapshot/WbI32Gl5jiOXmE464csvNzdyRwYjCfqQ I've added a few annotations on the charts to help understand what's going on.
  2. There's no way in the app to unlink/remove the meter. I'm going to Factory Reset the wall connector and do recommissioning while recording the data from rs485 line. I will post the results separately.
  3. The lowest limit I can set is 40A. The app doesn't allow lower values. Unfortunately the charging doesn't stop when limit is exceeded. It is only reduced to 6A. The same happens when I disconnect the meter.

Btw, my wall connector is Tesla Universal Wall Connector, not TWC3. But I think they are the same software-wise.

KastB commented 3 weeks ago

1) This could really speak for reactive power: Unaffected by the resistance load of the oven (if you don't have an induction stove), capacitors of the EV charging would be in-line with more negative reactive load, and the induction of the motors in the AC could be correct positive reactive power. From what we learned in theory, this could very well be reactive power and it would make sense to place it close to the loads for each clamp. I never had a look on real-world reactive power data, so I wouldn't know for sure, but it sounds plausible. 2) That would be great! 3) That really is a pity. Maybe there is a 2nd limit when we greatly exceed the limit, which we could reach with the virtual meter. Otherwise we need manual intervention to stop charging at least at night.

Thank you very much for your efforts doing those recordings!

johado commented 3 weeks ago

Is it clear whats needed on the network side towards the WC3 to enable and configure the load balancing without an actual Neurio meter? (Protobuf messages mentioned) Does the vitals or other REST endpoint on the WC3 show anything related to load balancing or is it all protobuf? (I currently do my load balancing towards my car using the Tesla vehicle-command go program from an RPi using BLE so I don’t use the cloud API:s, but controlling the charger would be better.

frizzby commented 3 weeks ago

Unfortunately I didn't have time today to do the recommission, and tomorrow I leave for vacation for a few weeks. I have some vested interest myself in figuring out the rest of the modbus communication, so I will recommission and record the comms when I'm back home.