[Deprecated] Design Pattern: Time Of Day

Yes, because “not work” could be throws an error, does nothing at all, generates the wrong values, causes OH itself to crash, reboots your machine, …

As coded the Rule returns when vTimeOfDay is anything but “DAY”. Since it’s “EVENING” it will return and not run the rest of the Rule. As written, it only executes the rest of the rule when it is “DAY”.

I wanted it to execute only if vTimeOfDay is anything but “DAY”. This is how I understood your sample code:

rule "Some rule"
when
    // some trigger
then
  if(vTimeOfDay.state != "BED") return;

  // do stuff to do when it isn't BED time
end 
*/

I want my rule to do stuff when it isn’t DAY time. How would I do that?

In English that says “if vTimeOfDay.state is not “BED” exit the rule, otherwise run do stuff”.

So check whether it’s DAY and exit when vTimeOfDay is equal to DAY.

if(vTimeOfDay.state == "DAY") return;

Got it. So either leave the != statement and omit the return; or replace the != with ==. I got your example wrong then. Because the comment you wrote sounded like the rule will be executed at anytime but BED time whereas it actually is only at BED time.

Thank you for your help!

This might not be directly related to this Design Pattern - but I’m having an issue with using vTimeOfDay as a trigger in my rules.

When I use the following trigger:

when
  Item vTimeOfDay received update "EVENING"
then

My rule only runs when the DP is updated and changes state. My understanding of using “received update” was that it would continuously look to see if it is “EVENING” then always apply. That doesn’t seem to be the case.

How do I ensure my trigger runs regardless if it see the state change or not the first time but as long as the state is and remains what I use for the trigger it should run the rule?

Nope. No rule triggers in openHAB ever work like that. It’s an event driven system. When something, anything, updates vTimeOfDay to “EVENING” then the rule will run once. That’s an event.

If you tell us why you would want a rule running hundreds of times a second, we may be able to offer an event-driven way to do it. What are you trying to achieve?

1 Like

Hi, thanks for that info. I suppose I didn’t look at it that way and I believe I understand now how this rule and another rule that is similar is working slightly differently (due to timers, etc).

I suppose what I was attempting to achieve is that is something goes wrong with a rule - it will not run (I think I found why my rule would break after about 4-5 days) unless another rule (that runs in this DP) updates vTimeOfDay again.

But I suppose really it’s a matter of having rules that don’t stop working/break. That said, it’s extremely hard to find info about why rules would stop working after a few days. Nothing in the logs seems to be able to point towards why a rule stops. You kind of just have to seem to guess and stare at the code and hope you find something it seems.

Unless I am missing another way to diagnose rules?

Okay,recasting that purpose for an event driven world.
When system starts or target rule runs, start a timer.
If timer expires, ring alarm bell “rule has failed”
When target rule runs OK, reschedule timer for future.
If target rule runs in expected time,bell never rings.

Inserting multiple logInfo() is a simple way to monitor rules progress and the values it is dealing with.
Inserting logInfo() as a “here we go” as the first line in rule will tell you if it has triggered at all, rather than just failing to do what you expect.
Now you can stare at trigger conditions only, likely in conjunction with your events.log, to see what went wrong.

Although given the nature of the misunderstanding about triggers, there may be nothing misbehaving.

I actually do use logInfo inserts - but they don’t seem to do anything if the rule does run so I still don’t understand why the rule works for a while and then stops. Even after correcting it, I still have the same issue.

This is the rule file in question, I cannot seem to find anything wrong with it to be honest.

// Kitchen Cab Lights on in Evening
rule "Kitchen Cabinet lights on when Evening"
when
  Item vTimeOfDay received update "EVENING"
then
  sendCommand(KitchenLightCounter, ON)
  sendCommand(KitchenLightStove, ON)
  logInfo("Lights","Kitchen cabinet light on because TOD is Evening")
end

// Kitchen Cab Lights off after Evening
rule "Kitchen Cabinet lights off after Evening"
when
  Item vTimeOfDay received update "BED"
then
  sendCommand(KitchenLightCounter, OFF)
  sendCommand(KitchenLightStove, OFF)
  logInfo("Lights","Kitchen cabinet light off because TOD is Bed")
end

All they do is drop a message into your openhab.log
You need to look in that file.

Does this event actually happen, for example? You will find the evidence in your events.log
To be exact, updates to the same value are not normally logged to events.log, but I expect for this Item it would cause a logged change anyway.

Yes the event runs and other rules based on vTimeOfDay work, although the other rules use the trigger differently.

2020-02-01 17:26:00.018 [INFO ] [e.smarthome.model.script.Time Of Day] - Calculating time of day...
2020-02-01 17:26:00.052 [INFO ] [e.smarthome.model.script.Time Of Day] - Calculated time of day is EVENING

Excellent, you just didn’t say what you saw (or didn’t see). We’re not looking over your shoulder.

But I ask again, can you see the Item state change that you want to use as a trigger in the events.log?
A message from a rule claiming it has done it is not enough.

[quote=“rossko57, post:437, topic:15407”]
Excellent, you just didn’t say what you saw (or didn’t see). We’re not looking over your shoulder.[/quote]

I don’t see anything - the rule doesn’t seem to run randomly. Unless I am missing something?

Here is the entry from events.log - it has to run because my other rules depend on it also it changes state in my sitemap.

2020-02-02 07:36:00.050 [ome.event.ItemCommandEvent] - Item 'vTimeOfDay' received command DAY
2020-02-02 07:36:00.053 [vent.ItemStateChangedEvent] - vTimeOfDay changed from MORNING to DAY

Okay. What is not shown in your log excerpt is the vTimeOfDay Item changing to “EVENING”
If it does not change to “EVENING”, your problem rule will not run.

You’ve shown us some messaging from the rule that you think ought to change it to “EVENING”

Why not look in your events.log for the same date/time to see if the Item really did change to “EVENING” ?
You understand the rule that is doing the changing may have an error in it and may not always do what it is claiming to do. Let’s not assume, let’s find out.

I am assuming that time was an occasion where your problem rule did not run?

My last post is showing the events.log part you requested.

Also I did notice that the 2nd part of my rule tends to work correctly (the lights off part when vTimeOfDay = BED) so this is why I am even less understanding of why the first part doesn’t run when vTimeOfDay is working correctly for other things.

I’m sorry to say it seems like the rule IS executing according to the event.log (not sure how I missed it - I guess slowing down and reading helps lol) it is sending the command but for some reason the lights aren’t always coming on. Maybe the issue is elsewhere. But I appreciate the info about looking in the events.log.

2020-02-01 17:26:00.007 [vent.ChannelTriggeredEvent] - astro:sun:home:set#event triggered START
2020-02-01 17:26:00.025 [vent.ChannelTriggeredEvent] - astro:sun:minus90:daylight#event triggered END
2020-02-01 17:26:00.025 [vent.ChannelTriggeredEvent] - astro:sun:home:daylight#event triggered END
2020-02-01 17:26:00.054 [ome.event.ItemCommandEvent] - Item 'vTimeOfDay' received command EVENING
2020-02-01 17:26:00.060 [ome.event.ItemCommandEvent] - Item 'KitchenLightCounter' received command ON
2020-02-01 17:26:00.062 [ome.event.ItemCommandEvent] - Item 'KitchenLightStove' received command ON
2020-02-01 17:26:00.063 [vent.ItemStateChangedEvent] - vTimeOfDay changed from DAY to EVENING

Although I supposed that if the rule has an error when it won’t run there isn’t a place where it would log the failure to aid with troubleshooting is there?

I’m not sure how the log of the Item changing to DAY helps when we’re looking to confirm the existence of an EVENING trigger, but let’s move on.

Okay, you did say it ran sometimes. You need to identify a time when you expected it to run but it didn’t appear to. And examine events.log for that time.
Maybe that was it, but it’s not clear if the excerpt you’re showing us now relates to a time when it did or didn’t work, really.

If a rule had an error at execution - bad syntax or bad variable contents or whatever - you would get an error message in openhab.log

Your rule fires off two commands to different Items withing a few milliseconds. Maybe your binding or network cannot handle rapid fire. We know nothing about your Items.
Before going off down that path, satisfy yourself using logs that your rule triggers every time you expect it to, and issues both the commands that you expect it to.
You’ve wasted days on this already.

Hopefully it’s been useful getting familiar with these log files, they are so informative.

First of all thanks for showing this pattern here.

In my understanding, the main point of it is to avoid code duplications, especially with respect to checking trigger events multiple times because they can either be triggered by time alone or by an alternate trigger but then still depend on the time of day.

However, the problem I see is that even in your code example you are still doing this twice by e.g. defining the boundaries of your day times in the “when” section of the rule as cron triggeres and additionally again defining those time inside the rule programmatically - to be able to compare later.

In the end, this means that you still have the normal drawbacks of duplication, e.g. if a trigger time needs to be changed it needs to be changed at multiple locations for consistency. Do you see a way around it?

Personally, what I would like to do is to implement a logic that sets heating temperatures based on weekday and time of day AND also based on presence. That means, in the naiive approach I would have simple rules that trigger changing the temperature based on time (if presence is ON), one simple rule that turns heatings off if presence switches to OFF and another complex rule that triggers if presence changes to ON the new temperature, with the need to replicate the time based logic here.

I wonder if implementing your pattern above instead would actually help here? What is your opinion?

Thanks a lot, Torsten

Sort of. Its more a way to avoid repeating the same checks for state in multiple Rules. For example, instead of if(now.getHourOfDay > 6 && now.getHourOfDay < 12) in all of your Rules that care about this time period one uses if(vTimeOfDay.state.toString == "MORNING"). The code ends up being more self explanatory and if you decide morning needs to end at 10 instead of 12 you only need to change it in one place.

It’s a limitation with working with Rules DSL and dealing with the fact that some of the events are driven by Channel trigger events and others are driven by time. In the Python version of the DP (see the link to the helper libraries) that is not the case. It only uses DateTimeItems to define the time periods and triggers the Rules at startup or when they change and Timers to drive the state machine.

It’s also done this way for illustrative purposes. As described in the “What is a Design Pattern” post, linked to in the OP, the code in a DP posting is an example. It’s not necessarily complete nor is it necessarily the best approach. It is an example whose sole purpose is to illustrate the concepts of the design pattern. In this case, it is illustrating how you can convert events into a state machine and then use the state elsewhere. The problem when you do that based on time instead of events is you have to do more calculation to convert the event that triggered the Rule to a state, which is the duplicative code you are pointing to. There isn’t a similar problem with the irrigation example.

I suggest looking at the helper library version which you should be able to just copy and use. The only “coding” required is configuring Ephemeris and setting up your Items properly.

As for the wider approach, I would keep the presence and time of day Rules separate. Then have a Rule that triggers when time of day changes or presence changes and set the target temp or turn on/off the heat based on the time of day and presence states. That’s really the whole point of this DP. You have other Rules that care about presence and the time of day, so centralize all the logic that calculates the time of day and presence and in the rest of your Rules just check the state.

I am new to openHAB and trying to learn how to write rules. Ive started with this time of day rule (Code at very top of page).
I have basicaly installed the astro binding, and copy / paste the items file and rules file.
how ever im logging this error

13:31:56.663 [ERROR] [untime.internal.engine.RuleEngineImpl] - Error during the execution of startup rule 'Calculate time of day state': Invalid format: "NULL"

Any help would be appreaceated

You should have provided your rule, and you should have started a new thread for this.