tobiasfaust / SolaxModbusGateway

Modbus RTU to MQTT Gateway
GNU General Public License v3.0
55 stars 17 forks source link

QVolt HYB G3-3P inverter #8

Closed effix58 closed 1 year ago

effix58 commented 1 year ago

Hello, recently I got a QHome ESS hyb G3 System. According to some posts in the web, the QVolt inverter is very similar to Solax X3 hyb G4 (a re-labelled Solax inverter but is firmware identical?). I am searching for a possibility to get live data via RS485 modbus interface and to use it with FHEM. In the FHEM forum I got attention to your great project. Unfortunately the decimal values from the 32 bit register are much too high when choosing Solax X3. I had a look in the documentation of the register of the Solax X1/X3 hyb G4 (V3.21) which I found in the docs folder. Obviously the first two Bytes of the 32 bit register represent LSB and the next two Bytes MSB. In my opinion I have to exchange LSB and MSB to get correctly calculated decimal values. I checked that with the tool in raw data folder and the results were in line with the QCell App. What do you think about that? I want to check that for a longer period but I am not familiar with Github and Gitpod to change register.h properly. Would you kindly add a new inverter "QVolt HYB-G3-3P" in register.h? Here are the terms and positions, which were checked and evaluated with raw data tool besides "OffGrid" values:

"QVolt HYB-G3-3P": { "config": { "RequestLiveData": [ ["#ClientID", "0x04", "0x00", "0x00", "0x00", "0x77"], ["#ClientID", "0x04", "0x00", "0x78", "0x00", "0x77"] ], "RequestIdData": ["#ClientID", "0x03", "0x00", "0x00", "0x00", "0x14"], "ClientIdPos": 0, "LiveDataFunctionCodePos": 1, "LiveDataFunctionCode": "0x04", "IDDataFunctionCodePos": 1, "IdDataFunctionCode": "0x03", "LiveDataStartsAtPos": 3, "IdDataStartsAtPos": 3, "LiveDataErrorPos": 1, "LiveDataErrorCode": "0x84", "IdDataErrorPos": 1, "IdDataErrorCode": "0x83", "LiveDataSuccessPos": 1, "LiveDataSuccessCode": "0x04", "IdDataSuccessPos": 1, "IdDataSuccessCode": "0x03" }, "data": { "livedata": [ { "position": [215, 216], "name": "GridVoltage_R", "realname": "Grid Voltage L1", "datatype": "float", "factor": 0.1, "unit": "V" }, { "position": [217, 218], "name": "GridCurrent_R", "realname": "Grid Current L1", "datatype": "float", "factor": 0.1, "unit": "A" }, { "position": [219, 220], "name": "GridPower_R", "realname": "Grid Power L1", "datatype": "integer", "unit": "W" }, { "position": [221, 222], "name": "GridFrequency_R", "realname": "Grid Frequency L1", "datatype": "float", "factor": 0.01, "unit": "Hz" }, { "position": [223, 224], "name": "GridVoltage_S", "realname": "Grid Voltage L2", "datatype": "float", "factor": 0.1, "unit": "V" }, { "position": [225, 226], "name": "GridCurrent_S", "realname": "Grid Current L2", "datatype": "float", "factor": 0.1, "unit": "A" }, { "position": [227, 228], "name": "GridPower_S", "realname": "Grid Power L2", "datatype": "integer", "unit": "W" }, { "position": [229, 230], "name": "GridFrequency_S", "realname": "Grid Frequency L2", "datatype": "float", "factor": 0.01, "unit": "Hz" }, { "position": [231, 232], "name": "GridVoltage_T", "realname": "Grid Voltage L3", "datatype": "float", "factor": 0.1, "unit": "V" }, { "position": [233, 234], "name": "GridCurrent_T", "realname": "Grid Current L3", "datatype": "float", "factor": 0.1, "unit": "A" }, { "position": [235, 236], "name": "GridPower_S", "realname": "Grid Power L3", "datatype": "integer", "unit": "W" }, { "position": [237, 238], "name": "GridFrequency_T", "realname": "Grid Frequency L3", "datatype": "float", "factor": 0.01, "unit": "Hz" },
{ "position": [9, 10], "name": "PvVoltage1", "realname": "Pv Voltage 1", "datatype": "float", "factor": 0.1, "unit": "V" }, { "position": [11, 12], "name": "PvVoltage2", "realname": "Pv Voltage 2", "datatype": "float", "factor": 0.1, "unit": "V" }, { "position": [13, 14], "name": "PvCurrent1", "realname": "Pv Current 1", "datatype": "float", "factor": 0.1, "unit": "A" }, { "position": [15, 16], "name": "PvCurrent2", "realname": "Pv Current 2", "datatype": "float", "factor": 0.1, "unit": "A" },
{ "position": [19, 20], "name": "InverterTemperature", "realname": "Inverter Temperature", "datatype": "integer", "unit": "°C" }, { "position": [23, 24], "name": "PowerDC1", "realname": "Power DC 1", "datatype": "integer", "unit": "W" }, { "position": [25, 26], "name": "PowerDC2", "realname": "Power DC 2", "datatype": "integer", "unit": "W" }, { "position": [43, 44], "name": "BatVoltage", "realname": "Battery Voltage", "datatype": "float", "factor": 0.1, "unit": "V" }, { "position": [45, 46], "name": "BatCurrent", "realname": "Battery Current", "datatype": "float", "factor": 0.1, "unit": "A" }, { "position": [47, 48], "name": "BatPower", "realname": "Battery Power", "datatype": "integer", "unit": "W" }, { "position": [51, 52], "name": "BatTemp", "realname": "Battery Temperature", "datatype": "integer", "unit": "°C" }, { "position": [59, 60], "name": "BatCapacity", "realname": "Battery Capacity", "datatype": "integer", "unit": "%" }, { "position": [63, 64, 61, 62], "name": "OutputEnergyCharge", "realname": "Output Energy Charge", "datatype": "float", "factor": 0.1, "unit": "kWh" }, { "position": [67, 68], "name": "OutputEnergyChargeToday", "realname": "Output Energy Charge Today", "datatype": "float", "factor": 0.1, "unit": "kWh" }, { "position": [71, 72, 69, 70], "name": "InputEnergyCharge", "realname": "Input Energy Charge", "datatype": "float", "factor": 0.1, "unit": "kWh" }, { "position": [73, 74], "name": "InputEnergyChargeToday", "realname": "Input Energy Charge Today", "datatype": "float", "factor": 0.1, "unit": "kWh" }, { "position": [145, 146, 143, 144], "name": "feedinPower", "realname": "FeedIn Power to Grid", "datatype": "integer", "unit": "W" }, { "position": [149, 150, 147, 148], "name": "feedinEnergyTotal", "realname": "FeedIn Energy Total to Grid", "datatype": "float", "factor": 0.01, "unit": "kWh" }, { "position": [153, 154, 151, 152], "name": "consumEnergyTotal", "realname": "ConsumEnergy Total from Grid", "datatype": "float", "factor": 0.01, "unit": "kWh" }, { "position": [163, 164], "name": "EnergyTodayToGrid", "realname": "Today Energy to Grid", "datatype": "float", "factor": 0.1, "unit": "kWh" }, { "position": [169, 170, 167, 168], "name": "EnergyTotalToGrid", "realname": "Total Energy to Grid", "datatype": "float", "factor": 0.1, "unit": "kWh" }, { "position": [280, 281, 278, 279], "name": "OnGridRunTime", "realname": "OnGrid RunTime", "datatype": "float", "factor": 0.1, "unit": "h" }, { "position": [284, 285, 282, 283], "name": "OffGridRunTime", "realname": "OffGrid RunTime", "datatype": "float", "factor": 0.1, "unit": "h" }, { "position": [294, 295, 292, 293], "name": "OffGridYieldTotal", "realname": "OffGrid Yield Total", "datatype": "float", "factor": 0.1, "unit": "kWh" }, { "position": [294, 295], "name": "OffGridYieldToday", "realname": "OffGrid Yield Today", "datatype": "float", "factor": 0.1, "unit": "kWh" }, { "position": [296, 297], "name": "EChargeToday", "realname": "ECharge Today", "datatype": "float", "factor": 0.1, "unit": "kWh" }, { "position": [300, 301, 298, 299], "name": "EChargeTotal", "realname": "ECharge Total", "datatype": "float", "factor": 0.1, "unit": "kWh" }, { "position": [304, 305, 302, 303], "name": "SolarEnergyTotal", "realname": "SolarEnergy Total", "datatype": "float", "factor": 0.1, "unit": "kWh" }, { "position": [306, 307], "name": "SolarEnergyToday", "realname": "SolarEnergy Today", "datatype": "float", "factor": 0.1, "unit": "kWh" }, { "position": [312, 313, 310, 311], "name": "EnergyFeedin", "realname": "EnergyFeedin Today", "datatype": "float", "factor": 0.01, "unit": "kWh" }, { "position": [316, 317, 314, 315], "name": "EnergyConsum", "realname": "EnergyConsum Today", "datatype": "float", "factor": 0.01, "unit": "kWh" } ], "id": [ { "position": [3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], "name": "InverterSN", "realname": "Inverter SerialNumber", "datatype": "string" }, { "position": [17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30], "name": "FactoryName", "realname": "Factory Name", "datatype": "string" }, { "position": [31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42], "name": "ModuleName", "realname": "Module Name", "datatype": "string" } ] } },

ghost commented 1 year ago

Hi, of course, it´s possible to integrate your items :) Thanks for your support for this project. Are you sure about the order of LSB and MSB? Did you checked those with your inverter? You can use gitpod for that: Add your items in register.h, compile a new firmware and upload it to your ESP32

effix58 commented 1 year ago

Hi, thanks for your quick reply! Regarding the order of LSB and MSB look at the screenshot below from register description of Solax hyb X1/X3 G4 V3.21 for 3 examples of 32 bit register

grafik

First 2 Bytes represent LSB, second 2 Bytes MSB.

Here a screenshot of some 32 bit values I got with Solax X3 inverter selected in firmware (LSB and MSB not changed) grafik

Obviously the values are not realistic. When I change LSB and MSB in raw data tool for example for Feedin Power to grid I get the actual feedin power grafik

Did you observe a similar behaviour of the X1 inverter?

tobiasfaust commented 1 year ago

I ask regarding your Observation in Issue #5 We will See…..

tobiasfaust commented 1 year ago

Hi I will change the Solax X3 Definition. So you are able to use it for your Inverter :)

tobiasfaust commented 1 year ago

hi, can you please test Solax X3 config with your QHome ESS hyb G3 asap and in best case confirm it? Unfortuanally, my X1 should have the same config regarding OnGridRuntime (LSB, MSB), but i got not realistic values. So i have to use MSB,LSB

htefs commented 1 year ago

Hi Tobias, I checked it yesterday at my Hyb-G3-3P. The most values, are verifiable, but I have some variables, that seems to show wrong values. I have enabled all variables and made a screenshot. Please see attached image. The serial number of the inverter is not shown in the upper part, The value for "Off Grid current L1" is wrong. If I ever had so much current, fuses would have been blown away... The value for "FeedIn Power Phase L3" is definately wrong. I have nothing, that needs so much power, don't know. if the other two values for L1 and L2 ar correct. I asked QCells for a protocol description for the Hyb-G3-3P, but did not get an answer until today. It ssems, that they are not interested, that someone uses the RS485 for getting values from the inverter... Kind regards, Helge

Screenshot_20230209_221026_Firefox

effix58 commented 1 year ago

Hi, I checked the values with my QCell hyb G3 inverter especially from the 32 bit registers and found the same results like htefs postet some minutes before. I can confirm that MSB, LSB is correct for 32 bit register. Therefore the 3 values for "FeedinPower L..." are too high, because due to register.h they are LSB, MSB. I changed it in raw tool and got the correct values. { "position": [268, 269, 266, 267], "name": "FeedInPowerPhase_R", "realname": "FeedIn Power Phase L1", "datatype": "integer", "unit": "W" }, { "position": [272, 273, 270, 271], "name": "FeedInPowerPhase_S", "realname": "FeedIn Power Phase L2", "datatype": "integer", "unit": "W" }, { "position": [276, 277, 274, 275], "name": "FeedInPowerPhase_T", "realname": "FeedIn Power Phase L3", "datatype": "integer", "unit": "W" }, I also got an unreasonable high value for "OffGridCurrent L1". I tried to find the correct position of the "OffGrid... L.." registers by means of the Solax description but with no result. One minor thing: the unit of "OutputEnergyCharge Today" should be "kWh" instead of "W", isn't it? Otherwise it is a great and easy tool to monitor my equipment!

tobiasfaust commented 1 year ago

please check that fix

@htefs, do you get any raw data for ID-Data?

htefs commented 1 year ago

Can't check it at the moment. Have compiled new version and updated it per VPN, but it did not restart proper (no connection anymore). Need to look for it, if I'm back home in the evening. But I don't know, if this helps: the correct serieal number was shown in the test software (test_RS485_Solax_ESP32.ino). But I'll send an update about the new version today in the evening.

effix58 commented 1 year ago

Hi, I checked it with firmware version of yesterday. Besides the OffGrid...L... problem each value is correct, also the FeedinPowerL... values are in line with power load of some electrical consumers. Have a look at the screenshot below. The whole parameter are divided into two parts. The upper part is updated with the chosen interval (red), the lower part isn´t (black). I don't know why this is the case now.

grafik

I also tried to compile the today´s firmware version by means of Gitpod but I didn´t get firmware.bin file in the build folder.

htefs commented 1 year ago

Hi! Compiled yesterday. Offgrid current L1 shows wrong value, see attached image. Screenshot_20230211_173930_Firefox Inverter-serial number should be in 0 to 6 in live data? Dont know why, but there are no valid data, see image (or am I to stupid to use the raw data?) Screenshot_20230211_174249_Firefox I'm currently not at home for a few days, so I can't compile and install/test new version.

tobiasfaust commented 1 year ago

last commit was an major change, migration from standard webserver to AsyncWebserver. There was a little mistake, now a firmwarefile should be generated in gitpod correctly.

Please check your "RequestIdData" String. If you get data in test ino, it should works as well here.

Please use raw data test functionality to get the right item positions for "Offgrid current L1"

effix58 commented 1 year ago

Hi, Firmware.bin could be created but when testing it the values were not updated with selected interval. Values are only updated when item configuration page is reloaded. When choosing "Solax-X3" I do not get IdData. When selecting Solax-X1 I do get IdData and the correct SN of my inverter in "Status". Then I can change to Solax-X3 and the SN of inverter stays in Status till next reboot. Perhaps this helps to solve this issue. I am not familiar with test ino. I will try to get the correct positions of "OffGrid...L.." and test it. But this may take a little time, because test can be done only with a full battery and external grid off.

ghost commented 1 year ago

can you confirm both fixes? So i want to close this issue. For OffGrid...L item you can open a new one if you want :)

effix58 commented 1 year ago

Hi, sorry for being late with my comment. My equipment is down since 2 days for a certain reason. But I can confirm that ID-data now is shown also for Solax-X3 and also the web-page is updated with the selected interval. By chance I observed that I have to select the first item in configuration in each certain selection to get the web-page updated. This is not a problem for me, it is just a hint. Regarding the OffGridL.. item I will check when my equipment is up again, but these data are not essential to me. In my opinion you can close this issue. Again thanks a lot for your work!

tobiasfaust commented 1 year ago

Hi, thanks for your information. Yes thats right, only the selected active items will push out to MQTT and Webupdate.