Order items of a group

Hi everybody, I hope that somebody can help me. I’ve a rule which set lights in a group to the same value. That works fine. Now, I want to order the items in the group by their names to change the values in a special order. How can i get that?

var Collectors = Java.type("java.util.stream.Collectors");
var gNachtlichtAussen_Dimmer = ir.getItem("gNachtlichtAussen_Dimmer");
gNachtlichtAussen_Dimmer
        .getAllMembers()
        .stream()
        .forEach(function(i){ 
          events.sendCommand(i.name, ir.getItem("GartenbeleuchtungDimmer").getState());
          logger.info(i.name);
          java.lang.Thread.sleep(250);
        });

Many thanks and best regards
Peter

maybe this helps a little bit. Use sortby

for (gasPrice : gGasStationPrices.members.sortBy[ state as DecimalType ]) {
		
		    val String gasKey = gasPrice.name.substring(1, gasPrice.name.lastIndexOf('_'))

			var ContactItem stationOpen = ScriptServiceUtil.getItemRegistry.getItem("i"+gasKey+"_Open") as ContactItem
			var StringItem stationDisplay = ScriptServiceUtil.getItemRegistry.getItem("iSL_OH_GasStationItems_Display"+String::format("%02d", counter)) as StringItem
			
			stationDisplay.setLabel(transform("MAP", "i18n_gasstation.map", gasPrice.name.substring(1, gasPrice.name.lastIndexOf('_'))))

			if (stationOpen.state == OPEN) {

				stationDisplay.postUpdate(String::format("%.3f €", (gasPrice.state as DecimalType).doubleValue()))

			} else {

				stationDisplay.postUpdate(transform("MAP", "i18n_contact.map", stationOpen.state.toString))

			}
			
			counter++
			logInfo(ruleIdentifier, "Price for station {} processed.", gasKey)

		}

When using the Java stream API like this you can use the sorted() method. However that will order them based on their “natural” order. I’m not sure that Items have a natural order. Try it and report back if.

NOTE: use the items dict.

var Collectors = Java.type("java.util.stream.Collectors");
var gNachtlichtAussen_Dimmer = ir.getItem("gNachtlichtAussen_Dimmer");
gNachtlichtAussen_Dimmer
        .getAllMembers()
        .stream()
        .sorted()
        .forEach(function(i){ 
          events.sendCommand(i.name, items["GartenbeleuchtungDimmer"]);
          logger.info(i.name);
          java.lang.Thread.sleep(250);
        });

If that doesn’t work you can create a Comparitor but it would probably be easier to use a map to get a list of just the Item names. Strings do have a natural order.

var Collectors = Java.type("java.util.stream.Collectors");
var gNachtlichtAussen_Dimmer = ir.getItem("gNachtlichtAussen_Dimmer");
gNachtlichtAussen_Dimmer
        .getAllMembers()
        .stream()
        .map(function(i){ return i.name; })
        .sorted()
        .forEach(function(name){ 
          events.sendCommand(name, items["GartenbeleuchtungDimmer"]);
          logger.info(name);
          java.lang.Thread.sleep(250);
        });

That only really exists in rules DSL unfortunately. In Nashorn JavaScript it’s easiest to use the Java Stream API. In Python it’s easiest to use Python native ways of managing lists and dicts.

Speaking of the streams API in Rules DSL, you could also implement your for loop as

gGasStationPrices.members
                 .sortBy[ state as Number] // Use Number instead of DecimalType, it avoids some problems
                 .forEach[ gasPrice |
                     val gasKey = gasPrice.name.... // Don't force the type unless you have to

Hi Rich, thank you very much.

I try at first the sorted method:

var Collectors = Java.type("java.util.stream.Collectors");
var gNachtlichtAussen_Dimmer = ir.getItem("gNachtlichtAussen_Dimmer");
gNachtlichtAussen_Dimmer
        .getAllMembers()
        .stream()
        .sorted()
        .forEach(function(i){ 
          events.sendCommand(i.name, items["GartenbeleuchtungDimmer"]);
          logger.info(i.name);
          java.lang.Thread.sleep(250);
        });

That throws an exception:

Fail to execute action: 1
java.lang.ClassCastException: class org.openhab.core.library.items.DimmerItem cannot be cast to class java.lang.Comparable (org.openhab.core.library.items.DimmerItem is in unnamed module of
 loader org.eclipse.osgi.internal.loader.EquinoxClassLoader @279a773a; java.lang.Comparable is in module java.base of loader 'bootstrap')

So i try to use a map:

var gNachtlichtAussen_Dimmer = ir.getItem("gNachtlichtAussen_Dimmer");
gNachtlichtAussen_Dimmer
        .getAllMembers()
        .stream()
        .map(function(i){ return i.name; })  
        .sorted()
        .forEach(function(name){ 
          events.sendCommand(name, items["GartenbeleuchtungDimmer"])
          logger.info(name);
          java.lang.Thread.sleep(250);
        });

That works really fine! The items are sorted by their names. That’s my preferred solution!

Thank you very much