Dynamic ordering of items in sitemap

I decided to see if it could be done as I imagined, and it seems to work fine.
For testing I just made up these items, where all items that represent a battery level go in a group called gBatteryLevels, and each of these items has a corresponding item with the suffix _Pos, which goes in the group gBatteryPos (although that last group is not strictly needed).

Group gBatteryLevels
Group gBatteryPos

Number DoorSensor_Back_BatteryLevel "Back Door Battery Level [%d%%]" (gBatteryLevels)
Number DoorSensor_Front_BatteryLevel "Front Door Battery Level [%d%%]" (gBatteryLevels)
Number Remote1_Battery "Remote 1 Battery Level [%d%%]" (gBatteryLevels)
Number Remote2_Battery "Remote 2 Battery Level [%d%%]" (gBatteryLevels)

Number DoorSensor_Back_BatteryLevel_Pos "Back door Battery Pos [%d]" (gBatteryPos)
Number DoorSensor_Front_BatteryLevel_Pos "Front door Battery Pos [%d]"(gBatteryPos)
Number Remote1_Battery_Pos "Remote 1 Battery Pos [%d]"(gBatteryPos)
Number Remote2_Battery_Pos "Remote 2 Battery Pos [%d]"(gBatteryPos)

Of course you need to make sure that these made up items are in reality linked to a channel and get a value from that channel before moving on.
Assuming that is all done, you can make the rule that does the sorting whenever one of the battery level items changes:

import org.eclipse.smarthome.model.script.ScriptServiceUtil
import java.util.HashMap
import java.util.Map
import java.util.TreeMap

rule "Order battery levels"
when
    Member of gBatteryLevels changed
then
    // This section is only needed for first time, to get some values in the Position items: 
    // (can be removed after first time running this rule)
    DoorSensor_Back_BatteryLevel_Pos.postUpdate(1)
    DoorSensor_Front_BatteryLevel_Pos.postUpdate(2)
    Remote1_Battery_Pos.postUpdate(3)
    Remote2_Battery_Pos.postUpdate(4)
    
    var HashMap<Number, String> TestMap = new HashMap<Number, String>();
    for(var i=0; i<gBatteryLevels.members.length; i++){
        var LevelItem = gBatteryLevels.members.get(i)
        var PositionItem = ScriptServiceUtil.getItemRegistry.getItem(LevelItem.name + "_Pos")
        TestMap.put(LevelItem.state as Number, PositionItem.name)
    }
    var Map<Number, String> map = new TreeMap<Number, String>(TestMap)

    var i = 1
    for (String ItemName : map.values()) {
        ScriptServiceUtil.getItemRegistry.getItem(ItemName).postUpdate(i)
        i++
    }
end

Please note that this is something that I just made up in a relatively limited amount of time, so there might be more efficient ways to do this.

And as described in my previous post, then add the following to your sitemap:

Default item=DoorSensor_Back_BatteryLevel   visibility=[DoorSensor_Back_BatteryLevel_Pos    ==1]
Default item=DoorSensor_Front_BatteryLevel  visibility=[DoorSensor_Front_BatteryLevel_Pos   ==1]
Default item=Remote1_Battery                visibility=[Remote1_Battery_Pos                 ==1]
Default item=Remote2_Battery                visibility=[Remote2_Battery_Pos                 ==1]
Default item=DoorSensor_Back_BatteryLevel   visibility=[DoorSensor_Back_BatteryLevel_Pos    ==2]
Default item=DoorSensor_Front_BatteryLevel  visibility=[DoorSensor_Front_BatteryLevel_Pos   ==2]
Default item=Remote1_Battery                visibility=[Remote1_Battery_Pos                 ==2]
Default item=Remote2_Battery                visibility=[Remote2_Battery_Pos                 ==2]
Default item=DoorSensor_Back_BatteryLevel   visibility=[DoorSensor_Back_BatteryLevel_Pos    ==3]
Default item=DoorSensor_Front_BatteryLevel  visibility=[DoorSensor_Front_BatteryLevel_Pos   ==3]
Default item=Remote1_Battery                visibility=[Remote1_Battery_Pos                 ==3]
Default item=Remote2_Battery                visibility=[Remote2_Battery_Pos                 ==3]
Default item=DoorSensor_Back_BatteryLevel   visibility=[DoorSensor_Back_BatteryLevel_Pos    ==4]
Default item=DoorSensor_Front_BatteryLevel  visibility=[DoorSensor_Front_BatteryLevel_Pos   ==4]
Default item=Remote1_Battery                visibility=[Remote1_Battery_Pos                 ==4]
Default item=Remote2_Battery                visibility=[Remote2_Battery_Pos                 ==4]

Of course you will need to repeat this pattern if you have more than 4 battery level items, so the number of definitions in your sitemap will increase quadratically with the number of battery level items.

I hope this helps.