Device Capabilities

Starting from version 12.2.0, Homey Pro (Early) 2023 will shift its approach to favour custom capabilities over system capabilities, aligning with the behaviour already seen in Homey Pro 2016-2019.

Currently, when a custom capability on Homey Pro (Early) 2023 shares an ID with a system capability, system Flow cards are generated for that device. However, with the upcoming change, these Flow cards will no longer be available.

To ensure that existing Flows continue to work seamlessly, apps that use system IDs for custom capabilities will need to update their drivers. To avoid breaking Flow cards make sure to add a flow.compose.json to the effected Drivers containing the Flow cards with the same Flow IDs.

The capability IDs listed below are currently used in various apps as custom capabilities. Each file contains the Flow card ID's for that capability. By copying these Flow card ID's and adding them to your drivers flow.compose.json all Flows should keep running.

Device Flow Cards

When your app has multiple drivers that require the same device Flow card, you can put the Flow card definition in your .homeycompose. You can then add a device argument and a filter to make the Flow card appear for the right drivers. See device Flow arguments for more information.

/.homeycompose/flow/actions/disco_mode.json
{
  "title": { "en": "Disco mode" },
  "args": [
    {
      "type": "device",
      "name": "device",
      "filter": "driver_id=my_driver"
    }
  ]
}

Registering Run Listeners

For some Flow cards you will also need to register the correct listeners. The listeners for each capability can be found below the corresponding files. These listeners can be added to your app in the app.js onInit() function.

Duration

If you have enabled duration for any capabilities through the capability options, you will also have to add duration: true to each action Flow card that should support it in your driver.flow.compose.json.

/drivers/<driver_id>/driver.flow.compose.json
{
  "actions": [
    {
      "id": "on",
      "highlight": true,
      "duration": true,
      "title": { "en": "Turn on" }
    }
  ]
}

Capabilities

/app.js
this.homey.flow.getConditionCard('alarm_contact').registerRunListener((args, state) => {
  return args.device.getCapabilityValue('alarm_contact');
});
/app.js
this.homey.flow.getConditionCard('alarm_generic').registerRunListener((args, state) => {
  return args.device.getCapabilityValue('alarm_generic');
});
/app.js
this.homey.flow.getConditionCard('alarm_motion').registerRunListener((args, state) => {
  return args.device.getCapabilityValue('alarm_motion');
});
/app.js
this.homey.flow.getConditionCard('alarm_smoke').registerRunListener((args, state) => {
  return args.device.getCapabilityValue('alarm_smoke');
});
/app.js
this.homey.flow.getConditionCard('alarm_tamper').registerRunListener((args, state) => {
  return args.device.getCapabilityValue('alarm_tamper');
});
/app.js
this.homey.flow.getDeviceTriggerCard('homealarm_state_changed').registerRunListener((args, state) => {
  return args.device.getCapabilityValue('homealarm_state') === args.state;
});
this.homey.flow.getConditionCard('homealarm_state_is').registerRunListener((args, state) => {
  return args.device.getCapabilityValue('homealarm_state') === args.state;
});
this.homey.flow.getActionCard('set_homealarm_state').registerRunListener((args, state) => {
  args.device.setCapabilityValue('homealarm_state', args.state).catch(this.error);
});
/app.js
this.homey.flow.getConditionCard('on').registerRunListener((args, state) => {
  return args.device.getCapabilityValue('onoff');
});
this.homey.flow.getConditionCard('open').registerRunListener((args, state) => {
  return args.device.getCapabilityValue('onoff');
});
this.homey.flow.getActionCard('on').registerRunListener((args, state) => {
  args.device.setCapabilityValue('onoff', true).catch(this.error);
});
this.homey.flow.getActionCard('off').registerRunListener((args, state) => {
  args.device.setCapabilityValue('onoff', false).catch(this.error);
});
this.homey.flow.getActionCard('toggle').registerRunListener((args, state) => {
  const value = args.device.getCapabilityValue('onoff');
  args.device.setCapabilityValue('onoff', !value).catch(this.error);
});
this.homey.flow.getActionCard('open').registerRunListener((args, state) => {
  args.device.setCapabilityValue('onoff', true).catch(this.error);
});
this.homey.flow.getActionCard('close').registerRunListener((args, state) => {
  args.device.setCapabilityValue('onoff', false).catch(this.error);
});
/app.js
this.homey.flow.getActionCard('target_temperature_set').registerRunListener((args, state) => {
  args.device.setCapabilityValue('target_temperature', args.target_temperature);
});
/app.js
this.homey.flow.getDeviceTriggerCard('thermostat_mode_changed').registerRunListener((args, state) => {
  return args.device.getCapabilityValue('thermostat_mode') === args.thermostat_mode;
});
this.homey.flow.getConditionCard('thermostat_mode_is').registerRunListener((args, state) => {
  return args.device.getCapabilityValue('thermostat_mode') === args.thermostat_mode;
});
this.homey.flow.getActionCard('thermostat_mode_set').registerRunListener((args, state) => {
  args.device.setCapabilityValue('thermostat_mode', args.thermostat_mode).catch(this.error);
});

Last updated