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
Both rules above use Design Pattern: Associated Items
Again, we trade lots of redundant updates to Items for a vastly simpler rule.