Creating rules: how to make them general ? Shoudl I use proxy-items, or variables?

  • Platform information:
    • Hardware: RPI3
    • OS: Openhabian 2.4.0
    • Issue of the topic: reusability of a rules-condition

Team,
I’ve spend the last days creating some kind of countdown widget-like display.
Today was the day that I would like to transform this general rule, to a specific rule.

Real life:
I have 2 timed conditions, let’s call them
1/ making_bread, this takes 4 hours top, so I would like to display in openhab 04:00, 03:59, 03:58… till when the bread is ready.
2/ waterpump: I have created some dip-switches-kind of logic to tell my waterpump to stop working after 1; 2, 3,4,5 of 6 hours. Of course I would like to have openhab to show me a countdown display for this as well
Just to make clear: condition 1 and 2 have nothing to do with each other and work fine for the moment.
And to make more clear: the countdown animation for the bread will be on the dashboard panel bread, the totally different counting clock for the pump, will be on a different dashboard panel.

So the last days, I’ve been creating this ticking-clock countdown animation:


and this ‘rule’ works fine.
As you can see, it takes a global variable as ‘startvalue’ and the logic below the script handles the display, the ticking, the resetting.

But I found out now:
If I would like to plug-in my condition BREAD in the countdown logic, I would have to create 4 specific proxy-items because that’s how the rule is written to keep internally track of statuses.
If I would like to plug-in my condition WATERPUMP in the countdown logic, I would have to create 4 more proxy-items because that’s how the rule is written to keep internally track of statuses.

So here comes the question:
how to manage reusability of code (rules) in openhab the best way.
Storing statuses, counters, hooks in items?
Store them in local variables, global variables ?

Because, what I was dreaming of is something like this (dummy code)

//what this counting animation needs, is:
// 1/ where it should react on, how it know when to start
// 2/ from which startvalue it should start
// 3/ where it should send it's output to, which item is used to display counter*_bread, counter_pump

counterstart=breadcounterstart
counterreset=breadreset
countervalue=breadvalue
counteroutput=breadoutput
 
rule "Countdown initialise"  
when 
    System started
then
    <../..>
end

rule "Countdown start"  
when 
   <../..>
then
    <../..>
end

and save this rule as bread_counter.rules
Changing the header of the rule and replace all bread with pump, save it as pump_counter.rules and enjoy the magic.

However, I think the reality is not as easy as I would hope it would be maybe?
Some advise on this? Reusability seems mentioned here, but only shortly ?

Use Items instead of global variables. Then you can have just one set of Rules that handles the countdowns for both Timers. It also lets you take advantage of Design Pattern: Associated Items.

Then your code remains generic. Do not repeat code. You will use the name of the Item that triggers the Rule to construct the names of all the associated unbound Items that store the values you need. With the name you can get access to the Items to get their current state and postUpdate or sendCommand to those Items as needed.

Then your Rules code can be left generic and will work for these or any other countdown timer you may want to implement. If you want to add a new countdown timer all you have to do is add a new set of Items and add those Items to the right Groups and you never have to edit the Rules.

1 Like