How do I Increment an item state held in a variable?

Hi,
I am on OH2.5x and trying to work out how to add a number to var pointing to an item. I have no idea if that is an accurate description of what I trying to do. I feel like I have tried all variations, but I suspect I will have missed totally the way to solve this problem.

Here is a failing example, I am expecting the var to + 5 from its original value held in .state.

    var _Max = gHumidMax.members.findFirst[ max | max.name == "HO_Max_Humid" ]
	logInfo("Test.rules", " Max was " + _Max.state)		
	_Max = (_Max.state) as Number + 5
	logInfo("Test.rules", " Max now " + _Max.state)

I have tried all variations so have seen many different errors, I do note that if I change the last line to be

logInfo("Test.rules", " Max now " + _Max)

I do get the right answer but I really want to be able to reference it as _Max.state

Thanks

Paul

var _Max is not a item its a variable therefore it has no state

You need to define your item in an items file

2 Likes

This works, but it is a little cleaner to get the Item directly using…

You are changing _Max from an Item to a Number, so it would no longer have a state attribute. Instead, you could update the state of the Item using…

val new_Max_state = (_Max.state) as Number + 5
 _Max.postUpdate(new_Max_state)

… but you will then have to wait for the EventBus to read that state, so your next line will only log the old state. However, you can use…

val new_Max_state = (_Max.state) as Number + 5
 _Max.setState(new DecimalType(new_Max_state))

… but you will not receive an ItemStateEvent. Though, you will get an ItemStatedChangedEvent. So, be mindful of your rule triggers when using setState. All together…

import org.eclipse.smarthome.model.script.ScriptServiceUtil// add imports to the very beginning of the rule file, before global variables and rules
...
    val _Max = ScriptServiceUtil.getItemRegistry.getItem("HO_Max_Humid") as GenericItem
	logWarn("Test.rules", " Max was {}", _Max.state)		
	val new_Max_state = (_Max.state) as Number + 5
    _Max.setState(new DecimalType(new_Max_state))
	logWarn("Test.rules", " Max now {}", _Max.state)

I also used parameterized logging, which is safer and faster than using the + operator to concatenate strings.

1 Like

This is not doing what you think. Beforehand, _Max is an Item you got hold of via group.
So you add state and number … result is a number.
The result is put into variable _Max
_Max is now a number, not an Item. Rules don’t mind you changing variable types.
But it’s no longer an Item, it has no .state.

When you add useful diagnostic logInfos to your rules, please do show us the results.

Are you actually trying to send your maths result back to the original Item?

Thanks guys for all the great replies.

I can see now that I have changed the _Max from pointing to an item that has a state to a variable that does not have a state just a value.

Stepping back a little to view what I am trying to achieve I realise I may well have made some incorrect logic decisions.

I have a working rule that looks at thresholds and the current humidity reading and sets a humidity-state for the room. The new addition to the rule I am trying to introduce will take the change in a flag being set, to raise the max and target thresholds by a specified amount, for example 5 percent. I need the flag to stay in that condition so if I postUpdate the original item with the new value It means that would occur every time the rule fires it would increment, not good.

So in actual fact, I think I do want to do something similar to what I had mistakenly done which is to prime a local copy of a variable with the value found in the items state and then increment if the flag is ON. It is this variable I should then use from this point on in the rule as it has the value I wish to use, and then use the variable to determine the humidity state condition I wish to set. i.e. WET, DAMP, DRY etc…,

I am extremely tired right now, so I will not be changing anything until I can approach it fresh and wide awake. It is quite possible when I revist this thread I will see even more things than I recognise right now.

Once again

Thank you

Paul

Thankyou for this now we can probably help more.

Computers a dumb not like wives at all.

A wife asks her husband, a programmer, “Could you please go shopping for me and buy one carton of milk, and if they have eggs, get 6?”

A short time later the husband comes back with 6 cartons of milk and his wife asks, “Why did you buy 6 cartons of milk?”

He replies, “They had eggs.”

Now I will assume that you want to ask that you want to change a set variable using a sitemap so the user can change the setting.

You picked humidity Dry, Damp, Wet

So sitemap only interacts with items so lets create all the items we need.

Number Sensor_Humidity_Value "Humidity [%s]" // Data from sensor
Number Humidity_Setpoint_DRYtoDAMP "SET Dry to Damp [%s]"
Number Humidity_Setpoint_DAMPtoWET "SET Damp to WET [%s]"
String Humidity_STRING "Current State  [%s]"

Great maybe the sitemap could have this

Text item=Sensor_Humidity_Value icon="humidity"
Setpoint item=Humidity_Setpoint_DRYtoDAMP  minValue=0 maxValue=50 step=1
Setpoint item=Humidity_Setpoint_DAMPtoWET  minValue=50 maxValue=100 step=1
Text item=Humidity_STRING icon="humidity" 

Note the min and max values can be changed here

Then we would need a rule to change string you want to use or display.

rule "Set Humitity String"
when
    Item Sensor_Humidity_Value changed
then
  
  val DRYtoDamp = Humidity_Setpoint_DRYtoDAMP.state as Number
  val DamptoWET = Humidity_Setpoint_DAMPtoWET.state as Number

  if (newState < DRYtoDamp) {
     Humidity_STRING.sendCommand("DRY")

  } else if (newState >= DRYtoDamp && newState < DamptoWET) {
   Humidity_STRING.sendCommand("DAMP")

  } else {
    Humidity_STRING.sendCommand("WET")

  }

end