Widget from JSON

Hi,

I have solar inverter from which I can access the historical data HTTP requests.
The result I get is in form of:

<month_trend>
<d0>14762</d0>
<d1>36232</d1>
<d2>90970</d2>
<d3>97796</d3>
<d4>113705</d4>
<d5>107952</d5>
<d6>118276</d6>
<d7>109847</d7>
<d8>45837</d8>
<d9>0</d9>
<d10>0</d10>
<d11>0</d11>
<date>2022</date>
 </month_trend>

Getting the data in items is not a problem but I would like to show the results in a widget.
Since I am totally incompetent in YAML (or whatever the name of language for the widgets is called) I ask for help.

My first idea was to create a list with 12 rows, one for each month and then use labels with width that is proportional to the energy produced. However I do not get how to make the width of an object flexible. I tried searching in the forum, but all of the examples I found were with fixed width.

Basically I would want to have something like this:

width: calc(100% -items[props.item].state/100/props.range)

Can something like this be done?
Probably there are more clever solutions, but as a non programmer, this is what I came up with.

My widget so far:

uid: BarGraph
tags: []
props:
  parameters:
    - description: Range kWh
      label: Range
      name: range
      required: true
    - context: item
      description: An item
      label: Item
      name: item
      required: true
      type: TEXT
  parameterGroups: []
timestamp: Sep 18, 2022, 12:29:36 AM
component: f7-card
config:
  style:
    height: 40px
    background-color: yellow
    width: calc(100% - 50px)

slots:
  content:
    - component: f7-card-content
      config:
        style:
          position: absolute
          top: -5px
          left: 16px
          flex-direction: row
          display: flex
      slots:
        default:
          - component: Label
            config:
              text: '=items[props.item].state/100 + "  kWh"'

Thanks

Yes it can.

One of the fundamental concepts of the custom widget system (and one of the least intuitive, unfortunately), is the difference between a value and an expression. The way the custom widget yaml system is built, any of the values in the yaml are treated simply as string or number types. The style property of a component is (for nearly all the components) just passed along to the final element as the css properties for that element. So, in this case when you use:

style:
  width: calc(100% -items[props.item].state/100/props.range)

You are sending the whole calc(100% -items[props.item].state/100/props.range) string as the css propety. Css, of course, has no idea what the OH specific pieces items[props.item].state and props.range mean and just considers your value gibberish.

In order to send the css property in a form that css will recognize, you have to tell OH that it needs to evalute some expression before passing the value along and you do that by starting the value with an =. Then you can use a pared-down javascript-compatible expression syntax to build the string value that will make sense to Css. In this case you want the result to be a string like your later example calc(100% - 50px) with the only dynamic part being the number in front of the px. So it would look something like this:

width: ='calc(100% - ' + Number(items[props.item].state) / 100 / props.range + 'px )'

If your goal is to build a bar graph of these values, there are also several other options:

  1. The chart system in oh uses allows you to incorporate apache e-charts into widgets so you could build a bar graph in that with your data and have that as a widget. The method for creating charts isn’t fully documented yet, so you’ll have to use the e-charts docs and find examples on the forum to work from.
  2. Many users who want advanced charting capabilities use an external service such as Grafana and then import that graphs into OH.
1 Like

Thanks @JustinG, I understand the principle but I don’t know the right syntax.
The code worked for me.

Regarding the bar graphs, I can read the values totalized by the inverter, so no need to get the data from the database

This topic was automatically closed 41 days after the last reply. New replies are no longer allowed.