Hi,
i have some rules which are written multiple times for similar items. I want to have one rule which does the job for all items in one group.
Here are my rule files:
rule "Xiaomi Temp 1 Status Changed"
when
Item Xiaomi_Temp_1 received update
then
var SimpleDateFormat df = new SimpleDateFormat( "dd.MM., HH:mm" )
var String timestamp = df.format( new Date() )
Xiaomi_Temp_1_komplett.postUpdate(String::format("%.1f", (Xiaomi_Temp_1.state as DecimalType).floatValue()) + " °C / " + String::format("%.0f", (Xiaomi_Humidity_1.state as DecimalType).floatValue()) + " % (" + timestamp + ")")
end
rule "Xiaomi Temp 2 Status Changed"
when
Item Xiaomi_Temp_2 received update
then
var SimpleDateFormat df = new SimpleDateFormat( "dd.MM., HH:mm" )
var String timestamp = df.format( new Date() )
Xiaomi_Temp_2_komplett.postUpdate(String::format("%.1f", (Xiaomi_Temp_2.state as DecimalType).floatValue()) + " °C / " + String::format("%.0f", (Xiaomi_Humidity_2.state as DecimalType).floatValue()) + " % (" + timestamp + ")")
end
and so on...
How can i do this in one single rule? Can someone help me?
I aready have this kind of rule running for my lighting, but i can´t change this to work with the rules above…
And here are the second rules, same problem, i want them in one single rule:
rule "Xiaomi Temp 1 time since"
when
Time cron "0 * * * * ?"
then
var Number lastthingy1 = (Xiaomi_Temp_1_last_connection.state as DateTimeType).calendar.timeInMillis
var Number myminutes1 = ((now.millis - lastthingy1) / 60000)
Xiaomi_Temp_1_time_since.postUpdate(myminutes1)
end
rule "Xiaomi Temp 2 time since"
when
Time cron "0 * * * * ?"
then
var Number lastthingy2 = (Xiaomi_Temp_2_last_connection.state as DateTimeType).calendar.timeInMillis
var Number myminutes2 = ((now.millis - lastthingy2) / 60000)
Xiaomi_Temp_2_time_since.postUpdate(myminutes2)
end
and so on...
So the rule is just posting a Sring combining the temp and humidity reading, correct? So it is probably safe to assume that it doesn’t matter if this Item gets updated lots of times even if there is no change. I make this assumption because it makes the rule a whole lot easier.
Put all the Items into two Groups, one for Temp and one for Humidity. I’m assuming your current naming scheme remains consistent.
rule "Xiaomi Temp changed"
when
Item Xiaomi_Temps received update
then
val SimpleDateFormat df = new SimpleDateFormat( "dd.MM., HH:mm")
val String timestamp = df.format(new Date())
Xiaomi_Temps.members.forEach[temp |
val humidity = Xiaomi_Humidities.findFirst[hum | hum.name == temp.name.replace("Temp", "Humidity")]
postUpdate(temp.name+"_komplett", String::format("%.1f", (temp.state as DecimalType).floatValue()) + " °C / " +
String::format("%.0f", (humidity.state as DecimalType).floatValue()) + " % (" +
timestamp + ")")
]
end
Any time any Item in Xiaomi_Temps receives an update the rule triggers and the String Item gets updated for all the Temp Items. The String Items will get a lot of redundant updates but that is a small price to pay for the vastly simpler Rule.
For the second set of rules, we have the same approach.
Put the last_connection Items into a Group.
rule "Update Xiaomi Temp time since"
when
Time cron "0 * * * * ?"
then
Xiaomi_Temp_Last_Connections.members.forEach[ lastTime as DateTimeType |
val lastMillis = lastTime.calendar.timeInMillis
val mins = (now.millis - lastMillis) / 60000
val split = lastTime.split("_") // so we can reconstruct the time_since Item name
postUpdate(split.get(0)+"_"+split.get(1)+"_"+split.get(2)+"_time_since", mins)
]
end
I think it doesn´t matter, if there are lots of redundant updates.
EDIT:
For the second rule i get a warning and i think the rule isn´t doing anything…
2017-12-13 08:42:33.757 [WARN ] [el.core.internal.ModelRepositoryImpl] - Configuration model 'temperatur_anzeigen.rules' has errors, therefore ignoring it: [162,59]: no viable alternative at input '|'
The new group is defined like this:
Group Xiaomi_Temp_Last_Connections
I had errors some time ago with this kind of groups in design-pattern-rules, i had to define it in another way. Could this be the same problem? But last time it was a group which stores simple on-off switches, no datetime items?
The complete rule-file isn´t firing any more when the second rule is active.
And from the first rule i get this:
2017-12-13 12:59:48.092 [INFO ] [el.core.internal.ModelRepositoryImpl] - Validation issues found in configuration model 'temperatur_anzeigen.rules', using it anyway:
There is no context to infer the closure's argument types from. Consider typing the arguments or put the closures into a typed context.
Rule isn´t working.
But rest of the rules in the rule file work, while only the first rule is active. Whitz second rule active, none of the rules inside the rules-file worked.
There is a syntax error somewhere in the file at or around line 162, character 59. That isn’t a warning, it is an error. I’m not sure why it is only logged as a warning.
It has nothing to do with your Group definition.
Not having your full .rules file it is hard to say.
The quickest way to solve problems like this is to load your config into ESHD or, if you are on a recent snapshot, loaded into VSCode. It has to be a recent build to get the syntax checking.
The second one is also an error, but at least it isn’t ignoring the whole file. It can’t determine the type of something, maybe temp in the forEach? Again, the quickest way to solve this is using ESHD or VSCode.
With this changes, i get the following error every minute and rule isn´t working.
2017-12-14 08:40:00.002 [ERROR] [ntime.internal.engine.ExecuteRuleJob] - Error during the execution of rule Update Xiaomi Temp time since: The name '<XFeatureCallImplCustom>.split(<XStringLiteralImpl>)' cannot be resolved to an item or type.
EDIT1:
Could it be because of using "" and not '’ in the split-command?
EDIT2:
No, it was not, same error. But in my old rules with split i have used ’ instead of ".
EDIT3:
I made a loginfo for the the state of “val lastTime” and i get this: 2017-12-14T09:04:05.096+0100
So i think splitting with “_” will not give the right values back.