Timer check and delete

I have a problem with timer. I cannot understand why I cannot delete an existing timer.
var Timer mytimers = null at the beginning

then if I run the role that create a timer first time, it create a timer. On second run, I still have the timer running (and it run associated commands) but this part of code cannot find it to delete.

      if (mytimers != null) {
        mytimers.cancel()
        logInfo("Stufa","DBGzz: Timer active, delete it")
        mytimers = null
      }

I’ve tried if (mytimers !== null) (see in some example, really didn’t understand what exactly do for double !== instead of !=) with no luck.
I need to delete timer, there is another way?
And there is a way to see how many timers are running?
Thanks to all.

Beginning of what? Are you using xxx.rules file or GUI entered rule? It makes a big difference here.

Does mytimers ever get set to anything?
How do you know the rule runs?
How do you know it gets to the if() statement?
It’s usually worth showing us the whole thing. If you can’t see a problem in the part where you think the trouble is - maybe it is somewhere else.

I’m using (for the first time) the GUI mode for rule.
I’ve added many logInfo statement into my code (I’ll attach now) and the if() statement is not processed but code before and after was executed (logged into my openhab). Pls don’t blame at me for the uncleaned code but is not completed and I’m trying to use the DP with group in rules.

val oggettochiamata = triggeringItem
var Timer mytimers = null
var Timer mytimer_resetdelay = null
var String oggettoprincipale = null
var SwitchItem itemPrincipale

Thread.sleep(500)  //Ritardo per lettura stato corretto dell'item
logInfo("Stufa", "DBG iniziale: " + oggettochiamata.name + " --> " + oggettochiamata.state.toString())
val oggettochiamataParts = oggettochiamata.name.split("Timer")

if (oggettochiamata.name.indexOf("Timer") > 0) {
    oggettoprincipale = oggettochiamata.name.split("_Timer").get(0)
    itemPrincipale = gGF_FamilyRoom_Stufa.members.findFirst[ dt | dt.name == oggettochiamata.name.split("_Timer").get(0) ] as SwitchItem
    logInfo("Stufa", "DBG: " + "Contiene Timer")
} else { 
  itemPrincipale = gGF_FamilyRoom_Stufa.members.findFirst[ dt | dt.name == oggettochiamata.name ] as SwitchItem
  oggettoprincipale = oggettochiamata.name
  }
//val itemPrincipale = gGF_FamilyRoom_Stufa.members.findFirst[ dt | dt.name == oggettoprincipale.toString ] as SwitchItem
//oggettoprincipale = oggettochiamata.name.split("_Timer").get(0)
logInfo("Stufa", "DBG: " + "oggetto principale: " + itemPrincipale.name)  

  if (triggeringItem.name == oggettoprincipale) {
    //Comando generale stufa, nessun timer utilizzato
    if (mytimers != null) {
      logInfo("Stufa","DBGz: Timer attivo, cancello")
      mytimers.cancel()
      mytimers = null
    }
    gGF_FamilyRoom_Stufa.members.filter[ dt | dt.name != oggettochiamata.name  ].forEach[ i | i.postUpdate(OFF) ]
    //gGF_FamilyRoom_Stufa.members.filter[ dt | dt.name != oggettochiamata.name  ].forEach[ i | logInfo("Stufa", i.name + " andranno in OFF") ]
    if (mytimer_resetdelay != null) {
        mytimer_resetdelay.cancel()
        mytimer_resetdelay = null
    }
    mytimer_resetdelay = createTimer(now.plusMinutes(1), [|
        GF_FamilyRoom_Stufa_TimerDelay.sendCommand(15)
        ])
  }
  else { // Se arriva comando da timer
    if (oggettochiamata.state == OFF && (GF_FamilyRoom_Stufa.state.toString() != oggettochiamataParts.get(1).toUpperCase()) ) { //Se il timer di comando annulla l'attuale azione
      logInfo("Stufa", "Cancello il timer associato")
      if (mytimers != null) {
        mytimers.cancel()
        logInfo("Stufa","DBGzz: Timer attivo, cancello")
        mytimers = null
      }
    if (mytimer_resetdelay != null) {
        mytimer_resetdelay.cancel()
        mytimer_resetdelay = null
    }
    mytimer_resetdelay = createTimer(now.plusMinutes(1), [|
        GF_FamilyRoom_Stufa_TimerDelay.sendCommand(15)
        ])
      
    } else if (oggettochiamata.state == ON && (GF_FamilyRoom_Stufa.state.toString() != oggettochiamataParts.get(1).toUpperCase()) ) { //Se il comando di timer deve attivare il temporizzatore
      logInfo("Stufa", "DBG: " +  "Imposto un nuovo timer!!")
      if (mytimer_resetdelay != null) { //Reset timer azzeramento ritardo
        mytimer_resetdelay.cancel()
        mytimer_resetdelay = null
      }
      if (mytimers !== null) { //Reset ritardo acc/spegnimento
        mytimers.cancel()
          logInfo("Stufa","DBGzzz: Timer attivo, cancello")
        mytimers = null
      }
      var int delayvalue = (GF_FamilyRoom_Stufa_TimerDelay.state as DecimalType).intValue
      mytimers = createTimer(now.plusMinutes(delayvalue), [|
          //gGF_FamilyRoom_Stufa.members.filter[ dt | dt.name != oggettochiamata.name  ].forEach[ i | i.postUpdate(OFF) ]
          gGF_FamilyRoom_Stufa.members.filter[ dt | dt.name == oggettochiamata.name  ].forEach[ i | logInfo("Stufa", i.name + " spegnimento") ]
          logInfo("Stufa", "DBG: " + "Fine del timer, nuovo stato stufa: " + oggettochiamataParts.get(1).toUpperCase() + " chiamato da: " + oggettochiamata.name) 
          GF_FamilyRoom_Stufa.sendCommand(oggettochiamataParts.get(1).toUpperCase())
          oggettochiamata.postUpdate(OFF)
          GF_FamilyRoom_Stufa_TimerDelay.sendCommand(15)
          ])
    } else {
      logInfo("Stufa", "DBG: è accaduto l'imprevedibile!")
    }
  
  }

Okeydoke; as I said this makes a difference - what you’re trying to do simply won’t work in GUI entered DSL rules.
See -

The problem is that there is nowhere “outside” of the GUI rule to define a variable that continues to exists outside of the rule, between rule runs…

Ohhh… Sorry I didn’t see that discussion…My fault.
In fact I can use the .rules file or change scripting language. But before starting learning new language, do you have any suggestion?
For my problem for now I’ll move to rules file and go on…
Many thanks

No, I don’t know what your personal preferences are.