Reading and adjusting json or similar with OH3 widgets?

I would like to create an item which holds a ton of information, and is adjustable via the UI to simplify creating lights. I wish to simply create one of these virtual items per room or zone, and then do the actual adjustment of the physical items in the background via a rule.

It should hold a JSON payload (or something similar, like metadata), like so:

VirtualLight_Livingroom_Main:
{
   toggle:false,
   brightness:0,
   temperature:0,
   target_brightness:55,
   target_temperature:90,
   brightness_profile:"Sunlight follower 1 - brightness",
   temperature_profile:"Sunlight follower 2 - temperature",
   adaptive_mode:false
   use_RGB:false
   RGB_target:{red:0,green:0,blue:0}
}

Then, I’d like to be able to select what Widget card this item displays as. A basic widget might only display an on/off value and be linked to the toggle data, while a more advanced widget might have a toggle button but also two sliders for the temperature and brightness along with a settings button where I can toggle adaptive mode and select the profiles I want.

My questions:

  • Is this possible? I get a feeling that using string items to hold JSON is the “wrong” approach here…
  • How would I make a widget that…
    • Displays a toggle switch which is set to the initial state of the toggle
    • Changes the toggle value in the item when pressed
  • How would I make a widget that…
    • Displays two sliders for temperature and brightness
    • Reads the initial slider values from the item’s brightness and temperature
    • Allows adjustment of the sliders and updates them in the item

Consider looking at the Scene Control rule templates and UI widgets on the marketplace. You might be able to get the behavior you are after with any code at all.

Probably. If all else fails consider it but generally this is an antipattern.

The widget is going to show the current stage of the Item at the time it’s rendered. Or you can create a widget that doesn’t ever show the state of the item but of course it won’t change when you click on it.

See the UI references and examples posted to the forum (especially the Marketplace).

This is discussed a bit in the Getting Started Tutorial too.

As I mentioned, the widget will automatically render based on the current states of the items.

That’s literally what UI widgets are for.

I am aware of how to make a slider on a dimmer-type item or a toggle on a switch based item. What I don’t know how to do is make a slider or a switch act upon a string type item (or adjust metadata or something). My goal is specifically to have one item that holds all the information conceivable about a specific lighting zone, and have different widgets that that allow the viewing and editing of the different contents of that singular item.

In HabPanel’s widget system, I can do it. Here, for example, is a widget that parses data from a json String Item.

For example, I have the items in the .items file:

String Profilestore_list_percentages "List of profiles" (Timecontrol)
String RoomLight_Kitchen_Ambient1_Adaptive1 "JSON Store" (RoomLight_Virtual)

Where the first holds the value: (1) Adaptive Light Brightness,(2) Light Temperature Adaptive,(7) Adaptive Light Dimmer,(8) Adaptive Light Brightness Low,none,

And the second contains: {"mode":"on","profile":"(1) Adaptive Light Brightness"}

Then, I have a HabPanel widget to create, populate, and allow adjustment of the second item via a dropdown:

<font style="color:white">Brightness profile to follow:</font>

      <!-- Dropdown --> 
      <div class="btn-group cdropdown" uib-dropdown dropdown-append-to-body="true">
        <button id="single-button" type="button" class="btn btn-primary" uib-dropdown-toggle>
          {{$eval(itemState(getItem(config.light_item).name.replace('Toggle','Adaptive1'))).profile}}
          <span class="caret"></span>
        </button>
        <ul class="dropdown-menu" style="z-index:20000" uib-dropdown-menu role="menu" aria-labelledby="single-button">
          <li role="menuitem" ng-repeat="profile in itemState('Profilestore_list_percentages').split(',')">
            <a ng-click="sendCmd(getItem(config.light_item).name.replace('Toggle','Adaptive1'), '{&quot;mode&quot;:&quot;on&quot;,&quot;profile&quot;:&quot;'.concat(profile).concat('&quot;}') )">{{profile}}</a>
          </li>
        </ul>
      </div>
      <br></br> 

Which all looks like so:

I am asking how to recreate something similar in function or form for OH3

Sliders only work with Numbers. No widget can adjust Item metadata on it’s own. You’ll need separate Items that trigger a rule at which point there is no point to having the JSON or Item metadata in the first place.

Widgets only work with Items and Item’s states. Nothing more.

MainUI isn’t HABPanel. The two are built very differently with different underlying frameworks.

Keep using HABPanel.

Yes, I have a String-type Item with the state that is some text which is formatted as JSON. The YAML widgets can’t parse or manipulate this in any way?

I mean, that’s clear. I don’t expect that the same code will work and I could understand if a new approach is needed on my part, but that’s exactly why I’m asking this question. I don’t need to use JSON to store all this data, I just don’t want to do it with individual items for a variety of reasons.

But I would like to use MainUI? It looks nice.

Fine. But you can’t have one Item for multiple data channels on the UI.
That’s okay, you have multiple individual Items for your UI, and any change in any of them triggers a rule that contructs the aggregated version for whatever-it-is.

No

You can’t get there from here. There is only a small set of expressions that are possible in a UI widget. See Building Pages - Components & Widgets | openHAB.

You can indeed parse the JSON in an expression, no problem. But I can’t see a way to edit just a part of a JSON string as part of the widget action with the available expressions and configuration options. MainUI widgets are at least three layers removed from the raw JavaScript. HABPanel is much closer to raw JavaScript so you have lots more options, with the corresponding greater degree of complexity (and limitations).

Ultimately this is an XY Problem. You not only want to accomplishing something, you have pre-selected how you want to solve it and are only interested in that pre-selected approach. In this case, it’s just not going to work. You can’t solve this the way you want and still use MainUI. You have to choose a way that works in MainUI or you have to use HABPanel. You can’t have both.

MainUI, as with most everything else in OH, is built around Items. There are not shortcuts.

It is worth noting that the equivalence here is not between HabPanel and MainUI Widgets, but between HabPanel and the whole MainUI. As Rich and rossko have both laid out, you cannot do what you are looking for JUST with widgets, but that doesn’t mean you can’t do it with MainUI in its entirety. If you shift your point of view just a bit to see the widgets, items, and rules within MainUI as a unified whole then what you want to do is achievable.

Your usecase is far outside the standard so it’s not as easy to do as perhaps you might like, but all the different pieces are there. The example Rich linked to shows you how to do something very much like what you want and rossko’s outline of using different proxy items is similar very good solution. Either way, both results get you the same basic layout: Widget (very basic string processing) → Proxy Item(s) (data transport) → Rule (heavy string processing and item data modification).