I have a few routines that will send email when certain events happen, and they often will include an elapsed time, and I'd love to be able to have it send something like:
"XYZ was on for 3m10s" instead of saying "190 sec", or "XYZ was on for 1h13m" (instead of 4280 sec)
Yes, I can do the math myself for each routine (and build a string w/ several variables in it), but that gets tedious/cumbersome, and hard when trying to figure out whether to include or omit hours or seconds or whatever.
If there are ways to define functions/routines that RM can use, I'd happily write one (I am a SWE), I just don't know where to start with that, or if it's even possible to write ancillary/helper routines that RM can use(?)
e.g, if we could do something like %prettyprint(variable)% and have it format it (would be great to auto-scale as needed), that would be phenomenal
I'd be happy with just a function call that I have to assign to a variable as a string, and then print that var.
Anything like this exist?
Or, is this even possible, or would it have to be added into RM, itself?
This idea has been rattling around in my head for some time now, but your post kicked it up a notch. I pulled a late night last night and came up with what for now I'm calling Rule Functions. A Rule Function is a special rule that is invoked by another rule, passed a parameter, and returns a string. It doesn't have Triggers or Required Expressions. Its parameter is the name of a Hub Variable; this makes it possible to pass in any Hub Variable type. The Rule Function runs its actions, and uses a new action called 'Return string'. This action passes a result back to the calling rule, and exits the Rule Function.
Within the Rule Function, the parameter is accessed using %param%, which pulls in the value of the passed Hub Variable. An example, where the parameter is a Decimal Hub Variable:
With this addition, it would be possible (even if hard) to create a Rule Function that does "Pretty Print" and passes that string back. Such a function could be used by any number of rules, so it only has to be written once. My small example:
Saw that one coming. Ha! That won't happen until enough of you guys beat me up and guilt me into it. What, can't write anything down? I can tell already that would be a big pain in the ***.
Would this function method be able to handle a possibility of multiple rules invoking it simultaneously?
For example: If a rule to calculate a energy cost string from a device's energy reading. Two devices update energy at the same or at almost the same time. This might invoke the function before it has finished the previous execution?
With the same caveats and issues of any rule. That is, multiple simultaneous instances would be a problem for delays in IF-THEN, just as now for any rule. Otherwise, it wouldn't be a new problem. These functions are just rules with 3 special characteristics:
There is a param passed in (a specific identified Hub Variable) available in the rule as %param%.
Well, itās sorta like a āhub functionā and could be treated ālikeā hub variables and have itās own āsettingsā page with current value and usage info.
Also, any reason the function couldnāt alter the value of hub variables?
It's a rule, it can do anything a rule can do. It could have other things passed implicitly in other Hub Variables (essentially hard-wired choices, vs a parameter passed in), and it could return other results the same way, without returning a string. But rules can do those things already, and you can run a rule's actions from another rule already.
Subroutines? That would be the best Christmas present ever. Well, at least in the HE world.
How are they created, in RM or a new app? Could they be invoked from a button controller rule as well?
Is %param% a copy of, or reference to, the global var? If a copy of, and each invocation of the rule ends up with its own copy of the hub variable's value at the time of invocation, then multiple simultaneous instances shouldn't be a problem as far as the input value is concerned.
OK, please read above. These are RM rules with a selector that changes them to Rule Function (shown in screenshots above).
While I haven't touched Button Controllers 5.1 yet, it does use Rule 5.1 for each Button Rule, so yes, you could call Rule Functions from a Button Rule once I've gotten to that.
It grabs the value of the passed variable, and that is what is pulled up with %param%. So yeah, multiple instances don't pose any special problem as far as that goes.
So the "Rule Function to Return a String" toggle turns a rule into a rule function, and changes the labels and such on the fly? That wasn't obvious, to me anyhow. I assumed that toggle just turned on or off the ability of the function to return a value.
So these appear under Rule Machine in the apps page? Is there some distinction between rules and rule functions, or do we just have to use some naming convention?
Is there any reason that a Rule Function is limited to a string? It would be nice to pass an integer, decimal, or datetime and return the same type without having to do type conversion within the Rule Function.