Persistence: Possible to specify both time and value with postUpdate?

Is it possible to specify both the time and the value when calling postUpdate? Normally when calling postUpdate I specify the item and the value and the time that’s persisted on the DB is the time at which the postUpdate mathod was called. I’m working on rules to calculate and store the amount of electricity used every day, I have an item which is updated at 23:59:00 every night with the amount of electricity that was used that day. This allows me to graph the daily usage in Grafana. However, the issue I have is that because the postUpdate method is called at the end of the day then it appears in Grafana charts that the daily usage is 1 day behind reality because the data is persisted with a timestamp of the end of the day.

If I could have the rule that stores the daily history at the end of the day post data with a timestamp of the start of that day then the chart in Grafana would look correct. Is that possible?

IMHO the interface between openHAB and all persistence service is configured in the way you observed only.
Depending on the used database you might be able to manipulate the timestamp associated with each value.
To get such functionality you would need a rule doing the complete database functionality without any support of the build in functions of openHAB.

Two things:

If this is as it sounds, you should be using the method on the Item instead of the Action for postUpdate. See Rules | openHAB

As opus states, there is no way you can change or specify the timestamp.

And perhaps I’m not understanding the problem correctly. Let’s say it is 2/12. Do you want the timestamp to be 00:00 2/12/2019 or do you want the timestamp to be 00:00 2/13/2019?

If it’s the former then that doesn’t make sense to me because you don’t know the daily usage until the end of the day.

If it is the latter, then just create a Timer and don’t actually call the postUpdate for a minute so the timestamp ends up at the start of the next day.

1 Like

I didn’t explain that aspect clearly, I do use the method of the item:

electricityHouseTotalConsumptionDailyHistory.postUpdate(electricityHouseTotalConsumptionDaily.state as Number)

I’d like to achieve the former. Obviously, the system is only able to calculate the daily usage at the end of the day. Grafana charts plot data on the X axis using the timestamp of the value and since the timestamp of the value is, on my system, at 23:59:00 on each dat it appears that the consumption for 12/02/2019 is on the part of the X axis that represents 13/02/2019. To be precise, the consumption for 12/02/2019 occupies the part of the X axis from 12/02/2019_23:59:00 to 13/02/2019_23:59:00, at which point the consumption for 13/02/2019 is written. If I were back at school and I plotted a bar chart in that way my maths teacher would not be impressed. Then again, that was a long time ago and if I remember rightly he was a miserable old goat and nothing ever impressed him.

What I would like to achieve is that the consumption for 12/02/2019 is posted with a timestamp of 12/02/2019_00:00:00, consumption for 13/02/2019 posted with a timestamp of 13/02/2019_00:00:00, etc. This would let the bar chart look correct. I know it’s a fudge for an external system but it’s what I’d like to achieve. I’m also looking into a way to get Grafana to display the data how I want it.

Maybe I could do this by executing an influxDB insert from within a rule via a call to curl…

Take a look at this post. You can send a POST request to InfluxDB from a rule with any data you want and you can specify the timestamp. The persistence interface is simple and doesn’t let you use tags or different retention policies or set specific timestamps as you found which is a bit limiting.

That looks like exactly what I need, thanks! :slight_smile:

Can anyone suggest why the following rule doesn’t work:

rule "Store usage for day with timestamp at start of day"
when
    Item electricityTestInfluxDBUpdateSwitch received update
then
    logWarn("dev", "InfluxDB test rule starting...")
    if (influxWriteTimer === null) {
        val Number epochThisMorning = now.withTimeAtStartOfDay().millis / 1000
        logWarn("dev", "InfluxDB test rule timestamp = (" + epochThisMorning + ").")
        influxWriteTimer = createTimer(now, [|
	    sendHttpPostRequest(INFLUXDB_WRITE, "application/json", "electricityTestInfluxDBUpdate value=30 " + epochThisMorning, 3000) 
	    // sendHttpPostRequest(INFLUXDB_WRITE, "application/json", "electricityTestInfluxDBUpdate value=30 ", 3000) 
            influxWriteTimer = null
        ])
    } else {
        logWarn("dev", "Influx write timer is still running, not creating another")
    }
end

My understanding of the InfluxDB documentation is that to specify a timestamp you add an epoch time after the “value=X” statement. However, if I try that then no data is written to InfluxDB. If I remove the timestamp statement (as shown in the commented out httppost above) then the value of 30 is written to InfluxDB with a timestamp of the current time. So, I’m part way to a solution.

Could the trailing space at the end of the "value=30 " be being stripped out so the “30” and the epoch time are being concatenated? Or have I misunderstood the documentation?

If InfluxDB is rejecting it I would expect to see something in syslog at the time it tries to write. Anything there?

Also, have you done a logInfo with the string you are trying to write out? It’s a way to double check that it is appearing as you want.

Did anyone solve this?

I am using an API to retrieve river level data, which is timestamped. I would like to persist it with the time stamp of when it was created, not when I retrieved it.

Hopefully it would also allow me to store data for the future. I use the Octopus API to retrieve my variable electricity price for the forthcoming 24 hours. At the moment, I store the values in an array using a rule but persisting them to Influxdb would make them more accessible and allow me to look back at the rates over time.

I didn’t pursue this any further though I seem to remember someone else had got a similar rule working for a different requirement. I’ll see if I can find it again.

I use a batch file to write S.M.A.R.T. data to InfluxDB. Every 2 hours it writes 120 entries to the database with the correct time and value.

Maybe you can use it to get some inspiration to write a OH rule.

#!/bin/bash
#
# INSERT temp,host=hc2-4,disk=/dev/sda value=32 1559913487
# SELECT "host", "disk", "value" FROM "temp"

newline=$'\n'
smart_data=$(/usr/sbin/smartctl -l scttemphist -d sat /dev/sda|grep "*"|awk '{print $2" "$3" "$4}')
while read -r dat tim temp; do
    if echo "$dat" | grep '..('; then
        if echo "$dat" |grep '..(1'; then
            tim=`echo "$dat" | grep -o "[0-9]\+"`
        fi
        for ((number=1;number < $tim+1;number++)); do
            ((epoch+=60))
            influx_data+="temp,host=$(hostname),disk=/dev/sda value=$old_temp $epoch$newline"
        done
    else
        old_temp=$temp
        epoch=$(date -d "$dat $tim" +%s)
        influx_data+="temp,host=$(hostname),disk=/dev/sda value=$temp $epoch$newline"
    fi
done <<< "$smart_data"
curl -i -XPOST 'http://your.influxdb.server:8086/write?db=gluster_db&precision=s' --data-binary "$influx_data"

Thanks both.

Doing a bit more research, I found that you can write to the persistence service, including a timestamp, using the Openhab REST API, which can be called from a rule. The documentation isn’t great but the API Explorer makes it simple to format the right HTTP request. Good thing is the timestamp format in the persistence API is the same as the incoming timestamp on the data so I can process it as a string, which is good because date/time isn’t the easiest in rules.

My problem at the moment is I’m getting a “Persistence service cannot be modified error” but there’s another thread on that.