Skip to content

Commit

Permalink
[DOCS-469] Composite tiles document (#605)
Browse files Browse the repository at this point in the history
* composite tiles document

* Added note on icon parameter, changed Example section title

* Added intro to composite tiles section

* Added both parent and child tile code in the intro
  • Loading branch information
Raj Karamchedu authored and jimmyjames committed May 4, 2017
1 parent b125c41 commit 6620f15
Show file tree
Hide file tree
Showing 4 changed files with 220 additions and 2 deletions.
163 changes: 161 additions & 2 deletions composite-devices/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ and,
onOffCmd(0, channelNumber(dni))
}
----

.. _composite_device_child_device_handler:

Child Device Handler
Expand Down Expand Up @@ -105,6 +107,10 @@ Next, the below Device Handler code sets up the *outlet* of the Zooz ZEN20 Z-Wav
In the above example, the method calls, ``parent.childOn(device.deviceNetworkId)`` and ``parent.childOff(device.deviceNetworkId)``, are the means of communication between the parent and the child instances of this composite device.

----

.. _composite_device_deleting:

Deleting a Composite Device
---------------------------

Expand All @@ -124,8 +130,161 @@ If you try to delete a composite device from your SmartThings mobile app, then t

Note that the following applies for a composite device:



- A single SmartApp can control all the components, each independently, sending and receive messages from each component device.

- A single SmartApp can control all components together in an all-or-nothing fashion.

----

.. _composite_device_tiles:

Composite Device Tiles
----------------------

Child device tiles can be visually pulled together into a composite tile.
On SmartThings mobile app, such a composite tile represents a rich interface for the display and control of a composite device.

For example, consider a refrigerator composite device that is built with two child components, i.e., the fridge door and the temperature control.

In the fridge door child Device Handler, the tile for the fridge door ``mainDoor`` is defined normally with the ``standardTile`` method, as below:

.. code-block:: groovy
// Fridge door child component Device Handler
metadata {
definition (name: "Simulated Refrigerator Door", namespace: "smartthings/testing", author: "SmartThings") {
capability "Contact Sensor"
capability "Sensor"
capability "open"
capability "close"
}
tiles {
standardTile("mainDoor", "device.contact", width: 2, height: 2, decoration: "flat") {
state("closed", label:'Fridge', icon:"st.contact.contact.closed", backgroundColor:"#79b821")
state("open", label:'Fridge', icon:"st.contact.contact.open", backgroundColor:"#ffa81e")
}
}
...
}
Then, by using the method :ref:`childDeviceTile_DH_ref` within the refrigerator parent Device Handler, we can customize how the above fridge door tile ``mainDoor`` is pulled visually into the refrigerator composite tile.
See below:

.. code-block:: groovy
// Refrigerator parent Device Handler
metadata {
definition (name: "Simulated Refrigerator", namespace: "smartthings/testing", author: "SmartThings") {
capability "Contact Sensor"
}
tiles {
childDeviceTile("mainDoor", "mainDoor", height: 2, width: 2, childTileName: "mainDoor")
}
...
}
The example below illustrates how to put together a mobile visual interface on SmartThings mobile app for a simulated refrigerator composite device.

----

Example: Simulated refrigerator
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The simulated refrigerator in this example is a composite device with two components (child devices):

- The simulated main refrigerator (fridge) compartment, and
- A simulated freezer compartment.

Each compartment has its own door, its own temperature, and its own temperature setpoint.
Each compartment is modeled as a child device of the main refrigerator device.

From IDE, create a *New Device* (see :ref:`create-virtual-device`) and set it to *Type* "Simulated Refrigerator".
This will create the composite parent device *Simulated Refrigerator.*
You will see it appear in the *Things* view of your SmartThings mobile app.
Tap on it to see the *Detail* view of it.

The mobile app view of the Simulated Refrigerator composite device, with the detail view on the right, looks as below:

.. image:: ../img/composite-devices/sim_fridge_thing.png
:width: 350 px

.. image:: ../img/composite-devices/sim_fridge_detail.png
:width: 350 px


.. note::

If you are new to SmartThings tiles, see :ref:`device_handler_tiles` before you proceed further.

The composite device tile for the refrigerator door, shown in the top row of the detail view above, is put together as below:

- In the child Device Handler for the Simulated Refrigerator Door, the tile ``mainDoor`` is defined in the ``tiles()`` section. The ``width`` and ``height`` parameters defined here will be overridden by the parent Device Handler setting.

.. code-block:: groovy
metadata {
definition (name: "Simulated Refrigerator Door", namespace: "smartthings/testing", author: "SmartThings") {
capability "Contact Sensor"
capability "Sensor"
command "open"
command "close"
}
tiles {
standardTile("mainDoor", "device.contact", width: 2, height: 2, decoration: "flat") {
state("closed", label:'Fridge', icon:"st.contact.contact.closed", backgroundColor:"#79b821")
state("open", label:'Fridge', icon:"st.contact.contact.open", backgroundColor:"#ffa81e")
}
}
}
- In the Simulated Refrigerator parent Device Handler, the method :ref:`childDeviceTile_DH_ref` is used in the ``tiles()`` section to visually configure this child device ``mainDoor`` tile. The ``width`` and ``height`` settings here will override the settings for this tile in the child Device Handler.

.. code-block:: groovy
metadata {
definition (name: "Simulated Refrigerator", namespace: "smartthings/testing", author: "SmartThings") {
capability "Contact Sensor"
}
tiles {
childDeviceTile("mainDoor", "mainDoor", height: 2, width: 2, childTileName: "mainDoor")
}
...
}
def installed() {
state.counter = state.counter ? state.counter + 1 : 1
if (state.counter == 1) {
// A tile with the name "mainDoor" exists in the tiles() method of the child Device Handler "Simulated Refrigerator Door" above.
addChildDevice(
"Simulated Refrigerator Door",
"${device.deviceNetworkId}.2",
null,
[completedSetup: true, label: "${device.label} (Main Door)", componentName: "mainDoor", componentLabel: "Main Door"])
}
}
----

.. note::

While the ``width`` and ``height`` parameters in the ``childDeviceTile()`` in the parent Device Handler will override the settings of these parameters in the child Device Handler, any ``icon`` setting specified in the child Device Handler will *not* be overriden by the ``childDeviceTile()``.

----

Example composite tile code
^^^^^^^^^^^^^^^^^^^^^^^^^^^

Copy the following three composite device Device Handler files and create your own three Device Handlers with *From Code* option (see :ref:`create-device-handler`):

- Parent Device Handler file for the `Simulated Refrigerator <https://github.com/SmartThingsCommunity/SmartThingsPublic/blob/master/devicetypes/smartthings/testing/simulated-refrigerator.src/simulated-refrigerator.groovy>`_ composite parent device.
- Child Device Handler file for the `Simulated Refrigerator Door <https://github.com/SmartThingsCommunity/SmartThingsPublic/blob/master/devicetypes/smartthings/testing/simulated-refrigerator-door.src/simulated-refrigerator-door.groovy>`_ component device, and
- Child Device Handler for the `Simulated Refrigerator Temperature Control <https://github.com/SmartThingsCommunity/SmartThingsPublic/blob/master/devicetypes/smartthings/testing/simulated-refrigerator-temperature-control.src/simulated-refrigerator-temperature-control.groovy>`_ component device.

.. note::

Make sure to publish *For Me* the above three Device Handlers before you proceed further.


Follow the code in the Device Handlers you copied over to see how the rest of the visual layout is configured for the entire Simulated Refrigerator composite device.
Binary file added img/composite-devices/sim_fridge_detail.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/composite-devices/sim_fridge_thing.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
59 changes: 59 additions & 0 deletions ref-docs/device-handler-ref.rst
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,65 @@ Called within the `tiles()`_ method to define a tile often used in conjunction w
----

.. _childDeviceTile_DH_ref:

childDeviceTile()
-----------------

Called within the `tiles()`_ method in a parent Device Handler of a composite device to define the display of a child device tile.
The mobile user interface of a composite parent device is built typically by combining tiles from multiple child devices.

**Signature:**
``void childDeviceTile(String tileName, String componentName [, Map options, Closure closure])``

**Returns:**
void

**Parameters:**
`String`_ ``tileName`` - the name of the tile. This is used to identify the tile when specifying the tile layout.

`String`_ ``componentName`` - the name of the component child device. This name is the same as the ``componentName`` in the ``addChildDevice()`` in the composite parent Device Handler.

`Map`_ ``options`` *(optional)* - Various options for this tile. Valid options are found in the table below:

======================== =========== ===========
option type description
======================== =========== ===========
width `Integer`_ controls how wide the tile is. Default is 1.
height `Integer`_ controls how tall this tile is. Default is 1.
childTileName `String`_ name of the tile in the child Device Handler.
======================== =========== ===========

`Closure`_ ``closure`` *(optional)* - A closure that calls any `state()`_ methods to define how the tile should appear for various attribute values.

**Example:**

.. code-block:: groovy
metadata {
definition (name: "Simulated Refrigerator", namespace: "smartthings/testing", author: "SmartThings") {
capability "Contact Sensor"
}
tiles {
childDeviceTile("mainDoor", "mainDoor", height: 2, width: 2, childTileName: "mainDoor")
}
...
}
def installed() {
state.counter = state.counter ? state.counter + 1 : 1
if (state.counter == 1) {
// A tile with the name "mainDoor" exists in the tiles() method of the child Device Handler "Simulated Refrigerator Door"
addChildDevice(
"Simulated Refrigerator Door",
"${device.deviceNetworkId}.2",
null,
[completedSetup: true, label: "${device.label} (Main Door)", componentName: "mainDoor", componentLabel: "Main Door"])
}
}
----

command()
---------

Expand Down

0 comments on commit 6620f15

Please sign in to comment.