Hi,
Newb here, I’ve had some successes with OpenHAB, but I’m still learning how it all works.
I am having trouble understanding exactly how the rule system is executed.
The rule execution seems to be closer to the event driven programming I’ve done in .NET, as opposed to something more procedural. Is that a valid assessment? I can’t really find a good explanation of how rules are executed, so short of the examples I’m having trouble getting moving. I’m fine with the syntax, just not mechanisms that drive it.
Here is a real world solution that I’ve “Solved” but I’m trying to improve on by better understanding how the rules are triggered:
My Raspberry Pi is set up to serve it’s GPIO up to an MQTT server on my main OpenHAB box. rPi only sends data when a door is opened or closed in the house (I’ve wired GPIO to the reed switches on doors and windows that were pre-installed in the house).
Until OpenHAB gets an update published to the MQTT topic, each Item holds the state: “Uninitialized”. I can post to a ‘refresh’ topic, and the rPi’s python code will update each MQTT topic… so I can easily force a refresh, but I need to know when to force it.
So, I needed a rule that ‘self heals’ the states of the inputs if any of them ever goes Uninitialized, like they tend to do on bootup. Since some windows here don’t open for years, I’ll never have a state, and that is not cool.
Here is the rule I came up with:
/* Refresh of security system MQTT on Remote rPi */
rule "Refresh MQTT"
when
System started or
Time cron "0 0/5 * 1/1 * ? *" // Every 5 minutes
then
logInfo("Security rPi MQTT","Checking MQTT Status...")
gSecurity_Sensors?.members.forEach(Contact|
if (Contact.state == Uninitialized) {
logInfo("Security rPi MQTT","Sending MQTT Refresh Request Due to Uninitialized MQTT State")
sendCommand(RefreshSecurity, ON)
}
else {
// logInfo("Security rPi MQTT","No MQTT Refresh Needed")
}
)
end
The question is, how can I do this in an event driven way that does not require me to hit the rule with Cron every 5 minutes?
Essentially I want to know if a value is Uninitialized, and fire refresh until it is not (with a delay in there to not spam it). I don’t think changes need made in the rPi, because it is not the one losing the state.
Is there a way to achieve this with a rule?
Bonus question: How do I break the For Each loop after the first ‘Uninitialized’ contact? If they are all uninitialized it will send 8 or so refreshes, which is technically not a problem, but annoys me that I don’t know how to fix it. I could use a flag but that seems ugly.
Thanks.