Custom Widget: Item defined in property not shown

Hello everyone,

I am trying to build a custom widget to show my energy consumption in a bar chart.

But I have some troubles showing my Item defined in the property.

uid: strom_balkendiagramm_Stunde
tags: []
props:
  parameters:
    - context: item
      description: Main toggle item (use for single toggle or as main switch for group)
      label: Item
      name: item
      required: false
      type: TEXT
  parameterGroups: []
timestamp: Jan 31, 2022, 9:58:36 PM
component: f7-card
config:
  title: =props.title
  class:
    - padding-bottom
slots:
  default:
    - component: f7-row
      config:
        class:
          - margin-top
      slots:
        default:
          - component: f7-col
            config:
              width: 75
            slots:
              default:
                - component: oh-chart
                  config:
                    chartType: day
                    label: =props.chart1
                  slots:
                    grid:
                      - component: oh-chart-grid
                        config:
                          containLabel: false
                    xAxis:
                      - component: oh-category-axis
                        config:
                          gridIndex: 0
                          categoryType: day
                          weekdayFormat: default
                          monthFormat: default
                    yAxis:
                      - component: oh-value-axis
                        config:
                          gridIndex: 0
                          name: "kWh"
                    series:
                      - component: oh-aggregate-series
                        config:
                          name: Stromverbrauch
                          gridIndex: 0
                          xAxisIndex: 0
                          yAxisIndex: 0
                          type: bar
                          item: =[props.item]
                          dimension1: hour

When I use the name directly, it works:
item: Strom_Haus_Verbrauch

But with
item: =[props.item] this is not working.
I also tried only
item: =props.item or =(props.item)

So what am I doing wrong?

props is not an item object where you can just call the item’s properties. props is an object that contains only the keys you’ve defined in the widget. In this case, props.item just contains text that is the item name.

You’ve stumbled across an issue that had been troubling users since the introduction of the custom widget feature. By just having the item name it is not actually very easy to get the item label (the human readable identifying text). This is why, is you look at many of the widget examples in the forum they will have an item property and a separate label property defined at the top of the widget.

But when I look for example this widget:

He is using

- context: item
      description: the shutteritem
      label: Item
      name: itemShutter
      required: true
      type: TEXT
...

                    item: =props.itemShutter

And there it seems to work. So why it is not working for my case? I guess he is also accessing the item and not just the text

Nope. In any oh component, the item property is just a string of the item name. If you hunt around a little more you’ll find many examples where you can see this because theitem property is built up from a string concatenation excursion.
Further access to the item’s relevant properties for component function is achieved by the underlying code that supports the widgets.

The one exception to all of this is if you are using an oh-repeater in one of the forms that returns an array of items. In that case the loop variable contains an object with all the information about the item returned by the items api.

I already saw that the Items in some cases are built up by string concatenation like:

                      item: ='Strom_'+ props.item+'_Aktueller_Verbrauch'

or like:

                      item: "=items['Strom_'+ props.item+'_Aktueller_Verbrauch']"

But nothing is working. So the string concatenation is also not working in my case? Is there any possibility to get it working?

Sure. Your first post looks close. I suspect there are really only a few tweaks needed.

This line, as I outlined up above, returns nothing because the props object doesn’t have a title property as you haven’t declared one in the properties section. There are two easy solutions here:

  1. Change props.title to props.item. The title on your card will then be the name (e.g., Strom_Haus_Verbrauch from your example). This isn’t very pretty but it is a very easy.

  2. Add a title property to the widget as well. That will look something like:

  parameters:
    - context: item
      description: Main toggle item (use for single toggle or as main switch for group)
      label: Item
      name: item
      required: false
      type: TEXT
    - context: text
      description: Pretty card label
      label: Title
      name: title
      required: false
      default: You forgot to set a card title
      type: TEXT

This goes back to what we’ve been discussion up above. Once you open up the settings dialog for the widget and select an item from the list for this property, props.item equals the name of the item you selected. Nothing less and nothing more. In this case, that’s all you want: the name of the item because that’s the what this item property of the dataseries expects (if you check out the doc file on the oh-aggregate-series you see just says TEXT for this property). So short answer is that all you need is:

item: =props.item

The long answer is: the brackets that you had around that come from a different syntax. The one piece of information about all OH items that is available in the widgets is the current state of the item (and associated formatted version of the state, if that exists). These are held in the items object. In the items object there is a key for every Item name. That means that if you want to get the state of your Strom_Haus_Verbrauch item you would use items.Strom_Haus_Verbrauch.state. But, that’s hard coded and sometimes you want the widget to be able to get the state of a variable item (for example, whatever item has been put into the props.item value. To get a variable key from an object in this syntax you use the brackets. So, the form items[props.item].state says “evaluate props.item and use that string (which should hold the name of an item) to look in the items object for the state of that item”.

This becomes extremely useful when buildin more complicted widgets because associated items often have names that are built around the same root. For example, in a thermostat you might have an item for the current temperature FirstFloorTherm_Current and an item that holds the set temperature to heat to FirstFloorTherm_HeatSet. Now with just one piece of information (the base name of the thermostat item) you can build the item name for all the associated items easily in the same widget. To get the current temp you would use:

items[props.item + "_Current"].state

and to get the set temp

items[props.item + "_HeatSet"].state

Ah, I guess with the title there was a missunderstandig. I have no problem with the title.
The only issue was the Item which is not used.
I now use this:

item: =props.item

But it is not working.

This is my whole widget:

uid: strom_balkendiagramm_Stunde
tags: []
props:
  parameters:
    - context: item
      description: Main toggle item (use for single toggle or as main switch for group)
      label: Item
      name: item
      required: false
      type: TEXT
    - context: text
      description: Pretty card label
      label: Title
      name: title
      required: false
      default: You forgot to set a card title
      type: TEXT
  parameterGroups: []
timestamp: Feb 1, 2022, 5:39:12 PM
component: f7-card
config:
  title: =props.title
  class:
    - padding-bottom
slots:
  default:
    - component: f7-row
      config:
        class:
          - margin-top
      slots:
        default:
          - component: f7-col
            config:
              width: 75
            slots:
              default:
                - component: oh-chart
                  config:
                    chartType: day
                    label: "Strom"
                  slots:
                    grid:
                      - component: oh-chart-grid
                        config:
                          containLabel: false
                    xAxis:
                      - component: oh-category-axis
                        config:
                          gridIndex: 0
                          categoryType: day
                          weekdayFormat: default
                          monthFormat: default
                    yAxis:
                      - component: oh-value-axis
                        config:
                          gridIndex: 0
                          name: kWh
                    series:
                      - component: oh-aggregate-series
                        config:
                          name: Stromverbrauch
                          gridIndex: 0
                          xAxisIndex: 0
                          yAxisIndex: 0
                          type: bar
                          item: =props.item
                          dimension1: hour
                    tooltip:
                      - component: oh-chart-tooltip
                        config:
                          confine: true
                          smartFormatter: true
                    legend:
                      - component: oh-chart-legend
                        config:
                          bottom: 3
                          type: scroll
                    dataZoom:
                      - component: oh-chart-datazoom
                        config:
                          type: inside

But it is not working.

image
When I change the item to the Itemname it works:


                          item: Strom_Haus_Aktueller_Verbrauch

image

That’s interesting, that’s now entirely the correct form. Previously it used to be true that you couldn’t use expressions in the item property of the chart series, but I thought that had been fixed. It turns out, now that I look into it, that it wasn’t fixed for oh-aggregate-series only for some of the other series.

It’s not working because it’s not currently supported. You can file a feature request on github to get the aggregate series’ item field added to the list of properties that accept expressions, if you’d like.

Thank you for your hint, I created an issue in the git repo

Same for charting switches:

    - component: oh-time-series
      config:
        name: Light
        gridIndex: 0
        xAxisIndex: 0
        yAxisIndex: 0
        type: line
        areaStyle: {}
      slots:
        markArea:
          - component: oh-mark-area
            config:
              name: Light
              item: =props.light_item

PR should take care of issues (or better said, current limitations) mentioned in this thread - please feel free to check it out and let me know of any issues, thank you!

1 Like

eric1905, this is really great widget, many thanks. I have made few changes to it in order to calculate the delta values so I added a line

aggregationFunction: diff_last

I’m using InfluxBD so I had to add this.

Now my question is that can you somehow add a label (box) which would have the total daily electricity consumption. I haven’t tried to create a widget which would show e.g. monthly electricity consumption but this should be straightforward. I haven’t implemented Grafana and I wouldn’t like to use it because it would add one more complexity in my OH.