[HC3] Quick Apps – managing child devices

Many integrations create multiple devices in the Home Center. 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 with firmware 5.030 or higher.

Overview

When connecting to an IoT cloud service, other hubs or gateways, we usually download a list of their devices so they can be represented as separate ‘endpoints’ in the Home Center system. It is also important to set proper types for these devices as it ensures their compatibility with scenes, panels, voice assistance, etc.

Sample model

An example of a hub that aggregates IoT devices with HTTP API. The response with a list of devices presents as follow:

This data can be represented as the following structure:

Structure explanation:

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

Defining class for a child device

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

Classes in Quick Apps supports inheritance. It means that your class can extend other existing classes.
When defining new class you must implement its constructor (by defining a special method __init()).
To use Quick Apps built-in mechanism for handling child devices, we derive from class QuickAppChild.

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

We define classes to represent our child devices. Usually, we create class per device type.
For example: we want to handle childs with types: com.fibaro.binarySwitch, com.fibaro.multilevelSwicth and com.fibaro.temperatureSensor.
It is best to define 3 classes for that.

Defining method for new classes

Defining new methods for your classes, look the same as for class QuickApp.

An example of a class with all methods:

Because we derived from QuickAppChild class, we can use its methods (which are described further in this document). Mapping actions to methods work the same. So in this example, sending action turnOn to a child device represented by MyBinarySwitch class, will automatically call MyBinarySwitch:turnOff method.

Creating new child device

If we have all classes defined, we can now create our child devices. For that, we’ll use QuickApp:createChildDevice method like in the example below:

This will create a new device in the system type of com.fibaro.binarySwitch and with the name myChild. In the code, it will create an instance of class MyBinarySwitch. 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 child’s types into proper classes. This initialization will fill QuickApp.childDevices table.

It must be done in QuickApp:onInit method:

If for some reasons, you need to map multiple types into one class, just write:

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

Accessing parent/child members

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

We had to point it out, because 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 a login variable defined in the parent, you won’t be able to access it by self:getVariable inside your child class (yes, child devices can have their own variables). Example:

As shown above, it is possible to access child devices from the parent using QuickApp.childDevices table. To go the other way around: we can access parent inside a child class by using QuickAppChild.parent member. With this knowledge we can apply a simple fix to our previous example:

This way you can share resources between a parent and children. You can for example set up TCP connection in the parent, and reuse it in your child. There is no need to set up it in each child separately. Remember, don’t waste resources 😉

WARNING: QuickApp.childDevices is not accessible in a child’s constructor, only in their methods.

Keep your devices synchronized

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

We can take a look at our sample model:

When downloading devices model from a hub, we can store the original identifier of this device used on a hub. Then we can create some kind of map for our sample model, which may look like this: <hub device id> -> <hc device id>. We’ll be able to check which device from the Home Center represents a particular device from a hub. We would have to do this on child device creation.

Now by using devicesMap we can properly synchronize our devices. It can help us with updating properties as well.

April 9, 2020   1525    Tutorials    
Total 8 Votes:
2

Tell us how can we improve this post?

+ = Verify Human or Spambot ?

Comments are closed.