[SOLVED] Looking for Ideas on Garage door Solution

val means it’s a constant. You can’t change it. But you need to be able to change prevState. So you must use var.

When you declare prevState, you probably have to give it a type since you should be initializing it to null.

var String prevState = null

Thanks Rich… I´ll give it a try later…

Nope, did quite work…
First I tried your suggestion. I then get this warn & error:

2019-11-28 19:01:23.311 [WARN ] [me.internal.engine.RuleContextHelper] - Variable 'prevState' on rule file 'garagedoor.rules' cannot be initialized with value 'None': The name 'None' cannot be resolved to an item or type; line 1, column 24, length 4

2019-11-28 19:01:23.325 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule 'Garage door status': An error occurred during the script execution: Cannot assign a value in null context.

The I tried putting " " in the None. Then I get this error:

2019-11-28 19:02:59.927 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule 'Garage door status': An error occurred during the script execution: Could not invoke method: org.eclipse.smarthome.model.script.actions.BusEvent.postUpdate(org.eclipse.smarthome.core.items.Item,org.eclipse.smarthome.core.types.State) on instance: null

This is how the rule looks:

var String prevState = "None"

rule "Garage door status"

when 
      Item  GaragePortBottomSensor changed or
      Item  GaragePortTopSensor changed or
      Item  garage_bryggers_NV changed from OFF to ON
then
    var  newState = UNDEF
    val currState = GarageDoorState.state.toString

           // Garage door fully closed
     if(GaragePortBottomSensor.state.toString == "CLOSED" ) {
        newState = "CLOSED" }
   else
      
          // Garage door fully open                             
      if(GaragePortTopSensor.state.toString == "CLOSED" ) {
        newState = "OPEN" }

   else
          // Door is in motion
      if(currState != "STOPPED") {
        newState = "STOPPED" }

   else
         // Door is partially open but not moving
      if(prevState == "CLOSING") {
        newState = "OPENING" }
    else {
        newState = "CLOSING" }     

         // Could use persistence for this, keep track of the previous state so we can handle the STOPPED case
        prevState = currState
        GarageDoorState.postUpdate(newState)
end

None is the python version of null.

The error comes from the postUpdate so add logging and that line to see what newState is and make sure the Item name matches exactly how the Item is defined.

ARRRGH!
Still got problems…
newState do update. But it never updates to OPENING or CLOSING…
I still get this damn error about the “null”…

2019-11-28 21:58:46.628 [INFO ] [eclipse.smarthome.model.script.debug] - newstate is CLOSED
2019-11-28 21:58:46.634 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule 'Garage door status': An error occurred during the script execution: Could not invoke method: org.eclipse.smarthome.model.script.actions.BusEvent.postUpdate(org.eclipse.smarthome.core.items.Item,org.eclipse.smarthome.core.types.State) on instance: null
2019-11-28 21:58:46.901 [INFO ] [eclipse.smarthome.model.script.debug] - newstate is STOPPED

I´ve lost the overview of which items to create… I didnt have the newState item define. I do now.
But I also got another proxy item in the rule ¨GarageDoorState¨ Thats the one which doesnt update, I assume.

I have simply lost the overview now :frowning:

You only call postUpdate on an Item. When you see “Something.postUpdate”, “Something” has to be an Item.

And what you pass to postUpdate needs to be appropriate for the Item type. That’s why you need too log out what the variable newState is and make sure it’s appropriate.

You need to step back and analyze the code line by line and make sure you understand what reach like is doing. “Run” the coffee on paper. Write down each variable in a sheet of paper and what it’s set to. Then at reach line of code write what changes.

Honestly, if you can’t figure out the difference between a variable and an Item I don’t know if you will ever get this to work and it’s really frustrating to debug code over a forum like this. Many of these problems are something you should be able to figure out on your own, or at least rule out some of the obvious sources of problems like syntax errors, typos for Item names, stuff like that.

You know exactly what line is causing the error. You know, or at least should know, what postUpdate needs to work. And you should know how to log out a variable. If you don’t, see the docs where it’s all explained.

The proxy item GarageDoorState is defined as a String, which is suppose to be postUpdate´d from the value of newState. It just never happens. Insted I get the error. And I dont understand why, when newState do update. When newState become STOPPED, my proxyitem should become STOPPED as well. But it doesnt happen.

currState and prevState seems to be stucked on newState only.

I´m stucked on this!!
Maybe you´re right… I will never get this to work when I cant even postUpdate the item :rage:

I’ve asked you twice now to log out the value of currState before the call to postUpdate. Do you have any idea what that variable is set to before the postUpdate? If the Item name is right than there is something wrong with the value of currState. So find out what curr State actually is.

You’re driving in the dark and frustrated because you are running into the guard rails. Turn on the head lamps to see where you are going. Add some logging statements.

I did log everything…
newState updates to value STOPPED and CLOSED. currState and prevState both update to the value of newState… It doesnt make any sense.

This is what happens, when I hit the button to open the door, and I hit the button again to stop:

2019-11-29 00:49:34.928 [INFO ] [eclipse.smarthome.model.script.debug] -  newstate is UNDEF prevState is newState currState is newState
2019-11-29 00:49:34.965 [INFO ] [smarthome.model.script.debug STOPPED] -  newstate is STOPPED prevState is newState currState is newState garage door is newState
2019-11-29 00:49:34.970 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule 'Garage door status': An error occurred during the script execution: Could not invoke method: org.eclipse.smarthome.model.script.actions.BusEvent.postUpdate(org.eclipse.smarthome.core.items.Item,org.eclipse.smarthome.core.types.State) on instance: null

This is what happens, when I hit the button again to close the door.

2019-11-29 00:51:03.887 [INFO ] [eclipse.smarthome.model.script.debug] -  newstate is UNDEF prevState is newState currState is newState
2019-11-29 00:51:03.904 [INFO ] [smarthome.model.script.debug STOPPED] -  newstate is STOPPED prevState is newState currState is newState garage door is newState
2019-11-29 00:51:03.909 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule 'Garage door status': An error occurred during the script execution: Could not invoke method: org.eclipse.smarthome.model.script.actions.BusEvent.postUpdate(org.eclipse.smarthome.core.items.Item,org.eclipse.smarthome.core.types.State) on instance: null

And when it closed:

2019-11-29 00:51:11.697 [INFO ] [eclipse.smarthome.model.script.debug] -  newstate is UNDEF prevState is newState currState is newState
2019-11-29 00:51:11.709 [INFO ] [.smarthome.model.script.debug CLOSED] -  newstate is CLOSED prevState is newState currState is newState
2019-11-29 00:51:11.727 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule 'Garage door status': An error occurred during the script execution: Could not invoke method: org.eclipse.smarthome.model.script.actions.BusEvent.postUpdate(org.eclipse.smarthome.core.items.Item,org.eclipse.smarthome.core.types.State) on instance: null
2019-11-29 00:51:11.962 [INFO ] [eclipse.smarthome.model.script.debug] -  newstate is UNDEF prevState is newState currState is newState
2019-11-29 00:51:11.976 [INFO ] [smarthome.model.script.debug STOPPED] -  newstate is STOPPED prevState is newState currState is newState garage door is newState
2019-11-29 00:51:11.982 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule 'Garage door status': An error occurred during the script execution: Could not invoke method: org.eclipse.smarthome.model.script.actions.BusEvent.postUpdate(org.eclipse.smarthome.core.items.Item,org.eclipse.smarthome.core.types.State) on instance: null
2019-11-29 00:51:12.008 [INFO ] [eclipse.smarthome.model.script.debug] -  newstate is UNDEF prevState is newState currState is newState
2019-11-29 00:51:12.021 [INFO ] [.smarthome.model.script.debug CLOSED] -  newstate is CLOSED prevState is newState currState is newState
2019-11-29 00:51:12.025 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule 'Garage door status': An error occurred during the script execution: Could not invoke method: org.eclipse.smarthome.model.script.actions.BusEvent.postUpdate(org.eclipse.smarthome.core.items.Item,org.eclipse.smarthome.core.types.State) on instance: null

The sensors are “flapping” but that can hardly be the reason why the item doesnt update.

This is the rule incl logging:

var String prevState = null

rule "Garage door status"

when 
      Item  GaragePortBottomSensor changed or
      Item  GaragePortTopSensor changed or
      Item  garage_bryggers_NV changed from OFF to ON
then
    var  newState = UNDEF
    val currState = GarageDoorState.state.toString
            logInfo("debug", " newstate is " + newState + " prevState is " + prevState + " currState is " + currState)

  // Garage door fully closed
     if(GaragePortBottomSensor.state.toString == "CLOSED" ) {
        newState = "CLOSED"
            logInfo("debug CLOSED", " newstate is " + newState + " prevState is " + prevState + " currState is " + currState)
      }
   else
      
  // Garage door fully open                             
      if(GaragePortTopSensor.state.toString == "CLOSED" ) {
        newState = "OPEN" 
            logInfo("debug OPEN", " newstate is " + newState + " prevState is " + prevState + " currState is " + currState)
     }

   else

  // Door is in motion
      if(currState != "STOPPED") {
        newState = "STOPPED"
            logInfo("debug STOPPED", " newstate is " + newState + " prevState is " + prevState + " currState is " + currState + " garage door is " + GarageDoorState.state.toString)
     }

   else

 // Door is partially open but not moving
      if(prevState == "CLOSING") {
        newState = "OPENING" 
            logInfo("debug OPENING", " newstate is " + newState + " prevState is " + prevState, " currState is " + currState)
     }
   else {
        newState = "CLOSING" 
            logInfo("debug CLOSING", " newstate is " + newState + " prevState is " + prevState, " currState is " + currState)
     }     

 // Could use persistence for this, keep track of the previous state so we can handle the STOPPED case
        prevState = currState
          GarageDoorState.postUpdate(newState)
            logInfo("debug PostUpdate", " newstate is " + newState + " prevState is " + prevState, " currState is " + currState)
end


// Proxy items
// String   GarageDoorState

Okay, this makes little sense, so let’s sort that out first.
logInfo want strings to write out; if you give it things that aren’t strings it will do its best to handle it, but not always very well.

So you got to the message by this route -

    var  newState = UNDEF
    val currState = GarageDoorState.state.toString
            logInfo("debug", " newstate is " + newState + " prevState is " + prevState + " currState is " + currState)

newState is not of defined type, but you’ve set it equal to the keyword UNDEF so maybe it takes up UndefType. That’s not a string. Later on in the rule, you set newState to strings like "CLOSED". Variables in rules are pretty amorphous, but it’d make sense to start out life as a string.
var String newState = "UNDEF"

prevState is a global variable, persisting between runs of the rule, so whatever is in there is leftover from previous runs of the rule - with whatever unexpected values that made, because the rule is not functioning as you want.
However, we can pay attention to it being a string type. Unfortunately, the first declaration of it sets it to null. That’s not a string, so it’ll probably break your logInfo on the first pass of the rule. Better to set empty string “” or something - why not “NULL”, which mimics a uninitialized Item state.
var String prevState = "NULL"

Lastly, currState should already be a string - you set it equal to one. But the last time the rule ran it postUpdated whatever unexpected content newState had to the Item. Looks like that was the string “newState”
It wouldn’t hurt to be explicit about the type though.
val String currState = GarageDoorState.state.toString

Putting those tweaks together

   // must place before ANY rules in this file
var String prevState = "NULL"

rule ... etc.

    var String newState = "UNDEF"
    val String currState = GarageDoorState.state.toString
            logInfo("debug", " newstate is " + newState + " prevState is " + prevState + " currState is " + currState)

So this first log statement already doesn’t make sense. Nothing should ever log out the value “newState”. It should be STOPPED, CLOSED, et. Al. newState is the name of a variable, it should never be the value of a variable. How in the world did prevState and currState become “newState”? That’s not a valid state so I’m not surprised the rule blows up.

Clear the Item back to NULL. At some point you updated it to the state “newState”.

Initialize newState to “UNKNOWN”.
Also, everywhere we assign newState a String. But you initialize it to a State (UNDEF). Because you initialize it to a State newState s ends up being of type State and not if type String.

Just a short update on this one…
I wasn´t getting the wanted result from the rule above. The logfile wasnt clear/easy to read due to alot of flickering of the sensors, (between open and close). So I spend the weekend solving the flickering with a short rule. This “anti flickering” rule is working now. So I went back to dealing with the above rule, cause it´s not working the way it´s suppose to.
At first look, (after dealing with the flickering), it seems like debug log says CLOSING, when the door is actually OPENING. It also says CLOSING when the door is CLOSING. OPENED and CLOSED seems to be correct.

I´ll post more info later.