[HC3, HC3L, YH] Quick Apps – managing child devices

Many integrations create multiple devices in the gateway. This section, on the basis of examples, will explain how to add multiple devices with different types and capabilities.

WARNING: this function is available only on Home Center 3, Home Center 3 Lite and Yubii Home with firmware 5.030 or higher.

Overview

When connecting to an IoT cloud service, other hubs, or gateways, you will usually receive a list of devices. They can be represented as a single family with the hub as a parent and each device as a child (also called ‘endpoint’). Each child must be assigned a proper type (available in the FIBARO System) to ensure it is compatible with scenes, panels, voice assistants, etc.

Sample model

In this example, we will use a sample response from an HTTP API of a hub that aggregates IoT devices. The response with a list of devices presents as follows:


This data can be represented in the FIBARO System in the following structure:

Structure explanation:

  • com.fibaro.deviceController will represent the hub itself. Its job is to connect to the hub, parse the response data, and create child devices. Children will have types as below:
    • com.fibaro.binarySwitch will represent the device of a lightBulb type. state field is mapped to value property.
    • com.fibaro.multilevelSwitch will represent the device of a dimmableBulb type. state field is mapped to value property.
    • com.fibaro.temperatureSensor will represent the device of a temperatureSensor type. state field is mapped to value property.

Defining class for a child device

In Quick App you can define a new class as shown below:


Classes in Quick Apps support inheritance. It means that your class can extend other existing classes.
When defining a new class you have to implement its constructor (by defining a special method __init()).
To use Quick Apps built-in mechanism for handling child devices, it has to be derived from class QuickAppChild.

The example below presents a definition of a class called MyBinarySwitch, which derives from QuickAppChild class:


Classes are defined to represent child devices. It is the best practice to create a class for each device type.
For example, if you want to handle children with types: com.fibaro.binarySwitch, com.fibaro.multilevelSwitch and com.fibaro.temperatureSensor, you should define three classes, one for each of them.

Defining method for new classes

Defining new methods for your classes is done the same way as for the QuickApp class.

An example of a class with all methods:


Because the MyBinarySwitch was derived from QuickAppChild class, you can use all QuickAppChild methods (which are described further in this document).
Mapping actions to methods works the same as in a standard Quick App. So in this example, sending turnOn action to a child device represented by MyBinarySwitch class, will automatically call MyBinarySwitch:turnOff method.

Creating a new child device

After defining all classes, you can now create child devices using QuickApp:createChildDevice method like in the example below:


This will create a new device in the system with the type com.fibaro.binarySwitch and the name myChild. In other words, it will create an instance of MyBinarySwitch class. Every new child instance is automatically stored in QuickApp.childDevices member table. So you can access them like this:

Initializing child devices on Quick App startup

When Quick App starts it needs to initialize its child devices. It must know how to map children types into proper classes. This initialization will fill QuickApp.childDevices table.
Children initialization has to be done in QuickApp:onInit method:


If you need to map multiple types into one class, it can be done like this:

WARNING: if there is no class mapping for a type, QuickAppChild class will be used to create its instance.

Accessing parent member

WARNING: self inside of QuickApp methods is not the same self available in other classes.

It is a common mistake to treat self as a global variable. self refers to an instance of the current class (like for example this in Java language). For example, if you have defined ‘login’ Quick App variable in the parent, you will not be able to access it using self:getVariable inside your child’s class (yes, child devices can have their own variables).

Example of using self in parent with defined ‘login’ variable and child without the variable:


You can access parent member inside a child class by using QuickAppChild.parent. With this knowledge you can apply a simple fix to the previous example:


This way you can share parent resources with the children. For example, you can set up TCP client in the parent, and reuse it in your child. There is no need to set it up in each child separately.

Keeping your devices synchronized

Adding child devices is usually not a one-time action in the Quick App lifecycle. When we’re connected to a hub, its list of devices may change over time. Some devices may be added, some removed. The Quick App model should reflect the reality. It is necessary to distinguish which devices were already added to the gateway, which to add, and which need to be removed.

Let’s take a look at our sample model once again:


When downloading the device model from a hub, you can store the original identifier for this device (assigned by the connected hub). Then you can create a mapping for our sample model, which may look like this: <hub device id> -> <hc device id>. This will enable you to check which device on the gateway represents a particular device on the hub. You have to do this on child device creation.


Now by using devicesMap you can properly synchronize your devices. It can help you with updating properties as well.

April 9, 2020   5644    Tutorials    
Total 14 Votes:
5

Tell us how can we improve this post?

+ = Verify Human or Spambot ?

Comments are closed.