RM4: Is it a bug or me?

All of that looks right. What is it that you think is wrong? I don't understand why you want to trigger this at midnight. I suspect that AT midnight, the calculation for sunset has not yet advanced to the next day. But 23:59 would be today (which begins at 00:00:00), so the time test for between sunset-60 and 23:59 would be true (until the sunset day clock advances shortly after midnight).

Obviously, some things need to happen at midnight. But nothing happens in zero time. So, please explain what the purpose of a trigger at midnight is that is going to test time?

If what you want to do is to turn on lights at sunset-60 and off at midnight, do this instead:

Trigger:  Certain time sunset-60
Actions:  
   Turn on lights
   Wait for event: Certain time 00:00
   Turn off lights

Or, just use Simple Automation Rule instead.

1 Like

I see what its doing now. I think quite a few people will use midnight in rules. I understand that the sunset time may not have advanced yet and so the timestamp is kept and so the rule is in fact checking 2020-12-02 14:56 (sunset-60) to 2020-12-03 23:59 (~35 hours).

How does RM keep track of sunset for rules that go Sunset to Sunrise. If it rolled over all of a sudden the rule wouldn't match anymore once it's updated for the next day. So there must be something holding the value in the rule. Due to the this more common use implementing a fix to compare the sunset date to the current date, making the condition false, wouldn't work. To fix it RM would need to either:

  1. Check whether the action time would have occurred previously if the sunset time has not yet been updated to the current day
  2. Store the "actions to run" times as datetimes instead.

Isn't this less efficient though? A load of scripts in a wait state seems less desirable than a cron trigger.

The other issue I have with the wait for event action is what happens if the rule is triggered twice, or multiple times. Do I get multiple wait events all doing the same thing? And what happens if I turn party mode on afterwards? Conditional actions after the wait for event to check for this?

It doesn't. How sunset/sunrise is handled depends on the context. A trigger at sunset, or sunset plus offset, uses a system event to trigger it (along with a subsequent scheduled event in the case of positive offset). A trigger before sunset uses a more complex method (see below). Period calculations, such as between two times where sunset is involved, use a hub system method to return the datetime object of the relevant time, upon which calculations can be made. The onboard software astronomical clock is the source of these times.

At 00:00:00.000 a system job runs to calculate the new sunrise/sunset times, update location objects, and schedule sunrise/sunset events. I don't know off the top of my head when the sunrise/sunset time advances, it may be 00:00:01, or it may be at some point during 00:00:00. Irrespective, nothing happens in zero time, so hypothetically there could be a moment is a period of time after 00:00:00.000 when that has not completed yet. Attempting to test for that doesn't really make much sense, and would most likely not be deterministic, since nothing happens in zero time and how long something takes cannot be determined in advance. So a rule testing for time relative to a non-deterministic condition right at midnight will be non-deterministic. Fortunately, there are plenty of deterministic ways around this problem.

They are; all scheduled events are. Notice that you have a subscription to a system event called sunsetTime. This event happens every day right after another system event called 'sunset'. The times when these events happen is calculated every day from a software astronomical clock (the subject of the prior paragraph above). The sunsetTime event carries the time of the next day's sunset, thus allowing a calculation to be made to determine how long in the future that will be (i.e., 24 hours +/- a bit), and to schedule the sunset-60 event accordingly. That's what the beforeSunsetHandler does, is perform that math and schedule that event.

1 Like

What? All this does is create a cron scheduled event. There are no scripts in wait states anywhere. What a Wait does is either schedule an event, or subscribe to an event, and then the rule exits.

A Wait is canceled by the rule being triggered.

The first one happens as a consequence of the system sunset event. That in turn leads to the second one being scheduled as a cron event. You can't get cleaner than that.

Obviously, you're going to need to deal with that with some test somewhere as appropriate, but that has nothing to do with this time discussion, does it?

1 Like

Thank you for the detailed replies, very informative. I do appreciate it. I'm not sure I fully agree with the non-deterministic outlook. RM can know if the sunset has been updated or not when it runs so we can take action based on that. But for now I'll update the scripts and remove any triggers I have in RM that occur at midnight.

Most of this non-determinism is baked in by the very nature of an asynchronous multi-threaded system. It pops up in many areas, potentially, but with very low probability. Multiple things can happen "simultaneously" with unpredictable results as to actual order of execution. This is not a fully deterministic system.

What you're describing is such an edge case that I don't see coding around this situation (i.e. treating a midnight time period test as a special case). The special case is a rule triggered at midnight that wants to test a time period involving sunrise or sunset. Basically, every time period test would need to check if it was now midnight, if sunrise or sunset is involved in the period, keep in state tomorrow's sunrise and sunset just in case they are needed, and test the system sunrise or sunset date for either being yesterday's date so that it knew to use tomorrow's sunrise or sunset instead of today's. When you toss in that trigger times can be kept in variables, the implication is that every time period test becomes burdened with the check for it being midnight, etc.

There are easy ways to work around this. Seems more like something to be documented than addressed in code.

You don't have to avoid triggers at midnight. What should be avoided are time period tests at midnight involving sunrise or sunset.

2 Likes