Turn on items based on lowest runtime - where to start?

I would like to sort a list of items based upon its runtime, and then turn on the item with the lowest runtime, but I don’t know where to start. As an items file I have this:

Switch Item1         (gSwitches)
Switch Item2         (gSwitches)
Switch Item3         (gSwitches)
Switch Item4         (gSwitches)
Number runtimeItem1  (gRuntimes)
Number runtimeItem2  (gRuntimes)
Number runtimeItem3  (gRuntimes)
Number runtimeItem4  (gRuntimes)

As a rules file I have

var GenericItem Priority1
var GenericItem Priority2
var GenericItem Priority3
var GenericItem Priority4

rule "test rule"
when Item Testing changed then {

}
end

Assuming
Item1 has a RunTime of 5,
Item2 has a Runtime of 10,
item3 has a Runtime of 15 and
item4 has a Runtime of 20,

I’d like the priority to be given to the lowest Runtime, in this case the order should be

Priority1 = Item1
Priority2 = Item2
Priority3 = Item3
Priority4 = Item4

I’ve looked through the forum and tried a few examples but nothing seems to work for my scenario. Presumably the items and values can be stored in an Array, and then sorted, but my knowledge doesn’t extend this far

WHat you trying to do, sort them on the UI ?

I’m trying to switch battery chargers based upon available solar power, and distribute the charge evenly, so the one that’s ran the least gets turned on first

Hello,

You may want to look that this thread for the cumulative use or total runtime:

You will need extra items for the times, eg. item1_runtime…
You will need to put your items in groups. eg. gRuntime, gItems, gPriority…

You will then need to work with items in groups (the arrays mentionned in your post):

Regards

I’ve sorted the runtime calculations already, it’s triggering an item based upon the lowest runtime that I don’t know how to do.

Rename your items such as Item_1, runtimeItem_1…
You need to change the Priority items to number
Then do a group.sort (See above link)
Get the number in order and “save” into Priority_1, Priority_2…

Then when you want to turn your items on you can do:
sendCommand(“Item_” + Priority_1.state.toString, ON)…

1 Like

Thanks for the links, very helpful, for turning on I used

gChargerTimes.members.sortBy[(state as Number).intValue].forEach....

Is there a way of doing the sort in reverse order? For turning things Off I want to find which charger has ran the most.

Hi,
Not that I know of, but you can allways iterate through the list in reverse

val Times = gChargerTimes.members.sortBy[(state as Number).intValue].forEach....
for (int i=Times.length; i>=0; i--) {
    // Do your stuff
}

In the end I discovered that turning them off in order is as good a solution as any because with daytime solar availability it seems to even out. I’ve also added power monitoring so I can see which ones are nearly charged and terminate their charge early to allow longer battery life.

To update this thread for anyone following on I ended up with something based upon this

Items:

Group:Switch:OR(ON, OFF) gChargers  (gSOff)
Group gChargerTimes
Group gChargerPower

Switch Charger1 (gChargers)
Switch Charger2 (gChargers)
Switch Charger3 (gChargers)
Number MinsCharger1 (gChargerTimes)
Number MinsCharger2 (gChargerTimes)
Number MinsCharger3 (gChargerTimes)

Rules:

rule "increment charger runtime"
when Time cron "0 0/1 * * * ?" then	{
gChargers.members.filter(y | y.state == ON).forEach[onItem|
val rtItem = "Mins" + onItem.name.toString
var NewrtItem = gChargerTimes.members.findFirst[i | i.name == rtItem] as GenericItem //   
var rtOld = NewrtItem.state as Number
var Number rtNew = rtOld + 1
sendCommand(rtItem, rtNew.toString)
]
}
end

rule "turn chargers on"
when <the sun came out> then {
gChargerTimes.members.sortBy[(state as Number).intValue].forEach 
[ NumberItem lowestRuntime | 
val chargerName = lowestRuntime.name.toString.split('Mins').get(1)
var chargerItem = gInverterChargers.members.findFirst[i | i.name == chargerName] as GenericItem
if (chargerItem.state == OFF && UsablePower.state > 150){
	chargerItem.sendCommand(ON)
Thread::sleep(15000) // to allow power monitoring to respond
}
]
}
end

"rule turn chargers off"
when <the sun went in> then{
gInverterChargers.members.filter(oc | oc.state == ON).forEach[offchargerItem|
if (ChargeOFF > UsablePower.state as Number) 
{offchargerItem.sendCommand(OFF)}
Thread::sleep(15000) // to allow power monitoring to respond
]
}
end