Need help with simplifying item time stamping rule

Well, you can log when the last update was for them. That should give you an idea when it stopped working or maybe give us a clue as to what else could be going wrong.

    Thread::sleep(2500)
    Temperature.members.forEach[ temp |  
        logInfo("Temp", temp.name + "'s last update was " + temp.lastUpdate.toString) 
    ]
    val changedsensor = Temperature ...

Depending on what this spits out we will know whether or not the Items are being persisted and/or whether the Items are members of the group.

Here we go:

Aug 19 14:26:04 raspberrypi start.sh[700]: 2016-08-19 14:26:04.873 [INFO ] [runtime.busevents             ] - Temperature_Office state updated to 84.2
Aug 19 14:26:05 raspberrypi start.sh[700]: 2016-08-19 14:26:05.182 [INFO ] [runtime.busevents             ] - Humidity_Office state updated to 30.0
Aug 19 14:26:06 raspberrypi start.sh[700]: 2016-08-19 14:26:06.750 [INFO ] [org.openhab.model.script.Temp ] - Received an update from a temp sensor
Aug 19 14:26:08 raspberrypi start.sh[700]: 2016-08-19 14:26:08.458 [INFO ] [runtime.busevents             ] - Motion_Kitchen received command ON
Aug 19 14:26:08 raspberrypi start.sh[700]: 2016-08-19 14:26:08.908 [INFO ] [runtime.busevents             ] - Motion_Kitchen_Update state updated to 2016-08-19T14:26:08
Aug 19 14:26:13 raspberrypi start.sh[700]: 2016-08-19 14:26:13.261 [INFO ] [runtime.busevents             ] - HVAC_Fan_State state updated to 0
Aug 19 14:26:17 raspberrypi start.sh[700]: 2016-08-19 14:26:17.316 [INFO ] [runtime.busevents             ] - Motion_New state updated to CLOSED
Aug 19 14:26:18 raspberrypi start.sh[700]: 2016-08-19 14:26:18.294 [INFO ] [runtime.busevents             ] - HVAC_Temperature state updated to 80
Aug 19 14:26:18 raspberrypi start.sh[700]: 2016-08-19 14:26:18.732 [INFO ] [org.openhab.model.script.Temp ] - Temperature_Living's last update was 2016-08-16 10:25:44.0
Aug 19 14:26:18 raspberrypi start.sh[700]: 2016-08-19 14:26:18.829 [INFO ] [org.openhab.model.script.Temp ] - Temperature_Master's last update was 2016-08-19 14:14:49.0
Aug 19 14:26:18 raspberrypi start.sh[700]: 2016-08-19 14:26:18.853 [INFO ] [[org.openhab.model.script.Temp ] - Temperature_Office's last update was 2016-08-19 14:26:05.0
Aug 19 14:26:18 raspberrypi start.sh[700]: 2016-08-19 14:26:18.922 [INFO ] [org.openhab.model.script.Temp ] - HVAC_Temperature's last update was 2016-08-19 13:30:56.0
Aug 19 14:26:18 raspberrypi start.sh[700]: 2016-08-19 14:26:18.946 [INFO ] [org.openhab.model.script.Temp ] - Weather_Temperature's last update was 2016-08-19 14:23:28.0
Aug 19 14:26:28 raspberrypi start.sh[700]: 2016-08-19 14:26:28.850 [INFO ] [org.openhab.model.script.Temp ] - Found 0 updated sensors

So Temperature_Office's last update was 2016-08-19 14:26:05.0 which matches
2016-08-19 14:26:04.873 [INFO ] [runtime.busevents ] - Temperature_Office state updated to 84.2
right?

How odd. Yes, I would assume those two match. It also shows that it is taking persistence about 150 msec to persist the value.

The changedSince method is clearly not working for you (only thing I can think of to explain this behavior).

So we can either fight that dragon or pivot. I’d pivot.

Lets do the math ourselves.

val changedsensors = Temperature.members.filter[sensor|now.millis - sensor.lastUpdate.time <= 1000]

That will basically return true if there has been less than a second between now and the lastUpdate.

Another thing that might work is to sortBy lastUpdate and get the most recent one. This is actually what I usually do. I didn’t in the case of this example because I don’t have as much of an assurance that two events won’t happen really close together and consequently one of them would be lost. For example, lets say you are at the beginning of your 200 msec sleep and a new reading comes in. When the Thread::sleep ends there is a chance that that new event will now be the latest one and the event that actually triggered the rule in the first place would be lost.

But if that risk is acceptable this would turn the rule into:

    Thread::sleep(200)
    val mostRecent = Temperature.members.sortBy[lastUpdate].last
    val updateItem = TemperatureUpdate.members.filter[up|up.name == mostRecent.name+"_Update"].head
    updateItem.postUpdate(new DateTimeType)

NOTE: I just noticed you are using the same group for your Update Items and your Temperature Number Items. They need to be in different Groups. I invented a new TemperatureUpdate group in my code above.

Is this what’s breaking it?

Number		Temperature_Living			"LR Temperature [%.1f &deg;F]"						&lt;temperature&gt;	(Living,Temperature,IndoorTemp)		{ mysensors="1;1;V_TEMP", imperihab="room:Living Room,label:Living Room Temperature,hygroId:Humidity_Living" }
DateTime	Temperature_Living_Update	"Last update [%1$tm/%1$td/%1$tY %1$tl:%1$tM %1$tp]"	&lt;status&gt;		(Living)

I don’t have the updates in the Temperature group but I do have it in the Living group so that it displays when I show that group on my site map. Can I not do that?

Tried the first method:

import org.openhab.core.library.types.*

rule "A New Temperature Reported"
when
        Item Temperature_Living received update or
        Item Temperature_Master received update or
        Item Temperature_Office received update
then
    logInfo("Temp", "Received an update from a temp sensor")
    Thread::sleep(2500)
    Temperature.members.forEach[ temp |
    logInfo("Temp", temp.name + "'s last update was " + temp.lastUpdate.toString)
    ]
    // val changedsensor = Temperature.members.filter[sensor|sensor.changedSince(now.minusSeconds(5), "mysql")]
    val changedsensor = Temperature.members.filter[sensor|now.millis - sensor.lastUpdate.time <= 1000]
    logInfo("Temp", "Found " + changedsensor.size + " updated sensors")
    changedsensor.forEach[sensor |
        logInfo("Temp", "A sensor that changed is " + sensor.name)
        val updateItem = Temperature.members.filter[up|up.name == sensor.name+"_Update"].head
        logInfo("Temp", "The corresponding update Item is" + updateItem.name)
        updateItem.postUpdate(new DateTimeType)
    ]
end

Got this error:

Aug 19 15:15:34 raspberrypi start.sh[700]: 2016-08-19 15:15:34.776 [ERROR] [o.o.c.s.ScriptExecutionThread ] - Error during the execution of rule 'A New Temperature Reported': Could not invoke method: org.eclipse.xtext.xbase.lib.LongExtensions.operator_minus(long,byte) on instance: null

Again, thanks for your help and your persistence in helping me with this.

It will be a problem eventually. But it isn’t a problem right now because we aren’t getting that far in the code yet.

You can have it in any group or groups that you want to. But when you go searching for the Item by name (i.e. the filter[up|up.name == …]), you need to be searching in a group to which the Update Item is actually a member.

Personally I maintain separate groups for functional and display purposes. I would have both a Living and TemperatureUpdate group and make the Update a member of both. Then I’d search in TemperatureUpdate in my rule and put Living on your sitemap.

Though I will say that you will likely quickly discover that putting Items on your sitemap using Groups is exceptionally limiting. I actually don’t use Groups on my sitemap at all anymore.

!!! I didn’t have this much trouble when I was first learning this stuff. Grrrrr.

Lets force it to a long. I’m not sure which of these two is correct. The Rules DSL does weird things with numbers sometimes.

filter[sensor|(now.millis - sensor.lastUpdate.time) as long <= 1000]

filter[sensor|(now.millis - sensor.lastUpdate.time).longValue <= 1000]

First gives this error:
Aug 19 15:25:35 raspberrypi start.sh[700]: 2016-08-19 15:25:35.906 [ERROR] [o.o.c.s.ScriptExecutionThread ] - Error during the execution of rule 'A New Temperature Reported': Could not invoke method: org.eclipse.xtext.xbase.lib.LongExtensions.operator_minus(long,byte) on instance: null

Second gives me this error:
Aug 19 15:27:35 raspberrypi start.sh[700]: 2016-08-19 15:27:35.886 [ERROR] [o.o.c.s.ScriptExecutionThread ] - Error during the execution of rule 'A New Temperature Reported': Could not invoke method: org.eclipse.xtext.xbase.lib.LongExtensions.operator_minus(long,byte) on instance: null

Do I need some kind of extra include for the math?

Sigh… I thought I was going to make things easier! haha

No.

Sigh. now.millis is a long. sensor.lastUpdate.time is a long. Why does it think there is a byte?

I’ve never tried this and I’ve notices that filter lambdas can be tricky, but maybe we can make it a multiline lambda and break this down a bit more.

filter[sensor|
    logInfo("Temp", "Calculating time diff")
    val long timeDiff = now.millis - sensor.lastUpdate.time
    logInfo("Temp", "Time diff is " + timeDiff)
    timeDiff <= 1000 
]

I’m wondering if this is failing for a similar reason as the changedSince.

This may totally blow up in our faces though. In the past I’ve found filter and sortBy to be really finicky. For example, I do not put in spaces between ‘[sensor|’ on purpose as I’ve found that caused me errors.

Here’s what I got:

Aug 19 15:39:56 raspberrypi start.sh[700]: 2016-08-19 15:39:56.120 [INFO ] [c.internal.ModelRepositoryImpl] - Refreshing model 'newtemp.rules'
Aug 19 15:39:59 raspberrypi start.sh[700]: 2016-08-19 15:39:59.022 [INFO ] [runtime.busevents             ] - HVAC_CoolSetPoint state updated to 80
Aug 19 15:40:00 raspberrypi start.sh[700]: 2016-08-19 15:40:00.527 [INFO ] [runtime.busevents             ] - HVACRuntimeD state updated to 121
Aug 19 15:40:03 raspberrypi start.sh[700]: 2016-08-19 15:40:03.478 [INFO ] [runtime.busevents             ] - HVACRuntimeW state updated to 1391
Aug 19 15:40:03 raspberrypi start.sh[700]: 2016-08-19 15:40:03.517 [INFO ] [runtime.busevents             ] - HVACRuntimeDhr state updated to 2.01666667
Aug 19 15:40:03 raspberrypi start.sh[700]: 2016-08-19 15:40:03.590 [INFO ] [runtime.busevents             ] - HVACRuntimeStorehr state updated to 5.46666667
Aug 19 15:40:03 raspberrypi start.sh[700]: 2016-08-19 15:40:03.615 [INFO ] [runtime.busevents             ] - HVACRuntimeWhr state updated to 23.18333333
Aug 19 15:40:03 raspberrypi start.sh[700]: 2016-08-19 15:40:03.970 [INFO ] [runtime.busevents             ] - HVAC_Mode state updated to 2
Aug 19 15:40:09 raspberrypi start.sh[700]: 2016-08-19 15:40:09.386 [INFO ] [runtime.busevents             ] - Temperature_Office state updated to 86.0
Aug 19 15:40:09 raspberrypi start.sh[700]: 2016-08-19 15:40:09.584 [INFO ] [runtime.busevents             ] - Humidity_Office state updated to 41.0
Aug 19 15:40:11 raspberrypi start.sh[700]: 2016-08-19 15:40:11.357 [INFO ] [org.openhab.model.script.Temp ] - Received an update from a temp sensor
Aug 19 15:40:22 raspberrypi start.sh[700]: 2016-08-19 15:40:22.301 [INFO ] [runtime.busevents             ] - Motion_New state updated to CLOSED
Aug 19 15:40:23 raspberrypi start.sh[700]: 2016-08-19 15:40:23.329 [INFO ] [org.openhab.model.script.Temp ] - Temperature_Living's last update was 2016-08-16 10:25:44.0
Aug 19 15:40:23 raspberrypi start.sh[700]: 2016-08-19 15:40:23.423 [INFO ] [org.openhab.model.script.Temp ] - Temperature_Master's last update was 2016-08-19 14:14:49.0
Aug 19 15:40:23 raspberrypi start.sh[700]: 2016-08-19 15:40:23.446 [INFO ] [org.openhab.model.script.Temp ] - Temperature_Office's last update was 2016-08-19 15:34:09.0
Aug 19 15:40:23 raspberrypi start.sh[700]: 2016-08-19 15:40:23.513 [INFO ] [org.openhab.model.script.Temp ] - HVAC_Temperature's last update was 2016-08-19 15:17:32.0
Aug 19 15:40:23 raspberrypi start.sh[700]: 2016-08-19 15:40:23.536 [INFO ] [org.openhab.model.script.Temp ] - Weather_Temperature's last update was 2016-08-19 15:33:29.0
Aug 19 15:40:23 raspberrypi start.sh[700]: 2016-08-19 15:40:23.974 [INFO ] [runtime.busevents             ] - HVAC_Fan_State state updated to 0
Aug 19 15:40:33 raspberrypi start.sh[700]: 2016-08-19 15:40:33.990 [INFO ] [runtime.busevents             ] - HVAC_Temperature state updated to 80
Aug 19 15:40:38 raspberrypi start.sh[700]: 2016-08-19 15:40:38.995 [INFO ] [runtime.busevents             ] - HVAC_HeatSetPoint state updated to 65
Aug 19 15:40:43 raspberrypi start.sh[700]: 2016-08-19 15:40:43.252 [INFO ] [org.openhab.model.script.Temp ] - Calculating time diff
Aug 19 15:40:43 raspberrypi start.sh[700]: 2016-08-19 15:40:43.478 [ERROR] [o.o.c.s.ScriptExecutionThread ] - Error during the execution of rule 'A New Temperature Reported': Could not invoke method: org.eclipse.xtext.xbase.lib.LongExtensions.operator_minus(long,byte) on instance: null

I know I’ve taken up a lot of your time today and wouldn’t blame you if you’re tired of looking at this. I do have my old method that works as a fallback.

I’m actually surprised that multi-line filter worked. Who knew?

One last try and then we will either need to go to the sortBy method or concede defeat.

val long timeDiff = now.millis.longValue - sensor.lastUpdate.time.longValue
timeDiff <= 1000L

It is pretty disconcerting that the changedSince isn’t working though.

Aug 19 15:51:45 raspberrypi start.sh[700]: 2016-08-19 15:51:45.244 [ERROR] [o.o.c.s.ScriptExecutionThread ] - Error during the execution of rule 'A New Temperature Reported': Could not invoke method: org.eclipse.xtext.xbase.lib.LongExtensions.operator_minus(long,byte) on instance: null

Yeah, I quit :slight_smile: Thanks for the efforts. I may try sortBy later.

I know that this is an old post but I just wanted to express my disappointment that this was never solved. Is the extend language really so cryptic that there are scenarios where finding a solution to a problem is complicated to the point where its better just to accept that it can’t be done?