Timeseries and current state

Hello All,

I’m still missing something about timeseries functionnality, and how to handle the current state of an item with time series properly.

Let me explain my case:

I’ve got a monthly energy consumption data from an energy provider, with historical value for month M-2, M-1, and current Month.
If I push data to timeseries, using the sendTimeSeries function, I’ve got the following result in influx DB

0    Conso_Month     value 2387.121        2025-01-01T03:40:04.046Z
1    Conso_Month     value 2666.551        2025-02-01T03:38:46.296Z
2    Conso_Month     value  1284.02        2025-03-01T04:12:09.610Z

And when asking the rest persistence service:

rest/persistence/items/Conso_Month?
                      serviceId=influxdb&
                      &starttime=2024-09-15T14%3A11%3A49.935Z
                      &endtime=2025-03-31T18%3A11%3A49.902Z
                      &boundary=false
                      &itemState=true
{
   "name": "Linky_Melody_Monthly_Conso_Month",
   "datapoints": "3",

    "data": [
       {
          "time": 1735686000000,
          "state": "2387.121"
       },
       {
           "time": 1738364400000,
           "state": "2666.551"
       },
       {
           "time": 1740783600000,
           "state": "1284.0230000000001"
       }
   ]
}

So everything is ok in this case.
But if I try to display the current state of the item, I’ve got a null value because i’ve don’t do any updateState call.

If now, I’ve update my code to make an updateState call:

updateKwhChannel(MONTHLY_GROUP, CHANNEL_CONSUMPTION, values.monthValue[idxCurrentMonth].value);
updateTimeSeries(MONTHLY_GROUP, CHANNEL_CONSUMPTION, values.monthValue, true);

I’ve now have the following result in InfluxDB

0    Conso_Month     value 2387.121        2025-01-01T03:40:04.046Z
1    Conso_Month     value 2666.551        2025-02-01T03:38:46.296Z
2    Conso_Month     value  1284.02         2025-03-01T04:12:09.610Z
3    Conso_Month     value  1284.02         2025-03-16T13:12:57.446Z

Line 2 is coming from the sendTimeSeries.
Line 3 is coming from the updateState call.

If I try to display the current value, I’ve got the correct result : 1284.02 which is the currentState.
But if I call the rest persistence service:

rest/persistence/items/Conso_Month?
                      serviceId=influxdb&
                      &starttime=2024-09-15T14%3A11%3A49.935Z
                      &endtime=2025-03-31T18%3A11%3A49.902Z
                      &boundary=false
                      &itemState=true
{
   "name": "Linky_Melody_Monthly_Conso_Month",
   "datapoints": "3",

    "data": [
       {
          "time": 1735686000000,
          "state": "2387.121"
       },
       {
           "time": 1738364400000,
           "state": "2666.551"
       },
       {
            "time": 1740783600000,
            "state": "1284.0230000000001"
       },
       {
             "time": 1742113051179,
             "state": "1284.0230000000001"
       },
       {
             "time": 1742113176648,
             "state": "1284.0230000000001"
       }   
     ]
}

I’ve got 3 lines for the last month entry !
The first one is coming from the sendTimeSeries call.
The second one is coming from the updateState call, timestamp correspond to this call.

And for the last one, it is generated by the parameters “itemState=true” in the URL call.
When I refresh the rest call, the timestamp for the third entry change every time.

I’ve even try to not send the current month value to sendTimeSeries.
I Still have a duplicate line in rest call for the current itemState

{
   "name": "Linky_Melody_Monthly_Conso_Month",
   "datapoints": "3",

    "data": [
       {
          "time": 1735686000000,
          "state": "2387.121"
       },
       {
           "time": 1738364400000,
           "state": "2666.551"
       },
       {
            "time": 1742113960507,
            "state": "1284.0230000000001"
       },
       {
             "time": 1742113993275,
             "state": "1284.0230000000001"
       }
      ]
}

First one is when I call the updateState, and the last one with updating timestamp on each refresh !
This is a little better because I’ve don’t have a duplicate entry in my graph, but the last entry displayed on the graph is with timestamp of the updateState called, so give a strange graph with a empty space between month -1 and currentMonth. So not very great !

So my question is why I have duplicate entries between entry 2 and entry 3.
For me openhab rest call should answer only the 3 entry, no ?

If someone can help me to understand what I missing there.

Full code is available there :slight_smile:

Thanks,
Laurent.

Sure this topic is for your binding but I would suggest this is more for the development category.

I think I see what you want to achieve but check if I made wrong assumptions.
Let’s analyze step-by-step

TimeSeries

That’s not the root cause why state value is null. The above TimeSeries starts 1st Jan and ends 1st March. For March 16th there’s no value inside the TimeSeriers so it’s null.

My proposal:

  • remove updateState call
  • add an addtional element in your TimeSeries with timestamp LATEST_TIMESTAMP.plus(1,ChronoUnit.MONTHS) and value 0

This should solve all your further topics below!

Sidenote
The delivered TimeSeries looks quite awkward. I mean value

0    Conso_Month     value 2387.121        2025-01-01T03:40:04.046Z

is the complete consumption from Jan, right? And timestamp is Jan 1st? Shouldn’t it be Jan 31st? Also

2    Conso_Month     value  1284.02        2025-03-01T04:12:09.610Z

is till March 16th and timestamp is March 1st? Looks like consumption is adding up at the beginning of the month.

Graph

This has also to do with the delivered timestamps. First value 01.01. second 01.02. (31 days), third 16.03. (45 days) => bigger gap. If you deliver TimeSeries as proposed with 0 value for the next month this should be corrected also.

Hello Weumann,

I will try your suggestion to remove the updatState and add an extra value to the timeseries at the end.This seems a good idea.

You’ re right about timestamp, would be better if it’s aligned to end of month, and not at start.
I will review my code to do this. This is because currently I get consumption for each day, and sum them to get cunsomption for week, month, and year. But I take the first timestamp for a period, not the last timestamp of value of the period.

And yes, the consumption is adding up every day for the current month as I refresh the timeseries every night by replacing values. It’s currently working ok except this state / last value of series.

I will give a try to your suggestion, and let you know if it fix it like this.

Laurent.

As first step stay on your timestamps which you already have in place and only check the changes as I proposed with 0 value at April 1st and removal of updateState.

Hello weymann,

I’ve do not take time to test your solution so far, mainly because I experience another problems with time series.

I don’t know if you are familliar with time series implementation ? And certainly this is not the good place for this, let me know, I will reopen another thread and / or ticket somewhere else if need.

What happens in this new issue, is that sometimes, when I start openhab, my timeseries are correctly initialized, and sometime not, or even sometime half of them.

I’ve got four different time series, one for Daily, one for Weekly, one for Monthly and one for Yearly.

First I was thinking it was comming from my code, but don’t undestand why.
So I’ve take some time to trace the issue, and find something strange:

I put a trace on GenericItem::applyTimeSeries(), and one another trace in PersistenceManageImpl:timeSeriesUpdated().

Normally, appyTimeSeries should called PersistentManagerImple.timeSeriesUpdated().

But what I find is that sometimes, the timeSeriesListeners in applyTimeSeries is not initialize when applyTimeSeries is called.It seems to come mainly of the fact that there is a lot of item in the registry, and the loop in PeristenceManagerImpl:allItemsChaned is not fully end at this point :

@Override
public void allItemsChanged(Collection oldItemNames) {
itemRegistry.getItems().forEach(this::added);
}

Of course, I can delay a little bit my addon initialization to prevent this condition.
But it seems strange that there is not some sort of locking / protection in the PersistenceManagerImpl to prevent this.

What do you think about this ?

Laurent.

Something more.

What is very strange is that addingListener is done on a very low startLevel.
Seems to be 20, from persistence:restore marker.

And my binding is set to startLevel 80.
May be we hit a start level configuration issue in dev environnent ?

Will not be the first time, I remember to have done some modification last december for something like this : Update services.cfg by lo92fr · Pull Request #1697 · openhab/openhab-distro · GitHub.

Laurent.

Hard to say but the forum reports several startup issues. So my stomach feeling this isn’t about a TimeSeries issue.

An issue on my solarforecast binding is reported which stalls the startup at level 70.
After analysis it’s on openhab-core to solve this.

Hello weymann,

After tracing more in details, I’ve openned an issue on openhab core:

Hello weymann,

I’ve tested your solution to add another value = 0 in the timeseries with a future timestamp. That don’t change anything, the items currentSate stay to null. I also try with a value <>0 in case, but same result, state stay to null.

After a few more test, I find something else strange.

If I stay as before, sending only the timeseries, and not updating the state.

At first, the state value is null after the timeseries update.

But if I restart Openhab, even if I don’t do any modifications on the timeseries after the restart, then the state of the item is initialized to the last value of the time series.

I thinks this certainly come from something in the persistence:restore task on restart, but so far don’t trace it to understand what’s happening.

Definitively very strange behavior.

Laurent