# Custom Pairing Views

The pairing views consists of `.html` files in the `/drivers/<driver_id>/pair`-folder. Where the name of the file is the view ID, as `id` described in the App Manifest.

The pairing views have a few Homey-specific JavaScript functions available. They are documented below.

## Back-end API

The `session` property passed in `onPair` can control the front-end programmatically.

{% tabs %}
{% tab title="JavaScript" %}

<pre class="language-javascript" data-title="/drivers/<driver_id>/driver.js"><code class="lang-javascript">const Homey = require('homey');
<strong>
</strong>class Driver extends Homey.Driver {
  async onPair(session) {
    // Show a specific view by ID
    await session.showView("my_view");

    // Show the next view
    await session.nextView();

    // Show the previous view
    await session.prevView();

    // Close the pair session
    await session.done();

    // Received when a view has changed
    session.setHandler("showView", async function (viewId) {
      console.log("View: " + viewId);
    });
  }
}

module.exports = Driver;
</code></pre>

{% endtab %}

{% tab title="TypeScript" %}
{% code title="/drivers/\<driver\_id>/driver.mts" %}

```mts
import Homey from "homey";

export default class Driver extends Homey.Driver {
  async onPair(session: Homey.Driver.PairSession): Promise<void> {
    // Show a specific view by ID
    await session.showView("my_view");

    // Show the next view
    await session.nextView();

    // Show the previous view
    await session.prevView();

    // Close the pair session
    await session.done();

    // Received when a view has changed
    session.setHandler("showView", async (viewId: string) => {
      this.log("View:", viewId);
    });
  }
}

```

{% endcode %}
{% endtab %}

{% tab title="Python" %}
{% code title="/drivers/\<driver\_id>/driver.py" %}

```python
from homey import driver
from homey.pair_session import PairSession


class Driver(driver.Driver):
    async def on_pair(self, session: PairSession) -> None:
        # Show a specific view by ID
        await session.show_view("my_view")

        # Show the next view
        await session.next_view()

        # Show the previous view
        await session.prev_view()

        # Close the pair session
        await session.done()

        # Received when a view has changed
        async def on_show_view(view_id: str) -> None:
            self.log("View:", view_id)

        session.set_handler("showView", on_show_view)


homey_export = Driver

```

{% endcode %}
{% endtab %}
{% endtabs %}

## Front-end API

The following methods are available at the front-end to communicate with the back-end. The `Homey` object is globally available.

### Emit an event

`Homey.emit( String event, Mixed data ): Promise<any>`

Emit an event to your app. The function called will be the one registered by `session.setHandler( String event, Function callback )` in your driver implementation.

{% code title="/drivers/\<driver\_id>/driver.compose.json" %}

```javascript
{
  "name": { "en": "My Driver" },
  "class": "socket",
  "capabilities": ["onoff", "dim"],
  "images": {
    "small": "/drivers/my_driver/assets/images/small.png",
    "large": "/drivers/my_driver/assets/images/large.png",
    "xlarge": "/drivers/my_driver/assets/images/xlarge.png"
  },
  "pair": [
    {
      "id": "my_view"
    }
  ]
}
```

{% endcode %}

{% code title="/drivers/\<driver\_id>/pair/my\_view\.html" %}

```markup
<script type="application/javascript">
  Homey.emit("my_event", { foo: "bar" }).then(function (result) {
    console.log(result); // result is: Hello!
  });
</script>
```

{% endcode %}

{% tabs %}
{% tab title="JavaScript" %}
{% code title="/drivers/\<driver\_id>/driver.js" %}

```javascript
const Homey = require('homey');

class Driver extends Homey.Driver {
  async onPair(session) {
    session.setHandler("my_event", async function (data) {
      // data is { 'foo': 'bar' }
      return "Hello!";
    });
  }
}

module.exports = Driver;
```

{% endcode %}
{% endtab %}

{% tab title="TypeScript" %}
{% code title="/drivers/\<driver\_id>/driver.mts" %}

```mts
import Homey from "homey";

type MyEventData = {
  foo: string;
};

export default class Driver extends Homey.Driver {
  async onPair(session: Homey.Driver.PairSession): Promise<void> {
    session.setHandler("my_event", async (data: MyEventData): Promise<string> => {
      return "Hello!";
    });
  }
}

```

{% endcode %}
{% endtab %}

{% tab title="Python" %}
{% code title="/drivers/\<driver\_id>/driver.py" %}

```python
from typing import TypedDict

from homey import driver
from homey.pair_session import PairSession


class MyEventData(TypedDict):
    foo: str


class Driver(driver.Driver):
    async def on_pair(self, session: PairSession) -> None:
        async def on_my_event(data: MyEventData) -> str:
            return "Hello!"

        session.set_handler("my_event", on_my_event)


homey_export = Driver

```

{% endcode %}
{% endtab %}
{% endtabs %}

### Receive an event

`Homey.on( String event, Function callback )`

Listen to a message from your app. You can trigger this function from your app by calling `session.emit()`.

{% code title="/drivers/\<driver\_id>/pair/start.html" %}

```markup
<script type="application/javascript">
  Homey.on("hello", function (message) {
    Homey.alert(message); // Hello to you!
    return "Hi!"; // send a reply back to the pairing session

    // you can return a promise if you need to do some async
    // work before replying to the message.
  });
</script>
```

{% endcode %}

{% tabs %}
{% tab title="JavaScript" %}
{% code title="/drivers/\<driver\_id>/driver.js" %}

```javascript
const Homey = require('homey');

class Driver extends Homey.Driver {
  async onPair(session) {
    session.setHandler("showView", async (viewId) => {
      if (viewId === "start") {
        const data = await session.emit("hello", "Hello to you!");
        console.log(data); // Hi!
      }
    });
  }
}

module.exports = Driver;
```

{% endcode %}
{% endtab %}

{% tab title="TypeScript" %}
{% code title="/drivers/\<driver\_id>/driver.mts" %}

```mts
import Homey from "homey";

export default class Driver extends Homey.Driver {
  async onPair(session: Homey.Driver.PairSession): Promise<void> {
    session.setHandler("showView", async viewId => {
      if (viewId === "start") {
        const data: string = await session.emit("hello", "Hello to you!");
        console.log(data); // Hi!
      }
    });
  }
}

```

{% endcode %}
{% endtab %}

{% tab title="Python" %}
{% code title="/drivers/\<driver\_id>/driver.py" %}

```python
from typing import TypedDict

from homey import driver
from homey.pair_session import PairSession


class MyEventData(TypedDict):
    foo: str


class Driver(driver.Driver):
    async def on_pair(self, session: PairSession) -> None:
        async def on_show_view(view: str) -> None:
            if view == "start":
                data: str = await session.emit("hello", "Hello to you!")
                print(data)  # Hi!

        session.set_handler("showView", on_show_view)


homey_export = Driver

```

{% endcode %}
{% endtab %}
{% endtabs %}

### Set a Title

`Homey.setTitle( String title )`

Set the window's title.

#### Example

{% code title="/drivers/\<driver\_id>/pair/start.html" %}

```markup
<script type="application/javascript">
  Homey.setTitle(Homey.__("pair.title"));
</script>
```

{% endcode %}

### Set a Subtitle

`Homey.setSubtitle( String subtitle )`

Set the window's subtitle.

#### Example

{% code title="/drivers/\<driver\_id>/pair/start.html" %}

```markup
<script type="application/javascript">
  Homey.setSubtitle(Homey.__("pair.subtitle"));
</script>
```

{% endcode %}

###

### Show a View

`Homey.showView( String viewId )`

Navigate to another view. The parameter `viewId` should be an ID as specified in your App Manifest.

{% code title="/drivers/\<driver\_id>/pair/start.html" %}

```markup
<script type="application/javascript">
  Homey.showView("list_devices");
</script>
```

{% endcode %}

### Previous View

`Homey.prevView()`

Show the previous view.

### Next View

`Homey.nextView()`

Show the next view.

### Get the current view

`Homey.getCurrentView()`

Returns the current view ID.

### Create a device

`Homey.createDevice( Object device ): Promise<Object>`

Create a device with the properties in `device`.

The `device` object must at least contain the properties `data` and `name` and may contain `icon`, `class`, `capabilities`, `capabilitiesOptions`, `store` and `settings`.

#### Example:

{% code title="/drivers/\<driver\_id>/pair/start.html" %}

```markup
<script type="application/javascript">
  Homey.createDevice({
    // The name of the device that will be shown to the user
    name: "My Device",

    // The data object is required and should contain only unique properties for the device.
    // So a MAC address is good, but an IP address is bad (can change over time)
    data: {
      id: "abcd",
    },

    // Optional: The store is dynamic and persistent storage for your device
    store: {
      // For example store the IP address of your device
      address: "127.0.0.1",
    },

    // Optional: Initial device settings that can be changed by the user afterwards
    settings: {
      pincode: "1234",
    },
  })
    .then(function (result) {
      Homey.done();
    })
    .catch(function (error) {
      Homey.alert(error);
    });
</script>
```

{% endcode %}

### Get current zone

`Homey.getZone(): Promise<string>`

Get the Zone ID of the active Zone. The promise resolves to the zone id.

### Get view options

`Homey.getOptions( [String viewId] ): Promise<Object>`

Get the options of a view, or the current view when `viewId` is omitted. The promise resolves to the `viewOptions` of the specified view.

View options may be added to a view by specifying an `options` object in the App Manifest.

### Set navigation close

`Homey.setNavigationClose()`

Remove all navigation buttons and show a single *Close* button.

### Close the pair session

`Homey.done()`

Close the pairing window.

### Alert dialog

`Homey.alert( String message[, String icon] ): Promise<void>` Show an alert dialog. The second parameter `icon` can be `null`, `error`, `warning` or `info`.

### Confirm dialog

`Homey.confirm( String message[, String icon] ): Promise<boolean>` Show a confirm dialog. The second parameter `icon` can be `null`, `error`, `warning` or `info`.

The promise will resolve to `true` when the user pressed `OK`.

### Popup

`Homey.popup( String url )` Show a popup with a remote website.

### Internationalisation

`Homey.__( String key [, Object tokens] )`

Translate a string programmatically. The first argument `key` is the name in your `/locales/__language__.json`. Use dots to get a sub-property, e.g. `settings.title`. The optional second argument `tokens` is an object with replacers.

{% code title="/drivers/\<driver\_id>/pair/start.html" %}

```markup
<script type="application/javascript">
  function onHomeyReady(Homey) {
    alert(Homey.__("pair.title")); // will alert "Settings page title"
  }
</script>
```

{% endcode %}

Within your custom views, you can also use translations. For example:

{% code title="/drivers/\<driver\_id>/pair/start.html" %}

```markup
<span data-i18n="pair.title"></span>
<p data-i18n="pair.intro"></p>
```

{% endcode %}

Read more about translations in the [internationalization guide](/the-basics/app/internationalization.md).

### Show the loading overlay

`Homey.showLoadingOverlay()`

Shows the loading overlay.

### Hide the loading overlay

`Homey.hideLoadingOverlay()`

Hides the loading overlay.

### Get a view's store value

`Homey.getViewStoreValue( String viewId, String key ): Promise<any>`

Get's a view's store value. Promise will resolve to the requested value.

### Set a view's store value

`Homey.setViewStoreValue( String viewId, String key, Mixes value): Promise<void>`

Set a view's store value.

#### Example

{% code title="/drivers/\<driver\_id>/pair/start.html" %}

```markup
<script type="application/javascript">
  var devicesArray = [
    {
      name: "My Device",
      data: {
        id: "abcd",
      },
    },
  ];
  Homey.setViewStoreValue("add_devices", "devices", devicesArray);
</script>
```

{% endcode %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://apps.developer.homey.app/advanced/custom-views/custom-pairing-views.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
