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.