Arguments

Flow arguments allow Flow cards to ask for user input.

Flow card arguments are passed as an input to your Flow card, users can pick the argument values when creating or editing a Flow.

Arguments must have a type that determines how they are shown. For example, a dropdown argument allows a user to pick one value from a predefined set of options, whereas a text argument shows an input field.

Don't overuse arguments! In our experience, Flow cards with just one or two arguments are the most popular.

Argument Types

The following are all available argument types that you can use in your Flow cards and the options that you can use with those types.

Text

"type": "text"

Regular text input. Text, Number and Boolean tokens can be dropped in this field as well.

Attributes

Name

Type

Description

Example

placeholder

translation object

Text to show without input

{ "en": "Hello, World!", "nl": "Hallo, Wereld!" }

title

translation object

Text shown above argument

{ "en": "Sentence", nl": "Zin" }

Example

/.homeycompose/flow/actions/greet.json
{
"title": { "en": "Say a greeting" },
"titleFormatted": { "en": "Say [[sentence]]" },
"args": [
{
"type": "text",
"name": "sentence",
"title": { "en": "Sentence" },
"placeholder": { "en": "Hello!" }
}
]
}

Autocomplete

"type": "autocomplete"

This is the same as a text input, but with an additional autocomplete popup. The returned value when the card is run, is one of the objects provided in the autocomplete array. In order to provide autocomplete results you need to register an autocomplete listener for the Flow card with FlowCard#registerArgumentAutocompleteListener()

Attributes

Name

Type

Description

Example

placeholder

translation object

Text to show without input

{ "en": "YouTube", "nl": "Dumpert" }

title

translation object

Text shown above argument

{ "en": "Application", nl": "Applicatie" }

Example

/.homeycompose/flow/actions/play_artist.json
{
"title": { "en": "Play an Artist" },
"titleFormatted": { "en": "Play an Artist [[artist]]" },
"args": [
{
"type": "autocomplete",
"name": "artist",
"title": { "en": "Artist" },
"placeholder": { "en": "Ludwig van Beethoven" }
}
]
}
/app.js
const Homey = require('homey');
class App extends Homey.App {
async onInit() {
const launchAppCard = this.homey.flow.getActionCard("play_artist");
launchAppCard.registerArgumentAutocompleteListener(
"artist",
async (query, args) => {
const results = [
{
name: "Wolfgang Amadeus Mozart",
description: "Joannes Chrysostomus Wolfgangus Theophilus Mozart",
icon: "https://path.to/icon.svg",
// For images that are not svg use:
// image: 'https://path.to/icon.png',
// You can freely add additional properties
// that you can access in registerRunListener
id: "...",
},
];
// filter based on the query
return results.filter((result) => {
return result.name.toLowerCase().includes(query.toLowerCase());
});
}
);
}
}
module.exports = App;

If you don't filter based on the query, it will cause the autocomplete results to appear unresponsive. The easiest way to filter the results is to compare name and query in lowercase as shown above.

Number

"type": "number"

Regular text input. Tokens can be dropped in this field as well.

Attributes

Name

Type

Description

Example

min

number

Minimum input value

40

max

number

Maximum input value

90

step

number

Step size

10

placeholder

translation object

Text to show without input

{ "en": "In degree celsius", "nl": "In graden celsius" }

title

translation object

Text shown above argument

{ "en": "Temperature", nl": "Temperatuur" }

Example

/.homeycompose/flow/actions/wash_clothes.json
{
"title": { "en": "Wash clothes" },
"titleFormatted": { "en": "Wash clothes at [[temperature]] degrees celsius" },
"args": [
{
"type": "number",
"name": "temperature",
"title": { "en": "Temperature" },
"placeholder": { "en": "In degree celsius" },
"min": 40,
"max": 90,
"step": 10
}
]
}

Range

"type": "range"

A slider with a minimum and maximum value.

Attributes

Name

Type

Description

Example

min

number

Minimum input value

0

max

number

Maximum input value

1

step

number

Step size

0.01

label

string

The units after the number

%

labelMultiplier

number

Number is shown after multiplying by this factor

100

labelDecimals

number

Number of decimals to round to

2

title

translation object

Text shown above argument

{ "en": "Brightness", nl": "Helderheid" }

Example

/.homeycompose/flow/actions/set_brightness.json
{
"title": { "en": "Set brightness" },
"titleFormatted": { "en": "Set brightness to [[brightness]]" },
"args": [
{
"type": "range",
"name": "brightness",
"title": { "en": "Brightness" },
"min": 0,
"max": 1,
"step": 0.01,
"label": "%",
"labelMultiplier": 100,
"labelDecimals": 2
}
]
}

Date

"type": "date"

Date input (presented in dd-mm-yyyy)

Attributes

Name

Type

Description

Example

placeholder

translation object

Text to show without input

{ "en": "When to ..", "nl": "Wanneer te .." }

title

translation object

Text shown above argument

{ "en": "Birthday", nl": "Verjaardag" }

Example

/.homeycompose/flow/actions/birthday_surprise.json
{
"title": { "en": "Birthday surprise" },
"titleFormatted": { "en": "Surprise you on [[birthday]]" },
"args": [
{
"type": "date",
"name": "birthday",
"title": { "en": "Birthday" },
"placeholder": { "en": "18-05-1994" }
}
]
}

Time

"type": "time"

Time input (presented in HH:mm)

Attributes

Name

Type

Description

Example

placeholder

translation object

Text to show without input

{ "en": "When to ..", "nl": "Wanneer te .." }

title

translation object

Text shown above argument

{ "en": "Time", nl": "Tijd" }

Example

/.homeycompose/flow/actions/activate_alarm.json
{
"title": { "en": "Activate the alarm" },
"titleFormatted": { "en": "Activate the alarm at [[activationtime]]" },
"args": [
{
"type": "time",
"name": "activationtime",
"title": { "en": "Time" },
"placeholder": { "en": "13:37" }
}
]
}

"type": "dropdown"

A dropdown list with pre-defined values

Attributes

Name

Type

Description

Example

values

array

An array of possible values

[ { "id": "value1", "label": { "en": "Value 1" } } ]

title

translation object

Text shown above argument

{ "en": "My title", nl": "Mijn titel" }

Example

/.homeycompose/flow/triggers/rain_start.json
{
"title": { "en": "It is going to rain in..." },
"titleFormatted": { "en": "It is going to rain in [[when]]" },
"args": [
{
"type": "dropdown",
"name": "when",
"title": { "en": "When it will rain" },
"values": [
{ "id": "5", "label": { "en": "5 minutes" } },
{ "id": "10", "label": { "en": "10 minutes" } },
{ "id": "15", "label": { "en": "15 minutes" } }
]
}
]
}

Color

"type": "color"

A color picker that returns a HEX color, e.g. #FF0000.

Example

/.homeycompose/flow/actions/set_tile_color.json
{
"title": { "en": "Set tile color" },
"titleFormatted": { "en": "Set tile color to [[background]]" },
"args": [
{
"type": "color",
"name": "background"
}
]
}

Droptoken

A droptoken is a special Flow card Argument that only allows the user to enter a Flow Token or Homey Logic variable. You can add a droptoken to your Flow card by specifying, for example, "droptoken": ["number"]. You can use the any of the following types: string, number, boolean or image. A Flow card can only have a single droptoken but you can specify multiple allowed types.

Example

/.homeycompose/flow/conditions/equal.json
{
"title": { "en": "Is equal" },
"titleFormatted": { "en": "[[droptoken]] equals [[value]]" },
"droptoken": ["number"],
"args": [
{
"type": "number",
"name": "value"
}
]
}

Device

"type": "device"

When you add a device argument to your flow card, and provide a driver_id filter, e.g. "filter": "driver_id=yourdriverid", the flow card will only be displayed for devices that belong to that specific driver.

If the device was already there because the device's class is a supported device class (e.g. light), your cards will be appended to the existing stack of cards. An example would be a Light driver that has a 'disco' mode, next to on/off, dim and color.

If the card has more than one device fields, the other fields will behave like an autocomplete-like argument, which show devices paired in your app.

See the Flow guide Device cards section for more information about device arguments _**_and filters.

Optional arguments

By default all Flow card arguments are required however if you want to allow an argument to be optional you can set the required property to false.

If an argument is not required and is not provided by the user it may be undefined in your Flow card run handler.

Example

/.homeycompose/flow/actions/post_data.json
{
"title": { "en": "Post data to URL" },
"titleFormatted": { "en": "Post [[data]] to [[url]]" },
"args": [
{
"type": "text",
"name": "url",
"title": { "en": "URL" },
"placeholder": { "en": "https://example.com" }
}
{
"type": "text",
"name": "data",
"required": false,
"title": { "en": "Body" },
"placeholder": { "en": "message" }
}
]
}

Action Card duration

If you are creating an Action Flow card, a card for the ...then column, you can set the duration property. This property allows users to choose a duration for the action. If a user provides this argument to the Flow card, it will be passed to the card handler as an argument named duration in milliseconds.

"duration": true has precedence over an argument with "name": "duration" as they are both provided as arguments to the same handler. You should not create a Flow card with the duration property and an argument named "duration".

Example

/.homeycompose/flow/actions/run_animation.json
{
"title": { "en": "Run animation" },
"titleFormatted": { "en": "Run animation [[animation]]" },
"duration": true,
"args": [
{
"type": "dropdown",
"name": "animation",
"title": { "en": "Animation" },
"values": [
{ "id": "rainbow", "label": { "en": "Rainbow" } },
{ "id": "kitt", "label": { "en": "KITT" } },
{ "id": "pulse", "label": { "en": "Pulse" } }
]
}
]
}
/app.js
const Homey = require('homey');
class App extends Homey.App {
async onInit() {
const runAnimationAction = this.homey.flow.getActionCard("run_animation");
runAnimationAction.registerRunListener(async (args, state) => {
if (args.duration != null) {
// do something with the duration
// (e.g. run an animation for duration milliseconds)
}
});
}
}
module.exports = App;

Subscribing to argument changes

It might be useful to know when a trigger has changed. For example a Twitter app may have a Flow card that triggers a Flow when a specific hashtag is tweeted. In order to implement this behaviour the app needs to know what hashtags to search for. By subscribing to argument changes the app knows when the argument values have changed and update the list of hashtags it is looking for.

/app.js
const Homey = require('homey');
class App extends Homey.App {
async onInit() {
const myAction = this.homey.flow.getActionCard("my_action");
myAction.on("update", () => {
this.log("update");
myAction.getArgumentValues().then((args) => {
// args is [{ "my_arg": "user_value" }]
});
});
}
}
module.exports = App;

Flow State

When a Flow is triggered and the Flow Trigger card has arguments, your app needs to validate that the current state matches with the arguments the user chose for the Flow. This listener is executed for each Flow that uses this Flow Trigger card.

For example, a rain_start Flow Trigger card can have a location argument so that the Flow is only triggered when it is raining in the place the user has selected.

/.homeycompose/flow/triggers/rain_start.json
{
"title": { "en": "It starts raining" },
"tokens": [
{
"name": "mm_per_hour",
"type": "number",
"title": { "en": "mm/h" },
"placeholder": { "en": "5" }
}
],
"args": [
{
"name": "location",
"type": "text"
}
]
}
/app.js
const Homey = require('homey');
const RainApi = require('rain-api');
class App extends Homey.App {
async onInit() {
const rainStartTrigger = this.homey.flow.getTriggerCard("rain_start");
rainStartTrigger.registerRunListener(async (args, state) => {
// args is the user input,
// for example { 'location': 'New York' }
// state is the parameter passed in trigger()
// for example { 'location': 'Amsterdam' }
// If true, this flow should run
return args.location === state.location;
});
RainApi.on('raining', (city, amount) => {
const tokens = { mm_per_hour: amount }; // for example 3
const state = { location: city }; // for example "Amsterdam"
// trigger the card
rainStartTrigger.trigger(tokens, state)
.then(this.log)
.catch(this.error);
});
}
}
module.exports = App;