Create a Toggled iQ Device

The goal is to create a driver which will transform ECP gateway int Toggled iQ IoT gateway. It allows you to control devices in Toggled iQ network remotely, and gather all telemetry. Toggled iQ USB dongle (bridge) is needed for Mesh communication. Driver is regularly updated since new features/devices are released.

See more info at https://toggled.com/solutions/lighting-controls/

Details

We assume that the user is familiar with Toggled iQ basics.

Devices currently supported:
  • legacy tube (4 feet, BLE device name starts with 'tTu ')
  • modern tubes (2/3/4 feet, BLE device name starts with 'tTu2'/'tTu3'/'tTu4')
  • can light ('tCa2')
  • legacy switch ('tSw ')
  • modern switch ('tSw2')
  • occupancy sensor ('tSe ')
  • area controller ('tAC ')
  • plug controller ('tPC ')

Network is created (devices provisioned) using mobile application. It is not recommended to edit Thing models manually for correct work.

Driver receives every Mesh message and generates telemetry according to it. State of each device (telemetry data) exactly describes state of real device.

When Thing Property is set driver sends corresponding Mesh command and updates its state properly.

Separate Thing Model is used for groups/areas. When group property is changed it affects all devices within that group. Also some group properties (outputLevel/powerState) will be updated when device(s) from that group change its dim level, scene or power state. TOGGLED_AVERAGE_GROUPS environment variable should be set to "yes" for this functionality.

Thing Descriptions

Example:
{
    "@type": [
        "swx:toggledIQ",
        "swx:tube"
    ],
    "title": "ToggledIQ Tube #1",
    "properties": {
        "meshId": {
            "title": "MeshId",
            "description": "Device MeshId (address)",
            "type": "number",
            "minimum": 32769,
            "maximum": 65535,
            "readOnly": false
        },
        "dimLevel": {
            "title": "DimLevel",
            "description": "Current dim level",
            "type": "number",
            "maximum": 255,
            "readOnly": false
        },
        "outputLevel": {
            "title": "OutputLevel",
            "description": "Actual output level",
            "type": "number",
            "maximum": 255,
            "readOnly": false
        },
        "groupUids": {
            "title": "Groups",
            "description": "Groups device belongs to",
            "type": "array",
            "readOnly": false
        },
        "maxTrim": {
            "title": "MaxTrim",
            "description": "MaxTrim",
            "type": "number",
            "maximum": 255,
            "readOnly": false
        },
        "minTrim": {
            "title": "MinTrim",
            "description": "MinTrim",
            "type": "number",
            "maximum": 255,
            "readOnly": false
        },
        "powerState": {
            "title": "PowerState",
            "description": "On - 1, Off - 0",
            "type": "number",
            "maximum": 1,
            "readOnly": false
        },
        "scene": {
            "title": "Scene",
            "description": "Current scene id (1 - 255, 0 - off scene)",
            "type": "number",
            "maximum": 255,
            "readOnly": true
        },
        "scenes": {
            "title": "Scenes",
            "description": "Device scenes",
            "type": "array",
            "readOnly": false
        },
        "vacancyTimeout": {
            "title": "VacancyTimeout",
            "description": "VacancyTimeout  in seconds (0 - off, max - 2147)",
            "type": "number",
            "maximum": 2147,
            "readOnly": false
        }
    },
    "actions": {
        "savegroup": {
            "title": "SaveGroup",
            "description": "Sets tube group at slot <index> to <id> ",
            "input": {
                "@type": "SaveGroupAction",
                "type": "object",
                "properties": {
                    "id": {
                        "type": "integer",
                        "minimum": 1,
                        "maximum": 255
                    },
                    "index": {
                        "type": "integer",
                        "maximum": 15
                    }
                }
            }
        },
        "savescene": {
            "title": "SaveScene",
            "description": "Saves current tube state as scene <id> at slot <index>",
            "input": {
                "@type": "SaveSceneAction",
                "type": "object",
                "properties": {
                    "id": {
                        "type": "integer",
                        "minimum": 1,
                        "maximum": 255
                    },
                    "index": {
                        "type": "integer",
                        "maximum": 15
                    }
                }
            }
        },
        "selectscene": {
            "title": "SelectScene",
            "description": "Applies scene <id> with <modifier> to device",
            "input": {
                "@type": "SelectSceneAction",
                "type": "object",
                "properties": {
                    "id": {
                        "type": "integer",
                        "minimum": 1,
                        "maximum": 255
                    },
                    "modifier": {
                        "type": "integer",
                        "minimum": -128,
                        "maximum": 127
                    }
                }
            }
        }
    }
}
Important properties that define every Toggled iQ device/group are:
meshId
Address in Mesh network
groupUids
Parent groups IDs (thingID).

Edge Applications

Due to Kubernetes approach used on ECP Toggled Driver (chart name "ecp-toggled-driver") needs another application running - Serial Proxy (chart name "ecp-serial-proxy"). Serial Proxy provides access to Toggled dongle (serial port), relay all message from/to Mesh network and handles different situation like driver container restart, dongle probing, etc.