Force UI update on setting 'uiComponent: null'

Hi,

Is there a way to force an UI reload for a Device.

Use-Case: A certain function is disabled in the App/Device Settings and in the ‘onSettings’ the corresponding button is hidden using:

await this.setCapabilityOptions(buttonID, {
        uiComponent: null
      });

However when closing the Settings, the UI is not updated and the button is still shown/visible.

Is there a way to force and update (or if needed close the UI)?

To add to this it does update when you close the view (manual user interaction) and re-open it but that is not great user experience - hence the update / reload question…

There seems to be a bug in the latest app versions as often the capabilities don’t update while the UI is open and require the user to close and open it again.

1 Like

Hey @Jeroen_S,

Have you ever gotten this to work? I am also looking into implementing the option for the user to hide uninteresting capabilities from the app settings.

@Adrian_Rockall, do you know if this bug also apply to the Homey web app?

Not really just took on it was a bug.

For me not a real issue because it only happens when you change the settings and when you close the view and open it again it then it is okay - until you change settings again, but that hardly ever happens.

Do you need to do it on the fly?

I’m trying to hide certain capabilities (sensors) from the app’s GUI based on user settings. However, I’m having trouble getting the sensors to hide as expected.

Here’s the relevant part of my device.js file where I set the uiComponent in the onSettings method:

async onSettings({ oldSettings, newSettings, changedKeys }) {
  this.log('Settings changed:', { oldSettings, newSettings, changedKeys });

  for (const key of changedKeys) {
    switch (key) {
      default:
        if (key.includes('pump')) {
          await this.setCapabilityOptions(key, {
            uiComponent: newSettings[key] ? 'sensor' : null
          });
        }
        break;
    }
  }
}

And here’s the relevant part of my driver.compose.json file:

{
  "type": "group",
  "label": { "en": "Show/Hide Sensors" },
  "children": [
    {
      "id": "pump1",
      "type": "checkbox",
      "label": { "en": "Show Pump 1" },
      "value": true
    },
    {
      "id": "pump2",
      "type": "checkbox",
      "label": { "en": "Show Pump 2" },
      "value": true
    },
    {
      "id": "pump3",
      "type": "checkbox",
      "label": { "en": "Show Pump 3" },
      "value": true
    },
    {
      "id": "pump4",
      "type": "checkbox",
      "label": { "en": "Show Pump 4" },
      "value": true
    },
    {
      "id": "pump5",
      "type": "checkbox",
      "label": { "en": "Show Pump 5" },
      "value": true
    },
    {
      "id": "pump6",
      "type": "checkbox",
      "label": { "en": "Show Pump 6" },
      "value": true
    }
  ]
}

I have tried restarting the app after setting e.g. pump1 to false, but the sensor is still visible in the UI. Any suggestions?

Mine is not that different I call an update function:

  async updateUIButtons(buttonID, buttonEnable) {
    this.writeLog(`Updating UI Button: ${buttonID}, Enabled: ${buttonEnable}`);

    if (buttonEnable) {
      await this.setCapabilityOptions(buttonID, { uiComponent: "button" });
    } else {
      await this.setCapabilityOptions(buttonID, { uiComponent: null });
    }
  }

Do you change the settings through the settings menu or programmatically? (the latter does not trigger the onSettings?). Also if you log the key value is it the right object?

Thanks @Jeroen_S,

I tried your code to set uiComponent to null for an enum sensor, but it remain visible at all time in the UI.

Here is the relevant code that I use:

this.updateUISensors("pump1", false); //Calling the function to show or hide capabilities


  async updateUISensors(sensorId, Enable) {
    this.log(`Updating UI Button: ${sensorId}, Enabled: ${Enable}`);

    if (Enable) {
      await this.setCapabilityOptions(sensorId, { uiComponent: "enum" });
    } else {
      await this.setCapabilityOptions(sensorId, { uiComponent: null });
    }
  }
pump1.json:
{
  "type": "enum",
  "title": {
    "en": "Pump 1"
  },
  "values": [
    {
      "id": "off",
      "title": {
        "en": "Off"
      }
    },
    {
      "id": "low",
      "title": {
        "en": "Low"
      }
    },
    {
      "id": "high",
      "title": {
        "en": "High"
      }
    }
  ],
  "uiComponent": "sensor",
  "icon": "assets/icons/pumpMode.svg",
  "getable": true,
  "setable": false
}

Any thoghts? Thx!