OH4: Overview Page with widgets causing Android App to Crash (Suspected)

Hi All

I have openHAB running on an Android Tablet using the Android App.

Recently the APP started crashing multiple times a day - sometimes with unloadable reports, sometimes not.
I eventually managed to get some logs which I submitted and the suspicion was that the APP was not at fault but that the “WebView (Chrome) process and/or the graphics driver crashed”.

I tried everything to work around that, including a Factory Reset of the device.

As a last resort I removed everything except a Clock Widget from the Overview Page. With it like that the Page has been stable for more than a day.

I have added back all the oh-cells except for the last two created ones and seems stable too.

What I would like to understand is how the Overview page could cause the Android App to crash while “IDLE” with oh-cell closed?

Do these unopened oh-cells still get rendered somehow that could cause this?

How do I work out what in my oh-cell could be causing the issue?

Overview Page with possible culprits removed:

I think the answer here is “partially”. The cell contents container is the same whether the cell is opened or not, and if you have other elements in there with cell-opened-fade-in class then those contents are indeed loaded even if the cell is closed, they just have an opacity of 0 which then gets animated to 100 to get the fade-in effect.

Whether or not that’s what’s causing the issue is hard to say, but it’s definitely a possibility. You should be able to inspect the page in a desktop browser and see if the elements are actually listed in the rendered page code even with the cells closed.

Thanks Justin. I did investigate this and yes - the components do seem to be rendered.

I have managed to narrow down the issue to a specific widget (by manually removing each cell till the issue was no longer evident) - and in fact to the “work around” that you proposed for getting Charts to refresh. My Code is as follows,

Cell calling Widget:

component: oh-cell
config:
  title: Power Usage
slots:
  background:
    - component: f7-block
      config:
        style:
          --cell-green: rgba(165,236,176,255)
          --cell-red: rgba(255,156,151,255)
          --cell-yellow: rgba(254,229,128,255)
          background-color: '=(Number.parseFloat(items.SunSynk_vac_L1_L2.state) >10) ? "var(--cell-green)" : "var(--cell-red)"'
          height: 100%
          margin: 0
          padding: 0
          position: absolute
          width: 100%
    - component: f7-block
      config:
        style:
          bottom: 5px
          left: 0px
          margin: 0
          padding: 0
          position: absolute
          width: 100%
      slots:
        default:
          - component: oh-button
            config:
              popupOpen: .poweruse-pop
              style:
                height: 100%
                width: 100%
              text: OPEN
    - component: f7-popup
      config:
        class: poweruse-pop
        style:
          --f7-popup-tablet-height: 720px
          --f7-popup-tablet-width: 360px
          background-color: rgb(220,220,220)
          border-radius: 30px
          height: 720px
          text-overflow: ellipsis
          width: 360px
      slots:
        default:
          - component: widget:Test_SunSynk_PowerUsage_V4b
            config:
              popupClose: .poweruse-pop
              tooltipEnable: true

Actual Widget Code:

uid: Test_SunSynk_PowerUsage_V4b
tags: []
props:
  parameterGroups: []
timestamp: Sep 11, 2023, 9:40:09 AM
component: f7-block
config:
  style:
    margin: 0
    padding: 0
  title: SunSynk Power Usage
slots:
  default:
    - component: f7-block
      config:
        style:
          --f7-popup-tablet-height: 720px
          --f7-popup-tablet-width: 360px
          background: rgb(220,220,220)
          border-radius: 20px
          height: 720px
          margin: 0
          padding: 0
          position: absolute
          top: 0px
          width: 360px
      slots:
        default:
          - component: oh-button
            config:
              clearVariable:
                - mpptDetailShow
              large: true
              popupClose: .modal-in
              style:
                background: rgb(220,220,220)
                color: white
                display: flex
                height: 30px
                left: 5px
                position: absolute
                top: 5px
                width: 30px
                z-index: 999
            slots:
              default:
                - component: f7-icon
                  config:
                    color: white
                    f7: clear_fill
                    style:
                      color: black
                      font-size: 20px
                      margin: auto
          - component: Label
            config:
              style:
                font-size: 25px
                font-weight: 500
                padding-left: 70px
                width: 100%
              text: SunSynk Power Usage
          - component: f7-block
            config:
              style:
                margin: 0
                padding: 0
                top: 0px
            slots:
              default:
                - component: oh-gauge
                  config:
                    borderBgColor: gray
                    borderColor: green
                    borderWidth: 20
                    class:
                      - margin-top
                    labelText: Essential
                    max: 8800
                    min: 0
                    size: 150
                    style:
                      left: 20px
                    type: semicircle
                    value: =(Number.parseFloat(items.SunSynk_inv_Total_Power_175.state) - (Number.parseFloat(items.SunSynk_gen_To_Mi_Power_166.state) - Number.parseFloat(items.SunSynk_acL1_Power_167.state))) + " W"
                    valueFontSize: 15
                    valueText: =(Number.parseFloat(items.SunSynk_inv_Total_Power_175.state) - (Number.parseFloat(items.SunSynk_gen_To_Mi_Power_166.state) - Number.parseFloat(items.SunSynk_acL1_Power_167.state))) + " W"
                    valueTextColor: green
                - component: oh-gauge
                  config:
                    borderBgColor: gray
                    borderColor: blue
                    borderWidth: 20
                    class:
                      - margin-top
                    labelText: Non-Essential
                    max: 3000
                    min: 0
                    size: 150
                    style:
                      left: 40px
                    type: semicircle
                    value: =(Number.parseFloat(items.SunSynk_Load_Grid.state) - Number.parseFloat(items.SunSynk_acL1_Power_167.state) < 10)?(0):((Number.parseFloat(items.SunSynk_Load_Grid.state) - Number.parseFloat(items.SunSynk_acL1_Power_167.state)))
                    valueFontSize: 15
                    valueText: =(Number.parseFloat(items.SunSynk_Load_Grid.state) - Number.parseFloat(items.SunSynk_acL1_Power_167.state) < 10)?("0 W"):((Number.parseFloat(items.SunSynk_Load_Grid.state) - Number.parseFloat(items.SunSynk_acL1_Power_167.state)) + " W")
                    valueTextColor: blue
                - component: oh-gauge
                  config:
                    borderBgColor: gray
                    borderColor: green
                    borderWidth: 20
                    class:
                      - margin-top
                    item: SunSynk_Load_Grid
                    labelText: Grid
                    max: 10000
                    min: 0
                    size: 150
                    style:
                      left: 20px
                    type: semicircle
                    valueFontSize: 15
                    valueTextColor: green
                - component: oh-gauge
                  config:
                    borderBgColor: gray
                    borderColor: green
                    borderWidth: 20
                    class:
                      - margin-top
                    item: SunSynk_Battery_Power
                    labelText: Battery
                    max: 8000
                    min: -8000
                    size: 150
                    style:
                      left: 40px
                    type: semicircle
                    valueFontSize: 15
                    valueTextColor: green
                - component: oh-link
                  config:
                    action: variable
                    actionVariable: mpptDetailShow
                    actionVariableValue: '=(vars.mpptDetailShow == "null") ? true : !(vars.mpptDetailShow)'
                    style:
                      height: 100%
                      width: 100%
                      z-index: 0
                  slots:
                    default:
                      - component: oh-gauge
                        config:
                          borderBgColor: gray
                          borderColor: green
                          borderWidth: 20
                          class:
                            - margin-top
                            - margin-bottom
                          item: SunSynk_MPPT_TOTAL
                          labelText: MPPT Total
                          max: 6600
                          min: 0
                          size: 150
                          style:
                            left: 5px
                          type: semicircle
                          valueFontSize: 15
                          valueTextColor: green
          - component: f7-block
            config:
              style:
                background: white
                border: 1px solid black
                border-radius: 20px
                left: 15px
                margin: 0
                opacity: 1
                overflow: hidden
                padding: 0
                position: absolute
                top: 133px
                width: 330px
              visible: =(vars.mpptDetailShow) == true
            slots:
              default:
                - component: oh-gauge
                  config:
                    borderBgColor: gray
                    borderColor: green
                    borderWidth: 20
                    class:
                      - margin-top
                      - margin-bottom
                    item: SunSynk_MPPT1_House
                    labelText: MPPT 1 House
                    max: 3300
                    min: 0
                    size: 145
                    style:
                      left: 10px
                      margin: 0
                      padding: 0
                    type: semicircle
                    valueFontSize: 15
                    valueTextColor: green
                - component: oh-gauge
                  config:
                    borderBgColor: gray
                    borderColor: blue
                    borderWidth: 20
                    class:
                      - margin-top
                      - margin-bottom
                    item: SunSynk_MPPT2_Garage
                    labelText: MPPT 2 Garage
                    max: 3300
                    min: 0
                    size: 145
                    style:
                      left: 30px
                      margin: 0
                      padding: 0
                    type: semicircle
                    valueFontSize: 15
                    valueTextColor: blue
          - component: f7-block
            config:
              style:
                background-color: rgba(232,232,232)
                border: 1px solid black
                border-radius: 10px
                height: 50px
                left: 10%
                marhin: 0
                padding: 0
                top: -20px
                width: 80%
            slots:
              default:
                - component: oh-icon
                  config:
                    icon: '=(items.SunSynk_Battery_Status.state === "Trickling") ? "charge_battery" : (items.SunSynk_Battery_Status.state === "Charging") ? "charge_battery" :(items.SunSynk_Battery_Status.state === "Idling") ? "full_battery" : (items.SunSynk_Battery_Status.state === "Discharging") ? "middle_battery" : (items.SunSynk_Battery_Status.state === "Critical") ? "empty_battery" : "error"'
                    style:
                      position: absolute
                    width: 50px
                - component: Label
                  config:
                    style:
                      font-size: 25px
                      font-weight: 500
                      left: 50px
                      position: absolute
                      top: 5px
                      white-space: nowrap
                    text: =(items.SunSynk_Battery_Status.state)
                - component: Label
                  config:
                    style:
                      font-size: 25px
                      font-weight: 500
                      position: absolute
                      right: 10px
                      top: 5px
                      white-space: nowrap
                    text: =(items.SunSynk_Battery_SOC.state)
          - component: f7-block
            config:
              key: =Math.random() + items.UI_Refresh_Timer.state
              style:
                border: black
                border-radius: 20px
                bottom: 10px
                margin: 0
                padding: 0
                position: absolute
                width: 100%
            slots:
              default:
                - component: oh-chart
                  config:
                    chartType: ""
                    label: Power
                    period: 4h
                  slots:
                    dataZoom:
                      - component: oh-chart-datazoom
                        config:
                          type: inside
                    grid:
                      - component: oh-chart-grid
                        config:
                          containLabel: false
                    legend:
                      - component: oh-chart-legend
                        config:
                          bottom: 5
                          type: scroll
                    series:
                      - component: oh-time-series
                        config:
                          color: green
                          gridIndex: 0
                          item: SunSynk_Load_Grid
                          name: Essential
                          type: line
                          xAxisIndex: 0
                          yAxisIndex: 0
                      - component: oh-time-series
                        config:
                          color: blue
                          gridIndex: 0
                          item: ShellyEM_UPS_Watt
                          name: Non-Essential
                          type: line
                          xAxisIndex: 0
                          yAxisIndex: 0
                    tooltip:
                      - component: oh-chart-tooltip
                        config:
                          confine: true
                          smartFormatter: true
                    xAxis:
                      - component: oh-time-axis
                        config:
                          axisLabel:
                            color: black
                            fontSize: 10
                            rotate: -45
                          gridIndex: 0
                    yAxis:
                      - component: oh-value-axis
                        config:
                          axisLabel:
                            color: black
                            fontSize: 10
                          gridIndex: 0
                          min: 0
                          name: W

As soon as I removed key: =Math.random() + items.UI_Refresh_Timer.state from the last oh-block containing the oh-chart the issue seems to go away.

Would be interested to hear if you have any suggestions etc. The refresh is not critical for me in this case, but a nice to have.

Was very surprised though that the issue occurred with the widget not even actively displayed.

Thanks
Mark

Sounds to me like something is just getting overloaded. Charting is not a trivial processing task. There’s quite a bit of data transfer as the persistence database gets queried each time (especially depending on the frequency of the time series and the time frame of the chart), then the e-charts library has to render the data as an svg before it gets displayed. I don’t know the specs on the tablet you’re using, but it’s possible that’s just too much to ask it to do constantly at the refresh rate you’ve selected.

You could try using a lower refresh rate and see if that decreases the problem.

You can also try to use the visible property on the whole popup. When visible is false, a component (and therefore all it’s children) is just not rendered. Because you’re using an oh-button, you can use the popupOpen and oh actions simultaneously, so you could set a variable with that button that controls the visible property on the popup. Of course, the popup close buttons would have to clear that variable also which means it will have to be a page level variable instead of just in the widgets so that all the components have access to it.

Thanks Just for your as usual insightful response.
I agree that something may be getting overloaded. The tablet is not the most powerful but was able to happily run Minecraft etc. before I took it over from my kids.

I really like this idea, so gave it a go with a small widget that I use as the basis for my others.

As usual with me I ran into a few issues:

Applying the visibility to the f7-popup did not work, so my next best option was to apply to the f7-block inside the popup.

I then also ran into the issue with variables on the Overview page - similar issue to what I have had before

  • Works in widget builder
  • Works on a layout page
    *Works on Overview page when in Run Mode from Settings
    *Does NOT work on Overview page

This is the YAML for what I created.

component: oh-cell
config:
  on: true
  title: '="Template:  " + vars.visibleTemplate'
slots:
  background:
    - component: f7-block
      config:
        style:
          --cell-green: rgba(165,236,176,255)
          --cell-red: rgba(255,156,151,255)
          --cell-yellow: rgba(254,229,128,255)
          height: 100%
          margin: 0
          padding: 0
          position: absolute
          width: 100%
    - component: f7-block
      config:
        style:
          bottom: 5px
          left: 0px
          margin: 0
          padding: 0
          position: absolute
          width: 100%
      slots:
        default:
          - component: oh-button
            config:
              popupOpen: .template-pop-test
              action: variable
              actionVariable: visibleTemplate
              actionVariableValue: '=(vars.visibleTemplate == "null") ? true: !(visibleTemplate)'
              style:
                height: 100%
                width: 100%
              text: OPEN
    - component: f7-popup
      config:
        class: template-pop-test
        style:
          --f7-popup-tablet-height: 720px
          --f7-popup-tablet-width: 360px
          background-color: rgb(220,220,220)
          border-radius: 30px
          height: 720px
          text-overflow: ellipsis
          width: 360px
      slots:
        default:
          - component: f7-block
            config:
              popupClose: .template-pop-test
              visible: =(vars.visibleTemplate) == true
              style:
                --f7-popup-tablet-height: 720px
                --f7-popup-tablet-width: 360px
                background-color: rgb(220,220,220)
                border-radius: 30px
                height: 720px
                margin: 0
                padding: 0
                text-overflow: ellipsis
                width: 360px
            slots:
              default:
                - component: oh-button
                  config:
                    clearVariable:
                      - visibleTemplate
                    large: true
                    popupClose: .modal-in
                    style:
                      background: rgb(220,220,220)
                      color: white
                      display: flex
                      height: 30px
                      left: 5px
                      position: absolute
                      top: 5px
                      width: 30px
                      z-index: 999
                  slots:
                    default:
                      - component: f7-icon
                        config:
                          color: white
                          f7: clear_fill
                          style:
                            color: black
                            font-size: 20px
                            margin: auto
                - component: Label
                  config:
                    style:
                      font-size: 25px
                      font-weight: 500
                      padding-left: 110px
                      width: 100%
                    text: Template
                - component: f7-block
                  config:
                    style:
                      --f7-popup-tablet-height: 300px
                      --f7-popup-tablet-width: 326px
                      background-color: rgba(232,232,232)
                      border: 1px solid black
                      border-radius: 10px
                      margin: 0
                      padding: 0
                      position: absolute
                      height: 10px
                      width: 326px
                  slots: {}

Not working from Overview page:
Not Working from Overview

Working from Overview Rune Mode Page:
Working from RunMode

I seem to bump my head on this Variables issue with Overview a lot…

Cheers
Mark

Oh yeah, I forgot about that.

Does it work if you don’t make it a page level variable but just keep it at the level of the cell that has the popup? That scope should probably be sufficient.

Another option would be to stop the refreshing while the popup is closed. You should have a rule that is changing the item which changes the state of UI_Refresh_Timer, you can add another item switch item e.g., UI_Refresh_Toggle, and set that in the condition of the rule (But Only IF...UI_Refresh_Toggle == ON). Then instead of changing a variable in your widget, if that widget sends ON and OFF commands to the toggle item then the graph will still be rendered all the time but only refreshing when displayed (i.e., the toggle item is on).

The one caveat with this is that when you first open the graph it may still be showing an old version and, depending on your refresh rate, you may have to wait a bit to see the new graph. You can easily fix this by also adding the UI_Refresh_Toggle state to the key property as well. Then the graph will also refresh every time the popup is opened.

I set the value in the oh-cell, and only tried to set a default vlue at the Page level.

It seems that when using the Overview page, variables in general do not work.

The only way I have been able to get them to work is to call a completely separate widget using widget:xxx, which is not ideal.

I have for now removed the refresh completely. But as you mentioned you can then get a stale chart. Have to refresh the Overview page to get an update.

I will have a look at you rother suggestions. So thank you for that.