This is almost an application. But if you struictly follow the pattern, your sendCommands would only be at the end. Let’s see if we can do that…
// 1. See if the rule needs to run
// The rule needs to run any time any member of gHneed changes
// 2. Calculate what needs to be done.
// gf and ff always follow the corresponding need and bf needs to be ON if any need is ON
val bf = if(BF_Heating_need.state == ON || GF_Heating_need.state == ON || FF_Heat_need.state == ON) ON else OFF
val gf = GF_Heating_need.state // follows the need Item so just use that
val ff = FF_Heating_need.state // follows the need Item so just use that
// 3. Do it
if(bf != BF_Heating_Pump.state) BF_Heating_Pump.sendCommand(bf)
if(gf != GF_HEating_Pump.state) GF_Heating_Pump.sendCommand(gf)
if(ff != FF_HEating_Pump.state) FF_Heating_Pump.sendCommand(ff)
We can further reduce it to
val bf = if(BF_Heating_need.state == ON || GF_Heating_need.state == ON || FF_Heat_need.state == ON) ON else OFF
if(bf != BF_Heating_Pump.state) BF_Heating_Pump.sendCommand(bf)
if(GF_Heating_need.state != GF_Heating_Pump.state) GF_Heating_Pump.sendCommand(GF_Heating_need.state)
if(FF_Heating_need.state != FF_Heating_Pump.state) FF_Heating_Pump.sendCommand(FF_Heating_need.state)
Or, if you don’t care if the Pump receives a command that is the same as it’s current state
BF_Heating_Pump.sendCommand(BF_Heating_need.state == ON || GF_Heating_need.state == ON || FF_Heat_need.state == ON) ON else OFF)
GF_Heating_Pump.sendCommand(GF_Heating_need.state)
FF_Heating_Pump.sendCommand(FF_Heating_need.state)
Another way to do the comparison would be
BF_Heating_Pump.sendCommand(if(gHneed.members.filter[ i | i.state == ON ].size > 0) ON else OFF)
GF_Heating_Pump.sendCommand(GF_Heating_need.state)
FF_Heating_Pump.sendCommand(FF_Heating_need.state)
Or if you define your Group as
Group:Switch:OR(ON,OFF) gHneed
The rule can become
BF_Heating_Pump.sendCommand(gHneed.state)
GF_Heating_Pump.sendCommand(GF_Heating_need.state)
FF_Heating_Pump.sendCommand(FF_Heating_need.state)