OH3 Java changes for Door rule

Hello all,

Im working through OH2.5 Rules DSL to OH3 updates and I can see there are a number of changes.

This rule keeps track of doors/gates, but errors:



rule "Keep track of the last time a door was opened or closed"
when
  Member of gDoorSensors changed
then
  if(previousState == NULL) return;

  val name = triggeringItemName
  val state = triggeringItemName.state.toString
  // Update the time stamp
  postUpdate(name+"_LastUpdate", now.toString)

  // Set the timer if the door is open, cancel if it is closed
  if(state == OPEN) sendCommand(name+"_Timer", "ON")
  else postUpdate(name+"_Timer", "OFF")

The error:

Script execution of rule with UID 'gategarage-1' failed: 'state' is not a member of 'java.lang.String'; line 9, column 15, length 24 in gategarage

I think its this line:

 val state = triggeringItemName.state.toString

Any suggestions? This will be a long road I feel :frowning:

As the name of the variable implies, triggeringItemName is the name of the Item, it’s not the Item itself. A name doesn’t have a state.

But even in OH 2.x you didn’t need to get the state of the triggeringItem directly. What if it changed in the mean time? You should have been using newState to begin with. That’s an implicit variable containing the state that the Item changed to to trigger the rule. So just eliminate the line where you define state and use newState wherever you used state.

1 Like

Right, so delete

val state = triggeringItemName.state.toString

And where we referenced that val, state like here:

if(state == OPEN) sendCommand(name+"_Timer", "ON")

change to:

 if(triggeringItemName.newState == OPEN) sendCommand(name+"_Timer", "ON")

No.

Delete the line and where you referenced the state

if(newState == OPEN) sendCommand(name+"_Timer", "ON")

triggeringItemName is just a String. It’s the name of the Item that triggered the rule. There is no state on a String.

2 Likes

Ok.

So , triggeringItemName is just the name of the item. triggeringItem.newState is the state of that item?

This is another rule which uses this

Old Rule

import org.eclipse.smarthome.model.script.ScriptServiceUtil
rule "Lock: Update lock states after alarm_raw event" when
    Item FrontDoor_DoorLock_Alarm_Raw received update then
    val actionItem = gLock.members.findFirst[ item | item.name.toString == triggeringItemName.toString.replace("_Alarm_Raw","") ]
//    logInfo("Rules", "Lock: Alarm events: {}=[{}]",actionItem.name,triggeringItem.state.toString)
    switch (transform("JSONPATH","$.type",triggeringItemName.state.toString)) {
        case "ACCESS_CONTROL" : {
            switch (transform("JSONPATH", "$.event", triggeringItemName.state.toString)) {
                      case "1" : {
                   actionItem.postUpdate(ON)
                     logInfo("FrontDoor", "Lock: Alarm events: {} updated to Locked",actionItem.name)
                   val StringBuilder message = new StringBuilder("Front Door Locked via")
                     logInfo("FrontDoor", "Lock: {}",message.toString)
                   switch (transform("JSONPATH", "$.level", triggeringItemName.state.toString)) {
                        case "1" : {

New rule?

import org.eclipse.smarthome.model.script.ScriptServiceUtil
rule "Lock: Update lock states after alarm_raw event" when
    Item FrontDoor_DoorLock_Alarm_Raw received update then
    val actionItem = gLock.members.findFirst[ item | item.name.toString == triggeringItem.toString.replace("_Alarm_Raw","") ]
//    logInfo("Rules", "Lock: Alarm events: {}=[{}]",actionItem.name,triggeringItem.state.toString)
    switch (transform("JSONPATH","$.type",triggeringItem.state.toString)) {
        case "ACCESS_CONTROL" : {
            switch (transform("JSONPATH", "$.event", triggeringItem.state.toString)) {
                      case "1" : {
                   actionItem.postUpdate(ON)
                     logInfo("FrontDoor", "Lock: Alarm events: {} updated to Locked",actionItem.name)
                   val StringBuilder message = new StringBuilder("Front Door Locked via")
                     logInfo("FrontDoor", "Lock: {}",message.toString)
                   switch (transform("JSONPATH", "$.level", triggeringItem.state.toString)) {
                        case "1" : {

No no no. I just don’t know how to say it more clearly.

There’s no newState variable on a String just like there is no state. triggeringItemName is just a String. You can only do String things with it. Strings have no state, no newState, no previousState. You can’t get the members of a String.

It’s just a String, a sequence of letters and numbers. Nothing more.

Look at the if statement I posted. triggeringItemName appears nowhere. You want the state of the Item that triggered the rule with a change? Literally just use newState and just newState. Look at the docs: Rules | openHAB. Those are all the variables that are injected into your rule when it runs and what they are set to.

  • item.name.toString is redundant. It’s already a String. Just use item.name
  • triggeringItemName.toString is redundant. It’s already a String
  • As shown in the docs I linked to, triggeringItem only exists when the rule is triggered by a Member of trigger. This rule is not using a Member of trigger so use newState.toString.

triggeringItemName.newState is the state of that item, THAT WAS A TYPO!

The docs are written by programmers, for programmers. Hence the questions - if it was straight forward I wouldnt ask. This is the crux of the issue, it’s just so complex for non programmers who cant grasp it