[Deprecated] Design Pattern: Time Of Day

OK, if you have non-astro events that failed too the problem isn’t Astro. So next look at openhab.log to verify that the ToD rule ran when it was supposed to or failed to run.

I should note that we will only be successful figuring this problem out if you understand how this rule works. If you don’t, study the code and ask questions. we will be going back and forth forever if you don’t understand how the rule is supposed to work.

The rule appears to run just fine. It appears to only trigger on the cron events though, would that be right based off the below? Not the astro events

ris@openhab2:/etc/openhab2/rules$ cat /var/log/openhab2/openhab.log | grep "Calculating time of day"
2019-02-01 20:00:00.003 [INFO ] [e.smarthome.model.script.Time Of Day] - Calculating time of day...
2019-02-01 23:00:00.002 [INFO ] [e.smarthome.model.script.Time Of Day] - Calculating time of day...
2019-02-02 00:01:00.002 [INFO ] [e.smarthome.model.script.Time Of Day] - Calculating time of day...
2019-02-02 06:00:01.764 [INFO ] [e.smarthome.model.script.Time Of Day] - Calculating time of day...
2019-02-02 19:59:00.004 [INFO ] [e.smarthome.model.script.Time Of Day] - Calculating time of day...
2019-02-02 21:02:14.022 [INFO ] [e.smarthome.model.script.Time Of Day] - Calculating time of day...
2019-02-02 21:02:38.952 [INFO ] [e.smarthome.model.script.Time Of Day] - Calculating time of day...
2019-02-02 21:05:51.838 [INFO ] [e.smarthome.model.script.Time Of Day] - Calculating time of day...
2019-02-02 21:20:40.785 [INFO ] [e.smarthome.model.script.Time Of Day] - Calculating time of day...
2019-02-02 23:00:00.225 [INFO ] [e.smarthome.model.script.Time Of Day] - Calculating time of day...
2019-02-03 00:01:00.002 [INFO ] [e.smarthome.model.script.Time Of Day] - Calculating time of day...
2019-02-03 06:00:01.951 [INFO ] [e.smarthome.model.script.Time Of Day] - Calculating time of day...
2019-02-03 19:58:00.003 [INFO ] [e.smarthome.model.script.Time Of Day] - Calculating time of day...
2019-02-03 23:00:00.184 [INFO ] [e.smarthome.model.script.Time Of Day] - Calculating time of day...
2019-02-04 00:01:00.002 [INFO ] [e.smarthome.model.script.Time Of Day] - Calculating time of day...
2019-02-04 06:00:01.526 [INFO ] [e.smarthome.model.script.Time Of Day] - Calculating time of day...
2019-02-04 19:58:00.003 [INFO ] [e.smarthome.model.script.Time Of Day] - Calculating time of day...
2019-02-04 21:32:39.345 [INFO ] [e.smarthome.model.script.Time Of Day] - Calculating time of day...
2019-02-05 19:57:00.003 [INFO ] [e.smarthome.model.script.Time Of Day] - Calculating time of day...
2019-02-06 19:56:00.002 [INFO ] [e.smarthome.model.script.Time Of Day] - Calculating time of day...
2019-02-07 19:55:00.003 [INFO ] [e.smarthome.model.script.Time Of Day] - Calculating time of day...
2019-02-08 06:31:00.295 [INFO ] [e.smarthome.model.script.Time Of Day] - Calculating time of day...
2019-02-08 19:54:00.003 [INFO ] [e.smarthome.model.script.Time Of Day] - Calculating time of day...
2019-02-09 19:53:00.003 [INFO ] [e.smarthome.model.script.Time Of Day] - Calculating time of day...
2019-02-10 18:23:22.892 [INFO ] [e.smarthome.model.script.Time Of Day] - Calculating time of day...
2019-02-10 18:27:37.218 [INFO ] [e.smarthome.model.script.Time Of Day] - Calculating time of day...
2019-02-10 19:53:00.009 [INFO ] [e.smarthome.model.script.Time Of Day] - Calculating time of day...
2019-02-10 20:03:49.158 [INFO ] [e.smarthome.model.script.Time Of Day] - Calculating time of day...
2019-02-10 20:56:33.279 [INFO ] [e.smarthome.model.script.Time Of Day] - Calculating time of day...
2019-02-10 23:00:00.008 [INFO ] [e.smarthome.model.script.Time Of Day] - Calculating time of day...
2019-02-11 00:01:00.003 [INFO ] [e.smarthome.model.script.Time Of Day] - Calculating time of day...
2019-02-11 06:00:00.013 [INFO ] [e.smarthome.model.script.Time Of Day] - Calculating time of day...
2019-02-11 19:52:00.004 [INFO ] [e.smarthome.model.script.Time Of Day] - Calculating time of day...

You have cron triggers for 00:01, 06:00, and 23:00. The log it also showing it running at 20:00, 19:59ish, and 21:32ish which implies astro events are firing too.

OK, ill keep an eye on it. Its now 6.30am and its showing MORNING so its working (I did restart OH2 for othe reasons a day or so ago)

@rlkoshak, Firstly, I’d like to thank you for this DP. I can really see the benefit of using this, I’m planning on using this to switch exterior lights on. I’ve been reading through all this thread in great depth.

I would be grateful if could you please provide the most up-to-date rule for this DP which is setup as milliseconds, as you said there is no point in creating DateTime objects again.

Thanks in advance :slight_smile:

The latest of everything is now in the OP…

I’ve c&p everything recently and it works just fine.

EDIT - I mean I’ve c&p the example into my instance of OH, not that I’ve updated the OP…that is all the work of rikoshak…

2 Likes

As MF said, I keep the original post up to date with the latest version.

1 Like

Amazing, Thank you both.

Just wasnt too sure! :slight_smile:

Thanks Rich for keeping this item open and updating it. It is one of the best tutorials on home control. Been using it for a few years and while I’m loving Node-Red none of its logic comes close to this pattern design.

Thanks dd

I did have one question if someone could answer, may be a silly one though!

Im happy with all the below:

  System started or // run at system start in case the time changed when OH was offline
  Channel 'astro:sun:home:rise#event'    triggered START or
  Channel 'astro:sun:home:set#event'     triggered START or
  Channel 'astro:sun:minus90:set#event'  triggered START or
  Time cron "0 1 0 * * ? *" or // one minute after midnight so give Astro time to calculate the new day's times
  Time cron "0 0 6 * * ? *" or
  Time cron "0 0 23 * * ? *"

However, having Time cron of 0 1 0 * * ? * doesnt this mean it will trigger every minute? If not, how does it know it is one minute after midnight?

Apologies if this is a silly question!

Thank you all :slight_smile:

This expression means…

0               1                   0                *                         *              ?                        *
the zero second of the first minute of the zero hour of every day of the month of every month of every day of the week of every year

If you changed the second 0 to a *, it would the first minute of every hour. Does that help?

2 Likes

That makes absolute sense - thank you so much for the clarification :slight_smile:

1 Like

Does anybody still has problems with Astro scheduling? Basically it works okay, until I change any part of the OH config (not related to it’s rules/items/things). After that, most scheduling works, but changing state from EVENING is not. If I re-run manually the rule it will update to the current ToD. However if I leave it there as it is, it will only change state next day… (to DAY if I’m right).

Hi,

Funnily enough I’ve noticed this too the past couple of days, I go from EVENING to UNKNOWN and it won’t change until just after midnight when it goes to BED, ie it totally skips NIGHT…

I haven’t had tine to debug it yet as I’m doing other stuff…but maybe that’s the problem, but me doing other stuff is what is causing it…?

EDIT - I wonder if it’s because I rebooted??? Despite the system rest on reboot in the rules…hummm.

Like you, I also didn’t had time to debug this, but as you look back here, there were always issues like this, which is related to Astro (and no one could find why this happens). I had running openHab for a month without a restart, it worked fine until I changed something in the config (for almost a month). Now I restarted openHab, it worked again for days, I had to add new items/rules to my setup, the recalculation stopped again (after a few days…).

Which Channels do you mean ? Item-Channels like grouprise, set, …” or groupphase” ?
Or Trigger-Channels ?
At the moment I didn’t noticed a bug, but I will have a look on it today and give you my results.

I’m working with OH2.5 M1

Cheers,
Peter

Edit:
Sorry for my fault :upside_down_face:. I didn’t read the complete post, so I thought you are discussing about problems with Astro-Binding.
Now I installed the DP of Rich from the top of the post and will see what happens :wink:

I can’t seem to get this to work. I see the entry in my log files about calculating the time of day, but it never calculates anything. I think at least part of the problem might be:

String vTimeOfDay “Current Time of Day [MAP(weather.map):%s]”

If I use that as-is, I get errors about an entry in the MAP not found. I have the ‘weather_en.map’ file from the map-files.zip download; I renamed ‘weather_en.map’ to ‘weather.map’ and put it in my ‘/etc/openhab2/transform’.

I changed the line, instead, to read:

String vTimeOfDay “Current Time of Day [%s]”

but now while the MAP error is gone, the ‘vTImeOfDay’ string never gets populated. To confirm this, I added the following to my sitemap:

Frame
{
Text item=vTimeOfDay
}

and the value never gets changed; is just remains as a “dash”. So I guess my question is: what value do I have to put in “weather.map” to make the original string work, or what do I have to change to make it work the way I have it?

Thanks! :slight_smile:

Don’t go down that path. The problem isn’t the map.

See How to Debug a Rule

I now have installed the DP of Rich and tested in several versions. As @rlkoshak said, the problem is not the map.
I found out, when I made changes(i.e the Label) in the Channel-linked items the values are lost. When waiting for the interval-time (i.e. interval=300) of the defined Astro-Thing they will be updated again. But only the “normal-ones”. The Scheduling will not work for those Things and channel-linked Items with Offset.

If the Rule starts (with Debug-Points) and if a value is not set, the Logger shows

2019-04-16 10:32:05.744 [INFO ] [e.smarthome.model.script.Time Of Day] - Calculating time of day...
2019-04-16 10:32:05.769 [INFO ] [e.smarthome.model.script.Time Of Day] - Calculating time of day...1
2019-04-16 10:32:05.788 [INFO ] [e.smarthome.model.script.Time Of Day] - Calculating time of day...2
2019-04-16 10:32:05.806 [INFO ] [e.smarthome.model.script.Time Of Day] - Calculating time of day...3
2019-04-16 10:32:05.814 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule 'Calculate time of day state': Invalid format: "NULL"

when it comes to NULL-Value.

After a Restart of OH2 or Bundle-Restart all values are set. But one can see in the Logger what happens.

2019-04-16 11:01:38.536 [INFO ] [thome.binding.astro.internal.job.Job] - Scheduled Astro event-jobs for thing astro:sun:stowing1
2019-04-16 11:01:38.640 [INFO ] [thome.binding.astro.internal.job.Job] - Scheduled Astro event-jobs for thing astro:moon:local
2019-04-16 11:01:38.654 [INFO ] [ding.astro.handler.AstroThingHandler] - Scheduled Positional job astro:moon:local every 300 seconds
2019-04-16 11:01:38.799 [INFO ] [thome.binding.astro.internal.job.Job] - Scheduled Astro event-jobs for thing astro:moon:local
2019-04-16 11:01:38.820 [INFO ] [ding.astro.handler.AstroThingHandler] - Scheduled Positional job astro:moon:local every 300 seconds
2019-04-16 11:01:38.866 [INFO ] [thome.binding.astro.internal.job.Job] - Scheduled Astro event-jobs for thing astro:sun:local
2019-04-16 11:01:38.891 [INFO ] [ding.astro.handler.AstroThingHandler] - Scheduled Positional job astro:sun:local every 300 seconds
2019-04-16 11:01:38.979 [INFO ] [thome.binding.astro.internal.job.Job] - Scheduled Astro event-jobs for thing astro:sun:local
2019-04-16 11:01:39.037 [INFO ] [ding.astro.handler.AstroThingHandler] - Scheduled Positional job astro:sun:local every 300 seconds
2019-04-16 11:01:39.059 [INFO ] [thome.binding.astro.internal.job.Job] - Scheduled Astro event-jobs for thing astro:sun:minus90
2019-04-16 11:01:39.246 [INFO ] [thome.binding.astro.internal.job.Job] - Scheduled Astro event-jobs for thing astro:sun:stowing
2019-04-16 11:01:39.500 [INFO ] [thome.binding.astro.internal.job.Job] - Scheduled Astro event-jobs for thing astro:sun:stowing2

The Re-Scheduling will only work for for the “Normal-Tings”

I’m using the following Set-Up:

RPi 3B, OH2.5M1

rich_time.items:

Group gRichTime "Rich's Daytime"
//String    vTimeOfDay       "Current Time of Day [MAP(weather.map):%s]" <time>  (gRichTime)
String    vTimeOfDay       "Current Time of Day [%s]"             <time>          (gRichTime)  // Testversion without transformation
DateTime  vMorning_Time    "Morning [%1$tH:%1$tM]"                <sunrise>       (gRichTime)
DateTime  vSunrise_Time    "Day Test1 [%1$tH:%1$tM]"              <sun>           (gRichTime)     {channel="astro:sun:local:rise#start"}
DateTime  vSunset_Time     "Evening Test1 [%1$tH:%1$tM]"          <sunset>        (gRichTime)     {channel="astro:sun:local:set#start"}
DateTime  vNight_Time      "Night [%1$tH:%1$tM]"                  <moon>          (gRichTime)    
DateTime  vBed_Time        "Bed [%1$tH:%1$tM]"                    <bedroom_blue>  (gRichTime)    
DateTime  vEvening_Time    "Late Afternoon Test1 [ %1$tH:%1$tM]"  <sunset>        (gRichTime)     {channel="astro:sun:minus90:set#start"}

rich_time.rules:

val logName = "Time Of Day"

rule "Calculate time of day state" 
when
  Item Dummy4 changed to ON or
  System started or // run at system start in case the time changed when OH was offline
  Channel 'astro:sun:local:rise#event'    triggered START or
  Channel 'astro:sun:local:set#event'     triggered START or
  Channel 'astro:sun:minus90:set#event'  triggered START or
  Time cron "0 1 0 * * ? *" or // one minute after midnight so give Astro time to calculate the new day's times
  Time cron "0 0 6 * * ? *" or
  Time cron "0 0 23 * * ? *"
then

  logInfo(logName, "Calculating time of day...")

  // Calculate the times for the static tods and populate the associated Items
  // Update when changing static times
  // Jump to tomorrow and subtract to avoid problems at the change over to/from DST
  val morning_start = now.withTimeAtStartOfDay.plusDays(1).minusHours(18)
  vMorning_Time.postUpdate(morning_start.toString) 
  logInfo(logName, "Calculating time of day...1")

  val night_start = now.withTimeAtStartOfDay.plusDays(1).minusHours(1)
  vNight_Time.postUpdate(night_start.toString)
  logInfo(logName, "Calculating time of day...2")

  val bed_start = now.withTimeAtStartOfDay
  vBed_Time.postUpdate(bed_start.toString)
  logInfo(logName, "Calculating time of day...3")

  // Convert the Astro Items to Joda DateTime
  val day_start = new DateTime(vSunrise_Time.state.toString) 
  logInfo(logName, "Calculating time of day...4")
  val evening_start = new DateTime(vSunset_Time.state.toString)
  logInfo(logName, "Calculating time of day...5")
  val afternoon_start = new DateTime(vEvening_Time.state.toString)
  logInfo(logName, "Calculating time of day...6")

  // Calculate the current time of day
  var curr = "UNKNOWN"
  switch now {
    case now.isAfter(morning_start)   && now.isBefore(day_start):       curr = "MORNING"
    case now.isAfter(day_start)       && now.isBefore(afternoon_start): curr = "DAY"
    case now.isAfter(afternoon_start) && now.isBefore(evening_start):   curr = "AFTERNOON"
    case now.isAfter(evening_start)   && now.isBefore(night_start):     curr = "EVENING"
    case now.isAfter(night_start):                                      curr = "NIGHT"
    case now.isAfter(bed_start)       && now.isBefore(morning_start):   curr = "BED"
  }

  // Publish the current state
  logInfo(logName, "Calculated time of day is " + curr)
  vTimeOfDay.sendCommand(curr)
end

astro.things:

//    Astro - Binding Geo-Position  geolocation="xx.xxxxxx,y.yyyyyy,zzz"

Thing astro:sun:local     "Sonnen Daten"    [geolocation="xx.xxxxxx,y.yyyyyy,zzz", interval=300]
Thing astro:moon:local    "Mond Daten"      [geolocation="xx.xxxxxx,y.yyyyyy,zzz", interval=300]
                                        

Thing astro:sun:minus90   "Offset -90"     [geolocation="xx.xxxxxx,y.yyyyyy,zzz", interval=300]{
  Channels:
    Type rangeEvent : set#event [
      offset=-90
    ]
    Type start : set#start [
      offset=-90
    ]
    Type end : set#end [
      offset=-90
    ]
  }

Thing astro:sun:stowing   "Offset -180"     [geolocation="xx.xxxxxx,y.yyyyyy,zzz", interval=300]{
  Channels:
    Type rangeEvent : set#event [
      offset=-180,
      earliest="19:40"
    ]
  }
Thing astro:sun:stowing1   "Offset 200"     [geolocation="xx.xxxxxx,y.yyyyyy,zzz", interval=300]{
  Channels:
    Type rangeEvent : noon#event [
      offset=200,
      earliest="13:00"
    ]
    Type rangeEvent : set#event [
      offset=90,
      earliest="20:10"
    ]
    Type start : rise#start [
      offset=90,
     earliest="09:00"
    ]
    Type end : rise#end [
      offset=90
    ]
    Type start : set#start [
//      offset=90,
      earliest="23:50"
    ]
    Type end : set#end [
      offset=90
//      latest="21:50"
    ]
  }
  Thing astro:sun:stowing2   "Offset -90"     [geolocation="xx.xxxxxx,y.yyyyyy,zzz", interval=300]{
  Channels:
    Type rangeEvent : set#event [
      offset=-90
    ]
    Type start : set#start [
      offset=-90
    ]
    Type end : set#end [
      offset=-90
    ]
  }


So one can see, even if the interval is set in the Thing (minus90) it will not work. For me this looks like a bug in the binding :wink:

Cheers,
Peter

Btw: Is there an icon for <tod>. Didn’t find one.

Thanks or your help. By adding in the additional “logInfo” entries, I was able to sort things out and get a bit further, until I was getting the “NULL” value error. Based on that additional “logInfo” information, I was able to determine that it was failing to set a value for the ‘vEvening_Time’ value, which is the one with the ‘minus90’ value in the channel setting. I believe this is what fibu-freak was referring to just above in his response to me.

I am currently using PaperUI to manage my Things and the text files for everything else, but I don’t think that make a difference.

I see I can set an offset in PaperUI for the Astro Sunset, but than changes the actual sunset time, rather than allowing me to still have the proper sunset time, but apply an offset for another item (such as to the vEvening_Time item)