SSE / not seeing visibility changes in sitemap

  • Platform information:

    • OS: Latest Debian Docker Image
    • openHAB version: 2.5.4
  • Issue of the topic: Unable to subscribe (see) changes in “visibility” in sitemaps (SSE / REST API)

  • Please post configurations:
    This snippet works fine with classicui, and if I change SCP3 (from any client), classicui updates correctly:

Switch item=SCP3 label=“Rain Daily Accumulated” mappings=[1=“Hour”, 2=“Day”, 3=“Week”, 4=“Month”, 5=“4 Months” ] icon=“rain”
Chart item=Sensor_Garden_Rain_Daily period=h refresh=10000 service=“rrd4j” visibility=[SCP3==1,SCP3==“Uninitialized”]
Chart item=Sensor_Garden_Rain_Daily period=D refresh=10000 service=“rrd4j” visibility=[SCP3==2]
Chart item=Sensor_Garden_Rain_Daily period=W refresh=10000 service=“rrd4j” visibility=[SCP3==3]
Chart item=Sensor_Garden_Rain_Daily period=M refresh=10000 service=“rrd4j” visibility=[SCP3==4]
Chart item=Sensor_Garden_Rain_Daily period=4M refresh=10000 service=“rrd4j” visibility=[SCP3==5]

Using various combinations of http://servername:8080/rest/events I never see anything showing visibility has changed for elements within a sitemap, just the switch itself:

event: message
data: {“topic”:“smarthome/items/SCP3/state”,“payload”:“{"type":"Decimal","value":"4"}”,“type”:“ItemStateEvent”}

event: message
data: {“topic”:“smarthome/items/SCP3/statechanged”,“payload”:“{"type":"Decimal","value":"4","oldType":"Decimal","oldValue":"3"}”,“type”:“ItemStateChangedEvent”}

I found that if I added “?includeHidden=true” to querying the contents of a sitemap, the non-visible elements were included in the sitemap, but that only gets me half way as I also need to know when visibility changes for these elements.

Advise?

PS: The swagger at http://demo.openhab.org:8080/doc/index.html#/ does not show documentation for /rest/events ?

Don’t you want to look at the items directly vs the sitemap. Haven’t looked at rest api but I am asking are you using the correct key?

Is there an item value key?

No, because they are all the same item, ‘item=Sensor_Garden_Rain_Daily’ so the item itself does not change. The period to render in sitemap changes, “period=?”.

In other words, I think I need to track changes to a sitemap, not items, but don’t know how to do this, and can’t find documentation for this.

Can you fix the first post with code fences. It’s a button at the top in the editor. Paste the code in the paste code here spot. It allows for readability.

Also post item definition for period or did I miss that?

? you missed that, and its “fenced” in original post i made… Maybe your client is not rendering correctly?

Yes I see it is fenced. I have had this where a quote knocks it all off. On my phone it is unreadable. My laptop it is better.

You may have a browser refresh issue, basic ui has been known to have this.

That is as expected. The visibility isn’t something that generates an event on the event bus. I believe it’s something implemented wholly within the browser in the UI’s JavaScript. Subscribing to events you should see SCP3 changing and that’s it.

There is no way to get an event for when an element is visible or hidden. You would have to just use the state of SCP3 as a proxy for that.

I don’t think that is a swagger end point but the websocket endpoint. It’s typically only something that a UI needs to worry about as that is where the events are published that are used to update the UI as Item’s change state.

I too think you’re right in that its the UI Client’s to keep track of visibility, but your response is missing how it’s done.

Let me show you with an example with a simple sitemap that works correctly with the classic UI:

sitemap test1 label="Test1" {
  Text label="Graph1"
  {
    Switch item=SCP3 label="Rain (last 1 min)" mappings=[1="Hour", 2="Day", 3="Week", 4="Month", 5="4 Months" ]
    Chart item=Sensor_Garden_Rain period=h  refresh=10000 service="rrd4j" visibility=[SCP3==1,SCP3=="Uninitialized"]
    Chart item=Sensor_Garden_Rain period=D  refresh=10000 service="rrd4j" visibility=[SCP3==2]
    Chart item=Sensor_Garden_Rain period=W  refresh=10000 service="rrd4j" visibility=[SCP3==3]
    Chart item=Sensor_Garden_Rain period=M  refresh=10000 service="rrd4j" visibility=[SCP3==4]
    Chart item=Sensor_Garden_Rain period=4M refresh=10000 service="rrd4j" visibility=[SCP3==5]
  }

  Text label="Graph2"
  {
    Chart item=Sensor_Garden_Rain_Daily period=h  refresh=10000 service="rrd4j" visibility=[SCP3==1,SCP3=="Uninitialized"]
    Chart item=Sensor_Garden_Rain_Daily period=D  refresh=10000 service="rrd4j" visibility=[SCP3==2]
    Chart item=Sensor_Garden_Rain_Daily period=W  refresh=10000 service="rrd4j" visibility=[SCP3==3]
    Chart item=Sensor_Garden_Rain_Daily period=M  refresh=10000 service="rrd4j" visibility=[SCP3==4]
    Chart item=Sensor_Garden_Rain_Daily period=4M refresh=10000 service="rrd4j" visibility=[SCP3==5]
  }
}

Downloading the sitemap using Chrome via the API as the UI Client would do: http://ohserver:8080/rest/sitemaps/test1?includeHidden=true

Bit long, but expanded the result using Free Online JSON Formatter - FreeFormatter.com to make it readable, and show that there is nothing linking the switch SCP3 to any of the charts.

{
“name”: “test1”,
“label”: “Test1”,
“link”: “http://ohserver:8080/rest/sitemaps/test1”,
“homepage”: {
“id”: “test1”,
“title”: “Test1”,
“link”: “http://ohserver:8080/rest/sitemaps/test1/test1”,
“leaf”: false,
“timeout”: false,
“widgets”: [
{
“widgetId”: “00”,
“type”: “Text”,
“visibility”: true,
“label”: “Graph1”,
“icon”: “text”,
“mappings”: ,
“linkedPage”: {
“id”: “00”,
“title”: “Graph1”,
“icon”: “text”,
“link”: “http://ohserver:8080/rest/sitemaps/test1/00”,
“leaf”: true,
“timeout”: false,
“widgets”: [
{
“widgetId”: “0000”,
“type”: “Switch”,
“visibility”: true,
“label”: “Rain (last 1 min)”,
“icon”: “number”,
“mappings”: [
{
“command”: “1”,
“label”: “Hour”
},
{
“command”: “2”,
“label”: “Day”
},
{
“command”: “3”,
“label”: “Week”
},
{
“command”: “4”,
“label”: “Month”
},
{
“command”: “5”,
“label”: “4 Months”
}
],
“item”: {
“link”: “http://ohserver:8080/rest/items/SCP3”,
“state”: “3”,
“type”: “Number”,
“name”: “SCP3”,
“label”: “Graph”,
“tags”: ,
“groupNames”:
},
“widgets”:
},
{
“widgetId”: “0001”,
“type”: “Chart”,
“visibility”: false,
“label”: “Rainfall (last 1 min) [0.00 mm]”,
“icon”: “rain”,
“mappings”: ,
“refresh”: 10000,
“service”: “rrd4j”,
“period”: “h”,
“item”: {
“link”: “http://ohserver:8080/rest/items/Sensor_Garden_Rain”,
“state”: “0.00”,
“stateDescription”: {
“pattern”: “%.2f mm”,
“readOnly”: false,
“options”:
},
“type”: “Number”,
“name”: “Sensor_Garden_Rain”,
“label”: “Rainfall (last 1 min)”,
“category”: “rain”,
“tags”: ,
“groupNames”: [
“ALL”,
“Outdoor”
]
},
“widgets”:
},
{
“widgetId”: “0002”,
“type”: “Chart”,
“visibility”: false,
“label”: “Rainfall (last 1 min) [0.00 mm]”,
“icon”: “rain”,
“mappings”: ,
“refresh”: 10000,
“service”: “rrd4j”,
“period”: “D”,
“item”: {
“link”: “http://ohserver:8080/rest/items/Sensor_Garden_Rain”,
“state”: “0.00”,
“stateDescription”: {
“pattern”: “%.2f mm”,
“readOnly”: false,
“options”:
},
“type”: “Number”,
“name”: “Sensor_Garden_Rain”,
“label”: “Rainfall (last 1 min)”,
“category”: “rain”,
“tags”: ,
“groupNames”: [
“ALL”,
“Outdoor”
]
},
“widgets”:
},
{
“widgetId”: “0003”,
“type”: “Chart”,
“visibility”: true,
“label”: “Rainfall (last 1 min) [0.00 mm]”,
“icon”: “rain”,
“mappings”: ,
“refresh”: 10000,
“service”: “rrd4j”,
“period”: “W”,
“item”: {
“link”: “http://ohserver:8080/rest/items/Sensor_Garden_Rain”,
“state”: “0.00”,
“stateDescription”: {
“pattern”: “%.2f mm”,
“readOnly”: false,
“options”:
},
“type”: “Number”,
“name”: “Sensor_Garden_Rain”,
“label”: “Rainfall (last 1 min)”,
“category”: “rain”,
“tags”: ,
“groupNames”: [
“ALL”,
“Outdoor”
]
},
“widgets”:
},
{
“widgetId”: “0004”,
“type”: “Chart”,
“visibility”: false,
“label”: “Rainfall (last 1 min) [0.00 mm]”,
“icon”: “rain”,
“mappings”: ,
“refresh”: 10000,
“service”: “rrd4j”,
“period”: “M”,
“item”: {
“link”: “http://ohserver:8080/rest/items/Sensor_Garden_Rain”,
“state”: “0.00”,
“stateDescription”: {
“pattern”: “%.2f mm”,
“readOnly”: false,
“options”:
},
“type”: “Number”,
“name”: “Sensor_Garden_Rain”,
“label”: “Rainfall (last 1 min)”,
“category”: “rain”,
“tags”: ,
“groupNames”: [
“ALL”,
“Outdoor”
]
},
“widgets”:
},
{
“widgetId”: “0005”,
“type”: “Chart”,
“visibility”: false,
“label”: “Rainfall (last 1 min) [0.00 mm]”,
“icon”: “rain”,
“mappings”: ,
“refresh”: 10000,
“service”: “rrd4j”,
“period”: “4M”,
“item”: {
“link”: “http://ohserver:8080/rest/items/Sensor_Garden_Rain”,
“state”: “0.00”,
“stateDescription”: {
“pattern”: “%.2f mm”,
“readOnly”: false,
“options”:
},
“type”: “Number”,
“name”: “Sensor_Garden_Rain”,
“label”: “Rainfall (last 1 min)”,
“category”: “rain”,
“tags”: ,
“groupNames”: [
“ALL”,
“Outdoor”
]
},
“widgets”:
}
]
},
“widgets”:
},
{
“widgetId”: “01”,
“type”: “Text”,
“visibility”: true,
“label”: “Graph2”,
“icon”: “text”,
“mappings”: ,
“linkedPage”: {
“id”: “01”,
“title”: “Graph2”,
“icon”: “text”,
“link”: “http://ohserver:8080/rest/sitemaps/test1/01”,
“leaf”: true,
“timeout”: false,
“widgets”: [
{
“widgetId”: “0100”,
“type”: “Chart”,
“visibility”: false,
“label”: “Accumulated Daily Rainfall [0.84 mm]”,
“icon”: “rain”,
“mappings”: ,
“refresh”: 10000,
“service”: “rrd4j”,
“period”: “h”,
“item”: {
“link”: “http://ohserver:8080/rest/items/Sensor_Garden_Rain_Daily”,
“state”: “0.84”,
“stateDescription”: {
“pattern”: “%.2f mm”,
“readOnly”: false,
“options”:
},
“type”: “Number”,
“name”: “Sensor_Garden_Rain_Daily”,
“label”: “Accumulated Daily Rainfall”,
“category”: “rain”,
“tags”: ,
“groupNames”: [
“ALL”,
“Outdoor”
]
},
“widgets”:
},
{
“widgetId”: “0101”,
“type”: “Chart”,
“visibility”: false,
“label”: “Accumulated Daily Rainfall [0.84 mm]”,
“icon”: “rain”,
“mappings”: ,
“refresh”: 10000,
“service”: “rrd4j”,
“period”: “D”,
“item”: {
“link”: “http://ohserver:8080/rest/items/Sensor_Garden_Rain_Daily”,
“state”: “0.84”,
“stateDescription”: {
“pattern”: “%.2f mm”,
“readOnly”: false,
“options”:
},
“type”: “Number”,
“name”: “Sensor_Garden_Rain_Daily”,
“label”: “Accumulated Daily Rainfall”,
“category”: “rain”,
“tags”: ,
“groupNames”: [
“ALL”,
“Outdoor”
]
},
“widgets”:
},
{
“widgetId”: “0102”,
“type”: “Chart”,
“visibility”: true,
“label”: “Accumulated Daily Rainfall [0.84 mm]”,
“icon”: “rain”,
“mappings”: ,
“refresh”: 10000,
“service”: “rrd4j”,
“period”: “W”,
“item”: {
“link”: “http://ohserver:8080/rest/items/Sensor_Garden_Rain_Daily”,
“state”: “0.84”,
“stateDescription”: {
“pattern”: “%.2f mm”,
“readOnly”: false,
“options”:
},
“type”: “Number”,
“name”: “Sensor_Garden_Rain_Daily”,
“label”: “Accumulated Daily Rainfall”,
“category”: “rain”,
“tags”: ,
“groupNames”: [
“ALL”,
“Outdoor”
]
},
“widgets”:
},
{
“widgetId”: “0103”,
“type”: “Chart”,
“visibility”: false,
“label”: “Accumulated Daily Rainfall [0.84 mm]”,
“icon”: “rain”,
“mappings”: ,
“refresh”: 10000,
“service”: “rrd4j”,
“period”: “M”,
“item”: {
“link”: “http://ohserver:8080/rest/items/Sensor_Garden_Rain_Daily”,
“state”: “0.84”,
“stateDescription”: {
“pattern”: “%.2f mm”,
“readOnly”: false,
“options”:
},
“type”: “Number”,
“name”: “Sensor_Garden_Rain_Daily”,
“label”: “Accumulated Daily Rainfall”,
“category”: “rain”,
“tags”: ,
“groupNames”: [
“ALL”,
“Outdoor”
]
},
“widgets”:
},
{
“widgetId”: “0104”,
“type”: “Chart”,
“visibility”: false,
“label”: “Accumulated Daily Rainfall [0.84 mm]”,
“icon”: “rain”,
“mappings”: ,
“refresh”: 10000,
“service”: “rrd4j”,
“period”: “4M”,
“item”: {
“link”: “http://ohserver:8080/rest/items/Sensor_Garden_Rain_Daily”,
“state”: “0.84”,
“stateDescription”: {
“pattern”: “%.2f mm”,
“readOnly”: false,
“options”:
},
“type”: “Number”,
“name”: “Sensor_Garden_Rain_Daily”,
“label”: “Accumulated Daily Rainfall”,
“category”: “rain”,
“tags”: ,
“groupNames”: [
“ALL”,
“Outdoor”
]
},
“widgets”:
}
]
},
“widgets”:
}
]
}
}

There is nothing to show why a specific Chart is visible or not, it just true or false, as the logic itself is stripped out. How is the UI client supposed to figure out what to do when the state of SCP3 changes?

a) Is the way I download the sitemap incorrect and missing an attribute to include the logic?
b) does the UI need to subscribe to “something” to know the sitemap has changed (visibility) ?

You would have to look at the source code for BasicUI to see how it does it. But I can say that controlling what is and is not visible will be implemented using one or more generic JavaScript functions and or it’s implemented on the server side. If I were to guess, when the sitemap page is loaded, those rows with visibility are registered with a function that watches for events on the Items in the conditionals and shows/hides the rows as the Item changes state.

Remember, when you downloaded the sitemap via the API, all you’ve downloaded is the raw material that the HTML/JavaScript that actually runs and displays the sitemap uses to build up the screen you see. There won’t be any logic in that JSON, just definitions. You need to look at the source code, or at a minimum the sources that make up the webpage in your browser (or look on github).

Yes, that rest/events websocket you’ve already discovered. When the Item changes state it triggers something (again, I’m guessing a JavaScript function(s)) to change the visibility of those rows that use that Item to control it’s visibility.

Thanks for trying, unfortunately without any technical details, there’s not much here to go on. I’ll try reaching out to the devs on github and see if I get a better response there.

If anyone has technical details on how to see when visibility in sitemaps changes, not items, please do let me know.

I’m not sure it does change, at all. visibility= is just an instruction to the UI. It’s up to the UI to listen/subscribe for changes in the controlling Item, and then render the line or not.

1 Like

Jepp I know, what i need is to subscribe to an event, either:

a) an event that sitemap has changed so the client re-downloads the sitemap and looks for the changes in visibility

b) an event with what changed within a sitemap, similar to how changes to items are streamed using /events/items

It’s the technical details on how to accomplish either of these that is the issue. All the posts so far just re-iterate what I already know. Hunting around in git commits is beyond painful and should be fully documented.

I’ve just stumbled upon https://github.com/eclipse/smarthome/pull/2030
It looks like a combination of post, get, get is needed to make this happen, and there appears to be a few iterations of how it was implemented, as I’m now seeing something in chrome…

I’ll do a short write up in https://github.com/openhab/openhab-docs/issues/1211 if / when I figure it out.

Ah, you want the UI to refresh the sitemap structure/content. I don’t think any of the existing UIs do that … probably because sitemap itself was never intended to have a dynamic structure. I wouldn’t expect there to be any events related to sitemap file changes. You could perhaps construct your own folder update listener and have it toggle some magic Item that your UI could listen do, then issue a browser style refresh?

visibility or not has nothing to do with this. A refresh would be a refresh, affecting all of the sitemap instructions.

Be aware you could be flogging a dead horse, and although sitemaps may be retained into OH3 they are likely to be handled differently.

No, this is the solution: https://github.com/eclipse/smarthome/pull/2030, just needs to modify it a little. It’s the same as subscribing to item changes, just for sitemaps.

Can’t wait for OH3, need this for my Android client and some new functionality I’m adding.