Error in temperature history rule

Hello
I am trying to get a historical value of a temperature element throughout the life of my OH (which since the last reinstallation is not much) I have tried with the rules that I publish below and I have no result, I also have them added to the persistence configuration file

`rule “Update max and min historicas temperatures exterior”
when
Item Temperatura changed or
Time cron “0 0 0 * * ?” or
System started
then

postUpdate(Temp_Max_hist, Temperatura.historicState().state)

end

thank you
ps-I have searched and I have not seen anything on the subject, something quite strange, I understand that perhaps I have not searched well, sorry for my English

What persistence are you using? You cannot get any historical data without some form of persistence.

if you look in your openhab.log you might see error messages.

.historicState() fetches from persistence your Item’s state at a past moment in time (if it can !).
It follows that historicState() needs you to tell it which of the large number of past moments in time that you mean. In other words, you have to give it a target datetime that you want data from.
Example
var oldRecord = myItem.historicState(now.minusMonths(6))

It’s not really clear what you have in mind? Are you trying to get the average over a long period, or something? You might look at the other persistence methods.

If it is “getting the oldest data”, that is harder than it looks - historicState() can only give the state at a given moment. In reality, that is usually the database record from just before the moment you asked for. But there is not an easy way to ask for the very oldest record, apart from trying past dates and seeing what works.

Thank you very much what speed in answering like this
I use the rrd4j persistence system
I try to keep a history of the highest and lowest temperature of the entire time the system has been operating

@rossko57
I don’t understand what they mean to me

".historicState () fetches from persistence your Item’s state at a past moment in time (if it can!).
It follows that historicState () needs you to tell it which of the large number of past moments in time that you mean. In other words, you have to give it a target datetime that you want data from.
Example
var oldRecord = myItem.historicState (now.minusMonths (6)) "

could you give me a complete example

thank you very much again

Sure

var oldRecord = youPutYourItemNameHere.historicState(now.minusMonths(6))
if (oldRecord !== null) {
   logInfo("test", "The data was " + oldRecord.state.toString)
   logInfo("test", "Datestamped "  + String::format("%1$td/%1$tm/%1$tY", oldRecord.timestamp)
} else {
   logInfo("test", "There was no persisted data for that time")
}

hi, i tried this like you told me, this way

rule “Update max and min historical exterior temperatures”
when
Item Temperature changed or
Time cron “0 0 0 * *?” or
System started
then

var oldRecord = Temperature.historicState (now.minusMonths (6))
if (oldRecord! == null) {
logInfo (“test”, “The data was” + oldRecord.state.toString)
logInfo (“test”, “Datestamped” + String :: format ("% 1 $ td /% 1 $ tm /% 1 $ tY", oldRecord.timestamp))
}
else {
logInfo (“test”, “There was no persisted data for that time”)
}
end

and the only thing I get in the log when the temperature value changes is this

2020-09-02 18: 22: 19.348 [INFO] [.eclipse.smarthome.model.script.test] - There was no persisted data for that time

We will continue looking for solutions …

Greetings

That sounds as if no persistence service has been setup correctly.
How does your files rrd4j.persist and rrd4j.cfg look like?

What is your default persistence service?
Does it have any data from six months ago?
Why not try and see if it has any data for an hour ago?

1 Like

I have changed for this

var oldRecord = Temperature.historicState (now.minusDays (5))

and the log collects this

2020-09-02 19: 14: 07.990 [INFO] [.eclipse.smarthome.model.script.test] - The data was 30.518973214285715

2020-09-02 19: 14: 08.008 [INFO] [.eclipse.smarthome.model.script.test] - Datestamped 08/28/2020

I thought it was the highest temperature but that value changes I do not understand what value that rule gets, this is another value that came out

2020-09-02 19: 23: 18.632 [INFO] [.eclipse.smarthome.model.script.test] - The data was 30.456473214285715
2020-09-02 19: 23: 26.787 [INFO] [.eclipse.smarthome.model.script.test] - Datestamped 08/28/2020

@opus the persistence service seems to work because in addition to extracting data I see a graph in the habpanel from the first day I reinstalled OH2

Thank you very much, I’ll keep looking

How do you try to keep highest and lowest readings? A single max over the whole time or the daily/weekly / etc max saved in a database?
The code shown so far doesn’t do anything to that concern.

I am looking for a maximum and a minimum of the entire database

You need the .maximumSince and.minimumSince.
Note that rrd4j (in the default config) does store averages if you are looking further then 8 hours into the past.

but I don’t know how to formulate the rule …

rossko57 did give you the useable code, just replace .historicState with .minimumSince or .maximumSince.

An easy way to get an early DateTime is to use DateTime(0), which returns 00:00:00 GMT on January 1, 1970, converted to your system’s timezone.

Here is a quick example using Jython…

from org.joda.time import DateTime

from core.actions import PersistenceExtensions
from core.log import logging, LOG_PREFIX

LOG = logging.getLogger("{}.TEST".format(LOG_PREFIX))

LOG.warn("{}".format(items["Weather_Temp_Max_F_0"]))
LOG.warn("{}".format(DateTime(0)))

maximum = PersistenceExtensions.maximumSince(ir.getItem("Weather_Temp_Max_F_0"), DateTime(0))
minimum = PersistenceExtensions.minimumSince(ir.getItem("Weather_Temp_Max_F_0"), DateTime(0))

LOG.warn("Max: {}, date: {}".format(maximum.state, maximum.timestamp))
LOG.warn("Min: {}, date: {}".format(minimum.state, minimum.timestamp))

@opus your help is correct I already see the minimum temperature and double changing one part and I also see the maximum temperature, thank you very much

@5iver I’m sorry to tell you that when modifying “(now.minusDays (15)) by (now.DateTime (0))” I get this error in the log

2020-09-02 21: 31: 47.270 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule ‘Update max and min historical exterior temperatures’: The name ‘DateTime’ cannot be resolved to an item or type; line 19, column 43, length 11

I will look at the link you put me, unfortunately my English is quite bad and it will cost me time to see the document

thank you both very much

For the rules DSL, you would use something like this…

val maximum = Weather_Temp_Max_F_0.maximumSince(new DateTime(0))
val minimum = Weather_Temp_Max_F_0.minimumSince(new DateTime(0))

logWarn("Rules", "Max: {}, date: {}", maximum.state, maximum.timestamp)
logWarn("Rules", "Min: {}, date: {}", minimum.state, minimum.timestamp)

follows me not valid it does not use the old values, I am trying to change the number of days and every time I make a change for some reason it changes the value for a higher one

I’m not sure what you were saying :slightly_smiling_face:. Here is a bit more detail on what I was suggesting. This rule is untested and assumes that your Temperature Item is not utilizing UoM. I am also not sure what your persistence will do with a very old date, but JDBC can handle it.

rule "Update max and min historical exterior temperatures"
when
    Item Temperature changed
    or
    Time cron "0 0 0 * * ?"
then
    val current_state = Temperature.state
    if (current_state == NULL) {
        return
    )
    val minimum_value = Temperature.minimumSince(new DateTime(0)).state
    val maximum_value = Temperature.maximumSince(new DateTime(0)).state
    if (current_state < minimum_value) {
        Temp_Min_hist.postUpdate(current_state.toString)
        logInfo ("test", "The current value '{}' was less than the previous minimum '{}', so it was updated", current_state, minimum_value)
        return
    } else if (current_state > maximum_value) {
        Temp_Max_hist.postUpdate(current_state.toString)
        logInfo ("test", "The current value '{}' was greater than the previous maximum '{}', so it was updated", current_state, maximum_value)
        return
    }
    logInfo ("test", "The current value '{}' did not require updating the previous minimum '{}' or maximum '{}'", current_state, minimum_value, maximum_value)
end

hi, i used your rule and for now i get this bug …

2020-09-07 23: 30: 50.305 [WARN] [ui.internal.items.ItemUIRegistryImpl] - Exception while formatting value ‘org.openhab.core.persistence.internal.QueryablePersistenceServiceDelegate$1@e639af’ of item Dia_Temp_min with format '% 1 $ td /% 1 $ tm /% 1 $ tY ': d! = Java.lang.String

2020-09-07 23: 30: 58.429 [WARN] [ui.internal.items.ItemUIRegistryImpl] - Exception while formatting value ‘org.openhab.core.persistence.internal.QueryablePersistenceServiceDelegate$1@e639af’ of item Dia_Temp_min with format '% 1 $ td /% 1 $ tm /% 1 $ tY ': d! = Java.lang.String