Has the Process For Secure Inclusion of Z-Wave Locks Changed?

Well, I did say

And I was wrong. The BurpUp/Dn worked correctly. But I forgot there was a rule involved to get the time to update. I just re-saved the identical rule file (except for a character in a comment area) and the time is back updating correctly. So this is the second case where one of my rules files stopped executing until I re-save it.

I can’t find anyone else that is experiencing this problem so it might be something with my files (items or rules) or my installation. In fact my items and rules files have grown in a somewhat haphazard way and I am considering recreating them in a more orderly fashion. Does anyone have any other suggestions for “cleaning up” my system?

Some people are taking the opportunity to build things from scratch in OH3.

If you are running OH from an SD card, try a fresh one.

quote=“PeteC, post:21, topic:109307”]
I can’t find anyone else that is experiencing this problem
[/quote]

Wow… just search for “rules stop working” and you’ll find a bunch of similar issues :slightly_smiling_face:. This is usually caused by the same thing and it is discussed many times in the forum. The old rule engine allows rules instances of rules to execute asynchronously, and they are limited to a threadpool of 5 threads. Without seeing your rules, there is no way to help you find where this limitation could be causing your rules to stop. If you want to figure it out on your own, look for Thread::sleep, executeComandLine, never ending lops, http actions, any long running rules, rules that just never end, etc. Here is one of the main topics…

Find where the threads are being eaten up, increase the threadpool, or use the new rule engine with scripted automation. If you are thinking of rewriting your rules anyhow, this is a great time to make the move away from the rules DSL. I highly recommend Jython and the helper libraries. I have some add-ons in the Eclipse IoT Marketplace, so you can install through the UI.

I think it is time to change the tile of this topic, which has gone down a very long and winding rabbit hole!

You are right. Would it be possible to start a new thread off of my post of about Dec 3? The one that starts, “Scott, You nailed the problem”? That is where you fixed my inclusion process with this particularly ornery Black and Decker lock.

But that is also the post where I first find that re-saving a rule brings it back to life.
Is this new thread something I can do or do I have to ask a moderator to do it? I would hate to bother them if I don’t have to. I think I would title it something like “Rule Restored By Saving Again”. Do you think I should type up an explanation for the new thread or would cross linking them be sufficient?

I sure did when I discovered this re-saving method. But none of the responses were even close to this re-save issue. I can’t believe I discovered some “short cut” to getting rules to work that these other, far more knowledgeable users didn’t discover. And I tried to follow the responses but they rapidly go beyond my knowledge base. And it was hard for me to determine that an actual solution resulted. And if it did I don’t think I have enough knowledge to implement it. Although I did buy a kindle book on Json.for beginners just a day ago.

As for “Thread…”, timeouts, sendHttp etc. I am sure my rules don’t do things like that. I have only 6 rule files. Three of them are for the three locks. All the do is translate responses like “type:xxx value yyy” to text like “Lock Un-Secured by User #”. But I did a text search of the files for those terms and the translate files don’t have any of those terms. Note, the one translate file for the B&D lock is the one that goes dormant and comes back with a re-save.

For the other three rules files the only term that the text search finds is

Time cron "0 0 22 * * ?" 

It is used three times.
One is “If it is 10:00 PM and the garage door is open, close the garage door”.
Another is “If it is 10:00 PM and the garage light is on send me a text message”.
Another is, " If it is 10:00 PM lock the three door locks".
From my (limited) understanding, these don’t start threads.
Also, the B&D lock will lock in response to this rule even if the translate rule is dormant. The door locks and it the B&D reports, type”:“24”,“value”:“1” which should translate to , “Lock Secured by Controller – Successful (Fully extended)” but since the translate rule is dormant, my B&D items don’t get updated and continue to display the text from the last time the rule executed before going dormant.

A moderator would need to split it. The easiest way to call a mod is to flag the post, select Other, and explain.

Moderators are moderators because they want to be moderators. If it is a bother, then they shouldn’t be a moderator.

You will find other discussions about resaving rule files fixing a stuck rule. This is nothing new. There hasn’t been an update to openHAB core for a year!

If you are not going to share your rule files, then use the process of elimination and remove all of your rules except for one. Slowly add the rule files back in until the problem occurs. When it hangs, remove the last rule file that you added and add its rules one at a time until you find the offending rule.

As I’ve said though, this could be a hardware issue. Sorry to repeat myself, but I don’t recall if you ever answered… are you running OH from an SD card? Also, what version of OH are you using?

In the old rule engine, all rules consume a thread from the threadpool when triggered. Croin triggered rules are no different.

[emphasis added]

What is ‘this rule’? The only rule you have posted is “Ignore Bogus Reports”. Is that the ‘translate’ rule?

By display, do you mean in a UI? Did you refresh your browser? Are there any log entries?

1 Like

I will get to the moderator soon.

openHAB Distribution Version Information
----------------------------------------
build-no        : Release Build
online-repo     : https://openhab.jfrog.io/openhab/libs-release

Repository        Version
----------------------------------------
openhab-distro  : 2.5.10
openhab-core    : 2.5.0
openhab1-addons : 1.14.0
openhab2-addons : 2.5.10
karaf           : 4.2.7

I am not sure what you are asking about running from an SD card. I am using a Raspberry Pi with a micro SD card that contains the OS, Openhab, all the other stuff that comes with the Noobs package.
Here are my rules files. They contain a lot of my notes to help me remember what I was doing and why. I am not a real power user. I might go months before I might want to make a change. The notes help but they may conflict within themselves or be obsolete.
The rule "“Ignore Bogus Reports” posted Dec 6 is the one for the B&D lock. It is the one that does a translation and goes dormant every few days.
The other rule that I caught dormant one time is:

//Test to see if I can capture the time when watchdog happens
// It  just uses a switch Bump_Time  


rule "Capture Time"


when
//    Item Bump_Time changed //use to test functionality in a classicUI sitemap.
	Item WatchDogBurp changed
	
then
logDebug("Bump_Time changedXXX", "From On to Off") 
When_Bumped.postUpdate( new DateTimeType())
end

The translate rules for the two other locks are below. These have never gone dormant. Rule “Yale YRD110 Rule” has been installed for over a year. Rule “New Yale YRD110 Rule” has been installed for a month or so. You can see that all three translate rules are identical except for changes in text fields.

rule "Yale YRD110 Rule"

// I tried to use a map file to change the text but it sometimes fsiled and reported
// stuff like {"type"\:"112","value"\:"0"} not Master code changed or user added at keypad
// refreshing the screen would "fix" it. 
// So I will use a technique like I used for the B&D Lock

when
    Item Porch_Alarm_Raw changed  
	
then
	//PorchDoorReportTime.postUpdate([%1$tH:%1$tM])
//Process the JSON from the raw alarm to get the Type and Value 
    var actionType = transform("JSONPATH", "$.type",triggeringItem.state.toString)  // these SOBs are strings
    var actionTypeValue = transform("JSONPATH", "$.value", triggeringItem.state.toString)
    logDebug("RULE_SYSTEM", "Porch Lock: Alarm events: TFormed State: {}, StateValue: {}", actionType, actionTypeValue)
	
		if(actionType !="0"){
	
	
	
    switch (actionType) {
        //Locking actions
        case "9": {
            Porch_Alarm_Virtual.postUpdate("Motor jammed")
			Porch_Alarm_Virtual_Short.postUpdate("Jammed")
            logDebug("RULE_SYSTEM", "{} Motor Jammed", "PorchLock")
        }

		case "18": {
            Porch_Alarm_Virtual.postUpdate("Keypad lock")
			Porch_Alarm_Virtual_Short.postUpdate("Secured")
            logDebug("RULE_SYSTEM", "{} Keypad lock", "PorchLock")
			}
        case "19": {
            Porch_Alarm_Virtual.postUpdate("Motor jammed")
			Porch_Alarm_Virtual_Short.postUpdate("Jammed")
            logDebug("RULE_SYSTEM", "{} Keypad unlock", "PorchLock")
			}
		case "21 ": {
		if (actionTypeValue=="1"){
				Porch_Alarm_Virtual.postUpdate("Manual lock by thumb")
				Porch_Alarm_Virtual_Short.postUpdate("Secured")
				logDebug("RULE_SYSTEM", "{} Manual lock by thumb", "PorchLock")
			}
			else{
				Porch_Alarm_Virtual.postUpdate("Manual lock by touchpad")
				Porch_Alarm_Virtual_Short.postUpdate("Secured")
				logDebug("RULE_SYSTEM", "{} Manual lock by touchpad", "PorchLock")
			}
			}
        case "22": {
            Porch_Alarm_Virtual.postUpdate("Manual unlock")
			Porch_Alarm_Virtual_Short.postUpdate("Un-Secured")
            logDebug("RULE_SYSTEM", "{} Manual unlock", "PorchLock")
			}
        case "24": {
            Porch_Alarm_Virtual.postUpdate("RF lock")
			Porch_Alarm_Virtual_Short.postUpdate("Secured")
            logDebug("RULE_SYSTEM", "{} RF lock", "PorchLock")
			}
		case "25": {
            Porch_Alarm_Virtual.postUpdate("RF unlock")
			Porch_Alarm_Virtual_Short.postUpdate("Un-Secured")
            logDebug("RULE_SYSTEM", "{} RF unlock", "PorchLock")
        }
        case "27": { 
            Porch_Alarm_Virtual.postUpdate("Auto re-lock cycle complete")
			Porch_Alarm_Virtual_Short.postUpdate("Secured")
            logDebug("RULE_SYSTEM", "{} Auto re-lock cycle complete", "PorchLock")
			}
		case "33": {
            Porch_Alarm_Virtual.postUpdate("User deleted")
            logDebug("RULE_SYSTEM", "{} User deleted", "PorchLock")
        }
		case "112":  {
            Porch_Alarm_Virtual.postUpdate("Master code changed or user added at keypad")
            logDebug("RULE_SYSTEM", "{} Master code changed or user added at keypad", "PorchLock")
			}
        case "113":  {
            Porch_Alarm_Virtual.postUpdate("Lock has completed Handing Cycle")
            logDebug("RULE_SYSTEM", "{} Lock has completed Handing Cycle", "PorchLock")
			}
		case "129": {
            Porch_Alarm_Virtual.postUpdate("Lock has completed Handing Cycle")
            logDebug("RULE_SYSTEM", "{} Lock has completed Handing Cycle", "PorchLock")
			}
		case "130": {
            Porch_Alarm_Virtual.postUpdate("RF module (in door) power restored")
            logDebug("RULE_SYSTEM", "{} RF module (in door) power restored", "PorchLock")
			}
        case "161": {
			if (actionTypeValue=="1"){
				Porch_Alarm_Virtual.postUpdate("Tamper Alarm attempts exceeded")
				logDebug("RULE_SYSTEM", "{} Tamper Alarm attempts exceeded", "PorchLock")
				}
			else{
			     Porch_Alarm_Virtual.postUpdate("Front escutcheon removed")
				logDebug("RULE_SYSTEM", "{} Front escutcheon removed", "PorchLock")
				}
			}
        case "167": {
            Porch_Alarm_Virtual.postUpdate("Battery low")
            logDebug("RULE_SYSTEM", "{} Battery low", "PorchLock")
			}
        case "168": {
            Porch_Alarm_Virtual.postUpdate("Battery critical")
            logDebug("RULE_SYSTEM", "{} Battery critical", "PorchLock")
			}
        case "169": {
            Porch_Alarm_Virtual.postUpdate("Battery too low")
            logDebug("RULE_SYSTEM", "{} Battery too low", "PorchLock")
			}
        default : {
            Porch_Alarm_Virtual.postUpdate ("Unknown Alarm Type " +actionType + "  Value " +actionTypeValue)
            logDebug("RULE_SYSTEM_Default", "{} Unknown Alarm Type  " +actionType + "  Value  " +actionTypeValue, "PorchLock")
        }
    }
	}
	
end


rule "New Yale YRD110 Rule"

// I tried to use a map file to change the text but it sometimes failed and reported
// stuff like {"type"\:"112","value"\:"0"} not Master code changed or user added at keypad
// refreshing the screen would "fix" it. 
// So I will use a technique like I used for the B&D Lock

when
    Item Garage_Alarm_Raw changed  
	
then

//Process the JSON from the raw alarm to get the Type and Value 
    var actionType = transform("JSONPATH", "$.type",triggeringItem.state.toString)  // these SOBs are strings
    var actionTypeValue = transform("JSONPATH", "$.value", triggeringItem.state.toString)
    logDebug("RULE_SYSTEM", "Garage Lock: Alarm events: TFormed State: {}, StateValue: {}", actionType, actionTypeValue)
	
		if(actionType !="0"){
	
	
	
    switch (actionType) {
        //Locking actions
        case "9": {
            Garage_Alarm_Virtual.postUpdate("Motor jammed")
			Garage_Alarm_Virtual_Short.postUpdate("Jammed")
            logDebug("RULE_SYSTEM", "{} Motor Jammed", "GarageLock")
        }

		case "18": {
            Garage_Alarm_Virtual.postUpdate("Keypad lock")
			Garage_Alarm_Virtual_Short.postUpdate("Secured")
            logDebug("RULE_SYSTEM", "{} Keypad lock", "GarageLock")
			}
        case "19": {
            Garage_Alarm_Virtual.postUpdate("Motor jammed")
			Garage_Alarm_Virtual_Short.postUpdate("Jammed")
            logDebug("RULE_SYSTEM", "{} Keypad unlock", "GarageLock")
			}
		case "21 ": {
		if (actionTypeValue=="1"){
				Garage_Alarm_Virtual.postUpdate("Manual lock by thumb")
				Garage_Alarm_Virtual_Short.postUpdate("Secured")
				logDebug("RULE_SYSTEM", "{} Manual lock by thumb", "GarageLock")
			}
			else{
				Garage_Alarm_Virtual.postUpdate("Manual lock by touchpad")
				Garage_Alarm_Virtual_Short.postUpdate("Secured")
				logDebug("RULE_SYSTEM", "{} Manual lock by touchpad", "GarageLock")
			}
			}
        case "22": {
            Garage_Alarm_Virtual.postUpdate("Manual unlock")
			Garage_Alarm_Virtual_Short.postUpdate("Un-Secured")
            logDebug("RULE_SYSTEM", "{} Manual unlock", "GarageLock")
			}
        case "24": {
            Garage_Alarm_Virtual.postUpdate("RF lock")
			Garage_Alarm_Virtual_Short.postUpdate("Secured")
            logDebug("RULE_SYSTEM", "{} RF lock", "GarageLock")
			}
		case "25": {
            Garage_Alarm_Virtual.postUpdate("RF unlock")
			Garage_Alarm_Virtual_Short.postUpdate("Un-Secured")
            logDebug("RULE_SYSTEM", "{} RF unlock", "GarageLock")
        }
        case "27": { 
            Garage_Alarm_Virtual.postUpdate("Auto re-lock cycle complete")
            logDebug("RULE_SYSTEM", "{} Auto re-lock cycle complete", "GarageLock")
			}
		case "33": {
            Garage_Alarm_Virtual.postUpdate("User deleted")
            logDebug("RULE_SYSTEM", "{} User deleted", "GarageLock")
        }
		case "112":  {
            Garage_Alarm_Virtual.postUpdate("Master code changed or user added at keypad")
            logDebug("RULE_SYSTEM", "{} Master code changed or user added at keypad", "GarageLock")
			}
        case "113":  {
            Garage_Alarm_Virtual.postUpdate("Lock has completed Handing Cycle")
            logDebug("RULE_SYSTEM", "{} Lock has completed Handing Cycle", "GarageLock")
			}
		case "129": {
            Garage_Alarm_Virtual.postUpdate("Lock has completed Handing Cycle")
            logDebug("RULE_SYSTEM", "{} Lock has completed Handing Cycle", "GarageLock")
			}
		case "130": {
            Garage_Alarm_Virtual.postUpdate("RF module (in door) power restored")
            logDebug("RULE_SYSTEM", "{} RF module (in door) power restored", "GarageLock")
			}
        case "161": {
			if (actionTypeValue=="1"){
				Garage_Alarm_Virtual.postUpdate("Tamper Alarm attempts exceeded")
				logDebug("RULE_SYSTEM", "{} Tamper Alarm attempts exceeded", "GarageLock")
				}
			else{
			     Garage_Alarm_Virtual.postUpdate("Front escutcheon removed")
				logDebug("RULE_SYSTEM", "{} Front escutcheon removed", "GarageLock")
				}
			}
        case "167": {
            Garage_Alarm_Virtual.postUpdate("Battery low")
            logDebug("RULE_SYSTEM", "{} Battery low", "GarageLock")
			}
        case "168": {
            Garage_Alarm_Virtual.postUpdate("Battery critical")
            logDebug("RULE_SYSTEM", "{} Battery critical", "GarageLock")
			}
        case "169": {
            Garage_Alarm_Virtual.postUpdate("Battery too low")
            logDebug("RULE_SYSTEM", "{} Battery too low", "GarageLock")
			}
        default : {
            Garage_Alarm_Virtual.postUpdate ("Unknown Alarm Type " +actionType + "  Value " +actionTypeValue)
            logDebug("RULE_SYSTEM_Default", "{} Unknown Alarm Type  " +actionType + "  Value  " +actionTypeValue, "GarageLock")
        }
    }
	}
	
end


This is the rule file for controlling my garage door opener:

//Overhead Garage Rules

rule "Return Switch to Off"
// Returns the switch stste to Off after pulsing the Opener 
when
    Item ChangeOverheadDoor changed	
then
//logDebug("garagedoor", "From On to Off") 
	ChangeOverheadDoor.sendCommand(OFF)
end

rule "If Open At 10:PM, close it"

when 
	
	Time cron //"0/10 * * ? * *" // ten seconds
	//"0 0/1 * * * ?" // Every minute
	"0 0 22 * * ?" // At 10 PM 
	//"0 0/5 * * * ?" //  I don't remember
then
	if(GarageOverheadState.state.toString=="open")  //crap I tried everything before I stumbled on this
		{//logError("garagedoor", "inside if") //Try if (GarageOverheadState.state == “closed”) next time.
		ChangeOverheadDoor.sendCommand(ON)
		//createTimer(now.plusSeconds(5))
		ChangeOverheadDoor.sendCommand(OFF)}
		sendMail("7169136751@txt.att.net", "Text Notification, Garage Door Closing at 10:00 PM")
	//logError("garagedoor", "just after if")
//	if (GarageLightState.state.toString=="off")
//		(sendMail("7169136751@txt.att.net", "Text Notification, Garage lights On at 10:00 PM")) 
end

rule "If Garage Light is On at 10:PM, send text"

when 	
	Time cron //"0/10 * * ? * *" // ten seconds
	//"0 0/1 * * * ?" // Every minute
	"0 0 22 * * ?" // At 10 PM "0 0 22 * * ?" 
	//"0 0/5 * * * ?" //  I don't remember
then
	logInfo("garagelight", "Time Match")
	{if (GarageLightState.state.toString=="On") //The mapp converts Off to OFF
		{
		logInfo("garagelight", "Light State Match")
		//From OH Mail Actions  sendMail(String to, String subject, String message)
		sendMail("7169136751@txt.att.net", "Text Notification", "Garage lights On at 10:00 PM")
		}
	}
end

Below is my original home rules file which contains a collection of rules. I have edited out email addresses and phone numbers.

//This is the rules file

// These "Opening" texts are from mqtt.   my.map just gives a replacement text to go to the UI
// sendMail("email address"."Will become the subject",the state from the mqtt) 
// How to do an OR>>> if(triggeringItem.state ==  "Closing" || triggeringItem.state == "Opening")    

//******Door***************
rule "Send Any Door via Mail and Text"
when
    Member of DoorSensors changed
then
	if(triggeringItem.state == "Opening" || triggeringItem.state=="OpeningOrTampRemoved")    
	{if (SendEmailMode.state == ON)
		// The line below puts an entry in the OpenHAB log.
		{logInfo("Door", "Sending notification via Email because {} is Opening.",triggeringItem.name)
		// The line below sends an email
		sendMail("XXX@XXX.com", "Mail Notification, door opening" ,triggeringItem.name)
    	        }
          
	if (SendTextMode.state == ON)
		{logInfo("Door", "Sending notification via Text because {} is Opening.",triggeringItem.name)
		sendMail("nnnnnnnnnnn@txt.att.net", "Text Notification, door opening" ,triggeringItem.name)
	//	sendMail("nnnnnnnnnn@txt.att.net", "Text Notification, door opening" ,triggeringItem.name)
    	        }
    }
end



///**********Window*****
rule "Send Any Window via Mail and Text"
when
    Member of WindowSensors changed
then
	if(triggeringItem.state == "Opening")    
	{if (SendEmailMode.state == ON)
		{logInfo("Window", "Sending notification via Email because {} is Opening.",triggeringItem.name)
		sendMail(XXXX@XXXX.com", "Mail Notification, Window opening" ,triggeringItem.name)
    	        }
	if (SendTextMode.state == ON)
		{logInfo("Window", "Sending notification via Text because {} is Opening.",triggeringItem.name)
		sendMail("NNNN@txt.att.net", "Text Notification, Window opening" ,triggeringItem.name)
		}
        }
end



//*********SmokeHeat
rule "Send Any SmokeHeat via Mail"
when
    Member of SmokeHeat changed
then
	//if(triggeringItem.state ==  "Opening")
	if(triggeringItem.state ==  "Smoke" || triggeringItem.state ==  "Heat")    
	{if (SendEmailMode.state == ON)
		//{logInfo("SmokeHeat", "Sending notification via Email because {} is Opening.",triggeringItem.name)
		{logInfo("SmokeHeat", "Sending notification via Email because {} is Smoke.",triggeringItem.name)
		sendMail("XXXX@XXXX.com", "Mail Notification, SmokeHeat" ,triggeringItem.name)
    	}
    }
end

rule "Send Any SmokeHeat Text Message" //We should be able to eliminaate this.
when
    Member of SmokeHeat changed
then

    //if(triggeringItem.state == "Opening") 
    if(triggeringItem.state ==  "Smoke" || triggeringItem.state ==  "Heat")    
	{if (SendTextMode.state == ON)
		//{logInfo("SmokeHeat", "Sending notification via Text because {} is Opening.",triggeringItem.name)
		{logInfo("SmokeHeat", "Sending notification via Email because {} is Smoke.",triggeringItem.name)
		sendMail("NNNN@txt.att.net", "Text Notification, SmokeHeat" ,triggeringItem.name)
    	}
    }
end
 
//******************GlassBreak  Need to update when we find out the GlassBreak code
rule "Send Any GlassBreak via Mail"
when
    Member of GlassBreak changed
then
	if(triggeringItem.state != "Alive")  // Under Test
	{if (SendEmailMode.state == ON)
		{logInfo("GlassBreak", "Sending notification via Email because {} Heat or Smoke.",triggeringItem.name)
		sendMail("XXXX@XXXX.com", "Mail Notification, GlassBreak" ,triggeringItem.name)
    	}
    }
end

rule "Send Any GlassBreak Text Message"
when
    Member of GlassBreak changed
then

    if(triggeringItem.state != "Alive")   // Under Test
	{if (SendTextMode.state == ON)
		{logInfo("GlassBreak", "Sending notification via Text because {} Heat or Smoke",triggeringItem.name)
		sendMail("NNNN@txt.att.net", "Text Notification, GlassBreak" ,triggeringItem.name)
    	}
    }
end

//**************This is a test of sending a Lock/unlock command to the porch when the porch door changes.
//************I don't know what that ^^^^^^^^^^^^ means.  I think this closes the locks at 10 PM (and now the Overhead garage door)

rule "Send lock to porch, garage, and Front lock"
when 
	Time cron //"0/10 * * ? * *" // ten seconds
	//"0 0/1 * * * ?" // Every minute
	"0 0 22 * * ?" // At 10 PM 
	//"0 0/5 * * * ?" //  I don't remember
then	
	//logError("garagedoor", "reached time cron")
	Porch_Lock_Door.sendCommand(ON)
	Garage_Lock_Door.sendCommand(ON)
	Front_Lock_Door.sendCommand(ON)
	//logError("garagedoor", "just before if")
	//if(GarageOverheadState.state.toString.contains("open"))  //crap I tried everything before I stumbled on this
	
end

Yes it is. Even if it is dormant, when the command goes out to lock at 10:00PM it locks just like the Yale locks.

If you are running OH on an SD, you should already be doing regular backups and have an SD on standby, as the card you are using WILL fail. SD cards do not last forever and can fail catastrophically, meaning everything is gone. Sometimes they are bad right out of the box, but it is not realized until much later. What I have been suggesting is that your SD card may be damaged and causing the issue. Swap your existing card for another and see if that helps.

I do not see anything in your rules that would cause your rules to eat up threads or to lock up. However, here are some pointers cleaning things up :slightly_smiling_face:. I’m a little surprised that the DSL allows for triggers to span multiple lines, but even if it works, it is very difficult to read. The formatting that you are using also makes things difficult to read. For example, this…

	if(triggeringItem.state == "Opening")    
	{if (SendEmailMode.state == ON)
		{logInfo("Window", "Sending notification via Email because {} is Opening.",triggeringItem.name)
		sendMail(XXXX@XXXX.com", "Mail Notification, Window opening" ,triggeringItem.name)
    	        }
	if (SendTextMode.state == ON)
		{logInfo("Window", "Sending notification via Text because {} is Opening.",triggeringItem.name)
		sendMail("NNNN@txt.att.net", "Text Notification, Window opening" ,triggeringItem.name)
		}
        }

… is much easier to read like this…

    if (triggeringItem.state == "Opening") {
        if (SendEmailMode.state == ON) {
            logInfo("Window", "Sending notification via Email because {} is Opening.", triggeringItem.name)
            sendMail("XXXX@XXXX.com", "Mail Notification, Window opening", triggeringItem.name)
        }
        if (SendTextMode.state == ON) {
            logInfo("Window", "Sending notification via Text because {} is Opening.", triggeringItem.name)
            sendMail("NNNN@txt.att.net", "Text Notification, Window opening", triggeringItem.name)
        }
    }

This way, the curly brackets help show where the blocks start and end. There was also a missing quote in the email address for the first sendMail, but I expect that got deleted when obfuscating the address. If you use VS Code with the OH extension for editing your rules, it will make things a lot easier. In “If Garage Light is On at 10:PM, send text”, there is a complete extra set of curly brackets.

Sorry for the lecture… take it or leave it!

Could you be more specific what you mean here? By dormant, do you mean it is not logging, the UI is not updating, there is nothing be logged, etc? How is the rule dormant of the lock is still locking?

Nothing to be sorry for. I always want to know how the experienced users do it.
To create and edit I use Notepad++ with the user defined language download for OH. It supplies colored text and highlights matching brackets, etc. It is a lot faster then VS and doesn’t argue with me when I want to do something like VS always seems to. Below, I included a snip of the B&D rule about the example I created to explain the situation. BTW, I started using the term “Dormant” for when a rules file doesn’t run anymore but will resume running after re-saving.
Below is what I captured when the rule (B&D Lock.rules) is working (not dormant). I’ll have to wait for it to go dormant to get the other situation but I think I can describe it well enough now.

Here is the Habpanel widgets for the B&D lock. Actually, below the screen is the battery report but we don’t need that,

The first widget (Change Front) will send a command for the lock to change state when clicked. It uses the item:

Switch Front_Lock_Door "F Lock State" <door> {channel="zwave:device:fe40ab17:node32:lock_door"}

The second widget (Front State) is a very compact one for use on a cellphone. It corresponds to an item:

String Front_Alarm_Virtual_Short "FS State"

The third widget (Front Alarm Raw) is the alarm_raw straight from the z-wave and corresponds to the item:

String Front_Alarm_Raw "F Alarm Raw type" {channel="zwave:device:fe40ab17:node32:alarm_raw"}

The fourth widget (Front Lock Status) translates the alarm_raw to the full text from the manufacturer or whoever. It corresponds to the item:

String Front_Alarm_Virtual "F Lock StateV "

Now, I clicked the Change Front switch which caused the following log entries:

The first line is left over from something else.
Here is the pertinent section of the B&D rules file to work in parallel:

The log entries from the second, third and fourth line show the progression of the Change command.
The fifth line of the log shows the Alarm_Raw changed, to {“type”:“25”,“value”:“1”}. When it hits the rules file it causes the first blue line in the log, then the next log line comes from case “25”, first line and is the text for the fourth widget followed by the second blue line which is caused by the, logDebug… line. Then the last line which is for the second widget.
This is what happens when the rules file works and this is the resulting UI:


If it is dormant, there will be nothing in the log after the:

2020-12-13 22:00:04.554 [vent.ItemStateChangedEvent] - Garage_Alarm_Raw changed from {"type":"22","value":"1"} to {"type":"24","value":"1"}

and the second and fourth widget will continue to display what ever they had from the last time the rule ran.

I hope this isn’t too detailed.

BTW, while I was typing this I got a bogus entry from this lock:

2020-12-13 21:27:11.773 [vent.ItemStateChangedEvent] - Front_Alarm_Raw changed from {"type":"25","value":"1"} to {"type":"22","value":"0"}

Type 25, value 0 is not in the list of valid cases.

So I have been pondering this problem and I get the feeling the solution may not be within OpenHAB. I am convinced that when the B&D rule goes dormant and doesn’t run, it requires the rule file to be re-saved to get it back operating.
I am going to try to duplicate this re-save operation external to OH. Luckily I have another program running on the same computer that is independent of OH. I will see if just opening and closing the rules file in that program will be enough to bring the rule back to operating. If that works I will add some lines of code to the program to periodically open and close the file. Maybe once a day or so.
Right now I am waiting for it to go dormant so I can test this.