Changed behaviour of "UNDEF" states since 5.0.1

running OH5.0.1 in Docker.

Did something change from 5.0 to 5.0.1? All of a sudden all of my rules won’t work anymore, if I compare values of items with “UNDEF”.

My use case is simple: If I “unset” an item, I use “UNDEF” for it. So I know, it’s UNDEF and not NULL. Which again in my rules I do ask like this:

console.debug("EMS_CmdMinSoC: " + items.getItem("EMS_CmdMinSoC").numericState);

if (items.getItem("EMS_CmdMinSoC").numericState != "UNDEF") {
  // do something
}

which results into this log:

2025-08-25 15:44:00.349 [DEBUG] [i.EmsExternalBatteryManagementUpdate] - EMS_CmdMinSoC: null

My expectation would be to get the exact state I get, when I ask via UI/API:

http://192.168.78.20:8080/rest/items/EMS_CmdMinSoC/state

Response body
UNDEF

Is there any way to achieve the differentiation between “NULL” and “UNDEF” in JS Scripting (ECMA Script 262 Edition 11)?

PS: behaviour doesn’t change, if I use .state instead of .numericState

I’m surprised this ever worked.

From the docs:

.numericState ⇒ number|null: State as number, if state can be represented as number, or null if that’s not the case

UNDEF cannot be represented as a number so that would return null and null != "UNDEF" is true.

If you want to test for NULL and UNDEF you would use:

if(item.getItem("EMS_CmdMinSoC").isUninitialized) {

or to be a little less self documenting:

if(item.getItem("EMS_CmdMinSoC").numericState !== null) {

To test just for UNDEF you would use:

if(items.getItem("EMS_CmdMinSoC").state == "UNDEF") {

That’s what you get when you call .state. But when you call .numericState or .quantityState you get null back if the state of the Item is not a Number or a QuantityType. As far as I know this is how .numericState and .quantityState has always worked so it’s odd this code worked before. It shouldn’t have ever worked.

Show that code. .state always returns the state of the Item as a String. It never returns null.

no, that’s what bothers me, both .numericState and .state return “null” (but only since 5.0.1):

console.debug("EMS_CmdMinSoC: " + items.getItem("EMS_CmdMinSoC").state);
2025-08-25 17:11:40.795 [DEBUG] [i.EmsExternalBatteryManagementUpdate] - EMS_CmdMinSoC: null

If I can’t test for “UNDEF” apart from “NULL”, but both act the same regardless, why is there those two states possible in OH5 in the first place?

in <5.0.1 I got a “true/false” for both .state and .numericState

This did indeed change in 5.0.1. I’ve filed an issue:

https://github.com/openhab/openhab-js/issues/462

The old behavior with .numericState and .quantityState was incorrect. They always should have returned null when the Item’s state was NULL or UNDEF. But .state should always return the state as a String, even if it’s NULL or UNDEF so that is a regression.

In the mean time you can work around the problem by installing the openhab node module and toggling on “Do not cache…” in the JS Scripting settings. Then edit $OH_CONF/automation/js/node_modules/src/items/items.js and remove the line that calls _isNullOrUndefined(rawState) from _stateOrNull. It should be around line 27. The function should look like:

function _stateOrNull (rawState) {
  if (rawState === null) return null;
  return rawState.toString();
}

Or you can change your rules to use the rawState.

console.debug("EMS_CmdMinSoC: " + items.getItem("EMS_CmdMinSoC").rawState.toString());
1 Like

bit of a work, but seems feasible. Thanks as usual, Rich!