Save button or Homey.alert not working in custom pairing view

Hi everyone

I’m a total beginner in Homey app development, and I ran into a silly issue I just can’t figure out.

I created a custom pairing view with a simple form to enter IP and Port for a WiFi bulb. But for some reason, the Save button doesn’t seem to work, or maybe Homey.alert() is silently failing — I can’t tell what’s going wrong.

I followed the official documentation here:
Custom Pairing Views — Homey Developer Docs

I might be misunderstanding something fundamental, and even ChatGPT couldn’t give me a working fix.

Here’s my enter-credentials.html:

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>Enter WiFi Bulb Info</title>
  <script src="/homey.js" data-origin="pair"></script>
  <style>
    body { font-family: sans-serif; padding: 20px; }
    .homey-header { margin-bottom: 20px; }
    .homey-form-group { margin-bottom: 15px; }
    label { display: block; margin-bottom: 5px; font-weight: bold; }
    input { width: 100%; padding: 8px; box-sizing: border-box; }
    .homey-button-primary {
      padding: 10px 20px;
      font-size: 16px;
      background-color: #007bff;
      color: white;
      border: none;
      border-radius: 4px;
      cursor: pointer;
      width: 100%;
      margin-top: 10px;
    }
    .homey-button-primary:hover {
      background-color: #0056b3;
    }
  </style>
</head>
<body>
  <header class="homey-header">
    <h1 class="homey-title">Enter WiFi Bulb Information</h1>
    <p class="homey-subtitle">Please enter the IP and Port of your device</p>
  </header>

  <div class="homey-form-group">
    <label for="bulb_ip">Bulb IP</label>
    <input id="bulb_ip" type="text" placeholder="192.168.1.100">
  </div>

  <div class="homey-form-group">
    <label for="bulb_port">Port</label>
    <input id="bulb_port" type="number" value="80" min="1" max="65535">
  </div>

  <button id="save" class="homey-button-primary">Save</button>

  <script type="application/javascript">
    Homey.alert("fronted loading");

    const ipInput = document.getElementById('bulb_ip');
    const portInput = document.getElementById('bulb_port');
    const saveBtn = document.getElementById('save');

    Homey.on("welcomeMessage", function (message) {
      Homey.alert(message);
    });

    Homey.on("validationResult", function (message) {
      Homey.alert(message);
    });

    saveBtn.addEventListener('click', function () {
      const bulb_ip = ipInput.value.trim();
      const bulb_port = Number(portInput.value.trim());

      if (!bulb_ip || isNaN(bulb_port) || bulb_port < 1 || bulb_port > 65535) {
        Homey.alert('Please enter a valid IP (e.g. 192.168.1.100) and Port (1-65535)');
        return;
      }

      Homey.emit("save", { bulb_ip, bulb_port })
        .then(function (result) {
          if (result.success) {
            Homey.alert('IP and Port saved successfully!');
            Homey.done();
          }
        })
        .catch(function (err) {
          Homey.alert('Error: ' + (err?.message || 'Failed to save'));
        });
    });
  </script>
</body>
</html>

And here’s my driver.js:

'use strict';
const Homey = require('homey');

module.exports = class MyDriver extends Homey.Driver {
  async onInit() {
    this.log('v2 has been initialized');
  }

  async onPair(session) {
    this.log('Pairing started');

    session.setHandler('save', async function ({ bulb_ip, bulb_port }) {
      this.log(`Received IP: ${bulb_ip}, Port: ${bulb_port}`);

      const ipRegex = /^(25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)){3}$/;
      if (!bulb_ip || !ipRegex.test(bulb_ip)) {
        await session.emit('validationResult', 'Invalid IP address (e.g. 192.168.1.100)');
        throw new Error('Invalid IPv4 address');
      }

      if (isNaN(bulb_port) || bulb_port < 1 || bulb_port > 65535) {
        await session.emit('validationResult', 'Invalid Port (must be 1-65535)');
        throw new Error('Invalid port number');
      }

      await session.emit('validationResult', 'IP and Port verified successfully!');
      await session.done();
      return { success: true };
    }.bind(this));

    session.setHandler('showView', async function (viewId) {
      this.log('Switched to view:', viewId);
      if (viewId === 'enter-credentials') {
        await session.emit('welcomeMessage', 'Please enter your WiFi Bulb\'s IP and Port');
      }
    }.bind(this));

    await session.showView('enter-credentials');
  }

  async onPairListDevices() {
    return [];
  }
};

Any idea why Homey.alert() might not be showing anything, or why the Save button seems unresponsive? I’m probably missing something obvious.

Thanks in advance!

Moved to Developers

Don’t tell me you were surprised by that? :zany_face:

Your script starts with Homey.alert("fronted loading"), are you saying that that doesn’t work already? If it does, then the conclusion is that Homey.alert() works as expected and there’s something else wrong.

Run the pairing session from a regular browser (here) while you have your browser’s developer tools/JS console open, and see if any errors occur.

You can also add logging steps (using plain console.log()) everywhere to see which code is still reached, and where it stops. Your issue will be somewhere in between.

1 Like

Thanks a lot for pointing out browser debugging! I honestly thought pairing could only be tested through the mobile app, and I had no idea the web version could expose logs like that.

Once I opened the pairing session in a regular browser and checked the console, I got way more visibility — tons of logs I couldn’t see before. That helped me pinpoint the issue quickly.

Appreciate the tip!

1 Like