Persisting and restoring dateTime values

I have sunrise and sunset times queried from a web service in my system. I only have a rrd4j peristence service configured (apart from exec and logging). When I update my items or rules, the value for Sunset / Sunrise is lost.

I think I have the persistence file set correctly, to RestoreOnStartup for the Astro group (which contains these items)

	Astro*			: strategy = everyChange, restoreOnStartup

Is this a case where rrd isn’t a suitable storage location for time based states/values? Or do I simply have my configuration wrong somehow?

The RRD4J service is not right now not able to persist DateTimeValues (and also no Strings).
For this you will have to use the db4o persistence or some other.

Been working quite much about this bug until I found this thread that tell that rrd4j does not persist DateTimeValues Maybe this “feature” should be added to the Wiki ? Will try db4o.

I am not sure, if this has been solved or there is a solution posted somewhere else. In any case, here is my solution for persisting date and time values and restoring them.
Feel free to comment. Before you comment you must know:
a) I am running: openHAB 1.x and
b) I tried for hours with different types and conversions. Nothing worked for me except the solution below.

Some background:
I want openHAB to control my house differently in winter. Therefore, I have a winter mode item that is either ON or OFF. It is turned ON (by code not shown here) when the outside air temperature is less than 5 °C and is turned OFF, when it reaches 15 °C. In addition to the different behaviour of other rules, there is a warning message “frost alarm” sent to our mobiles via Telegram, when the winter mode is turned ON. So I can for example turn off the water for the garden, or I can see, when it is safe to put some plants back on the terrace after the winter.
To be sure, when the winter mode has been changed for the last time, a second item is storing this date and time whenever the winter mode changes from ON to OFF and from OFF to ON (but not for updates, that do not change the value).
As this (date and time type) item cannot be persisted (I am using RRD4J), the last change time was always gone after restarting openHAB. And this is, where we begin:

First of all, we need the items in the .items file:

Switch Winter_Modus				"Wintermodus"					{ knx="0/0/5" }
DateTime Winter_Modus_last_Change		"letzte Änderung [%1$td.%1$tm. %1$tH:%1$tM]"
Number Winter_Modus_last_Change_millis		"letzte Änderung [%d]"

Please note that the mode is also synced with my KNX installation and the date does not show the year as I don’t need it (but the data would allow this).

Secondly, we need to make Winter_Modus and Winter_Modus_last_Change_millis persistent in rrd4j.persist:

Strategies
{
	everyMinute		: "0	* * * * ?"
	default = restoreOnStartup
}

Items
{
	Winter_Modus			: strategy = everyMinute, everyUpdate, restoreOnStartup
	Winter_Modus_last_Change_millis	: strategy = everyMinute, everyUpdate, restoreOnStartup
}

We can show all values in the .sitemap, but it does not make sense to show Winter_Modus_last_Change_millis as it is only used internally for persistence:

Frame label="Wintermodus"
{
	Text item=Winter_Modus				icon="climate"	label="Status [MAP(de.map):%s]"	valuecolor=[ON="black"]

	Text item=Winter_Modus_last_Change		icon="calendar"
	// Text item=Winter_Modus_last_Change_millis	icon="calendar"
}

And now to the important .rules part. There are three rules:

The first rule is executed when the winter mode changes to ON. It updates both last change items with the current time and issues the “frost alarm”:

rule "Wintermodus ein und Frostalarm melden"
when
	Item Winter_Modus changed to ON
then
	Winter_Modus_last_Change.postUpdate (now.toString)
	Winter_Modus_last_Change_millis.postUpdate (now.millis)

	val String msg = "Frostalarm! Wintermodus eingeschaltet."

	sendTelegram ("mobile1", msg)
	sendTelegram ("mobile2", msg)
end

The second rule is similar, but executed when the winter mode changes to OFF. It updates both last change items again, but does not telegram an alarm:

rule "Wintermodus aus"
when
	Item Winter_Modus changed to OFF
then
	Winter_Modus_last_Change.postUpdate (now.toString)
	Winter_Modus_last_Change_millis.postUpdate (now.millis)
end

So, now we have the last change time displayed in the sitemap as a string and it is also persisted in the database as a numeric value.

This was pretty easy. But we want the numeric value back into openHAB when it is restarted. To achieve it, we need to convert the numeric value back to a date time string. This is where I was stuck for hours and I came back with this:

import java.text.SimpleDateFormat
import org.joda.time.DateTime

rule "Winter_Modus_last_Change restaurieren"
when
	System started
then
	if ((Winter_Modus_last_Change.state != Undefined) && (Winter_Modus_last_Change.state != Uninitialized)) return false
	
	var Number millis = Winter_Modus_last_Change_millis.state
	if ((millis != Undefined) && (millis != Uninitialized))
	{
		val SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ")
		val dt = new DateTime(millis.longValue)
		val String str = sdf.format(dt.toDate)

		Winter_Modus_last_Change.postUpdate (str)
	} else logWarn ("Winter_Modus_last_Change restaurieren", "Bug: No millis in DB!")
end

As you can see, the code is only executed, if the date and time string item has ‘no’ value to avoid overwriting data if openHAB is not restarted but the rules have been changed.
After getting the numeric value (restored from the persistence service), it is converted and posted into the date and time string item. If the item has never been persisted, a warning is logged instead.

I hope, I could help @andre or @Denis_Lambert. Let me know, if you could improve my code (or you find it completely useless :slight_smile:).

Best regards,
Stefano