Rule 3.0: Time, Variable Math and Logic

Time and Variable Math

With build 2.1.0.116 Rule 3.0 gets another feature addition: the ability to perform math operations and comparisons on Global Variables. Also, it is now possible to set the current time in seconds or milliseconds of Unix Epoch Time.

Dealing with dates and time is always a messy affair for computer software. There are so many formats, so many variations, and so many elements to the defining a moment in time. Unix simplified all of this into a single large number, the number of milliseconds since 00:00:00 UTC January 1, 1970. Using this number one can derive other representations of times, and find differences between two times by simply subtracting one number from another. Milliseconds of time divided by 1000 is seconds, divided again by 60 is minutes, etc.

First came the addition of setting a Global variable to now(). now() is a system function that returns Unix Time. Suppose I want to know how long a door has been left open. If I capture the time it opens by setting a variable called Open to now(), and then later set another variable called Now the same way, then Now minus Open is the number of milliseconds the door has been open. I could use that information to trigger some automation.

As soon as one has numbers flying around like Unix Time (as I write this the time is 1558307477, a super obvious representation -- not!), one wants to manipulate them with simple arithmetic. Do to that in Rule Machine, we need mathematical operators, we need to do a little math.

Rule 3.0 now can do this with Set Variable. One choice is Variable Math. It allows you to do simple math on two numbers, and put the result of the calculation into a Global Variable. The operators supported are:

+ addition
- subtraction
* multiplication
/ division
% remainder

negate
absolute
round
random

The first five operators use two operands. The last four operators use a single operand. The operands can each be a Global Variable or a constant number. Numbers can be whole numbers or decimal fractions.

Comparisons and Logic (again)

When setting a Boolean Global Variable, there are now available comparison operations and logical operators, the Boolean equivalent of math. For comparisons, we have the normal set of comparison operators:

=
!=
<
<=
> 
>=

These each expect two operands, that can be either Global Variables (Numbers or Decimals) or constants.

For logic we can do operations on Boolean Global Variables. The operators supported are:

AND
OR
XOR
NAND
NOR
XNOR
NOT

All of these except NOT use two operands. If you are wondering about these, XOR (exclusive OR) is essential the same as 'not equal'. XOR is true if either but not both operands are true. XNOR, the opposite of XOR, is essentially the same as 'equal'. XNOR is true if both operands or true or both are false. NAND is the same as NOT AND, and NOR is the same as NOT OR. These six operators represent the six types of logic gates that all digital electronics are built from.

7 Likes

Getting the below when trying to set a Global Number or Decimal variable with random.

2019-05-22 08:03:36.337 pm errorgroovy.lang.GroovyRuntimeException: Ambiguous method overloading for method java.lang.Double#multiply.
Cannot resolve which method to invoke for [null] due to overlapping prototypes between:
[class java.lang.Character]
[class java.lang.Number] (appButtonHandler)

Kind of wish I had waited for this post, I spent a lot of time on Wikipedia reflecting on how badly my Math teachers failed me. :blush:

Is there Daylight Savings in Epoch time? :wink:

1 Like

I'm not getting this. Can you show the action in question?

The variable remains unchanged at 0.0

You didn't specify a value for Random. It has to have a number or variable.

The way it works is that it creates a random number between 0 and 1, and multiplies it by the number you give it. So if you want a random number between 0 and 100, you give it 100.

2 Likes

It didn't make me so I broke the mouse trap :wink:

Was trying to figure out exactly the value did but now that I put one in it looks like I'm in fact setting the upper bound of random like I was hoping it would be. I just can't get a random of a max of the declared variable type by leaving it blank (besides setting it in the constant)?

Anyway, looks like it works now and its exactly what I've been wanting since Rule Machine 3.0 came out. I've been wishing for this new stuff.

What about leap seconds :wink:

1 Like

This is pretty cool... I'll have to play with this, but I may even be able to get rid of a user app or two with this functionality.

Thanks for all of the great improvements in RM!

2 Likes

Ironically, it was a post that you made a few months ago that prompted me to rework RM. You pointed out several things that were shortcomings. If we were to find that post, you'd find that those points you made have been addressed now. Along the way, I learned a few things about how to make the UI work better, as evidenced by the new Actions UI. It isn't perfect, but it sure beats what there was before!

7 Likes

Well, you have outdone yourself.

The interface is much easier to use / more consistent / just 'better', and new features like global variables and conditional actions really expand what you can do in RM.

For instance, 1.0.9 collapsed my # of rules by almost 50% - from conditional actions allowing me to combine 2 rules into 1. Which while functionally equivalent, it will be much easier to understand and maintain the rules having functions fully contained in a single rule.

I have a few nested loop routines I use in some user apps that I need to think if there is a way around in RM. If so I can probably get rid of 80% of my user apps...

One I'm thinking may way through would functionally look like this (if you could do nested IFs, of course):

if (temp1 > temp2 + 2) then
.....if (vDimmer2 >= 20) then
..........Dim: vDimmer1: 100
..........Adjust: vDimmer2 by -10
.....end if
end if

EDIT: Well, what do you know... (for the record, in production I don't move vents every minute, that short interval was for testing) :smile:

2 Likes

Wait, can you do nested IFs now?

Oh you can with conditional statements.

No nested IF-THEN. But no restriction on Simple Conditional action. So after an IF-THEN, or in the ELSE-IF part or the ELSE part, you can have Simple Conditional actions.

Bruce, would it be possible to give us the option to do math equations with more than two variables at a time?

vartotal=var1+var2+var3+var4+var5?

Thanks in advance!

2 Likes

Yes, that!

I didn't even try to convert some of the applications I would have, thinking that there was no nesting of IF statements. Once I realized you could nest simple conditional statements, the world opened back up to me. :slight_smile:

it doesn’t look like Fade dimmers over time supports a variable for time. is that an option that could be added?

thanks

Yes, this will be in the next release. Also, while doing that I discovered a bug with using a variable as the target dimmer level, and that will be fixed also.

Can we also get the addition of using a variable for the delay in a "custom action"?

That's a pretty large request, as it entails the entire mechanism of specifying delays attached to actions. You can just use a Delay Actions ahead of that action with a variable number of seconds.

Download the Hubitat app