# 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](https://apps.developer.homey.app/the-basics/app/internationalization).

### 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 %}
