The solution provided by
AustralIan is pretty much dead on. However, you need to determine if an upper limit must be set on batteries not at full capacity. For instance, if one is only able to provide 10KW, is there any danger in demanding 10KW from it or should the demand be reduced to 9.5kW (95%) to allow it to charge?
If not, then you should do exactly what was described.
If so, however, then you will need logic that looks for a less than full capacity battery and multiply its available power by the maximum power factor (for instance, if 95% is the max you want to run the battery at, then multiply the available power by 0.95 and use the result in the total available power calculation).
So your code will:
1. Read in all of the available power values from the ModBus addresses and store them to variables (like B1_AP for battery 1 available power)
2. (If required; If not, skip to 3) Determine if any batteries have less than maximum available power and multiply the available power by the maximum power factor. You should write to a new variable (like B1_AP*Max_Power => B1_EP for battery 1 effective power). If the battery has full available power, have the logic simply move the available power value to the effective power value (like B1_AP => B1_EP).
3. Add up all of the EP values (or just the AP values if step 2 is not required) and store the sum in a variable (like B_TAP for battery total available power) and divide 1500000 by the sum. Store the quotient in a variable (like B_DP for battery demand percentage). This will be the percent of available power that each battery will have to deliver to meet the demand of 1.5MW. If the value is greater than 1, write 1 to this variable, as you cannot exceed the available power of the batteries.
4. Multiply the DP value with the EP value (or AP value if step 2 is not required) and send them to the ModBus addresses for the commanded power from each battery.
What data type are the ModBus values? Are the real (floating point), Double Integers, Integers, etc.? Your calculations and variables should all be reals to simplify everything for you. If the ModBus addresses are not reals, then you will need to convert them to and from reals for the available values and demanded values, respectively, using Any_To_X instructions.
Breaking up everything into individual variables will allow you to monitor everything from an HMI or SCADA system more easily.