I am in the middle of having a brain **** and hoping you guys can get me back on track.

I have some code in a marshalling PLC (CompactLogix L30ER) which is adjusting the load outputs of generators based on the available fuel which is working fine.

However we now want to introduce a priority system whereby a value from 1-3 is set in an external database (I can read write from this already) and I adjust the generators in order based on this priority value - So if for example Generator 1 is set with a priority of 1 it will increase load first and decrease load last, if however it is a priority 2 then it will wait until the other generators with priority 1 have reached their max load and so on

I am sure there is an elegant solution to this but I currently cant see the wood for the trees.

You could have a three-element array where item 0 is highest priority, 1 = second, 2 = third. The database would set the array element values corresponding to the generator ID's. A capacity pointer will have the value 0, 1, or 2 depending on how much generation is currently in use. Short-term changes in load will affect the generator ID referenced by this pointer. When it exceeds the current generator capacity, add one to the pointer and activate the next generator ID in the array. It is similar for decreasing capacity and deactivating generators.
We do this with compressors and cooling towers, and it readily extends to more complicated scenarios with using fractional capacity across units (e.g., 25%, 25%, 25%, 50%, 50%...) or within units (e.g., 25%, 50%, 75%, 100%, 25%, 50%, ....) depending on how the array contents are defined and interpreted by the capacity adjustment routine.
Of course, the system should be shut down when the capacity strategy (i.e., array values) is adjusted from the database, or very carefully if done on-the-fly.

Thanks for the reply, really useful and got me thinking. Once complexity I neglected to mention (told you I was in a spin !) is that there could be multiple generators using the same priority.....Will this approach still accommodate ?

It depends on how the priority system is supposed to work. If the behavior is such that two generators at the same priority means they are interchangeable, but that you still run one of them to maximum before activating the next one; then the priority array only needs to have generators of equal priority adjacent to each other. For example, say generator A is priority 2, B is 1, and C is 1. The array contents would either be (B, C, A) or (C, B, A). [If implementing as an integer array, you would define A, B, and C to numbers; letters are used here for clarity.]

It gets trickier if equal priorities mean running two generators at the same output, and both must be maxed out before activating the next priority. That would require another level of indirection coming off of the priority array. The capacity control routine would need to scan the list of generators at the current priority to manipulate all of them before moving to the next priority.

Thanks for the info thus far, sadly it is the trickier of the two options. So if I have 2 generators (A & B) both at priority 1 they need to increase to their max load simultaneously before moving onto increasing any generators set to priority 2,3 and so on

For each unique "duty" (1, 2 or 3) that exists, you therefore have 5 steps (let's assume that a duty of 0 means the generator is disabled).

So, first thing to do is work out how many total sequence steps you have. If you have duty set to 1, 2, 3 then you have 15. If you have duty set to 1, 1, 3 you have 10. If you have duty set to 0, 1, 1 you have 5. There are a few ways to approach this, but even brute force is only a handful of instructions.

Once you have this number, move it into the preset of a counter. That counter is your load/unload master control.

Use your counter to count up and down as necessary (just remember to limit the count where necessary - e.g. if your counter is up to 15 and one generator gets switched to duty 0, then you'll need to drop it back down to 10).

If the counter is at 0, no generators running (theoretically).
If a generator has duty 1, it will load 20% at count 1, and 100% at count 5.
If a generator has duty 2, it will load 20% at count 6, and 100% at count 10.
If a generator has duty 3, it will load 20% at count 11, and 100% at count 15.
Again, there are a few ways to approach this, but even brute force is not overly complex.

This will work no matter what combination of duties you have. Of course, there's the potential issue that if you have duties 1, 1 and 3 - nothing will happen while the counter counts between 5 and 10. Likewise, if you have nothing on duty 1, no generators will turn on until the counter gets to 6. If either of these are issues, you can tweak things to suit - have the counter check to see if there is an available generator for it's current loading step, and if not, immediately count to the next one. Or, you could force duties to not leave gaps. Or, you could slap your operators with a wet fish every time they do something silly with the duty numbering until they learn not to. So many possibilities!

I would probably go with a 2-dimensional array where, say, the rows are priority groups and the columns are generator ID's within each group. An Active-Priority pointer would indicate the highest priority group (row) with available capacity.
When the capacity control routine needs to change capacity it would reference the Active-Priority to find the ID's of generators in that group by examining non-zero columns in that row. Those generator(s) would be manipulated together, and if all are running at maximum, increment the Active-Priority pointer and start increasing the next, lower priority group. Likewise on decreasing capacity, when all are turned off, decrement the priority pointer to the next, higher priority group.
Since your number of columns would be the maximum possible generators at specific priority, and the number of rows equal to the total number of generators, this ID table will likely be sparsely populated.
[In practice, I would probably add a column (e.g., col zero) to indicate status of the group (e.g., empty, capacity full, capacity available) and have the capacity control routine scan that column to decide which group to operate on (i.e., highest priority with available capacity), rather than relying on the Active-Priority pointer.]