Hey all, I have come across an issue that doesn’t seem like it should be an issue to me.
I have my rules files orginized in the following way:
All lighting related rules go in lighting.rules
All hvac related rules go in hvac.rules
Irrigation is irrigation.rules
And security is security.rules
The problem I come across is when a rules file starts to get too big, some rules in it will fire for just fine for a while, but then they stop firing and won’t fire until I restart OH, yet they work perfectly when I put them in their own rules files.
I have been able to replicate this on multiple different setups.
My current setup is Openhabian custom install on ubuntu server 16.0.4 LTS OH 2.1
Platform information:
Hardware: CPUArchitecture/RAM/storage
OS: what OS is used and which version
Java Runtime Environment: which java platform is used and what version
openHAB version:
Issue of the topic: please be detailed explaining your issue
Please post configurations (if applicable):
Items configuration related to the issue
Sitemap configuration related to the issue
Rules code related to the issue
Services configuration related to the issue
If logs where generated please post these here using code fences:
Please gather as much information you can including debug logs when the rules stop firing, watch the memory usage and CPU, and file an issue on the ESH repo.
How big is too big? I know some users have .rules files that run in the thousands of lines. I personally spend a lot of effort to make sure my rules are short and simple so I’ve not seen anything like this.
Is suppose too big isn’t the right statement here as it varies.
The thing about that is, I am unsure. One file Has a bunch of short simple rules in it. And the rule that quits firing is also very simple.
While on the other hand i have another simple rule in a file with some more complex rules. And the one simple rule quits firing. The only thing Ive been able to do to ensure they always fire is to put them in their own .rules file
I dont have time right now to go through the logs, but I will this evening. The cpu stays around 11% and memory is almost always below 50%
I don’t have anything with Thread::sleep and I’m not sure what you mean by reentrant locks.
here is my lighting.rules:
//////////////// Garage Lighting //////////////////
rule "Garage Motion"
when
Item GarageMotion received update
then
if (grageMotionEnable.state==ON){
sendCommand(garageMotionBit,ON)
sendCommand(garageLightsTimer,ON)
if(GarageOneLights.state==ON)sendCommand(garageMotionBit,OFF)
if (GarageOneLights.state!=ON)sendCommand(GarageOneLights,ON)
}
end
rule "Turn Off Garage Lights"
when
Item garageLightsTimer received update OFF
then
if(grageMotionEnable.state==ON&&GarageOneLights.state!=OFF)sendCommand(GarageOneLights,OFF)
end
rule "Enable Garage Motion"
when
Item GarageOneLights changed from ON to OFF
then
if(grageMotionEnable.state!=ON)sendCommand(grageMotionEnable,ON)
end
rule "Disable Garage Motion 1"
when
Item GarageOneLights received command ON
then
if(garageMotionBit.state==OFF)sendCommand(grageMotionEnable,OFF)
else (garageMotionBit.state==ON)sendCommand(garageMotionBit,OFF)
end
rule "Disable Garage Motion 2"
when
Item garageLightsFast received command ON
or
Item Garage_One_Remoteb2 received command ON
then
sendCommand(grageMotionEnable,OFF)
end
////////////// Foyer Keypad /////////////
rule "Foyer Lights - KeypadB"
when
Item FoyerLights received update
then
if (FoyerLights.state >= 1 && keypadSwitchB.state != ON)sendCommand(keypadSwitchB,ON)
else(FoyerLights.state==0 && keypadSwitchB.state != OFF)sendCommand(keypadSwitchB,OFF)
end
rule "Keypad D - LR Lights"
when
Item keypadSwitchD changed
then
if (keypadSwitchD.state==ON && LRLights.state != 100)sendCommand(LRLights,100)
if (keypadSwitchD.state==OFF && LRLights.state != 0)sendCommand(LRLights,0)
end
rule "LR Lights - KeypadD"
when
Item LRLights received update
then
if (LRLights.state >= 1&& keypadSwitchD.state != ON)sendCommand(keypadSwitchD,ON)
if (LRLights.state == 0&& keypadSwitchD.state != OFF)sendCommand(keypadSwitchD,OFF)
end
rule "Dinning Lights - KeypadE"
when
Item DinningLights received update
then
if (DinningLights.state >= 1&& keypadSwitchE.state != ON)sendCommand(keypadSwitchE,ON)
if (DinningLights.state == 0&& keypadSwitchE.state != OFF)sendCommand(keypadSwitchE,OFF)
end
rule "Kitchen Lights - KeypadF"
when
Item KitchenLights received update
then
if (KitchenLights.state >= 1&& keypadSwitchF.state != ON)sendCommand(keypadSwitchF,ON)
if (KitchenLights.state == 0&& keypadSwitchF.state != OFF)sendCommand(keypadSwitchF,OFF)
end
rule "Basement Stairwell - KeypadG"
when
Item BasementStairwellLights received update
then
if (BasementStairwellLights.state >= 1&& keypadSwitchG.state != ON)sendCommand(keypadSwitchG,ON)
if (BasementStairwellLights.state == 0&& keypadSwitchG.state != OFF)sendCommand(keypadSwitchG,OFF)
end
and this is the rule that stops firing after a while, I have put it in a separate lighting-1.rules:
///////////jory
rule "Jory lava lamp control"
when
Item JoryLavaLamps received update
then
if(JoryLavaLamps.state==100){
if(JoryLight.state!=0)JoryLight.sendCommand(0)
if(JoryLamps.state!=20)JoryLamps.sendCommand(20)
}
if(JoryLavaLamps.state==0){
if(JoryLight.state!=0)JoryLight.sendCommand(0)
if(JoryLamps.state!=0)JoryLamps.sendCommand(0)
}
end
Do you see in events.log that JoryLavaLamps is being updated? Have you added a logging statement to verify whether the Rule is in fact not triggering versus just not doing what you expect?
I’m just trying to rule out some of the things you could do inside your Rules that could cause them to stop responding. Both Thread::sleep and ReentrantLock can tie up an exeuction thread, eventually leaving none left to run your Rules while waiting for the sleeps to end or the locks to be released.
Just this one, I have another rule I have taken out of hvac.rules that has the same behavior here:
rule "Convert broadlink tempC to TempF"
when
Item RMProTempC changed
then
var Number BLtempC = RMProTempC.state as DecimalType
var Number BLtempF = (BLtempC * 1.8) + 32
RMProTempF.postUpdate(BLtempF)
end
I do, every time always see an update from JoryLavaLamps
I Have not, I understand the importance of logging but I haven’t been able to figure out how to implement it (I’m not a very good programmer, I come from writing stuff in C for the arduino, and just pick up bits as I go along)
rule "Jory lava lamp control"
when
Item JoryLavaLamps received update
then
if (JoryLavaLamps.state==100) {
if(JoryLight.state!=0)JoryLight.sendCommand(0)
if(JoryLamps.state!=20)JoryLamps.sendCommand(20)
}
else if (JoryLavaLamps.state==0) {
if(JoryLight.state!=0)JoryLight.sendCommand(0)
if(JoryLamps.state!=0)JoryLamps.sendCommand(0)
}
else {
logInfo("OOPS", "was not expecting " + JoryLavaLamps.state)
}
end
Have another look at the if-else structure.
My example was if XX elseif YY else ZZ
Only one of those three conditions can be met (in this case the third is one that we were not really expecting, and is just there in case of errors).
Note that one of the three blocks must always execute.
Your rewrite boils down to
if XX
if YY else ZZ
This is not quite the same, it is possible for none of the code blocks to execute.
Consider what happens if the test is neither XX nor YY. In this case you aren’t expecting that to happen, but the extra “else” part ZZ to warn you about the suprise won’t get executed.
It’s not a big deal, but thinking through “what if” things like this can help avoid unintended behaviour in rules.
Unfortunately I don’t have any solutions but will say that I chased these types of problems since migrating from 1.8 to OH 2 a year ago. Logging isn’t usually the fix for this issue because as you are seeing, logging also stops when the rule stops. It got so bad for me that I actually have 2 instances of OH running on two separate machines that monitor each other and rules have a clutch that switch which server is active because rule processing would go down often and randomly.
I’ve been on 2.2 since it came out and thus far, rules have been working without a hangup. You may want to consider trying 2.2 to see if your problem resolves.
I did switch from mysql to jdbc-mysql and a few other little tweaks during my 2.1 - 2.2 migration so there could be other things that helped.
I quite agree. The logInfo is there to determine the nature of what has gone wrong - is the rule not firing, is it that values are not as expected etc.
My point is that I have tried repeatedly to raise logging level on the rules engine to debug and trace as well as filling all of my rules with debugging logs and in the end, the rules just simply stop processing and none of the logs really show anything. Others found the same thing. One moment a rule fires and all rule based logs spew, the next moment, the event shows the item change and absolutely nothing happens in the root logger.
Because we can’t put a finger on or show exactly where, when, why or a reproducible setup… we have gained little traction in looking for assistance.
At this point, I’m holding my breath that 2.2 and or tweaks I made during the migration have fixed it as my rules have been humming along without pause.
Have you tried putting the rules that dont fire in their own .rules file? Its what I’ve been doing and it seems to work out alright, I was just really wanted to organize my rules into fewer, more comprehensive files. I’ve got to say it is kind of a bummer others have been able to witness this issue, but have found no solutions.
I’ve updated to 2.2 now, still having the same issue, Im currently using mysql persistence, if I have time today I’ll se about moving to jdbc-mysql. What other tweaks have you made?
default.rules - lights and generic stuff
climatecontrol.rules - heat and ac
security.rules - security system based rules
I haven’t tried breaking them out any further. If I had a single or collection of rules that stopped I would try something like that but my experience was that when a rule stopped, they ALL stopped.
There were a lot of little tweaks that probably have no consequence. I migrated to stretch from jessie. I changed exec, astro and network bindings to their 2.0 counterparts. I stopped using weather binding and starting using the wunderground binding instead. Database changed from mysql to mariadb.
There have been a few that have opened one or two but they usually don’t go anywhere because we cannot reproduce or get any good logs as nothing consistent is happening and no errors are thrown… it just stopped triggering rules. I personally haven’t opened any issues because I knew I wouldn’t be able to substantiate my issue so why bother.
We did once track down a bug in harmony binding that helped some.
I do have a decent collection of sleeps (very short designed to delay a second for persistence to catch up) that perhaps that was my issue and why I no longer (thus far) see it in 2.2. IDK. Jury is still out. I sometimes would get hours, sometimes days and occasionally a few weeks before it would crash.