Rule: check if last update of item was in the last half hour?

Hey,

I’m setting up a openhab config which reads out several DIY battery powered arduino sensors with RFM69 transceivers, they communicate through MQTT, which is all working as it should.

Because it are battery powered devices, I’m trying to make a rule that checks for last Update of those instances. if the sensors haven’t been updated in the last 30 minutes and if it is between 6am and 11pm, I get an e-mail saying me which devices are not updating anymore. Or at least that’s the purpose, I’m using the same technique as in this rules example: check battery status

[code]
// Check last update if no update for the last half hour, sends a msg
import org.openhab.core.library.types.*
import org.openhab.core.persistence.*
import org.openhab.model.script.actions.*
import org.openhab.core.library.types.DecimalType

import org.openhab.joda.time.*

import org.openhab.binding.mpd.*
import org.openhab.binding.mqtt.*

val String mailTo = “xxx@xxx.xx”

rule “Check every hour for last update of all nodes”
when
Time cron “0 0/30 7-23 * * ?”
then
if (! Update_time.allMembers.filter([now.minusMinutes(30).isAfter((state as DateTimeType).calendar.timeInMillis)]).empty) {
val report = Update_time.allMembers.filter([state]).sortBy([state]).map[
name + “: " + state.format(”%d%%")
].join("\n")

            val message = "Last Updates:\n\n" + report + "\n\nRegards,\n\nopenHab"

            sendMail(mailTo, "Updates failed", message)
    }

end[/code]

The cron job works, but I get the following error:

java.lang.ClassCastException: org.openhab.core.library.types.DateTimeType cannot be cast to java.lang.Boolean

below is the rule that calculates the times of last update, this one works as it should:


when
  Item itm_doorbell_uptime_mqtt received update
then
        postUpdate(mqtt_doorbell_LastUpdate, new DateTimeType())
end

Anybody that can help with solving my problem, thx.

I’m using JSR223 (Python) instead of the Xtend rule language, but I’m guessing the filter operator doesn’t like the DateTimeType and wants a boolean expression.

You have an error in your filter. It needs to read:

if (! Update_time.allMembers.filter(member | now.minusMinutes(30).isAfter((member.state as DateTimeType).calendar.timeInMillis)).empty) {

In the filter you have to give the current item being iterated over a name in order to get at its properties, in this case the state. You do this by providing the name with a ‘|’ and then your lambda.

@steve1 I would say too, but the expression inside the filter should produce a boolean, as far as I can see.

@rlkoshak the solution you proposed produces the same error.

I’m quite confused as why it doesn’t work. as far as I can see, it should work, as the isAfter should produce a boolean expression.

I thought the state in

Update_time.allMembers.filter([state])...

was a DateTimeType because of the type cast in the previous expression.

[state] is indeed a DateTimeType but the expression inside the filter should produce a boolean because i’m comparing it with now.minusMinutes(30) so the outcome should produce a boolean.

I understand and maybe this is something I don’t understand about the Xtend-based rules, but there are two usages of the filter operator in the sample code you posted. The first compares the DateTimeType value to now.minusMinutes(30). The second usage, when initializing the report var, is just “filter([state])”. Is that DateTimeType also somehow being converted to a boolean?

That seems to be the problem indeed.

I hadn’t realised the problem could be there. Thx for the insight.

Also my programming knowledge dates from a couple of years ago, so I’m quite rusty and never worked in Java or xtend.

Hi @lone_black_rider - Could you please post your complete working rule. I want to do a similar thing.

At the moment I don’t have it working yet and I had some other stuff to configure, so it’s still a something to work out.