Thing Status Change causes complete rules refresh

Openhab 5.1.3

I have been having a problem where all my rules (DSL / File Based) would reload where i thought it was a rule that was causing this but narrowed it down specifically to the status change of a THING, i thought it was specific to Pushover, but i tested it against other things and i get the same results. I didn’t notice this in 5.0 but am seeing it now in 5.1.3

Here’s an example of a thing i’m changing the status against and the logs

DISABLING THE THING:
specifically this line:

2026-04-21 08:46:53.053 \[DEBUG\] \[e.model.rule.jvmmodel.RulesRefresher\] - Thing automation action removed => rules are going to be refreshed
2026-04-21 08:46:53.040 \[INFO \] \[ab.event.ThingStatusInfoChangedEvent\] - Thing ‘pushover:pushover-account:doors’ changed from ONLINE to UNINITIALIZED
==> /var/log/openhab/openhab.log <==
2026-04-21 08:46:53.050 \[DEBUG\] \[e.model.rule.jvmmodel.RulesRefresher\] - bundle org.openhab.core.model.rule:5.1.3 (207)\[org.openhab.core.model.rule.jvmmodel.RulesRefresher(235)\] : dm ThingActions tracking 352 MultipleDynamic removed {org.openhab.core.thing.binding.ThingActions}={service.id=614, service.bundleid=311, service.scope=singleton} (enter)
2026-04-21 08:46:53.052 \[DEBUG\] \[e.model.rule.jvmmodel.RulesRefresher\] - bundle org.openhab.core.model.rule:5.1.3 (207)\[org.openhab.core.model.rule.jvmmodel.RulesRefresher(235)\] : invoking unbind: removeThingActions: parameters \[org.openhab.binding.pushover.internal.actions.PushoverActions\]
2026-04-21 08:46:53.053 \[DEBUG\] \[e.model.rule.jvmmodel.RulesRefresher\] - Thing automation action removed => rules are going to be refreshed
2026-04-21 08:46:53.053 \[DEBUG\] \[e.model.rule.jvmmodel.RulesRefresher\] - bundle org.openhab.core.model.rule:5.1.3 (207)\[org.openhab.core.model.rule.jvmmodel.RulesRefresher(235)\] : invoked unbind: removeThingActions
2026-04-21 08:46:53.054 \[DEBUG\] \[e.model.rule.jvmmodel.RulesRefresher\] - bundle org.openhab.core.model.rule:5.1.3 (207)\[org.openhab.core.model.rule.jvmmodel.RulesRefresher(235)\] : dm ThingActions tracking 352 MultipleDynamic removed (unbind) {org.openhab.core.thing.binding.ThingActions}={service.id=614, service.bundleid=311, service.scope=singleton}
2026-04-21 08:46:53.054 \[DEBUG\] \[e.model.rule.scoping.RulesClassCache\] - bundle org.openhab.core.model.rule:5.1.3 (207)\[org.openhab.core.model.rule.scoping.RulesClassCache(236)\] : dm ThingActions tracking 348 MultipleDynamic removed {org.openhab.core.thing.binding.ThingActions}={service.id=614, service.bundleid=311, service.scope=singleton} (enter)
2026-04-21 08:46:53.054 \[DEBUG\] \[e.model.rule.scoping.RulesClassCache\] - bundle org.openhab.core.model.rule:5.1.3 (207)\[org.openhab.core.model.rule.scoping.RulesClassCache(236)\] : invoking unbind: removeThingActions: parameters \[org.openhab.binding.pushover.internal.actions.PushoverActions\]
2026-04-21 08:46:53.055 \[DEBUG\] \[e.model.rule.scoping.RulesClassCache\] - bundle org.openhab.core.model.rule:5.1.3 (207)\[org.openhab.core.model.rule.scoping.RulesClassCache(236)\] : invoked unbind: removeThingActions
2026-04-21 08:46:53.055 \[DEBUG\] \[e.model.rule.scoping.RulesClassCache\] - bundle org.openhab.core.model.rule:5.1.3 (207)\[org.openhab.core.model.rule.scoping.RulesClassCache(236)\] : dm ThingActions tracking 348 MultipleDynamic removed (unbind) {org.openhab.core.thing.binding.ThingActions}={service.id=614, service.bundleid=311, service.scope=singleton}
2026-04-21 08:46:53.055 \[DEBUG\] \[.core.model.script.ScriptServiceUtil\] - bundle org.openhab.core.model.script:5.1.3 (210)\[org.openhab.core.model.script.ScriptServiceUtil(239)\] : dm ThingActions tracking 353 MultipleDynamic removed {org.openhab.core.thing.binding.ThingActions}={service.id=614, service.bundleid=311, service.scope=singleton} (enter)
2026-04-21 08:46:53.056 \[DEBUG\] \[.core.model.script.ScriptServiceUtil\] - bundle org.openhab.core.model.script:5.1.3 (210)\[org.openhab.core.model.script.ScriptServiceUtil(239)\] : invoking unbind: removeThingActions: parameters \[org.openhab.binding.pushover.internal.actions.PushoverActions\]
2026-04-21 08:46:53.056 \[DEBUG\] \[.core.model.script.ScriptServiceUtil\] - bundle org.openhab.core.model.script:5.1.3 (210)\[org.openhab.core.model.script.ScriptServiceUtil(239)\] : invoked unbind: removeThingActions
2026-04-21 08:46:53.056 \[DEBUG\] \[.core.model.script.ScriptServiceUtil\] - bundle org.openhab.core.model.script:5.1.3 (210)\[org.openhab.core.model.script.ScriptServiceUtil(239)\] : dm ThingActions tracking 353 MultipleDynamic removed (unbind) {org.openhab.core.thing.binding.ThingActions}={service.id=614, service.bundleid=311, service.scope=singleton}
2026-04-21 08:46:53.057 \[DEBUG\] \[nal.engine.action.ThingActionService\] - bundle org.openhab.core.model.script:5.1.3 (210)\[org.openhab.core.model.script.internal.engine.action.ThingActionService(248)\] : dm ThingActions tracking 340 MultipleDynamic removed {org.openhab.core.thing.binding.ThingActions}={service.id=614, service.bundleid=311, service.scope=singleton} (enter)
2026-04-21 08:46:53.057 \[DEBUG\] \[nal.engine.action.ThingActionService\] - bundle org.openhab.core.model.script:5.1.3 (210)\[org.openhab.core.model.script.internal.engine.action.ThingActionService(248)\] : invoking unbind: removeThingActions: parameters \[org.openhab.binding.pushover.internal.actions.PushoverActions\]
2026-04-21 08:46:53.057 \[DEBUG\] \[nal.engine.action.ThingActionService\] - bundle org.openhab.core.model.script:5.1.3 (210)\[org.openhab.core.model.script.internal.engine.action.ThingActionService(248)\] : invoked unbind: removeThingActions
2026-04-21 08:46:53.057 \[DEBUG\] \[nal.engine.action.ThingActionService\] - bundle org.openhab.core.model.script:5.1.3 (210)\[org.openhab.core.model.script.internal.engine.action.ThingActionService(248)\] : dm ThingActions tracking 340 MultipleDynamic removed (unbind) {org.openhab.core.thing.binding.ThingActions}={service.id=614, service.bundleid=311, service.scope=singleton}
==> /var/log/openhab/events.log <==
2026-04-21 08:46:53.059 \[INFO \] \[ab.event.ThingStatusInfoChangedEvent\] - Thing ‘pushover:pushover-account:doors’ changed from UNINITIALIZED to UNINITIALIZED (DISABLED)

ENABLING THE THING:
specifically this line:

2026-04-21 08:46:54.866 [DEBUG] [e.model.rule.jvmmodel.RulesRefresher] - Thing automation action added => rules are going to be refreshed
2026-04-21 08:46:54.864 \[DEBUG\] \[e.model.rule.jvmmodel.RulesRefresher\] - bundle org.openhab.core.model.rule:5.1.3 (207)\[org.openhab.core.model.rule.jvmmodel.RulesRefresher(235)\] : dm ThingActions tracking 353 MultipleDynamic added {org.openhab.core.thing.binding.ThingActions}={service.id=52033, service.bundleid=311, service.scope=singleton} (enter)
2026-04-21 08:46:54.865 \[DEBUG\] \[e.model.rule.jvmmodel.RulesRefresher\] - bundle org.openhab.core.model.rule:5.1.3 (207)\[org.openhab.core.model.rule.jvmmodel.RulesRefresher(235)\] : dm ThingActions tracking 353 MultipleDynamic already active, binding {org.openhab.core.thing.binding.ThingActions}={service.id=52033, service.bundleid=311, service.scope=singleton}
2026-04-21 08:46:54.865 \[DEBUG\] \[e.model.rule.jvmmodel.RulesRefresher\] - bundle org.openhab.core.model.rule:5.1.3 (207)\[org.openhab.core.model.rule.jvmmodel.RulesRefresher(235)\] : invoking bind: addThingActions: parameters \[org.openhab.binding.pushover.internal.actions.PushoverActions\]
2026-04-21 08:46:54.866 \[DEBUG\] \[e.model.rule.jvmmodel.RulesRefresher\] - Thing automation action added => rules are going to be refreshed
2026-04-21 08:46:54.866 \[DEBUG\] \[e.model.rule.jvmmodel.RulesRefresher\] - bundle org.openhab.core.model.rule:5.1.3 (207)\[org.openhab.core.model.rule.jvmmodel.RulesRefresher(235)\] : invoked bind: addThingActions
2026-04-21 08:46:54.866 \[DEBUG\] \[e.model.rule.jvmmodel.RulesRefresher\] - bundle org.openhab.core.model.rule:5.1.3 (207)\[org.openhab.core.model.rule.jvmmodel.RulesRefresher(235)\] : dm ThingActions tracking 353 MultipleDynamic added {org.openhab.core.thing.binding.ThingActions}={service.id=52033, service.bundleid=311, service.scope=singleton} (exit)
2026-04-21 08:46:54.866 \[DEBUG\] \[e.model.rule.scoping.RulesClassCache\] - bundle org.openhab.core.model.rule:5.1.3 (207)\[org.openhab.core.model.rule.scoping.RulesClassCache(236)\] : dm ThingActions tracking 349 MultipleDynamic added {org.openhab.core.thing.binding.ThingActions}={service.id=52033, service.bundleid=311, service.scope=singleton} (enter)
2026-04-21 08:46:54.867 \[DEBUG\] \[e.model.rule.scoping.RulesClassCache\] - bundle org.openhab.core.model.rule:5.1.3 (207)\[org.openhab.core.model.rule.scoping.RulesClassCache(236)\] : dm ThingActions tracking 349 MultipleDynamic already active, binding {org.openhab.core.thing.binding.ThingActions}={service.id=52033, service.bundleid=311, service.scope=singleton}
2026-04-21 08:46:54.867 \[DEBUG\] \[e.model.rule.scoping.RulesClassCache\] - bundle org.openhab.core.model.rule:5.1.3 (207)\[org.openhab.core.model.rule.scoping.RulesClassCache(236)\] : invoking bind: addThingActions: parameters \[org.openhab.binding.pushover.internal.actions.PushoverActions\]
2026-04-21 08:46:54.867 \[DEBUG\] \[e.model.rule.scoping.RulesClassCache\] - Updated cache entry: org.openhab.binding.pushover.internal.actions.PushoverActions
2026-04-21 08:46:54.868 \[DEBUG\] \[e.model.rule.scoping.RulesClassCache\] - bundle org.openhab.core.model.rule:5.1.3 (207)\[org.openhab.core.model.rule.scoping.RulesClassCache(236)\] : invoked bind: addThingActions
2026-04-21 08:46:54.868 \[DEBUG\] \[e.model.rule.scoping.RulesClassCache\] - bundle org.openhab.core.model.rule:5.1.3 (207)\[org.openhab.core.model.rule.scoping.RulesClassCache(236)\] : dm ThingActions tracking 349 MultipleDynamic added {org.openhab.core.thing.binding.ThingActions}={service.id=52033, service.bundleid=311, service.scope=singleton} (exit)
2026-04-21 08:46:54.868 \[DEBUG\] \[.core.model.script.ScriptServiceUtil\] - bundle org.openhab.core.model.script:5.1.3 (210)\[org.openhab.core.model.script.ScriptServiceUtil(239)\] : dm ThingActions tracking 354 MultipleDynamic added {org.openhab.core.thing.binding.ThingActions}={service.id=52033, service.bundleid=311, service.scope=singleton} (enter)
2026-04-21 08:46:54.868 \[DEBUG\] \[.core.model.script.ScriptServiceUtil\] - bundle org.openhab.core.model.script:5.1.3 (210)\[org.openhab.core.model.script.ScriptServiceUtil(239)\] : dm ThingActions tracking 354 MultipleDynamic already active, binding {org.openhab.core.thing.binding.ThingActions}={service.id=52033, service.bundleid=311, service.scope=singleton}
2026-04-21 08:46:54.869 \[DEBUG\] \[.core.model.script.ScriptServiceUtil\] - bundle org.openhab.core.model.script:5.1.3 (210)\[org.openhab.core.model.script.ScriptServiceUtil(239)\] : invoking bind: addThingActions: parameters \[org.openhab.binding.pushover.internal.actions.PushoverActions\]
2026-04-21 08:46:54.869 \[DEBUG\] \[.core.model.script.ScriptServiceUtil\] - bundle org.openhab.core.model.script:5.1.3 (210)\[org.openhab.core.model.script.ScriptServiceUtil(239)\] : invoked bind: addThingActions
2026-04-21 08:46:54.869 \[DEBUG\] \[.core.model.script.ScriptServiceUtil\] - bundle org.openhab.core.model.script:5.1.3 (210)\[org.openhab.core.model.script.ScriptServiceUtil(239)\] : dm ThingActions tracking 354 MultipleDynamic added {org.openhab.core.thing.binding.ThingActions}={service.id=52033, service.bundleid=311, service.scope=singleton} (exit)
2026-04-21 08:46:54.869 \[DEBUG\] \[nal.engine.action.ThingActionService\] - bundle org.openhab.core.model.script:5.1.3 (210)\[org.openhab.core.model.script.internal.engine.action.ThingActionService(248)\] : dm ThingActions tracking 341 MultipleDynamic added {org.openhab.core.thing.binding.ThingActions}={service.id=52033, service.bundleid=311, service.scope=singleton} (enter)
2026-04-21 08:46:54.869 \[DEBUG\] \[nal.engine.action.ThingActionService\] - bundle org.openhab.core.model.script:5.1.3 (210)\[org.openhab.core.model.script.internal.engine.action.ThingActionService(248)\] : dm ThingActions tracking 341 MultipleDynamic already active, binding {org.openhab.core.thing.binding.ThingActions}={service.id=52033, service.bundleid=311, service.scope=singleton}
2026-04-21 08:46:54.870 \[DEBUG\] \[nal.engine.action.ThingActionService\] - bundle org.openhab.core.model.script:5.1.3 (210)\[org.openhab.core.model.script.internal.engine.action.ThingActionService(248)\] : invoking bind: addThingActions: parameters \[org.openhab.binding.pushover.internal.actions.PushoverActions\]
2026-04-21 08:46:54.870 \[DEBUG\] \[nal.engine.action.ThingActionService\] - bundle org.openhab.core.model.script:5.1.3 (210)\[org.openhab.core.model.script.internal.engine.action.ThingActionService(248)\] : invoked bind: addThingActions
2026-04-21 08:46:54.870 \[DEBUG\] \[nal.engine.action.ThingActionService\] - bundle org.openhab.core.model.script:5.1.3 (210)\[org.openhab.core.model.script.internal.engine.action.ThingActionService(248)\] : dm ThingActions tracking 341 MultipleDynamic added {org.openhab.core.thing.binding.ThingActions}={service.id=52033, service.bundleid=311, service.scope=singleton} (exit)
==> /var/log/openhab/events.log <==
2026-04-21 08:46:54.873 \[INFO \] \[ab.event.ThingStatusInfoChangedEvent\] - Thing ‘pushover:pushover-account:doors’ changed from UNINITIALIZED (DISABLED) to INITIALIZING
2026-04-21 08:46:54.876 \[INFO \] \[ab.event.ThingStatusInfoChangedEvent\] - Thing ‘pushover:pushover-account:doors’ changed from INITIALIZING to UNKNOWN
2026-04-21 08:46:54.956 \[INFO \] \[ab.event.ThingStatusInfoChangedEvent\] - Thing ‘pushover:pushover-account:doors’ changed from UNKNOWN to ONLINE

Is this to be expected?

Based on the logs I’d say it’s expected.

Do you have any rules in this file triggered by a Thing status change?

Do you have any rules in this file that use a Thing Action?

Do you have any rules in this file that interact with Things in other ways? When a Thing changes status like that, all of the references to that Thing go stale and need to be recreated. Reloading the .rules file ensures that happens.

I can’t speak to whether this is a change between versions or anything like that but based on what I know that’s my explanation.

Yup, what helped me identify it is the rule refreshes were always happening at the 5 minute timestamp. I had a rule that will check a things status every 5 minutes, and if the thing was offline/unavailable it would restart it to establish the connection (all my pushover things).

Once i identified the thing restarts is what causes the problem i commented out this rule and i’m not getting these massive refreshes anymore.

What happens if you trigger the rule using a Thing status change trigger instead of a cron trigger? You might need to create a timer to do the restart but that might help with the refresh and retain the functionality.

I’m still not clear why this would have changed.

What’s the rule’s language?

Manually clicking the pause/play button on the THING in the UI causes rule refreshes to trigger, so its not a problem with the actual rule code. I originally thought it was my code untile i manually tested.

Here’s my rule as i was having problems at openhab system start and not all things going ONLINE - it appeared pushover would throttle requests, so this was just a watchdog to keep them online.

/* CRON Syntax */
/* Second | Minute | Hours | Day of Month | Month | Day of Week | Year (Optional) */

rule "Check Thing Status of Pushover and reEnable if ERRORd"
when
    Time cron "* 0/5 * * * ?"
then
       val PushoverUID_list = newArrayList(
           "pushover:pushover-account%3Alawnirrigation",
            "pushover:pushover-account%3Alocks",
            "pushover%3Apushover-account%3Apresence",
            "pushover%3Apushover-account%3Aopenhab",
            "pushover%3Apushover-account%3Awifi",
            "pushover%3Apushover-account%3Adoors",
            "pushover%3Apushover-account%3Ahottub",
            "pushover%3Apushover-account%3Acameras", 
			"pushover%3Apushover-account%3Atesla", 
			"pushover%3Apushover-account%3Agarage", 
            "pushover%3Apushover-account%3Acameras_group")

PushoverUID_list.forEach[ uid |
            //logInfo(filename+".R1", "Checking ("+uid+") Thing Status" )  

        var String deviceinfo = sendHttpGetRequest("http://username:password@op.en.hab.ip:8080/rest/things/"+uid+"/status")
        var String ThingStatus = transform("JSONPATH","$.status",deviceinfo)
		
        if(ThingStatus == "OFFLINE") {
          logInfo(filename+".R1", "Thing ("+uid+") is: " + ThingStatus + ". Attempting to Disable then Enable" )  
          sendHttpPutRequest("http://username:password@op.en.hab.ip:8080/rest/things/"+uid+"/enable", "text/plain", 'enabled')
          Thread::sleep(1000)
          sendHttpPutRequest("http://username:password@op.en.hab.ip:8080/rest/things/"+uid+"/enable", "text/plain", 'true')
        } else if(ThingStatus == "UNINITIALIZED") {
            logInfo(filename+".R1", "Thing ("+uid+") is: " + ThingStatus + ".  Attempting to Enable" )  
            	sendHttpPutRequest("http://username:password@op.en.hab.ip:8080/rest/things/"+uid+"/enable", "text/plain", "true") 
        } 
    ]
end

If it’s just during startup, the following rule would handle the use case without the very five minute polling.

configuration: []
triggers:
  - id: "1"
    configuration:
      startlevel: 40
    type: core.SystemStartlevelTrigger
conditions: []
actions:
  - inputs: {}
    id: "3"
    configuration:
      type: application/javascript
      script: >-
        const pushoverThings = things.getThings().filter( thing => thing.uid.includes("pushover:pushover-account" );

        pushoverThings.forEach( thing =>  thing.setEnabled(false) );

        actions.ScriptExecution.createTimer( time.toZDT('PT5M'), () => {
            pushoverThings.forEach( thing => things.setEnabled(true) );
            Java.type('java.lang.Thread').sleep(1000);
        }
    type: script.ScriptAction

This rule triggers when OH reaches start level 40, which is about as early as possible for rules to run and it’s before Things are initialized. First it disables all the Pushover Things. Then five minutes later is re-enables them, waiting one second between each Thing.