How to get rid of Item states UNDEF or NULL in Main UI

Hello,
I am struggling to prevent widgets in Main UI from displaying item states like UNDEF or NULL.
I understand that it’s not possible in the Model view in Administration but I have hoped to get rid of by using Javascript Transformation in the Pattern Parameter of State Description of an Item.
For testing I have used an Item linked to the Incoming_Call channel of a Fritz!Box Thing (AVM Fritz!Box binding). The item shows UNDEF as state when there is no call.

As Pattern I used

JS(SuppressUNDEF.js):%s

with a simple Javascript

(function(i) {
	var logger = Java.type("org.slf4j.LoggerFactory").getLogger("org.openhab");
	logger.info(i);	
	if (i == "-" || i == "UNDEF") {
		logger.info("=UNDEF");
		return "yyyyyyUNDEF"
		}
	logger.info("!=UNDEF");
	return "xxxxxxx!UNDEF"
})(input)

The widgets in the Main UI page are picked from the Model. For comparision I have built a sitemap with the same item.

First thing I have observed by the logger output from line 3 is that the input for the function is different for Main UI pages and sitemaps for the value UNDEF.
For sitemaps I have to compare to a dash, for Main UI pages to UNDEF.

In a sitemap the code works as expected showing yyyyyyUNDEF when there is no call

Sitemap_UNDEF

and xxxxxxx!UNDEF when the calling number is handed over as input to the Javascript.

Sitemap_CallingNumber

But in Main UI the result is only as planned when there is a calling number.

I can see that the compare to UNDEF works because I can see the log entry =UNDEF from line 5 but the widget still shows the value UNDEF and not the string form the return instruction in line 6.

Thanks for any hint how to get this working in Main UI

Rainer

1 Like

Have you applied this transformation on the Item’s State Description? MainUI does not use the label field of a textual Item definition. You have to set the pattern field in the State Description Item metadata. The format of that field is the same as what you would put between the [ ] for the label field of an Item’s text definition.

Yes, it’s in the State Description:

OK, so you know that the JS transformation is running.

You know that it’s running the log statement that prints =UNDEF.

Based on your last screen shot it’s executing that last return not the one immediately after the log statement.

One thing I’ve noticed is that return statements don’t always work as expected in Nashorn JavaScript.

Another thing I notice is you don’t have a semicolon after the return statements.

So I would first try adding semicolons after both return statements. If that doesn’t change anything put the last two lines in the function inside an else.

Thanks for the suggestions.

I have initially tried it with else but without logging. I have tried now first with additional semicolon:

(function(i) {
	var logger = Java.type("org.slf4j.LoggerFactory").getLogger("org.openhab");
	logger.info(i);	
	if (i == "-" || i == "UNDEF") {
		logger.info("=UNDEF");
		return "yyyyyyUNDEF";
		}
	logger.info("!=UNDEF");
	return "xxxxxxx!UNDEF";
})(input)

That gives me the same result with Main UI showing UNDEF and the following logging (added comments in front)

Value from Input ->           2021-08-30 18:50:32.057 [INFO ] [org.openhab                         ] - UNDEF
Logging inside If ->          2021-08-30 18:50:32.060 [INFO ] [org.openhab                         ] - =UNDEF
Value from Input when call -> 2021-08-30 18:53:18.102 [INFO ] [org.openhab                         ] - 97XXXXX,017XXXXXXXX
Logging outside If ->         2021-08-30 18:53:18.104 [INFO ] [org.openhab                         ] - !=UNDEF

And a transformed ouput as expected in sitemap with the logging below:

Value from Input ->           2021-08-30 19:01:12.540 [INFO ] [org.openhab                         ] - -
Logging inside If ->          2021-08-30 19:01:12.542 [INFO ] [org.openhab                         ] - =UNDEF
Value from Input when call -> 2021-08-30 19:02:15.749 [INFO ] [org.openhab                         ] - 97XXXXX
Logging outside If ->         2021-08-30 19:02:15.751 [INFO ] [org.openhab                         ] - !=UNDEF

Then I tried with else

(function(i) {
	var logger = Java.type("org.slf4j.LoggerFactory").getLogger("org.openhab");
	logger.info(i);	
	if (i == "-" || i == "UNDEF") {
		logger.info("=UNDEF");
		return "yyyyyyUNDEF";
	}
	else {
		logger.info("!=UNDEF");
		return "xxxxxxx!UNDEF";
	}
})(input)

Same result fort both Main UI and Sitemap
(don’t mind the difference in the log between Main UI and Sitemap. The Item state changes twice showing first only the callee number then callee and caller. Maybe the first status change isn’t always recognized)

As an additional info: I’ve got the idea when reading a forum post about the item state NULL for Group Items. A proposed solution was to but a blank in the transform pattern. That hasn’t worked for me either.

I have tried now it with a customized Javascript testing for NULL now and the result is identical. It works with sitemaps but won’t in Main UI.

Log out i in the transform to make sure you understand exactly what the transform is processing.

Does your Item have ‘state options’ metadata set by whatever binding it is linked to?

Querying the item with the rest API it looks different for me. Options is empty for both Items

{
  "link": "https://homeauto01.fritz.box:8443/rest/items/FRITZBox7560_EingehenderAnruf",
  "state": "UNDEF",
  "transformedState": "yyyyyyUNDEF",
  "stateDescription": {
    "pattern": "JS(SuppressUNDEF.js):%s",
    "readOnly": true,
    "options": []
  },
  "editable": true,
  "type": "Call",
  "name": "FRITZBox7560_EingehenderAnruf",
  "label": "Incoming Call",
  "category": "",
  "tags": [
    "Point"
  ],
  "groupNames": []
}
{
  "members": [],
  "link": "https://homeauto01.fritz.box:8443/rest/items/Zuhause",
  "state": "NULL",
  "transformedState": " ",
  "stateDescription": {
    "pattern": "JS(SuppressNULL.js):%s",
    "readOnly": false,
    "options": []
  },
  "editable": true,
  "type": "Group",
  "name": "Zuhause",
  "label": "Zuhause",
  "category": "",
  "tags": [
    "Location"
  ],
  "groupNames": []
}

Remember that Items are born with state NULL. I don’t think transformed state appears initially, something has to happen. Hopefully an attempt to read is enough, or you can never fix NULL.

Good to eliminate [options] from the picture.

1 Like

The first log output immediately before the if clause logs the value of i. I have put another logging for i inside the if clause. At both point in Main UI it’s a string exactly as displayed in the UI (UNDEF for one item, NULL for the other item) and also given by querying he item with the rest API.

When the transformation script is executed for a Sitemap, i is in both cases a dash and the transformation is applied to the ouput.

I am not sure about that. I can see the logging from the transformation before the Main UI page with the item is displayed. For testig purposes I have set up an Overview page with only cells with a link to other pages. The first logging entries appear before I have followed a link to a page that displays the item.

And for the item with the state UNDEF it should then display the transformed state when the calling is cancelled. But it’s still showing UNDEF.

Looking again, you DO have a "transformedState": " " of course, one space. Your transformations are working fine, but your widget is using raw state. End of my knowledge about MainUI. You’ll probably need to show what you’ve set for default widget on the Item (sitemap based UI doesn’t use any of that).

Yes, that’s right the rest query shows the result of the transformations.

I have not set any metadata besides the Transform Pattern in State Description.

So when adding a cell to Main UI by picking an item it’s using the default oh-label-cell for blocks

For testing I have added a masonry to get a different widget component. It’s oh-label-card then but the result is unchanged.

config:
  layoutType: responsive
  label: Test Main UI
blocks:
  - component: oh-block
    config: {}
    slots:
      default:
        - component: oh-grid-cells
          config: {}
          slots:
            default:
              - component: oh-label-cell
                config:
                  action: group
                  actionGroupPopupItem: Zuhause
                  item: Zuhause
                  title: Zuhause
                  stateAsHeader: true
                  expandable: false
              - component: oh-label-cell
                config:
                  item: FRITZBox7560_EingehenderAnruf
                  title: Incoming Call
                  stateAsHeader: true
                  expandable: false
              - component: oh-label-cell
                config:
                  item: LokaleZeit_Zeit
                  stateAsHeader: true
                  expandable: false
                  title: Time
masonry:
  - component: oh-masonry
    slots:
      default:
        - component: oh-label-card
          config:
            action: group
            actionGroupPopupItem: Zuhause
            item: Zuhause
        - component: oh-label-card
          config:
            item: FRITZBox7560_EingehenderAnruf
grid: []

As said, I don’t know much about MainUI but (raw) .state and (transformed) .displayState are both available.