Integration of a Fronius Symo Gen 24 plus Inverter via Modbus TCP

Hi Henrik @hossians,
I did, it’s working for me but might need some polishing before ready to release. At the moment, I’m managing when and how quickly the battery will be charged. Due to regulations here, my AC output to the grid is limited by 70% of the total kWp installed. Im fetching forecast data for PV production from solcast.com. If the forecast is above a certain threshold I limit battery charging to the peak hours of the day to make sure the system is always 100% productive.

The main part is to control the charging flow, this is done with the following command:

service: modbus.write_register
data:
  unit: 1
  value: '500' # charging value in Watt 
  hub: fronius1 # name of your modus hub
  address: 40366 # rmodbus register to control charging "InWRte" (-1 offset observed in the register numbering) 

If you want to control discharge, you can use address 40365 “OutWRte”

In my automation, it looks like this

# Solar Battery Charging Configuration
- alias: WRBatteryStoreExcessEnergy7k
  trigger:
    platform: numeric_state
    entity_id: sensor.derived_energy_pv_output_total
    above: 7000
    for:
      minutes: 2
  condition:  "{{ states('sensor.solcast_forecast')|int > 40 }}" 
  action:
    service: modbus.write_register
    data:
       unit: 1
       hub: fronius1
       address: 40366
       value: '1200'

The improvement I would still do is to implement some state information that charging has already been configured if this has triggered once - otherwise, in case of clouds or other impacts to your solar production, the condition is met multiple times in a short period and the register is written more often than necessary.

1 Like

Thank you Oscar! That is really good to know, then I can proceed with sourcing the Fronius inverter.
I’m planning to buy and sell “per hour” as we can see very big swings in the price over a 24h period. I don’t have the 70% limitation in Sweden so the battery and the inverter will be the limiting factor for selling, but buying we have a monthly power tariff so that is a little bit more tricky. Will have to do some nice calculations to find the optimal sell/buy rates and thresholds…
The list of registers that is writeable, where did you find them?

/Henrik

Thank you very much for the detailed explanation:) I tried to follow it, but , at my copy/paste level… no luck :sweat_smile:

I was hoping you have them already in the format you showed earlier , where my copy/paste/adapt/change_name would actually shine :laughing:

Cheers

Hi @Momo - after the upgrade to 2022.4 I noticed that the modbus values are not updated anymore. The reason was a change in the handling of data types in the modbus integration (see Remove generic data types INT, UINT, FLOAT in modbus by janiversen · Pull Request #67268 · home-assistant/core · GitHub). I will update my examples in the intial post in the next couple of hours. Which version are you running?

KRs, Oscar

Hi @soly3141 :slight_smile:

I’m running 2022.4.1.

The power values of MPPT1 and MPPT2 i have copied from @ipetrovits still update just fine .

This is how the updated reading section looks like. The changes are only in the first three sensors (reading_energy_main_meter, reading_energy_inverter_ac_output, reading_energy_battery_soc_scaled)

modbus:
  - type: tcp
    host: 192.168.x.x
    port: 502
    name: fronius1
    sensors:
      - name: reading_energy_main_meter
        slave: 200
        scan_interval: 2
        count: 2
        address: 40097
        data_type: float32
        unit_of_measurement: W
      - name: reading_energy_inverter_ac_output  
        unit_of_measurement: W
        slave: 1
        count: 2
        data_type: float32
        address: 40091
        scan_interval: 2
      - name: reading_energy_battery_soc_scaled
        slave: 1
        count: 1
        data_type: uint16
        address: 40361
        scan_interval: 2
      - name: reading_inverter_multiple_raw
        slave: 1
        count: 88
        address: 40265
        scan_interval: 2
        data_type: custom
        # Registers and positions in custom structure
        # 0  DCA_SF
        # 1  DCV_SF
        # 2. DCW_SF DC Energy scaling factor
        # 3. DCWH_SF
        # 4  1_ID
        # 5  1_DCA
        # 6. 1_DCV
        # 7. 1_DCW Energy string 1
        # 8  2_ID
        # 9. 2_DCA
        # 10 2_DCV
        # 11 2_DCW Energy string 2
        # 12 3_ID
        # 13 3_DCA
        # 14 3_DCV
        # 15 3_DCW Energy to battery, charging
        # 16 4_ID
        # 17 4_DCA
        # 18 4_DCV
        # 19 4_DCW Energy from battery, discharging
        structure: ">hhhh8x H16xHHH16x H16xHHH16x H16xHHH16x H16xHHH16x" 
2 Likes

Super:) Thank you !!

But now i’ll start from the top as newbie if thats ok.

Modbus should be set as float or int+SF?

Your meter address is 200 - where can i find that address in the web interface ? What i found on my system is SmartMeter Modbus address: 1

The slave 1 - i assume this is the first invertor. In case i have 2 invertors daisy chained and one smartmeter, i should make the same config for slave 2, correct?

Is there any way to retrieve the MPPT DC value ? Currently i get it using json API from history :frowning:

Thank you again and i hope you do not mind all the questions.

Hi, I have only a few mins so i’ll cherry pick from your questions, hoping others with multiple inverters and smartmeters will be able to help you in the rest (i have only 1 symo without smartmeter)

  • Modbus should be set as float or int+SF?
    Up to you, it was easier for me to find out that the register addresses are misaligned with the documentation (debugging standard integers and translating from hex was faster), and then i got stuck with this config. One caveat, if you read int+SF, those must be read in the same query. If you define multiple modbus entities, those will be separate queries. I thought that would be an edge case when during the readings the scale factor changes, it turned out to be occuring multiple times a day causing spikes in the data, messing up stats. You also will need a template entity to do the math.
    I did not change to float, because not all data can be read in float format, there is some registers still in int+sf format regardless of the default setting.
    i.e. MPPT data is in a different register if you’re in float mode, but the data is still in int+sf format.

  • Is there any way to retrieve the MPPT DC value ? Currently i get it using json API from history
    Realtime MPPT DC values only available via custom modbus at the moment. Btw i had issues with the json api - values not refreshing in time etc. so this was the reason for modbus at all.

Can you please elaborate ?

Modbus is not working yet with the new Update…isn´t it?

It should work, at least for me it does :wink:

If you have issues, did you try analysing your logs to find errors related to your modbus setup?

KRs

1 Like

okay, but the new release removes “int”, “uint” and “float” as data_types.

i have this one in my Modbus configuration :frowning:

modbus:
  - type: tcp
    host: 10.0.0.245
    port: 502
    name: fronius1
    sensors:
      - name: reading_energy_main_meter        
        slave: 200
        scan_interval: 2
        count: 2
        address: 40097
        data_type: float
        unit_of_measurement: W
      - name: reading_energy_inverter_ac_output          
        unit_of_measurement: W
        slave: 1
        count: 2
        data_type: float
        address: 40091
        scan_interval: 2
      - name: reading_energy_battery_soc_scaled        
        slave: 1
        count: 1
        data_type: uint
        address: 40361
        scan_interval: 2
      - name: reading_inverter_multiple_raw        
        slave: 1
        count: 88
        address: 40265
        scan_interval: 2
        data_type: custom
        # Registers and positions in custom structure
        # 0  DCA_SF
        # 1  DCV_SF
        # 2. DCW_SF DC Energy scaling factor
        # 3. DCWH_SF
        # 4  1_ID
        # 5  1_DCA
        # 6. 1_DCV
        # 7. 1_DCW Energy string 1
        # 8  2_ID
        # 9. 2_DCA
        # 10 2_DCV
        # 11 2_DCW Energy string 2
        # 12 3_ID
        # 13 3_DCA
        # 14 3_DCV
        # 15 3_DCW Energy to battery, charging
        # 16 4_ID
        # 17 4_DCA
        # 18 4_DCV
        # 19 4_DCW Energy from battery, discharging
        structure: ">hhhh8x H16xHHH16x H16xHHH16x H16xHHH16x H16xHHH16x"
1 Like

Hi @Vaioraner,
I have updated the documentation some time ago to adapt to the new data type handling: Integration of a Fronius Symo Gen 24 plus Inverter via Modbus TCP or this earlier post, specifically about the data type changes Integration of a Fronius Symo Gen 24 plus Inverter via Modbus TCP - #45 by soly3141

Does this help? KRs,
Oscar

1 Like

OMG! I am an Ideot :slight_smile:

you made my Day!

Thanks Oscar!
vielen Dank!

lg wolfgang

You can get past data from REST API, which is lagging and not realtime, but also had trouble with it, it was not stable.
Official and a 3rdparty integration is working well, but I havent seen any with MPPT values - therefore I made my system read all info from the inverter directly - via Modbus, where this data is available to read.
Possible that there will be an integration in the future handling this, maybe there is one already in development, but native modbus works rock solid. All the past errors with this interface was caused by breaking changes introduced…

1 Like

Can you post all your config for modbus please? and for the sensors in HA ? For all non tech people like me that have a really hard time doing it by themselves despide all the info provided.

Thank you

@hossians did you go for a Fronius or Sungrow inverter? I’m about to install sungrow hybrid inverter and battery in Torslanda and I want to control charge/discharge based on spot price as well as peak shaving.

@soly3141 thanks for sharing this.

I tried your example and everything works great, except for the reading of multiple raw values. I just don’t receive any data for that. Does that still work for you?

Thanks for this example!
During night I see a lot of peaks, which might be the try to start again. how do you handle this?

I got this working now using “1_DCst” and “2_DCst” (Operating state string 1+2). If it’s status is not “4” (which is normal operating), i set all depending values to 0. So now my graph is “clean”.