Get historicState of an item without Unit in JS Scripting

Using openHAB 3.4-release.

I’m trying to get the value of an item without unit. That works with the current state, but not with an historic state?

var PVLeistung = items.getItem("KOS_PVPower").rawState.intValue();
var PVLeistung10Unit = items.getItem("KOS_PVPower").history.historicState(interval10mins);
var PVLeistung10 = items.getItem("KOS_PVPower").history.historicState(interval10mins).intValue();

console.log("current PV power: " + PVLeistung);
console.log("PV power 10 mins ago (UoM): " + PVLeistung10Unit);
console.log("PV Power 10 mins ago (Int): " + PVLeistung10);

this leads to:

2023-03-28 20:23:21.080 [INFO ] [ab.automation.script.ui.evccDetectEV] - current PV power: 0
2023-03-28 20:27:33.345 [INFO ] [ab.automation.script.ui.evccDetectEV] - PV power 10 mins ago (UoM): 0 W
2023-03-28 20:23:21.132 [ERROR] [b.automation.script.javascript.stack] - Failed to execute script:
org.graalvm.polyglot.PolyglotException: TypeError: (intermediate value).getItem(...).history.historicState(...).intValue is not a function
...
2023-03-28 20:23:21.148 [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID 'evccDetectEV' failed: org.graalvm.polyglot.PolyglotException: TypeError: (intermediate value).getItem(...).history.historicState(...).intValue is not a function

How can I get an historicState without Units?

historicState() returns a HistoricItem object, not just a state value:

I don’t remember if the HistoricItem’s numericState is only 4.0 but you can try that or just plain rawState with the intValue() method.

hmmm. I tried this also, forgot to put in above:

var PVLeistung10 = items.getItem("KOS_PVPower").history.historicState(interval10mins).rawState.intValue();
2023-03-28 21:12:08.502 [ERROR] [b.automation.script.javascript.stack] - Failed to execute script:
org.graalvm.polyglot.PolyglotException: TypeError: undefined has no such function "intValue"
...
2023-03-28 21:12:08.520 [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID 'evccDetectEV' failed: org.graalvm.polyglot.PolyglotException: TypeError: undefined has no such function "intValue"

PS: .state delivers the state as String and .intValue() only works with rawState.

Correct, sorry about the mistype above. I’ll edit it.

That should work. The problem according to the error message:

Edit:
Means that your call to historicState(interval10mins).rawState is returning undefined.

Perhaps the change of the return value of historicState to a historicItem was more recent than I recall. What do you get if you dump the result of historicState?

console.log(utils.dumpObject(items.getItem("KOS_PVPower").history.historicState(interval10mins)));

I get this:

2023-03-29 08:08:29.834 [INFO ] [.openhab.automation.openhab-js.utils] - Dumping object...
2023-03-29 08:08:29.837 [INFO ] [.openhab.automation.openhab-js.utils] -   typeof obj = string
2023-03-29 08:08:29.839 [INFO ] [.openhab.automation.openhab-js.utils] -   Java.isJavaObject(obj) = false
2023-03-29 08:08:29.849 [INFO ] [.openhab.automation.openhab-js.utils] -   Java.isType(obj) = false
2023-03-29 08:08:29.851 [INFO ] [.openhab.automation.openhab-js.utils] -   string value = 431.82080993652346 W
2023-03-29 08:08:29.853 [INFO ] [g.openhab.automation.script.ui.test2] - undefined

If I do this:

console.log(utils.dumpObject(items.getItem("KOS_PVPower")));

then it’s a “real” object, I guess:

2023-03-29 08:09:49.463 [INFO ] [.openhab.automation.openhab-js.utils] - Dumping object...
2023-03-29 08:09:49.465 [INFO ] [.openhab.automation.openhab-js.utils] -   typeof obj = object
2023-03-29 08:09:49.467 [INFO ] [.openhab.automation.openhab-js.utils] -   Java.isJavaObject(obj) = false
2023-03-29 08:09:49.469 [INFO ] [.openhab.automation.openhab-js.utils] -   Java.isType(obj) = false
2023-03-29 08:09:49.504 [INFO ] [.openhab.automation.openhab-js.utils] -   getOwnPropertyNames(obj) = rawItem,history,semantics
2023-03-29 08:09:49.630 [INFO ] [.openhab.automation.openhab-js.utils] -   getAllPropertyNames(obj) = rawItem,history,semantics,constructor,type,name,label,state,rawState,members,descendents,isUninitialized,getMetadataValue,updateMetadataValue,upsertMetadataValue,updateMetadataValues,sendCommand,sendCommandIfDifferent,getToggleState,sendToggleCommand,postToggleUpdate,postUpdate,groupNames,addGroups,removeGroups,tags,addTags,removeTags,__proto__,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf,__defineGetter__,__defineSetter__,__lookupGetter__,__lookupSetter__
2023-03-29 08:09:49.631 [INFO ] [g.openhab.automation.script.ui.test2] - undefined

Well, that settles it.

Apparently the update to a historicItem return value was only 4.0. Because you are on 3.4, you’re getting the old stringified state return value instead. If you want that as a number without units you just need:

Number.parseFloat(items.getItem("KOS_PVPower").history.historicState(interval10mins))

which will automatically strip any non-numerical characters that follow the number in the string.

1 Like

I’m assuming this will still work in 4.0?

No, that’s the breaking change with historicState. With the newest helper library, it will start to return the object instead of the string and you’ll need to adjust the code to get the state from the historicItem object.

1 Like

Thanks for the heads up. OK, rewriting my rules for 4.0 it is! :wink: