Save state and reload state in rules

Hello,
I try to creat a rule to prevent that I locked out to my home from a roller shutter.
It should trigged by an item received a command, check if the door is open and if it is, save the received command, send a new one and if the door the get closed send the old command.

I have tried with this rule

var String WohnHSEalt = 0

// Wohnzimmer
rule "Aussperren verhindern HSE Wohnzimmer"
when
    Item Wohnzimmer_HSE_Rollade received update
then
    logInfo("Wohnzimmer HSE", "Aussperren Rule is triggered")
    if( FensterkontaktHSEWohnzimmerStatus == OPEN ) {
        WohnHSEalt = Wohnzimmer_HSE_Rollade.state.toString
        Wohnzimmer_HSE_Rollade.sendCommand(STOP)
        Thread::sleep(1000) 
        Wohnzimmer_HSE_Rollade.sendCommand(0)
        logInfo("WohnzimmerHSE", "Schließen gestoppt") 
    }
end

rule "Rollade auf Wert fahren wenn Fenster geschlossen wird"
when
    Item FensterkontaktHSEWohnzimmerStatus changed to CLOSED
then
    Wohnzimmer_HSE_Rollade.sendCommand(WohnHSEalt)
     logInfo("WohnzimmerHSE", "Schließen")
end

But it didn’t do what I intend it.
Can anyone help me what’s wrong?

Please post the log output when you run the rule.

2020-03-01 19:23:57.804 [vent.ItemStateChangedEvent] - FensterkontaktHSEWohnzimmerStatus changed from CLOSED to OPEN
2020-03-01 19:24:01.523 [ome.event.ItemCommandEvent] - Item 'Wohnzimmer_HSE_Rollade' received command UP
2020-03-01 19:24:01.538 [nt.ItemStatePredictedEvent] - Wohnzimmer_HSE_Rollade predicted to become UP
==> /var/log/openhab2/openhab.log <==
2020-03-01 19:24:01.545 [INFO ] [marthome.model.script.Wohnzimmer HSE] - Aussperren Rule is triggered
==> /var/log/openhab2/events.log <==
2020-03-01 19:24:01.552 [vent.ItemStateChangedEvent] - Wohnzimmer_HSE_Rollade changed from 70 to 0
==> /var/log/openhab2/openhab.log <==
2020-03-01 19:24:26.692 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule 'Rollade auf Wert fahren wenn Fenster geschlossen wird': An error occurred during the script execution: Could not invoke method: org.eclipse.smarthome.model.script.actions.BusEvent.sendCommand(org.eclipse.smarthome.core.items.Item,java.lang.String) on instance: null
==> /var/log/openhab2/events.log <==
2020-03-01 19:24:26.692 [vent.ItemStateChangedEvent] - FensterkontaktHSEWohnzimmerStatus changed from OPEN to CLOSED
==> /var/log/openhab2/openhab.log <==
2020-03-01 19:24:33.147 [INFO ] [marthome.model.script.Wohnzimmer HSE] - Aussperren Rule is triggered

See Why have my Rules stopped running? Why Thread::sleep is a bad idea. Change your code to use a timer.

I also can delete Thread::sleep its not necessary. But it didn’t execute the lines before the sleep. It didn’t sendCommand(Stop) or save the old command to the variable.

Try this and see what happens.

var String WohnHSEalt = 0
rule "Aussperren verhindern HSE Wohnzimmer"
when
    Item Wohnzimmer_HSE_Rollade received update
then
    logInfo("Wohnzimmer HSE", "Aussperren Rule is triggered")
    if( FensterkontaktHSEWohnzimmerStatus.state == OPEN ) {
        WohnHSEalt = Wohnzimmer_HSE_Rollade.state.toString
        Wohnzimmer_HSE_Rollade.sendCommand(STOP)
        Thread::sleep(1000) 
        Wohnzimmer_HSE_Rollade.sendCommand(0)
        logInfo("WohnzimmerHSE", "Schließen gestoppt") 
    }
    else if(FensterkontaktHSEWohnzimmerStatus.state == CLOSED){
        Wohnzimmer_HSE_Rollade.postUpdate(WohnHSEalt)
        logInfo("WohnzimmerHSE", "Schließen")
    }
end

I do not understand Wohnzimmer_HSE_Rollade is being sent both STOP and 0?

I’ve tried it and it will stop the roller shutter but also triggers the rules itself again and again

I also implemented that feature and used a lambda to avoid implementing this for each of my gazillions of doors. Maybe it’s of use to. But make sure you understand the code before you use it.
An example call would be check_close_shutter.apply(EG_Kueche_Rolladen_Tuer,EG_Kueche_Tuer_Kontakt,closure)

val Functions$Function3 <RollershutterItem,ContactItem,NumberItem,Boolean> check_close_shutter = [ shutter, door, percentage |
        if (door.state != OPEN) {
                logDebug("rules", shutter.label + "(" + shutter.name + ") wird auf " + percentage + " gefahren, shutter = " + shutter)
                var Number p = percentage
                shutter.sendCommand(p)
        } else
                logDebug("rules", shutter.label + " wird nicht geschlossen, da " + door.label + " geöffnet ist.")

        logDebug("rules", shutter.label + "(" + shutter.name + ") erledigt")
        true
]

I just edited it to use else if statement. See if that changes anything.

the rule triggered it self. Thats the new problem

I also made a change in the else if statement to postUpdate rather than sendCommand, was that change in your last rule test?

The problem here is, you want to send a command but the rule has to trigger to all updates, which includes sent commands.

Maybe it would suffice to catch the 0 change:

var String WohnHSEalt = 0

rule "Aussperren verhindern HSE Wohnzimmer"
when
    Item Wohnzimmer_HSE_Rollade received update
then
    if(Wohnzimmer_HSE_Rollade.state.toString != "0")
        logInfo("Wohnzimmer HSE", "Aussperren Rule is triggered")
        if( FensterkontaktHSEWohnzimmerStatus.state == OPEN ) {
            WohnHSEalt = Wohnzimmer_HSE_Rollade.state.toString
            Wohnzimmer_HSE_Rollade.sendCommand(STOP)
            Thread::sleep(1000)
            Wohnzimmer_HSE_Rollade.sendCommand(0)
            logInfo("WohnzimmerHSE", "Schließen gestoppt") 
        }
    }
end

Thanks, that’s true.
I’ve done it with some Timers to avoid the STOP Command. After 60 seconds the roller stopped alone.
So that’s my solution:

var String WohnHSEalt = 0
var Timer HSEFahrzeitWohnzimmer = null

rule "Aussperren verhindern HSE Wohnzimmer"
   when
       Item Wohnzimmer_HSE_Rollade received update
   then
       if(FensterkontaktHSEWohnzimmerStatus.state == OPEN && Wohnzimmer_HSE_Rollade.state != 0) {
           logInfo("WohnzimmerHSE", "Aussperren verhindern")
           HSEFahrzeitWohnzimmer = createTimer(now.plusSeconds(60)) [| if( Wohnzimmer_HSE_Rollade.state !=0 ) {
                                                                           WohnHSEalt = Wohnzimmer_HSE_Rollade.state.toString 
                                                                           Wohnzimmer_HSE_Rollade.sendCommand(0) 
                                                                           logInfo("WohnzimmerHSE", "Rollade hochfahren")}
                                                                           HSEFahrzeitWohnzimmer = null
                                                                           ]   
   }
   end

rule "Rollade auf Wert fahren wenn Fenster geschlossen wird"
   when
       Item FensterkontaktHSEWohnzimmerStatus changed to CLOSED
   then
       HSEFahrzeitWohnzimmer = createTimer(now.plusSeconds(60)) [| Wohnzimmer_HSE_Rollade.sendCommand(WohnHSEalt)
                                                                   logInfo("WohnzimmerHSE", "Rollade auf Wert fahren")
                                                                   ]
   end