rule "TimeOfDayRule"
when
System started or
Time cron "0 0 * ? * * *"
then
if (now.getHourOfDay() >= 00 && now.getHourOfDay() < 06){
myTimeOfDayMode.postUpdate("Night")
}
if (now.getHourOfDay() >= 06 && now.getHourOfDay() < 09){
myTimeOfDayMode.postUpdate("Morning")
}
if (now.getHourOfDay() >= 09 && now.getHourOfDay() < 16){
myTimeOfDayMode.postUpdate("Daytime")
}
if (now.getHourOfDay() >= 16 && now.getHourOfDay() < 23){
myTimeOfDayMode.postUpdate("Evening")
}
if (now.getHourOfDay() >= 23 && now.getHourOfDay() < 24){
myTimeOfDayMode.postUpdate("Night")
}
end
item file
String myTimeOfDayMode "My time of Day" <none> (gHome)
Various rules use this string value. I have another rules file in which at the top I’ve placed a file wide variable. Roughly typed in example here (untested)
var TOD = myTimeOfDayMode.state.asString
I’m away from computer right now, but ignoring syntax errors (it runs) further down the rules file
if (TOD == "Night") {
// do stuff
}
the rule worked with the variable inside the code block but as a global (file wide) variable, I’m guessing, it doesn’t pull a new value every time the rule runs? maybe only sets the variable the first time the rules file is loaded?
If so how do I do this? Without having to have the same item having it’s value checked in 6 or 8 places in one rules file
Basically @rossko57 already answered your question, but to make it more explicit:
If you want var TOD = myTimeOfDayMode.state.toString to be evaluated each time any of the rules in the file gets triggered, you should have that definition as the first part of the then of each rule.
That doesn’t have anything to do with DRY by the way, because in a lot of programming languages this will work the way you are now experiencing.
That’s really a misapplication of DRY. Even if this worked, which it doesn’t as already explained, the global variables only gets evaluated when the .rules file gets loaded, why would you create a new variable to store a value that you can access directly?
The whole point of the vTimeOfDay Item is so that it’s state gets checked in 6 or 8 places instead of having to perform the same calculation in 6 or 8 places. Putting the state of vTimeOfDay into a global variable doesn’t prevent you from repeating yourself, it just adds an extra step or redirection.
DRY applies to calculations and code that does the same thing over and over. It doesn’t apply when all that code does is access a value.
Or to put it another way, accessing an Item instead of a variable isn’t repeating anything.
There are valid reasons to capture an Item state into a variable - you might want to preserve it during the execution of a rule for example.
But otherwise it’s make-work. If defining the variable worked the way you wanted it to, it would still have to the same retrieve-process work as if you specified the Item directly.
I’m missing something. I’ve copied the rule “TimeofDayRule” and created a string myTimeOfDayMode in my item file but I still getting a rule error. I suspect I’m not initializing it correctly. What am I missing?
Post the error Tony and we’ll have a look
Most likely, as you say, the item is unitialized and currently undef or null
Use the REST api to check current state.
2019-05-04 07:42:11.899 [WARN ] [el.core.internal.ModelRepositoryImpl] - Configuration model ‘delarosa.rules’ has errors, therefore ignoring it: [30,1]: no viable alternative at input ‘rule’
no no, that helps, you have a syntax error somewhere in the code. At line 30 is where it runs a foul but the error could be several lines prior. You are missing a curly bracket (one of these { }) somewhere me thinks. Do you write your code in an editor? If not check out VS code
Check all your curly brackets and parenthsis to make sure they have a matching close curly bracket or parethesis
I think your post is not getting the typical amount of new user help from the rest of the forum regulars because this is an older thread that got discussed and basically was resolved.
You were right. It was an error before the rule. I was reading about defining variables and I entered a new
var String myDayofWeek =
right before the rule
var String myDayofWeek =
rule "TimeOfDayRule"
when
System started or
Time cron "0 0 * ? * * *"
then
if (now.getHourOfDay() >= 00 && now.getHourOfDay() < 06){
myTimeOfDayMode.postUpdate("Night")
}
if (now.getHourOfDay() >= 06 && now.getHourOfDay() < 09){
myTimeOfDayMode.postUpdate("Morning")
}
if (now.getHourOfDay() >= 09 && now.getHourOfDay() < 16){
myTimeOfDayMode.postUpdate("Daytime")
}
if (now.getHourOfDay() >= 16 && now.getHourOfDay() < 23){
myTimeOfDayMode.postUpdate("Evening")
}
if (now.getHourOfDay() >= 23 && now.getHourOfDay() < 24){
myTimeOfDayMode.postUpdate("Night")
}
end
I deleted that entry and I no longer have that error but my other rule is still not working. The following turns on the stereo when my wife arrives but only during the daytime. Using logInfo, I verify that the presence rule was triggered but not the If statement.
rule "Turn on stereo when Conchita comes home"
when
//Item PresenceCellConnie changed
Item PresenceCellTony changed
then
logInfo("Test", "Entering Presence rule!")
if (myTimeOfDayMode == "Daytime") {
val String CurrentTime = String::format( "%1$tm%1$td ", new java.util.Date )
if (PresenceCellConnie.state == ON){
sendTelegram("TelegramBots", CurrentTime+"Welcome Back Conchita!")
sendHttpPostRequest(URLCRXN560,xmlheader,PowerOn)
Thread::sleep(750)
sendHttpPostRequest(URLCRXN560,xmlheader,VolLvlPM)
sendHttpPostRequest(URLCRXN560,xmlheader,TunerSel)
//sendHttpPostRequest(URLCRXN560,xmlheader,FMPreset)
}
else {
sendHttpPostRequest(URLCRXN560,xmlheader,PowerOff)
}}
logInfo("Test", "Exiting Presence rule!")
end
How do I find out the current value of myTimeOfDayMode
What kind of thing is it? Seeing as you postUpdate to it an earlier rule, I’ll guess it is an Item. Is it a String type Item? That’s a complex object with name, label, etc. properties, but you’ll be interested in the state. Is it a String type Item?