How can I use a lambda function to update an int global variable?

Hello to everybody,
I’m currently using openHAB to control three Fritz!DECT 200 switches.
Even though I’m not a java programmer, I wrote a rule for each switch with the same logic but different parameters: each switch is assigned a priority and a power threshold. When the power threshold is exceeded, the rule checks if higher priority switches are above threshold (overload condition) and opens the switch if necessary. In this way the washing machine and the tumble dryer at the same time: openhab simply switches off the tumle drier when the washing machine heats the water but after that phase it switches it on again.

The rules modify the global variable Status (which is int): each rules raises or lowers the bit corresponding to the assigned priority.

I tried to use a lambda expression following the example on the wiki, but I’m not able to modify the Status variable.
Following some suggestions that I read in the forum, I’ve tried to use a Number Item, but I am unable to assign it to an int variable.

The expression
var int Status = StatusItem.state
is not accepted,while
var int Status = StatusItem.state as int
seems to be syntactically accepted, but the lambda expression is not executed after that statement.

I attach in the following the rule and the lambda function.
Thanks for your attention,
LionHe

/*Setting priority and thresholds of switches */

	val Number  threshold1=500 //cucina
	val int 	Priority1=3  /* 1 minima priorità,... 8 massima priorità */
	val Number  threshold2=500 //asciugatrice
	val int 	Priority2=1  /* 1 minima priorità,... 8 massima priorità */
	val Number  threshold3=650 //lavatrice. limite alzato per centrifuga
	val int 	Priority3=2  /* 1 minima priorità,... 8 massima priorità */
	var int StatusSwitch=(0x00) /* Valore iniziale pari a zero */

rule "Check Switch 2"
	when
		Item FritzSwitch2Power received update
	then
		var int BitSet   =(0x01<<Priority2)
		var int BitClear =BitSet.bitwiseXor(0xF)  /* workaround because  the NOT operator is not available */
		var Number SwitchPower
		var String tmp="Default2"
		
		if (PowerControl.state == ON) {
		
/* update Status bit according to actual power */

 	 		if(FritzSwitch2Power.state instanceof DecimalType) {
  				SwitchPower=FritzSwitch2Power.state as DecimalType
 	
			    if (SwitchPower > threshold2) {
		    		StatusSwitch=StatusSwitch.bitwiseOr(BitSet)		/* Set High Power Bit on */
		    		tmp="Switch2 High Power"+StatusSwitch
		    	} 
				else  {
					StatusSwitch=StatusSwitch.bitwiseAnd(BitClear)	/* Set High Power Bit off */
		    		tmp="Switch2 Low Power"+StatusSwitch
				}
			}

/* Switch ON or OFF the switch according to Status Bit*/
			if (StatusSwitch.bitwiseAnd(BitSet)!=0) tmp=tmp+"bit 1" else tmp=tmp+"bit 0" 
			if (StatusSwitch>>(Priority2+1) == 0) { // if no higher priority is in high power state
			 tmp=tmp+"no overload"
				if(FritzSwitch2.state == OFF) {  //then checks if switch needs to be set to ON
					sendCommand(FritzSwitch2,ON)    // it was OFF set it to ON            
					tmp=tmp+"Switch2 OFF->ON"
					}
			} else {                                        // higher priority loads are in high power
				if( (FritzSwitch2.state == ON) && ( StatusSwitch.bitwiseAnd(BitSet) != 0) ) { //is it ON and in high POWER?
					sendCommand(FritzSwitch2,OFF) //yes switch it OFF
					tmp=tmp+"Switch2 ON->OFF"
				} else {
   					tmp=tmp+"Switch2 unchanged"
   				}
			}
		} else {
			tmp="Check2 PowerControl OFF"
		}
		postUpdate(DebugMessage2,tmp)
end

The non working lambda function is the following

val org.eclipse.xtext.xbase.lib.Functions$Function6 SwitchControl = [
org.openhab.core.library.items.SwitchItem FritzSwitch,
org.openhab.core.library.items.NumberItem FritzSwitchPower,
org.openhab.core.library.items.NumberItem PowerStatusLocal,
org.openhab.core.library.items.StringItem DebugMessage,
int Threshold, int Priority |
logInfo(“Lambda”,“Lambda Started”)
val int BitSet = (0x01<<Priority) //as int
val int BitClear =BitSet.bitwiseXor(0xF) // as int
logInfo(“Lambda”,“after Bit”)
var Number SwitchPower=0
var String tmp="No Msg"
logInfo(“Lambda”,“after var declarations:”+(PowerStatusLocal.state as int) )
var int Status=PowerStatusLocal.state as int //LAMBDA FUNCTION STOPS HERE
logInfo(“Lambda”,“after Status”+Status)
if(FritzSwitchPower.state instanceof DecimalType) {
/* update Status bit according to actual power /
SwitchPower=FritzSwitchPower.state as DecimalType
if (SwitchPower > Threshold) {
Status=Status.bitwiseOr(BitSet) /
Set High Power Bit on /
tmp=“High Power”+Status+SwitchPower
}
else {
Status=Status.bitwiseAnd(BitClear) /
Set High Power Bit off */
tmp=“Low Power”+Status+SwitchPower
}
PowerStatusLocal.postUpdate(Status) //update Status variable after manipulation
} else tmp="No Decimal"
logInfo(“lambda”,tmp)
true
]

Could you instead try

var Number Status = StatusItem.state as Number

and then only set the Status variable to types that implement Number (like Integer, Double, BigDecimal, DecimalType)?

Thank you watou for your hint.
As I said, I am not skilled at all in object oriented programming, so forgive my naive questions: once i’ve read the Status variable how can I convert it from Number to int, so that I can manipulate bits with
Status=Status.bitwiseOr(BitSet)
(This expression does not work with Number variables)
Thank you for your help
Lionhe

No worries! Any object that implements Number has a method .intValue which returns an int:

var Number myNumber = MyItem.state as Number
var int myInt = myNumber.intValue
1 Like

I had to slightly modify it, because "as Number "was not accepted

var Number StatusNumber=PowerStatusLocal.state as DecimalType
var int Statusint = StatusNumber.intValue

Thank you again @watou
LionHe

1 Like