Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Non-string widget props with defaults are converted to strings when stored in JSONDB #2990

Open
Nadahar opened this issue Jan 8, 2025 · 3 comments
Labels
bug Something isn't working main ui Main UI

Comments

@Nadahar
Copy link
Contributor

Nadahar commented Jan 8, 2025

The problem

I don't know if this problem is actually in MainUI or in Core, but I'm posting here first. The problem probably doesn't just apply to widgets, but that's where I've observed it.

When you define a prop for a widget that is a boolean or a number and which has a default, the type isn't respected when the widget is stored, and everything seems to be converted to strings - which causes widgets to misbehave once retrieved from storage.

Example definition:

    - default: false
      description: Whether to show the LCD
      label: Show LCD
      name: showLCD
      required: false
      type: BOOLEAN

After storing and reopening the widget, this has "magically" been transformed to

    - default: "false"
      description: Whether to show the LCD
      label: Show LCD
      name: showLCD
      required: false
      type: BOOLEAN

When using this in an expression like =props.showLCD?, the default will in effect be "true" because it's not an empty string. Before the widget is stored (and the quotes added), the evaluation works correctly. To make it behave correctly after retrieval, one must instead do something like props.showLCD&&props.showLCD!='false'?. The issue is the same with numbers, where various bugs appear after retrieving the widget from storage.

By peeking in the JSONDB, I can see that the default values have already been converted to string before being stored, so it looks like the problem is somewhere "on the way to storage" - not during retrieval:

          {
            "default": "false",
            "description": "Whether to show the LCD",
            "label": "Show LCD",
            "name": "showLCD",
            "required": false,
            "type": "BOOLEAN"
          },

As can be seen, required is stored correctly and doesn't suffer from this issue.

It seems to me that the type should be taken into account when the default is converted, and I'm starting to realize that this problem probably is in Core.

@Nadahar Nadahar added bug Something isn't working main ui Main UI labels Jan 8, 2025
@Nadahar
Copy link
Contributor Author

Nadahar commented Jan 8, 2025

I think I've found the root cause, it's here:
https://github.com/openhab/openhab-core/blob/f00c7700cb13b4ab6dbc6a8e493f226d8099689c/bundles/org.openhab.core.config.core/src/main/java/org/openhab/core/config/core/dto/ConfigDescriptionParameterDTO.java#L33-L34

I don't know if it's possible to get Gson to serialize the same field to different types, it sounds "problematic". So, since the field is defined as a string, everything becomes a string.

It might be possible to keep it as an Object in the DTO class and write some "type adapter" or something that could handle it - I'm really not that well versed in Gson to know exactly how this could be solved. Alternatively, there could be some logic that looked at the type field and converted it back to the correct type when being retrieved, on the UI side.

I would maybe think that this problem is more general than just the UI though, as it seems like this problem applies to all configuration parameter storage.

@hmerk
Copy link

hmerk commented Jan 8, 2025

What if you don't put the default value in hyphens ? That's the way I normaly do.

@Nadahar
Copy link
Contributor Author

Nadahar commented Jan 8, 2025

What if you don't put the default value in hyphens ? That's the way I normaly do.

The hyphen is there just because it's the first field in the array entry. It marks where a new parameter begins. I can rearrange the order so that default isn't the first, and thus the hyphen is on some other field, but because the JSONDB will arrange the fields alphabetically, unless you have a field like context that comes before default, detault will have become the first field once you retrieve it. This is also a bit annoying IMO, but I understand it was to improve diff comparisons. To me, this just makes the fields "unorganized", I prefer to have name as the first field, as that makes it easier to find them for example, and I would like to have them in an order that has meaning (label before description etc.). But, I assume that the alphabetization has a benefit in some other scenario.

I'm pretty sure that this problem has nothing to do with the hyphen, it is a result of the deserialization in Core which "forces" the defaultValue field to be a String.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working main ui Main UI
Projects
None yet
Development

No branches or pull requests

2 participants