rule "Calculate time of day state"
when
System started or
Channel 'astro:sun:home:civilDawn#start' triggered START or
Channel 'astro:sun:home:civilDawn#end' triggered START or
Channel 'astro:sun:home:civilDusk#start' triggered START or
Channel 'astro:sun:home:civilDusk#end' triggered START or
Time cron "0 1 0 * * ? *" or
Time cron "0 0 1 * * ? *" or
Time cron "0 0 10 * * ? *" or
Time cron "0 0 12 * * ? *"
then
// logInfo(TimeOfDay, "Calculating time of day...")
val dawn_start = new DateTime(vDawn_Time.state.toString)
val morning_start = new DateTime(vMorning_Time.state.toString)
val forenoon_start = now.withTimeAtStartOfDay.plusDays(1).minusHours(14)
vForenoon_Time.postUpdate(forenoon_start.toString)
val noone_start = now.withTimeAtStartOfDay.plusDays(1).minusHours(12)
vNoon_Time.postUpdate(noone_start.toString)
val afternoon_start = new DateTime(vAfternoon_Time.state.toString)
val evening_start = new DateTime(vEvening_Time.state.toString)
val night_start = now.withTimeAtStartOfDay.plusDays(1).minusHours(23)
vNight_Time.postUpdate(night_start.toString)
// Calculate the current time of day
var curr = "UNKNOWN"
switch now {
case now.isAfter(dawn_start) && now.isBefore(morning_start) : curr = "DAWN"
case now.isAfter(morning_start) && now.isBefore(forenoon_start) : curr = "MORNING"
case now.isAfter(forenoon_start) && now.isBefore(noone_start) : curr = "FORENOON"
case now.isAfter(noone_start) && now.isBefore(afternoon_start) : curr = "NOON"
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) && now.isBefore(dawn_start) : curr = "NIGHT"
}
// Publish the current state
vTimeOfDay.sendCommand(curr)
end
I waited 2 days because I read somewhere that sometimes the rule will start working after a uncertain amount of time - but not in my case. Maybe I’m too blind after looking at the code for over 2 days
var curr = "UNKNOWN"
switch true {
case now.isAfter(dawn_start) && now.isBefore(morning_start)
And change the end of the rule like this.
if (vTimeOfDay.state.toString != curr) {
vTimeOfDay.sendCommand(curr)
}
Put all together like this:
rule "Calculate time of day state"
when
System started or
Channel 'astro:sun:home:civilDawn#start' triggered START or
Channel 'astro:sun:home:civilDawn#end' triggered START or
Channel 'astro:sun:home:civilDusk#start' triggered START or
Channel 'astro:sun:home:civilDusk#end' triggered START or
Time cron "0 1 0 * * ? *" or
Time cron "0 0 1 * * ? *" or
Time cron "0 0 10 * * ? *" or
Time cron "0 0 12 * * ? *"
then
// logInfo(TimeOfDay, "Calculating time of day...")
val dawn_start = new DateTime(vDawn_Time.state.toString)
val morning_start = new DateTime(vMorning_Time.state.toString)
val forenoon_start = now.withTimeAtStartOfDay.plusDays(1).minusHours(14)
vForenoon_Time.postUpdate(forenoon_start.toString)
val noone_start = now.withTimeAtStartOfDay.plusDays(1).minusHours(12)
vNoon_Time.postUpdate(noone_start.toString)
val afternoon_start = new DateTime(vAfternoon_Time.state.toString)
val evening_start = new DateTime(vEvening_Time.state.toString)
val night_start = now.withTimeAtStartOfDay.plusDays(1).minusHours(23)
vNight_Time.postUpdate(night_start.toString)
// Calculate the current time of day
var curr = "UNKNOWN"
switch true {
case now.isAfter(dawn_start) && now.isBefore(morning_start) : curr = "DAWN"
case now.isAfter(morning_start) && now.isBefore(forenoon_start) : curr = "MORNING"
case now.isAfter(forenoon_start) && now.isBefore(noone_start) : curr = "FORENOON"
case now.isAfter(noone_start) && now.isBefore(afternoon_start) : curr = "NOON"
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) && now.isBefore(dawn_start) : curr = "NIGHT"
}
// Publish the current state
if (vTimeOfDay.state.toString != curr) {
vTimeOfDay.sendCommand(curr)
}
end
hm, I’ve changed the parts you mentioned, but with no luck… I don’t even get a response in my events log that the vTimeOfDay state changed or is changing… any other suggestions??
Add logging to log out all of the times. I suspect you have gaps or times you expect to be before another are actually after. When that happens none of the conditions in the switch statement are true and you are left with UNKNOWN.
I got:
Dawn at #dawnstart
Morning at #dawnend
Forenoon is at 10:00
Noon is at 12:00
Afternoon is at #duskstart
Evening is at #duskend
Night is at 01:00
I think there is no situation where these times could overlap… but thanks anyway - what I don’t understand is what you mean with gapping times, could this actually happen in my case??
cheers Dan
edit:
I’m in Hamburg/Germany maybe this has something to do with summertime/wintertime switching e.g. GMT+1 + 01:00… just a thought
I’ve got all variables e.g. vDawn_Time, vMorning_Time etc. in my sitemap as text items to see if they’re working - all times are shown correctly!
What did you log to get those tunes? You need to log the vals (e. g. dawn_start) as they are the values being compared.
Check the dates as well. If ASTRO is failing then your ASTRO calculated items will be cut the wrong day.
I haven’t looked that closely at the switch statement but have seen people inadvertently set up a case where there was some time not covered by any of the case statements.
==> /var/log/openhab2/events.log <==
2019-01-04 21:01:40.748 [vent.ItemStateChangedEvent] - Date changed from 2019-01-04T21:00:40.742+0100 to 2019-01-04T21:01:40.743+0100
2019-01-04 21:01:40.748 [vent.ItemStateChangedEvent] - DateString changed from 2019-01-04 21:00:40 MEZ to 2019-01-04 21:01:40 MEZ
==> /var/log/openhab2/openhab.log <==
2019-01-04 21:01:40.819 [INFO ] [pse.smarthome.model.script.TimeOfDay] - The current value is2019-01-04T07:55:00.000+01:00 for Dawn
2019-01-04 21:01:40.820 [INFO ] [pse.smarthome.model.script.TimeOfDay] - The current value is2019-01-04T08:38:00.000+01:00 for Morning
2019-01-04 21:01:40.828 [INFO ] [pse.smarthome.model.script.TimeOfDay] - The current value is2019-01-04T16:14:00.000+01:00 for Afternoon
2019-01-04 21:01:40.830 [INFO ] [pse.smarthome.model.script.TimeOfDay] - The current value is2019-01-04T16:57:00.000+01:00 for Evening
==> /var/log/openhab2/events.log <==
2019-01-04 21:01:40.842 [ome.event.ItemCommandEvent] - Item 'vTimeOfDay' received command UNKNOWN
logging all times:
2019-01-04 21:07:50.792 [INFO ] [el.core.internal.ModelRepositoryImpl] - Refreshing model 'timeofday.rules'
2019-01-04 21:07:56.466 [INFO ] [pse.smarthome.model.script.TimeOfDay] - The current value is2019-01-04T07:55:00.000+01:00 for Dawn
2019-01-04 21:07:56.467 [INFO ] [pse.smarthome.model.script.TimeOfDay] - The current value is2019-01-04T08:38:00.000+01:00 for Morning
2019-01-04 21:07:56.469 [INFO ] [pse.smarthome.model.script.TimeOfDay] - The current value is2019-01-04T10:00:00.000+01:00 for Forenoon
2019-01-04 21:07:56.473 [INFO ] [pse.smarthome.model.script.TimeOfDay] - The current value is2019-01-04T12:00:00.000+01:00 for Noon
2019-01-04 21:07:56.476 [INFO ] [pse.smarthome.model.script.TimeOfDay] - The current value is2019-01-04T16:14:00.000+01:00 for Afternoon
2019-01-04 21:07:56.478 [INFO ] [pse.smarthome.model.script.TimeOfDay] - The current value is2019-01-04T16:57:00.000+01:00 for Evening
2019-01-04 21:07:56.480 [INFO ] [pse.smarthome.model.script.TimeOfDay] - The current value is2019-01-04T01:00:00.000+01:00 for Night
I have no further idea whats going wrong…
Switch case is “UNKNOWN”
I’m on my phone (and down with the flu) so can’t really do the analysis myself. What you need to do is put all of those times in a table, one row for each case statement and see how the times line up.
Are all times covered?
Are there overlaps?
Look at the case conditions, maybe there is a typo?
checked this another time and logged ‘now’… but even this was right. I think I’m going slightly mad on this and should give me a break…
Eddit:
I thought I fixed the problem yestereday, but I test the behavior for another day because I’m not sure if all conditions work to change all daytimes… and post an update here!
finally its working after adding daystart & dayend, because without it broke my calculation of daytimes… now it looks like that (with little cosmetic changes too )
rule "Calculate time of day state"
when
System started or
Channel 'astro:sun:home:civilDawn#event' triggered START or
Channel 'astro:sun:home:civilDawn#event' triggered END or
Channel 'astro:sun:home:civilDusk#event' triggered START or
Channel 'astro:sun:home:civilDusk#event' triggered END or
Time cron "0 1 0 * * ? *" or
Time cron "0 0 1 * * ? *" or
Time cron "0 0 10 * * ? *" or
Time cron "0 0 12 * * ? *"
then
logInfo("TimeOfDay", "Calculating time of day...")
val dawn = new DateTime(vDawn_Time.state.toString)
val morning = new DateTime(vMorning_Time.state.toString)
val forenoon = now.withTimeAtStartOfDay.plusDays(1).minusHours(14)
vForenoon_Time.postUpdate(forenoon.toString)
val noone = now.withTimeAtStartOfDay.plusDays(1).minusHours(12)
vNoon_Time.postUpdate(noone.toString)
val afternoon = new DateTime(vAfternoon_Time.state.toString)
val evening = new DateTime(vEvening_Time.state.toString)
val dayend = now.withTimeAtStartOfDay.plusDays(1)
vDayend_Time.postUpdate(dayend.toString)
val daystart = now.withTimeAtStartOfDay
vDaystart_Time.postUpdate(daystart.toString)
val bedtime = now.withTimeAtStartOfDay.plusDays(1).minusHours(23)
vBedtime_Time.postUpdate(bedtime.toString)
// Debug Logging
/*
logInfo("TimeOfDay", "The current value is "+dawn.toString+" for Dawn")
logInfo("TimeOfDay", "The current value is "+morning.toString+" for Morning")
logInfo("TimeOfDay", "The current value is "+forenoon.toString+" for Forenoon")
logInfo("TimeOfDay", "The current value is "+noone.toString+" for Noon")
logInfo("TimeOfDay", "The current value is "+afternoon.toString+" for Afternoon")
logInfo("TimeOfDay", "The current value is "+evening.toString+" for Evening")
logInfo("TimeOfDay", "The current value is "+dayend.toString+" for Dayend")
logInfo("TimeOfDay", "The current value is "+daystart.toString+" for Daystart")
logInfo("TimeOfDay", "The current value is "+bedtime.toString+" for Bedtime")
logInfo("TimeOfDay", "The current value is "+now+" for Now")
*/
// Calculate the current time of day
var curr = "UNKNOWN"
switch true {
case now.isAfter(bedtime) && now.isBefore(dawn) : curr = "BEDTIME"
case now.isAfter(dawn) && now.isBefore(morning) : curr = "DAWN"
case now.isAfter(morning) && now.isBefore(forenoon) : curr = "MORNING"
case now.isAfter(forenoon) && now.isBefore(noone) : curr = "FORENOON"
case now.isAfter(noone) && now.isBefore(afternoon) : curr = "NOON"
case now.isAfter(afternoon) && now.isBefore(evening) : curr = "AFTERNOON"
case now.isAfter(evening) && now.isBefore(dayend) : curr = "EVENING"
case now.isAfter(daystart) && now.isBefore(bedtime) : curr = "NIGHT"
}
// Debug Logging
logInfo("TimeOfDay", "It's "+curr.toString+" now")
// Publish the current state
if (vTimeOfDay.state.toString != curr) {
vTimeOfDay.sendCommand(curr)
}
end