Flow

The Flow Editor is where users create Flows for their Homey. As a developer, you can add new functionality from your app to the Flow Editor by exposing various cards.

A Flow consists of cards in three columns: when, and, then.

  • Cards in the when... column are called triggers. Your app tells Homey to fire a trigger, which will then run all of the user's flows with this trigger.
  • Cards in the ...and... column are called conditions. These are things that must be true, for the flow to continue. For example it is raining, or the vacuum cleaner is cleaning.
  • Cards in the ...then column are called actions. These are fired when the trigger has been fired, and all conditions are met.

Your app can expose any of these three card types, by defining them in your /app.json.

If your app contains one or more drivers, please note that most device classes already have their own flow cards. So most of the time it's not necessary to create them yourself.

/app.json

"id": "com.weather.example",
...
"flow": {
  "triggers": [
    {
      "id": "rain_start",
      "title": {
        "en": "It starts raining"
      },
      "hint": {
        "en": "When it will start raining more than 0.1 mm/h."
      },
    },
    {
      "id": "rain_stop",
      "title": {
        "en": "It stops raining"
      },
      "hint": {
        "en": "When it stops raining."
      },
    }
  ],
  "conditions": [
    {
      "id": "is_raining",
      "title": {
        "en": "It !{{is|isn't}} raining"
      },
      "hint": {
        "en": "This Flow will continue if it is/is not currently raining more than 0.1 mm/h."
      }
    },
    {
      "id": "raining_in",
      "title": {
        "en": "It's going to rain in..."
      },
      "titleFormatted": {
        "en": "It !{{is|isn't}} going to rain in [[when]]"
      },
      "hint": {
        "en": "This Flow will continue if it will/will not rain more than 0.1 mm/h within the given amount of time."
      },
      "args": [
        {
          "name": "when",
          "type": "dropdown",
          "values": [
            {
              "id": "5",
              "label": {
                "en": "5 minutes"
              }
            },
            {
              "id": "10",
              "label": {
                "en": "10 minutes"
              }
            },
            {
              "id": "15",
              "label": {
                "en": "15 minutes"
              }
            }
          ]
        }
      ]
    }
  ],
  "actions": [
    {
      "id": "stop_raining",
      "title": {
        "en": "Make it stop raining. Haha."
      }
    }
  ]
}

Defining Flow cards

All Flow cards must at least have an id and a title property. The id is used to refer to the Flow card from your source code. The title will be shown to the users and should be a short and clear description of what the Flow card does. A Flow card can have an optional hint property that can be used to pass additional information to the user that can not be included in the title.

 {
    "id": "rain_start",
    "title": {
      "en": "It starts raining"
    },
    "hint": {
      "en": "When it starts raining more than 0.1 mm/h."
    },
  },

When a Flow card contains arguments it may be necessary to change the title according to these arguments. Using the titleFormatted property it is possible to integrate argument values into the title of the Flow card.

{
  "titleFormatted": {
    "en": "Send a notification to [[person]]"
  }
}

For conditional Flow cards it is possible to change the title if the Flow card is inverted. This can be done using the !{{ text_normal | text_inverted }} syntax.

{
  "titleFormatted": {
    "en": "This Flow !{{is|is not}} inverted"
  }
}

Triggering a Flow

To fire a trigger, run the following code from anywhere in your app:

/app.js

let rainStartTrigger = this.homey.flow.getTriggerCard('rain_start');
rainStartTrigger.trigger()
  .catch(this.error)
  .then(this.log);

All of the Flows on the Homey, with the trigger rain_start will now fire.

More advanced triggers can be achieved using Tokens, State and Devices.

Listening for events

In your app, you should register a run listener for each Flow card. Conditions and Actions should always do this, and Triggers only when they have one or more Arguments.

Cards must resolve with a true value for the Flow to continue, or a false value to stop the Flow from executing. When the card is rejected, the Flow stops executing as well.

/app.js

let rainingCondition = this.homey.flow.getConditionCard('is_raining');
rainingCondition.registerRunListener(async (args, state) => {
  let raining = rain.isRaining(); // true or false
  return raining;
});

let stopRainingAction = this.homey.flow.getActionCard('stop_raining');
stopRainingAction.registerRunListener(async (args, state) => {
  let isStopped = rain.stop(); // true or false
  return isStopped;
});

Deprecating cards

Sometimes a Flow card that has been available in the past should be removed. To not break compatibility for users that were using it, add "deprecated": true to your Flow card in /app.json. It will still work, but won't show up anymore in the 'Add Card' list.


Child Topics