Actually I’m my current version, which I thought I had posted here, I don’t use the DateTime objects at all any more and just use the milliseconds. There is no reason to create objects as now.isBefore etc all can handle epoc as well.
Upon looking back I do see that I posted it but only in the Astro 2.0 section.
I tried to follow what you did in the OH2 section, but the only solution that I found that properly set the variables with the milliseconds was that convoluted mess. When I did
(Astro_Sun_Set_Time.state as DateTimeType).calendar.timeInMillis
without the extra stuff around it, it complained about calendar not having a timeInMillis field that it could find. Does it look okay to you?
Also, love the trick of doing the offset by changing the geolocation!
Your rule calls now more than once. Although every call will only differ some milliseconds, from a design pattern perspective it would be stricter to declare a val at the top of the rule that calls now once and use that value across the rule instead of now.
It would but I would consider that a micro optimization which is something I typically do not worry about unless and until I actually experience performance, logic, or timing problems. For a rule that executes five times over the course of the day and even with all the calls to now ends up only taking a hundred milliseconds or so to run I wouldn’t worry.
One could argue that it might make the rule more clear and easier to understand in which case I would consider the change.
However, in this case I do not see how defining a new variable to replace the calls to now would actually clarify anything.
Because I can’t sendCommand(null). It will generate an error. I could use curr = NULL which would set the state of vTimeOfDay to undefined but that would mean that whereever I check vTimeOfDay for some reason I’d need to check if it is NULL in addition to checking if it is “Evening”, for example. By using the String “UNKNOWN” I can avoid those extra checks and since the “UNKNOWN” state doesn’t drive any behavior it will not negatively impact any of my rules.
Honestly, “UNKNOWN” should never actually be sent to to the vTimeOfDay unless there is an error in the rule. I use it mainly to catch errors without breaking my other rules.
rule MyRule
when
Item TimeOfDay received command "AFTERNOON"
then
// do stuff
end
but it doesn’t seem to trigger. I know it is possible to use received command ON for switches. Is it possible at all to use a string after the received command? Or is it only possible to use
rule MyRule
when
Item TimeOfDay received command
then
switch(receivedCommand) {
case "AFTERNOON" : // do some stuff
case "BED" : // do other stuff
}
end
@rlkoshak I tried your example rule and noticed that the Astro event related triggers fire 3 times. (I get 3 logs for the EVENING (sunset) trigger). Do you have any clue why this could be happening?
rule "TimeOfDay"
when
System started or
Channel 'astro:sun:home:rise#event' triggered START or
Channel 'astro:sun:home:set#event' triggered START or
Channel 'astro:sun:minus30:set#event' triggered START or
Time cron "0 0 0,6,23 * * ? *"
then
val logger = 'rules.test.TimeOfDay'
val msg = 'De tijd is nu ' + now
pushover(msg)
logInfo(logger, msg)
end
The sun:minus30:set#event sent 3 pushover messages to my phone. So the event triggers the rule 3 times.
Next test will be the sun:home:set#event that will be triggered in half an hour
Update: Yep. That trigger also fired 3 times. Next test: separate rule for sunset event (no or triggers).
rule "TimeOfDay"
when
Channel 'astro:sun:home:set#event' triggered START or
then
val logger = 'rules.test.TimeOfDay'
val msg = 'De tijd is nu ' + now
pushover(msg)
logInfo(logger, msg)
end
No clue but nothing really changes functionally with the rule as written off it triggers multiple times. It only changes the Time of day when the newly calculated state is different from the current value.
Because I use groups so heavily in rules I almost always try to write them so multiple triggers do not break something.
Hi Rich,
I like your tutorial, thanks a lot!
I need little assistance for a further time span. I get from my squeezebox the alarm time (like 05:45) as a string. How can I convert it to use it similar to your examples. I need to define a “wakeup time” which starts 15 minutes before alarm time till alarm time.
I’m not in a place where I can give you real code.
Look into the joda DateTime classes to figre out how to parse a String into a DateTime object. Once you have that you can use the comparisons and math like above.
You can look at the alarm clock examples (here is a good one) and see about how you can generate an event to trigger the rule at that time.