Problem with my Garage rule

Hello,

I have written a rule for my Garage Door with two buttons, one for opening and one to close it, which openhab apparently cannot parse sucessfully, I do not receive any error it just takes forever and I have to restart openhab.

Using openhab 2.2 on raspian.

import java.util.concurrent.locks.ReentrantLock
var ReentrantLock lock = new ReentrantLock

val long Garagentor_TransitionTime = 15000

var DateTime Garagentor_TransitionStart = null
var Timer Garagentor_TransitionTimer = null
var long Garagentor_TransitionTime_adjusted = 15000 //If I use Garagentor_TransitionTime here the variable cannot be used later in the code, any suggestion why?

rule "Garagentor open"

when
    Item Garagentor_open changed to ON
then
    lock.lock

    if(Garagentor_TransitionTimer !== null){
        NS_Garage_4.sendCommand(ON)

//VITAL PART - AS SOON AS I ADD THIS THE WHOLE THING STOPS WORKING

        Garagentor_TransitionTime_adjusted = Garagentor_TransitionTime - (Garagentor_TransitionTime_adjusted - (now.millis - Garagentor_TransitionStart.millis))

//################

        if(CT_Garagentor == OPEN){
            CT_Garagentor.postUpdate(CLOSED)
        }else{
            CT_Garagentor.postUpdate(OPEN)
        }
    }else if(CT_Garagentor == CLOSED){
        NS_Garage_4.sendCommand(ON)
        Garagentor_TransitionStart = now
        Garagentor_TransitionTimer = createTimer(now.plus(Garagentor_TransitionTime_adjusted), [| 
            CT_Garagentor.postUpdate(OPEN)
        ])
    }
    Thread::sleep(1000)
    lock.unlock
end

rule "Garagentor close"

when
    Item Garagentor_close changed to ON
then
    lock.lock

    if(Garagentor_TransitionTimer !== null){
        NS_Garage_4.sendCommand(ON)

        //VITAL PART - AS SOON AS I ADD THIS THE WHOLE THING STOPS WORKING

        Garagentor_TransitionTime_adjusted = Garagentor_TransitionTime - (Garagentor_TransitionTime_adjusted - (now.millis - Garagentor_TransitionStart.millis))

//################

        if(CT_Garagentor == CLOSED)CT_Garagentor.postUpdate(OPEN)
        else CT_Garagentor.postUpdate(CLOSED)
    }else if(CT_Garagentor == OPEN){
        NS_Garage_4.sendCommand(ON)
        Garagentor_TransitionStart = now
        Garagentor_TransitionTimer = createTimer(now.plus(Garagentor_TransitionTime_adjusted), [| 
            CT_Garagentor.postUpdate(CLOSED)
        ])
    }
    Thread::sleep(1000)
    lock.unlock
end

rule "Garagentor Contact"

when
    Item CT_Garagentor changed
then
    Garagentor_TransitionStart = null
    Garagentor_TransitionTimer?.cancel()
    Garagentor_TransitionTimer = null
    Garagentor_TransitionTime_adjusted = Garagentor_TransitionTime
end

rule "NS_Garage_4 off"

when
    Item NS_Garage_4 changed to ON
then
    Thread::sleep(1000)
    NS_Garage_4.sendCommand(OFF)
end

I’m laboring on this for hour now but narrowing the error down to this particular line is all I could achieve.

I would very much appreciate your help on this.

Best Regards
Christoph

Without knowing your items:

if(CT_Garagentor.state == ...

etc.

Hello Harry, thanks for your answer.

My relevant Items are

Group:Switch:OR(ON,OFF) Garagentor_open "Garagentor Öffner" (Garage,Switches)
Group:Switch:OR(ON,OFF) Garagentor_close "Garagentor Schließer" (Garage,Switches)

Switch NS_Garage_4 "Garagentor Impuls" (Garage,Actors) {channel="homematic:HM-LC-Sw4-PCB:22497de9:OEQ1211791:4#STATE" }
Switch RC_Christoph_4_short "Fernbedienung Christoph 4" (Garage,Switches,Garagentor_open,Remotes) {channel="homematic:HM-RC-4-3:22497de9:OEQ0278975:4#PRESS_SHORT" }
Switch RC_Christoph_3_short "Fernbedienung Christoph 3" (Garage,Switches,Garagentor_close,Remotes) {channel="homematic:HM-RC-4-3:22497de9:OEQ0278975:3#PRESS_SHORT" }
Switch RC_Izzy_4_short "Fernbedienung Izzy 4" (Garage,Switches,Garagentor_open,Remotes) {channel="homematic:HM-RC-4-3:22497de9:NEQ1139162:4#PRESS_SHORT" }
Switch RC_Izzy_3_short "Fernbedienung Izzy 3" (Garage,Switches,Garagentor_close,Remotes) {channel="homematic:HM-RC-4-3:22497de9:NEQ1139162:3#PRESS_SHORT" }
Contact CT_Garagentor "Garagentor Status" (Contacts,Garage)

I don’t know why I ended up querying the Contact item without .status.
Unfortunately my problem with this line

Garagentor_TransitionTime_adjusted = Garagentor_TransitionTime - (Garagentor_TransitionTime_adjusted - (now.millis - Garagentor_TransitionStart.millis))

is not solved by this. Openhab gets stuck when trying to parse it

This seems a little excessively complex.

Some initial comments:

  • Always put a lock inside try/catch/finally. If you have an error in the middle of the locked section, your Rule will never execute again until you restart OH because the lock never gets unlocked.

  • Post errors that appear in the logs

  • Using locks and Thread::sleeps is a recipe for problems as well. It increases the likelihood that you will run out of Rules execution threads.

  • What are you using Garagentor_TransitionTime for? What are you using CT_Garagentor for?

  • now.plus(Garagentor_TransitionTime_adjusted) should probably be now.plusMillis

It is really hard to tell but it seems to me you are trying to get the proper labels and icons on your sitemap based on the state of the garage door. You can do this much more simply. Here is how I do it:

Items

Switch aGarageOpener1 "Garage Door Opener 1"
String GarageOpener1_Cmd
Contact vGarageOpener1 "Garage Door Opener 1 is [MAP(en.map):%s]"
  <garagedoor> (gDoorSensors,gDoorCounts)

aGarageOpener1 is a proxy Item that I use to trigger my Rule and to show on the sitemap. GarageOpener1_Cmd is the Item that actually sends the command to the opener. vGarageOpener1 is a reed sensor on the door that tells me when it is open.

Rules

val logName = "entry"

rule "A Garage Opener was triggered"
when
  Item aGarageOpener1 received command
then
  GarageOpener1_Cmd.sendCommand(ON)

  logInfo(logName, "Garage Opener 1 was triggered.")

  // send an alert if the garage controller is offline
  if(vNetwork_Cerberos.state == OFF) {
    aAlert.sendCommand("Attempting to trigger a garage opener but the controller is offline!")
  }
end

Sitemap

                Switch item=aGarageOpener1 icon="garagedoorclosed" mappings=[ON=Open]  visibility=[vGarageOpener1 == CLOSED]
                Switch item=aGarageOpener1 icon="garagedooropen"   mappings=[ON=Close] visibility=[vGarageOpener1 == OPEN]

Now clearly your setup will have to be a little different because you have two buttons, not just one, but again, I would ask why? It seems to add a bunch of extra complexity. Can you explain why you are approaching this like this?

First of all, thank you very much for your suggestions, especially for the sitemap.
By now I know I’ll have to rethink my rules for this door.

I just want to clarify why I felt it was necessary to add all that complexity
First, I don’t actually have a Door Contact (CT_Garagentor) so it is a virtual Contact that has to be updated after a predefined time and has to be recalculated whenever the action is stopped midway or (2/3 ways or whatever)

Second, I like explicit open/close buttons on my remote and I want that open-button to still be able to stop the door while it’s opening but not to trigger the subsequent close action.

Hope I’ve been more clear of my intentions this time.
I don’t know if I actually need all this but still it should be achievable.

Regards

That makes sense and is not clear from just the code posted.

Be aware though that based on what I’ve seen posted on this forum for roller shutters, this approach is not very reliable.

Does your opener actually support that?

Anyway, this is still easily achievable with a single Switch Item.

Item

Switch GarageOpener

Sitemap

rule "Garage triggered"
when
    Item GarageOpener received command
then
    // Garage OPEN pressed
    if(receivedCommand == ON) {
        // do open stuff
    }
    else {
        // do close stuff
    }
end

Sitemap

Switch item=GarageOpener icon="garagedoorclosed" mappings=[ON=Open,OFF=Close]

So that is already a simplification.

I don’t have time to help with the timing calculations but based on your descriptions of the problem, I’m all but positive was a combination of the locks and the Timers and not related to the calculations.