Homey Cloud

Everything you need to know to make your apps compatible with Homey Cloud.

The Homey Apps SDK is engineered to support both Homey Pro and Homey Cloud. Whether you developed your app for Homey Cloud or Homey Pro, it likely already works on both platforms. However there are some important differences that you should be aware of. This page will explain those differences and help you make sure your app offers the best experience to users whether they use Homey Cloud or Homey Pro.

You should not use "Homey Cloud" in user facing texts. Our products are Homey and Homey Pro. Homey Cloud is a term that is only used for developers to distinguish on what platform apps are running.

Architecture

It is important to know how your apps will be run in Homey Cloud. On Homey Cloud your app is responsible for more than one user at a time. We refer to this as multi-tenancy, which means that several app instances are created inside the same Node.JS process. In addition if your app has many users it will get started on several servers to spread the load.

Despite Homey Cloud running apps in the cloud it is still possibly to easily test your app during development. If you run homey app run while having a Cloud Homey selected, the Homey CLI will automatically guide you to install all the required tools. It will then run the app on your computer and connect it to Homey Cloud.

Verified apps

Because Homey Cloud is offered for a mainstream audience, we want to ensure every app is of great quality. To assist with this, we offer code-level support and in-depth app reviews as part of the Homey Verified Developer subscription. This subscription is required to publish your app to the App Store when targeting "platforms": [ "cloud" ] or "platforms": [ "local", "cloud" ].

Only official app integrations will be approved. This means an app submitted by a brand or submitted by a third party developer commissioned by said brand.

Publishing apps for Homey Pro does not require a subscription and will always remain free.

You can check whether your app passes some of the additional validation by running:

homey app validate --level verified

Adding supported platforms

To indicate that your app supports running on Homey Cloud you will need to add the platforms flag to your App, Driver and Flow manifests.

/.homeycompose/app.json
{
  "id": "my.company.example",
  "version": "1.0.0",
  "compatibility": ">=5.0.0",
  "platforms": ["local", "cloud"],
  "sdk": 3,
  // ...
}

Only SDK v3 is supported on Homey Cloud so before you start making your app compatible with Homey Cloud, make sure you are using SDK v3.

/.homeycompose/flow/triggers/rain_start.json
{
  "title": {
    "en": "It starts raining"
  },
  "hint": {
    "en": "When it starts raining more than 0.1 mm/h."
  }
  "platforms": ["local", "cloud"]
}

Each individual driver can list the supported platforms and the wireless connectivity that is used with the platforms and connectivity properties:

/drivers/<driver_id>/driver.compose.json
{
  "name": { "en": "My Driver" },
  "platforms": ["local", "cloud"],
  "connectivity": ["ble"],
  "class": "light",
  "capabilities": ["onoff", "dim"],
}

The available options for connectivity are:

Value

Description

lan

This is not possible with Homey Bridge, see SDK difference between Homey Pro and Homey Cloud.

cloud

This means that your Driver uses OAuth or Webhooks to connect to a cloud service.

ble

Use if your Driver connects to Bluetooth Low Energy devices.

zwave

Use if your Driver implements a Z-Wave device.

zigbee

Use if your Driver implements a Zigbee device.

infrared

Use if your Driver sends infrared signals.

rf433

Use if your Driver sends 433Mhz signals.

rf868

This is not possible with Homey Bridge.

Read the App Store Guidelines for more information.

Mutating global variables

In order to handle multi-tenancy for Homey Cloud, your app should not use global variables. Because the global scope is shared the values of global variables may be unpredictable.

This is a contrived example of what you should not do:

/app.js
const Homey = require('homey');

// BAD: This variable will be shared by several app instances
let count = 0; 

class App extends Homey.App {
  onInit() {
    count += 1;
  }
}

module.exports = App;

Instead you should set properties on your App, Driver or Device instances:

/app.js
const Homey = require('homey');

class App extends Homey.App {
  onInit() {
    // GOOD: this variable is only used by a single app instance
    this.count += 1;
  }
}

module.exports = App;

Cleanup

Multi-tenancy also means that your app should cleanup when an instance is destroyed. For example if a user removes an app. On Homey Pro that causes the entire app process to be killed but on Homey Cloud you need to put in some extra care to make sure all your resources are correctly released.

App lifecycle

In order to make this easier the Apps SDK as several "un-init" methods: App#onUninit(), Driver#onUninit(), and Device#onUninit(). These methods will be called when your app is destroyed so you can perform cleanup in them. For example:

/app.js
const Homey = require('homey');

class App extends Homey.App {
  async onInit() {
    this.api = new DeviceApi();
  }
  
  async onUninit() {
    this.api.destroy();
  }
}

module.exports = App;

Clearing Timers

Another case in which you need to take care to clean up when your app is uninstalled would be timers like setInterval() and setTimeout(). You should not call these directly, instead you should use this.homey.setInterval() or this.homey.setTimeout(). These act exactly the same as their regular counterparts but will automatically be cleared when your app is destroyed.

Make sure you don't do this:

/app.js
const Homey = require('homey');

class App extends Homey.App {
  onInit() {
    // BAD: the interval is not cleaned up after the app instance is destroyed
    setInterval(() => {
      // do something
    }, 10000);
  }
}

module.exports = App;

Instead write code like this:

/app.js
const Homey = require('homey');

class App extends Homey.App {
  onInit() {
    // GOOD: this will automatically be cleared when the app is destroyed
    this.homey.setInterval(() => {
      // do something
    }, 10000);
  }
}

module.exports = App;

Unhandled Promise rejections

On Homey Cloud unhandled promise rejections will cause the app to crash. Unhandled promise rejections can cause memory leaks and may indicate that your app is not correctly handling errors. If errors do not matter you can, in most cases, simply log the error using: .catch(this.error);

This behaviour is about to be standard in Node.JS and is therefore also coming to Homey Pro in the near future.

An example of this is Device#setCapabilityValue() which returns a promise. In order to prevent unhandled promise rejections you should add .catch(this.error).

Make sure you don't do this:

/drivers/<driver_id>/device.js
const Homey = require('homey');

class Device extends Homey.Device {
  async onInit() {
    // BAD: this returns a promise, which may cause an unhandled promise rejection
    this.setCapabilityValue('onoff', false);
  }
}

module.exports = Device;

Instead write code like this:

/drivers/<driver_id>/device.js
const Homey = require('homey');

class Device extends Homey.Device {
  async onInit() {
    // GOOD: catching the promise prevents unhandled promise rejections
    this.setCapabilityValue('onoff', false).catch(this.error);
  }
}

module.exports = Device;

SDK differences between Homey Pro & Homey Cloud

Homey Cloud apps are not allowed to do everything that apps on Homey Pro are allowed to do. The following Apps SDK features are not supported on Homey Cloud:

App Web API

Homey Cloud does not have support for App Web APIs. While this means that you cannot expose a complete REST API you can still receive Webhook updates. Read the Webhooks documentation to learn more.

App-to-app communication

App-to-app communication is usually pretty tricky for a user to setup and may break due to app changes. Because of this it is not supported on Homey Cloud. This means that apps that run on Homey Cloud cannot have homey:app:<appId> permissions. Likewise the homey:manager:api permission that allowed an app to use ManagerApi and the Homey Web API is not allowed.

Local Wi-Fi & Device Discovery

Homey Bridge does not support local Wi-Fi connections, therefore mDNS, SSDP and MAC discovery are not supported.

Obviously this means that ManagerCloud#getLocalAddress() is also not supported on Homey Cloud.

App Settings

To simplify the user experience, custom app settings views are not supported on Homey Cloud.

Any information your app might need to function should be asked for when pairing a device. If information needs to be updated you can use the "re-pair" pairing views so a users Flows don't become broken. Read the Custom Pairing Views documentation for more information.

Relative vs. Absolute Paths

On Homey Pro, apps are sandboxed and chroot'ed. On Homey Cloud, apps are run in a Docker container.

This means that the root-path / is different. On Homey Pro, / is your app's directory, and on Homey Cloud, / is the Linux root.

To ensure your app works on both platforms, always require files relatively, e.g. require('./assets/foo.js') or path.join(__dirname, 'myfile.svg').

Avoiding app review rejections for Homey Cloud

Because Homey Cloud is targeted at a broader audience not all the types of apps that are available on Homey Pro are going to be approved for Homey Cloud.

Apps that add Drivers for a brand of smart home devices are very welcome on Homey Cloud. However apps that add advanced functionality that can only be used in combination with other apps are going to be rejected.

Generally these kinds of apps are found in the "Tools" category on the Homey Apps Store. Most of these apps won't work on Homey Cloud because the homey:manager:api permission is not allowed to be used.

If you are a verified developer and are questioning whether your app idea will be allowed to be published on Homey Cloud be sure to get in touch with the developer support.

Last updated