Hi Francesco,
glad to hear that this was useful for someone out there
I’ve googled to look for custom data type and structure but I didn’t find any specific explanation.
Could you please point me to a tutorial or manual to understand how it works ?
At the end of the document there is a reference table of Format Characters - you will recognize those in my code. There are also some examples included how to do shortcuts: e.g. 8x means “8 padding bytes in a row”
I hope this was helpful, let me know if you have further questions.
Kind regards,
Oscar
many thanks for taking time to reply. I’m still need to study your script and also the Python doc… (I’m newbie). I’ve succeed to include Energy by reading directly the register (40285) then tempating by multiplying it for its multiplier…
Then to learn from your code:
you read 88 (registers, 16bit) from modbus TCP
data type: custom is required to keep the read values as they are…
structure: “>hhhh8x H16xHHH16x H16xHHH16x H16xHHH16x H16xHHH16x” directive let you to unpack each according to its type (short, unsigned short,…) as described for each in Fronius modbus table.
It’s correct to say ? “>” big endian, the first 4x “h” means firs parameters are unsigned short,…
so then in each index you will have the parameters decodified and ready accordingly…
am I correct ?
Still I can’t understand “8x” or “16x”. They might represent a parameter made of bit … but it doesn’t seem to match with Fronius table or even the list you provided becasue only ID might be this type of data… what I miss ?
Thank you for this !!
I was able to get the string power finally on my setup with Symo 10.
Can you please share how to get the voltages also please? DC voltage for strings and AC voltage for phases
Or even better the codes/sensors for all the data from Modbus - or at least everything you have.
I know it is a lot, and i’ve tried for at least 8 hours to do it myself, but it is well over my head …
Now i am using the API requests but i’d like to switch everything to modbus as it seems much better and faster.
Did you get any further with your plans to control the power flow to/from the battery? I’m in the phase to choose inverter and that is a hard requirement for me that I can control dynamically when to charge and discharge the battery (and preferable from Home Assistant).
I’m glad it helped. It is really not that hard once you figure it out for the first time - but the first time indeed - not that easy.
I followed a document called Modbus_TCP_RTU.pdf, downloaded from Fronius after registration.
Check the data you need:
i.e. AC power.
Search and find, keep in mind in my example I use int+SF (whole numbers + scale factor. If you have 50 as data and -2 as SF, data must be multiplied by 10 on the power of SF - in our example 50* 10^-2 = 50 * 0.01 = 0.5W)
After some trying and using modbus testing tool, you realize the doc is off by 1 register address as counting starts from 0 → so you’re looking for 40083 as start
you need 2 registers → count: 2
and you need an unsigned integer as data (watts never go below 0 ), and a signed as scale factor → structure: “Hh”
(source: struct — Interpret bytes as packed binary data — Python 3.10.4 documentation )
Then do the math in the template sensor by using the above dataset and split that az every colon char.
The MPPT values are trickier as those are not often together:
Remember, registers are off by 1, so startaddress + line address - 1
We start with register 40257
We need 38 registers in total
data is like Signed integer(h) + 32 junk(32x) + unsigned integer(H) + 38 junk(38x) + unsigned integer(H)
Junk registers will be skipped simply.
I’m not sure how this works with a smart meter, but from the docs it seems if you have monitoring tied to the inverter, you even could get consumption data out the same way.
You may also use float, for me hat did not work out somehow. Int+SF is rock solid if you read both values in the same entity. If it is divided to different modbus entities, there will be spikes as they won’t always align.
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”
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.
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?
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)
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
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.
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…