historicState Date format error (OH3.1)

Hi,
need bit of help with time … again (still quite confused)
So here is the thing, I’m aware of this topic, which helped in many cases

Now I’m trying to do lastMonth metering summary, which simply still complains about Dates.
So I need first day of last month and last day of last month

  val ZonedDateTime zdt = ZonedDateTime.now()
  val ZonedDateTime tst = zdt.toLocalDate().atStartOfDay(zdt.getOffset())
  
  val startDate  = tst.minusMonths(1).withDayOfMonth(1).withHour(0).withMinute(0).withSecond(0)
  val endDate    = tst.withDayOfMonth(1).withHour(0).withMinute(0).withSecond(0).minusMinutes(1)

  val startDate2 = now.minusMonths(1).withDayOfMonth(1).withHour(0).withMinute(0).withSecond(0)
  val endDate2   = now.withDayOfMonth(1).withHour(0).withMinute(0).withSecond(0).minusMinutes(1)

Both works, 2nd version is producing ugly fomat as

2021-12-01T00:00:00.427296+01:00[Europe/Prague]
2021-12-31T23:59:00.427296+01:00[Europe/Prague]

So let’s say Start/EndDate is better than Start/EndDate2

Then I want to extract data from persistence:

val startTotal = PVE_Total.historicState(startDate))
val endTotal = PVE_Total.historicState(endDate))

but that is erroring to the:

failed: Cannot format given Object as a Date

Tried as well from Docs:

PVE_Total.historicState(parse("2021-12-01T00:00:00.000Z"))

but that errors as well

Can pls somebody kick me to see what am not seeing? THanks

What doc did you see that in? I think you always have to say what you are trying to parse something into.

Who says that? Please give full error messages.

So far as I can see, your startDate should be a LocalDateTime type object? I’m not sure if historicState() will accept that type.

I guess historicState is same as minimumSince in terms of logic … maybe not

2022-01-11 14:42:50.494 [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID 'x_system-13' failed: Cannot format given Object as a Date in x_system

No idea which datetype historicstate wants, as i was not able to find what’s wrong.
For example in other rule I’m using this

val lst = (myItem.historicState(now.withYear(now.getYear - 1)).state as Number).floatValue

which works just fine… so maybe I need to define start/end somehow differently

hmmmm do i need to change that to the:

val startTotal = (PVE_Total.historicState(startDate)).state as Number).floatValues

damn… yes, sometimes forum help just to see it differently from VSC :slight_smile:

  val startTotal = (PVE_Total.historicState(startDate).state as Number).floatValue

works … :wink:

not sure if documentation is correct as there is

PowerMeter.historicState(now.truncatedTo(ChronoUnit.DAYS).withDayOfMonth(1))

seems like .state is needed

Only if you want to use the state. historicState() returns a complex object, which has state and timestamp elements to choose from.

well then it’s strange that this basically defines timestamp by startDate anyway

val startTotal = PVE_Total.historicState(startDate)

results in “failed: Cannot format given Object as a Date”

but this

  val startTotal = (PVE_Total.historicState(startDate).state as Number).floatValue

works without errors

maybe slight adjustments in documentation would be handy, anyway this community always helps :wink:

Well, the documents do actually show that you should be using a ZonedDateTime as the argument you pass to historicState and you get back a HistoricItem.

<item>.historicState(ZonedDateTime) Retrieves the State of an Item at a certain point in time (returns HistoricItem)

It goes on to state that

The most useful methods of the HistoricItem object returned by some queries, are .state and .getTimestamp

What needs to be adjusted here?

Assuming what you want is the state of PVE_Total at the startDate, the one that works without errors is the only documented way to get that. As rossko57 says HistoricState is a complex Object consisting of both a state and a timestamp. You can’t use it as if it were a number nor can you use it as if it were a state.

I can’t guess what that error means. There is no context and with the information supplied so far it’s not even certain that it is that line of code that is generating the error as opposed to some line you have later in the rule that tries to use startTotal in a String or to do some math with. It is an odd error but I see no reason why it should occur on that particular line by itself.

The timestamp I was talking about, belonging to the return object, is not the same as the one supplied by you and used to query.
Think about it, it’s really unlikely that any record exists for the exact millisecond that you requested. So the service returns you the next-oldest record with a datestamp of the actual record.

logInfo("test", "Querying " + startDate.toString)
val startRecord = PVE_Total.historicState(startDate)
logInfo("test", "My record state " + startRecord.state.toString)
logInfo("test", "My record stamp " + startRecord.getTimestamp.toString)