Persist future values with openhab

i would like to persist future values (Wheater Forecast) with openhab. as i read here, it’s not possible directly. I’m right ? Just to make sure…

So i need an extra service/rule to write directly to the database ?

Persistence persists values available “now”. A forecast for the future is available now, and so may be persisted.

The main issue you will encounter, is that your items can be persisted but that the persistence service will be unable to know that the persisted values actually refer to future data. In fact, the persistence layer only knows about the instant the data have been persisted.

For instance, you could define Group Based Persistence to persist all gWeatherCurrent and gWeatherForecast items, as in:

Number:Temperature Wx_Current_Temperature "Current temperature [%.1f %unit%]" <temperature> (gWeatherCurrent) /* ... */
Number:Temperature Wx_Temperature_in_01h  "Temperature in 1h [%.1f %unit%]"   <temperature> (gWeatherForecast) /* ... */
Number:Temperature Wx_Temperature_in_02h  "Temperature in 2h [%.1f %unit%]"   <temperature> (gWeatherForecast) /* ... */
// etc.

However, the persistence service doesn’t know the difference between Wx_Current_Temperature and Wx_Temperature_in_01h as both have been persisted at the same time. Hence, you can’t use e.g. JodaTime constructs out of the box on the forecast items since the persistence layer only knows about the instant the data have been persisted.

For instance, if you want to plot graphs depicting the evolution of the temperature forecast in the next 24 hours, you’ll have to perform the time mapping of the retrieved persisted data. Only you know that for a persisted weather forecast data set, that Wx_Temperature_in_01h refers to a point in time 1 hour after the time of Wx_Current_Temperature. Otherwise your current and forecast data will all be renderex at the same time: the time when the data have been persisted.

you are totally rigth, in case the the persistence time stamp represent the time of saving, but there are a lot of other cases, where it could be great to define the timesatmp or overwrite the time of saving to something else. Think about of messeage queues where the telegrams are saved later than they accour… if you are not use the timestamp for saving you should persist an object of value and timestamp of the event …

just my two cents

Okay, but you cannot do that with openHAB persistence.
As you say, the only thing you can do with OH persistence that is close would be to store, retrieve, and process together pairs of data+timestamp.
Or of course, some independent db access of your choice.

What’s the purpose of this exercise, just checking forecast accuracy or something?
You don’t need to store any extra time info for a data Item like “6hr forecast”. It’s always “6hr forecast” and you know that; you know when it was stored; you can calculate when the forecast was for.

yes i would like to chart forecasts like temperature, pv etc. and would like to have the real values in the same chart

In grafana you can easily use an offset. So in the above example give the 6 hour forecast a -6 hour offset and you can compare it to the actual temperature.

2 Likes

Thinks; a real cheat way to use the simple charts and standard persistence … create a fake Item 6 hours behind the forecast. For this chart job, you do not need the forecast until the “now” info is available anyway.

So, persist your forecast every minute (needed for charting I think)
Run a rule every minute that retrieves the forecast from 6 hours ago, posts that value to an intermediary Item (which you also need to persist for charting)
Now you can chart actual against forecast.

thanks for your hints! i will think about it… grafana still works, but i would like to have a single point for configuration etc…

That would only manage the past. Not the future.

Minute-based persistence is only required when using rr4j (spelling may be off) persistence. I’m using Influx.

I just wanted to share the answer I found to persisting future values.
With the rule below, 6 3-hour OpenWeatherMap rain predictions are stored in InfluxDB, at future timestamps, which are also part of the OpenWeatherMap data.

rule "Forecast 24H Persistence"
when
    Item LocalWeatherAndForecast_ForecastHours03_ForecastedRain received update
then
    var rain03H   = (LocalWeatherAndForecast_ForecastHours03_ForecastedRain.state as Number).floatValue.toString
    val time03H   = new DateTime(LocalWeatherAndForecast_ForecastHours03_ForecastTime.state.toString).millis.toString + "000000"
    var rain06H   = (LocalWeatherAndForecast_ForecastHours06_ForecastedRain.state as Number).floatValue.toString
    val time06H   = new DateTime(LocalWeatherAndForecast_ForecastHours06_ForecastTime.state.toString).millis.toString + "000000"
    var rain09H   = (LocalWeatherAndForecast_ForecastHours09_ForecastedRain.state as Number).floatValue.toString
    val time09H   = new DateTime(LocalWeatherAndForecast_ForecastHours09_ForecastTime.state.toString).millis.toString + "000000"
    var rain12H   = (LocalWeatherAndForecast_ForecastHours12_ForecastedRain.state as Number).floatValue.toString
    val time12H   = new DateTime(LocalWeatherAndForecast_ForecastHours12_ForecastTime.state.toString).millis.toString + "000000"
    var rain15H   = (LocalWeatherAndForecast_ForecastHours15_ForecastedRain.state as Number).floatValue.toString
    val time15H   = new DateTime(LocalWeatherAndForecast_ForecastHours15_ForecastTime.state.toString).millis.toString + "000000"
    var rain18H   = (LocalWeatherAndForecast_ForecastHours18_ForecastedRain.state as Number).floatValue.toString
    val time18H   = new DateTime(LocalWeatherAndForecast_ForecastHours18_ForecastTime.state.toString).millis.toString + "000000"
    var rain21H   = (LocalWeatherAndForecast_ForecastHours21_ForecastedRain.state as Number).floatValue.toString
    val time21H   = new DateTime(LocalWeatherAndForecast_ForecastHours21_ForecastTime.state.toString).millis.toString + "000000"
    var rain24H   = (LocalWeatherAndForecast_ForecastHours24_ForecastedRain.state as Number).floatValue.toString
    val time24H   = new DateTime(LocalWeatherAndForecast_ForecastHours24_ForecastTime.state.toString).millis.toString + "000000"
    val theString = "Rain value=" + rain03H + " " + time03H
                    + "\nRain value=" + rain06H + " " + time06H
                    + "\nRain value=" + rain09H + " " + time09H
                    + "\nRain value=" + rain12H + " " + time12H
                    + "\nRain value=" + rain15H + " " + time15H
                    + "\nRain value=" + rain18H + " " + time18H
                    + "\nRain value=" + rain21H + " " + time21H
                    + "\nRain value=" + rain24H + " " + time24H
    if (influxWriteTimer === null) {
        influxWriteTimer = createTimer(now, [|
            sendHttpPostRequest(INFLUXDB_WRITE, "application/json", theString, 3000)
            influxWriteTimer = null
        ])
    } else {
        logWarn("eagle", "Influx write timer is still running, not creating another")
    }
end
2 Likes

Could you please format your posted code lines according This