I have a Blockly rule set up to determine a Time of Day, (ToD), for the most part it runs off the astro setting for sunrise, sunset etc and does a very good job. I have a few other rules that fire off based on the ToD and had been getting some weird output. After checking those rules I’ve managed to trace it back to this rule, specifically the 2 variables where I have set a fixed time.
So, the Blockly rule is below and the log file below that.
In short, the rule sets 6 variables, 4 from the astro binding and 2 I’ve set fixed times. The issue is with these fixed times. At this time of year it runs the else statement ‘Sunrise is after 6:30’.
Dawn / Day / Twilight / Evening all run through and the ToD gets reported correctly but when it gets to NightStart, ie my fixed time of 22:29, it stays as Evening, and stays that way through until DawnStart happens and then it change to Dawn. So I never get a NIGHT.
The log files below suggest that the variables all have date / time entries. I’m a bit stumped…
Any ideas, TIA.
First, it’s worth noting that there might be a couple of easier ways to achieve this.
One way would be to create a separate rule for each time of day and simply trigger that rule using the proper astro Channel or your fixed time of day as appropriate. All the rule needs to do is command your time of day Item with that time of day. One advantage of this is it’s very simple and easy to understand what is going on. If you add the “Schedule” tag each rule will show up in the calendar view on the Schedule page in MainUI letting you track when the time of day changes. But most importantly, you can avoid this complicated set of logic. At the right time, the rule will trigger and command TimeOfDay as needed and you never have mess with
now and a bunch of if/else ifs to figure out which time period
now falls between. All you have to worry about is what time the time of day period starts. With the new
Time is <item> trigger, you can even set your fixed times of day from MainUI instead of hard coding them into the rule (see widgets linked to below).
Another way would be to install the Time Based State Machine rule template. You can install this from the marketplace (under Settings → Automation in MainUI) and then all you need to do is populate a set of Items with some Item metadata and instantiate the rule. The advantage is you can let someone else figure out this logic for you (you never have to mess with any code, that’s the point of rule templates). But you will have to populate some DateTime Items for your constant times of day, but with DateTime List Item and DateTime Standalone Widget that’s not to hard. There is another rule template which will move those Items to today’s date for you (again, no coding on your part).
Now to your problem.
DawnStart is coming from an Astro linked Item (it appears). That Item is populated sometime around midnight for that day. When this logic runs, Notice that DawnStart is 05:25 today and NightStart is 22:29 today. When the time reaches, for example 22:30, the else if evaluates to false because 22:30 is not between 05:25 and 22:29. So NIGHT can never happen.
You have to account for the fact that you actually won’t know when DawnStart is for tomorrow until after midnight. But then at that point NightStart will have moved to the next day too. You could adjust this by adding more else if statements for NIGHT where you test if
now is between NightStart and midnight tomorrow and another to test if
now is before DawnStart.
But I highly encourage you to adopt one of the above two as those will be easier for you to adjust and maintain in the long run. Neither approach will require any changes to code to add or remove new times of day in the future, for example.
Thanks for the ideas.
This was my first blockly rule and I’ve since come across your rules and add ons which do make more sense than how I wrote it so I will be going through the examples at some point and changing over but Id like to understand why this one isn’t working first.
And of course you are correct, I just need to set the NIGHT to be >= NightStart and it will be perfect…