I can move it. I’ve currently submitted it as a community library because it’s something that is more useful in general and doesn’t really have anything to do with supporting the interface between Python and openHAB itself. As I looked at the functions, it looked like hysteresis was an apple and core.utils was all oranges.
But I do see it as kind of the next layer up in building blocks for rules developers. The Helper Libraries are about making Python work with openHAB’s API. Hysteresis and the DPs would build on that to provide reusable bits of functionality like common calculations, management of one timer per Item, gatekeeper, etc. which seem best to go in Community. Or maybe best to start in Community and then migrate to the main libraries, but in some new module path. I don’t think they would belong in core.
What I’ve thought of so far which can all be implemented generically (some of these are more than just functions, one timer per Item and gatekeeper below are classes to allow users the option of having more than one active in a given set of rules at a time):
- hysteresis (obviously)
- management of one timer per Item (you’ve seen the first version of this code already, I’ve moved out from anti-flapping to just generic management)
- gatekeeper DP
- Time of Day DP (I want to try to generalize this to a generic state machine at some point)
- Generic Presence Detection
- Cascading Timers (e.g. lawn irrigation)
- Motion sensor timer
- Generic Is Alive?
- Manual trigger detection
- Countdown Timer (put how much time is left on a Timer on the sitemap)
- Event Limit (kind of the flip side of gatekeeper, instead of delaying a command, ignore the command until a certain amount of time has passed)
As I progress I’m sure I’ll think of more. Once I cover my own examples and DPs I hope to move on to DPs and tutorials posted by others.
I’m certain I can implement all of the above as either a module or a Script with all configuration taking place in configuration.py and in Items and Groups.
I have four implemented thus far (I’ve only submitted hysteresis as a PR so far, I’ll submit the others once I get feedback from the review of that one).
Oh, I’m not looking at avoiding them. I’m just thinking about rewriting Design Pattern: Working with Groups in Rules for the Helper Library docs and trying to figure out which approach to favor. It seems like most blogs and SO posts and the like indicate that List Comprehension is more pythonic, but so far I haven’t decided which is better for the user migrating from Rules DSL.
Rules DSL List stream interface (which comes from Java) has a more intuitive left to right layout. But the map/filter functions definitely have a inner to outer layout and list comprehension has a right to left layout and the syntax is more arcane. I’m not sure which would be easier for migrators to follow and wonder if we should recommend splitting them into separate lines for clarity.
It is clear that with the map/filter functions it does not stream. First all the filter stuff must complete and then the map starts working on the result. List comprehension appears to perhaps work more like the Java stream API where the results from the first operation are streamed to the next one as they become available (e.g. given, Blah.members.filter[ i | i.state == ON].map[state], the map will start running on the first matching result from the filter so you could have both the filter and the map running at the same time rather than the map waiting for the filter to finish).
For the library submission PR though, I’ll switch it to use list comprehension.