Ubisys C4

ModelC4
VendorUbisys
DescriptionControl unit C4
Exposesaction, linkquality
PictureUbisys C4

Notes

General

The ubisys C4 remote control unit seems to be primarily targeted to be directly bound to other ZigBee devices to control them. Therefore it does not emit plain "click" events or similar but can be configured to send ZigBee commands like on, off, toggle, cover up, cover down etc. from up to 6 endpoints (4 with on/off, level and scene clusters for lights and another 2 to control window covering devices). When used with Zigbee2MQTT all endpoints get bound to the coordinator automatically. Therefore all actions will be sent to the coordinator and forwarded to MQTT in addition to being sent directly via ZigBee to other devices that have potentially been bound manually (see Binding for more information). In its factory reset configuration an ubisys C4 just sends a toggle command (originating from endpoints 1 to 4 respectively) for each input. Therefore basic keypresses on attached momentary switches can be processed through Zigbee2MQTT even without further input configuration.

Configuring Inputs

The inputs of most ubisys devices can be configured in a very flexible way to map state transitions (e.g. 'released' to 'pressed') to Zigbee commands (e.g. 'toggle'). This even applies to the way in which these inputs control a local load (for ubisys devices other than the C4).

Templates

By publishing to zigbee2mqtt/FRIENDLY_NAME/set using the JSON properties configure_device_setup and input_action_templates the inputs can be configured using templates. This allows to configure some common use cases without having to fully dive into the details of input_actions (see Raw Configuration below).

Valid template types are:

  • toggle: Use one push button input to toggle the state of a light (or a similar actuator). A 'toggle' command will be sent on every push of the button.
  • toggle_switch: Use one stationary switch to toggle. A 'toggle' command will be sent when the switch is turned on as well as when the switch is turned off.
  • on_off_switch: Use one stationary switch to turn on and off. An 'on' command will be sent when the switch is turned on and an 'off' command when it is turned off. Helpful to ensure that lights stay synchronised when controlling a group.
  • on: Only send an 'on' command on every push of a button. Helpful to e.g. use a C4 as a more direct interface to some other physical device with a relay, e.g. to turn on all lights when the (physical) alarm system signals an intrusion.
  • off: Only send an 'off' command on every push of a button (also see on).
  • dimmer_single: Use one push button to toggle the state of a light and also to control its level. A short press will send a 'toggle' command and long presses will move the level up and down alternately.
  • dimmer_double: Use two push buttons to switch a light on and off and also to control its level. On the first input, a short press will send an 'on' command and a long press a 'move level up' command. On the second input, a short press will send an 'off' command and a long press a 'move level down' command.
  • cover: Use two push buttons to control a cover. A press on the first input will send a 'move up' command and if released within 1 second, it will send a 'stop' command. The same applies for the second input with 'move down' and 'stop' commands. This allows to use short presses to e.g. control the tilt of lift & tilt blinds whereas long presses will move up or down completely.
  • cover_switch: Use two stationary switches to control a cover. Similar to cover, but the 'stop' command will always be sent when a switch is turned off.
  • cover_up: Only send a 'move up' command on every push of a button (also see on).
  • cover_down: Only send a 'move down' command on every push of a button (also see on).
  • scene: Use a push button to select a scene (using its id). A short press will send a 'recall scene' command using scene_id and if scene_id_2 is present a long press will do the same using scene_id_2.
  • scene_switch: Use a stationary switch to select a scene. Very similar to scene: turning the switch on will send scene_id and turning it off will send scene_id_2 (if configured).

General attributes:

  • input: Optional, selects the input(s) to use for a template. If not specified, the first template will use input 0 and then it will be incremented automatically for every further template. In case a templates uses two inputs, input and input+1 will be used and following template will use input+2.
  • inputs: Optional, selects both inputs separately for templates using two inputs. Allows to e.g. switch up and down inputs in case they are wired differently. The following template will use Math.max(...inputs)+1.
  • endpoint: Optional, selects the outbound endpoint to use for sending the commands. The C4 only contains outbound endpoints starting with endpoint 1 (see above). For the other ubisys devices endpoint 1 usually is an inbound endpoint controlling the load, but starting at 2 or 3 they also contain outbound endpoints that are per default bound to their respective load controlling endpoint but can also be changed (e.g. from switch to push button) or unbound and rebound to e.g. control a different light using the second input of a S1-R or D1. If not specified, the first template will use the first available outbound endpoint on the specific device and then it will be incremented automatically for every further template. For a C4, cover templates will start at endpoint 5 (since endpoints 1-4 do not host a window covering cluster and can therefore only be used for lights etc).

The input(s) and endpoint used will also be output to the Zigbee2MQTT log (flagged as warnings but only to make sure they do not get suppressed).

Attributes only used with dimmer templates:

  • no_onoff_down: Optional, changes the commands sent to not automatically turn the light off when moving the level fully down. Useful to be able to dim a light down completely without turning it off.
  • no_onoff_up: Optional, changes the commands sent to not automatically turn the light on when moving the level up.
  • no_onoff: Optional, combination of no_onoff_up and no_onoff_down.
  • rate: Optional (default is 50), specifies the rate in steps per second when moving the level up or down.

Attributes only used with scene templates

  • scene_id: Mandatory, specifies the scene id to send for the primary function of the template (i.e. short button press or switch turned on).
  • group_id: Specifies the group id to send the 'recall scene' to (needs to be identical to the one used in the group definition in configuration.yaml / groups and to the one used when storing the scene. Can be omitted on subsequent scene templates.
  • scene_id_2: Optional, if present it specifies the scene id to send for the secondary function of the template (i.e. long button press or switch turned off).
  • group_id_2: Optional, specifies the group id to send with scene_id_2. Only needed if different from group_id.

On the C4, the respective outbound endpoint also needs to be bound to one or more target devices (see Binding below) for most of the template types (besides scene control).

Please also note that there seems to be a size limit on the amount of data that can successfully be written using input_action_templates, so not all combinations theoretically possible will work in reality.

Template Examples

"//_comment" fields are really just comments only, will be ignored (as any other additional JSON properties) and can certainly be omitted. They are just used here since normal JavaScript comments (//) would not be considered valid JSON and therefore Zigbee2MQTT would throw an error.

C4 Default Configuration

{
    "configure_device_setup": {
        "input_action_templates": [
            {
                "//_comment": "will automatically use input 0 and endpoint 1",
                "type": "toggle"
            },
            {
                "//_comment": "will automatically use input 1 and endpoint 2",
                "type": "toggle"
            },
            {
                "//_comment": "will automatically use input 2 and endpoint 3",
                "type": "toggle"
            },
            {
                "//_comment": "will automatically use input 4 and endpoint 4",
                "type": "toggle"
            }
        ]
    }
}

Control a dimming light with inputs 1 (up) and 0 (down) and use input 3 to toggle a different light

{
    "configure_device_setup": {
        "input_action_templates": [
            {
                "//_comment": "will automatically use endpoint 1",
                "type": "dimmer_double",
                "inputs": [1, 0]
            },
            {
                "//_comment": "will automatically use endpoint 2",
                "type": "toggle",
                "input": 3
            }
        ]
    }
}

Use separate up and down push buttons with a D1

{
    "configure_device_setup": {
        "input_action_templates": [
            {
                "//_comment": "will automatically use inputs 0 and 1 and endpoint 2 (first outbound endpoint on a D1)",
                "type": "dimmer_double"
            }
        ]
    }
}

Use stationary switches instead of push buttons with a J1

{
    "configure_device_setup": {
        "input_action_templates": [
            {
                "//_comment": "will automatically use inputs 0 and 1 and endpoint 2 (first outbound endpoint on a J1)",
                "type": "cover_switch"
            }
        ]
    }
}

Control a dimming light with inputs 0 and 1 and recall scenes with 3 and 4

{
    "configure_device_setup": {
        "input_action_templates": [
            {
                "//_comment": "will automatically use inputs 0 and 1 and endpoint 1",
                "type": "dimmer_double"
            },
            {
                "//_comment": "will automatically use input 3 (endpoint does not really matter for scenes)",
                "type": "scene",
                "group_id": 1000,
                "scene_id": 10
            },
            {
                "//_comment": "will automatically use input 4 and group id 1000",
                "type": "scene",
                "scene_id": 11
            }
        ]
    }
}

Raw Configuration

By publishing to zigbee2mqtt/FRIENDLY_NAME/set the following device attributes can be set to rawly configure inputs:

{
    "configure_device_setup": {
        "input_configurations": [0, 0, 0, 0],
        "input_actions": [
            [0, 13, 1, 6, 0, 2],
            [1, 13, 2, 6, 0, 2],
            [2, 13, 3, 6, 0, 2],
            [3, 13, 4, 6, 0, 2]
        ]
    }
}

For further details on these attributes please take a look at the ubisys C4 Technical Reference Manualopen in new window, chapter "7.8.5. Device Setup Cluster (Server)" (or the respective ubisys reference manual of the device in use in case it's not a C4) and the "ZigBee Device Physical Input Configurations Integrator's Guide" (which can be obtained directly from ubisys upon request). Each element in the input_configurations and input_actions arrays corresponds to a single byte. Therefore, fields longer than one byte (e.g. the "ClusterID" field in input_actions) are represented by multiple elements in the array, and the arrays may vary in length depending on the configuration being sent.

Please note that there seems to be a size limit on the amount of data that can successfully be written to input_actions, so not all configurations theoretically possible might work in reality.

By publishing to zigbee2mqtt/FRIENDLY_NAME/get/configure_device_setup the values of the configuration attributes can also be read back from the device. If you don't want configure_device_setup to always show up in the published payload, you can prevent them from being cached by configuring filtered_cache for this device or all devices using the device options.

devices:
  '0x0000000000000000':
    friendly_name: 'my_c4_controller'
    filtered_cache:
      - configure_device_setup

Binding

Most of the input_actions and input_action_templates (besides scene control) do not reference a target device directly but make use of the binding table of a specific outbound endpoint (for C4 see General above, for other ubisys devices take a look at the respective ubisys reference manual). For the C4, Zigbee2MQTT will always bind all endpoints to the coordinator automatically (so Zigbee2MQTT will be able to forward button presses to MQTT), but to control any other ZigBee device or group directly, it is necessary to bind the outbound endpoints used to the target (device or group).

When binding (or unbinding), it is important to explicitly specify the outbound endpoint as the source, e.g. zigbee2mqtt/bridge/request/device/bind payload {"from": "SOURCE_DEVICE_FRIENDLY_NAME/2", "to": "TARGET"} (also see Binding specific endpoint). Endpoints can be specified in numeric form and it is usually not necessary to specify an endpoint for the target device.

For ubisys devices other than the C4 this also allows to use the secondary input to control a different device. Example: Use the secondary input on a D1 (uses outbound endpoint 3 in the factory configuration) to control a separate ZigBee bulb:

mosquitto_pub -t zigbee2mqtt/bridge/request/device/bind -m '{"from": "DIMMER_FRIENDLY_NAME/3", "to": "ANOTHER_BULB_FRIENDLY_NAME"}'

Decoupling

For ubisys devices other than the C4 this even allows to completely decouple the local input from the local output. Example: Unbind the switch input from the local load and use it to instead control a group of lights without cutting the power to the bulbs (the switch output can still be controlled via ZigBee, e.g. via MQTT through Zigbee2MQTT):

mosquitto_pub -t zigbee2mqtt/bridge/request/device/unbind -m '{"from": "SWITCH_FRIENDLY_NAME/2", "to": "SWITCH_FRIENDLY_NAME"}'
mosquitto_pub -t zigbee2mqtt/bridge/request/device/bind -m '{"from": "SWITCH_FRIENDLY_NAME/2", "to": "GROUP_NAME"}'

To restore the original behavior you unbind the group and rebind the device:

mosquitto_pub -t zigbee2mqtt/bridge/request/device/unbind -m '{"from": "SWITCH_FRIENDLY_NAME/2", "to": "GROUP_NAME"}'
mosquitto_pub -t zigbee2mqtt/bridge/request/device/bind -m '{"from": "SWITCH_FRIENDLY_NAME/2", "to": "SWITCH_FRIENDLY_NAME"}'

OTA updates

This device supports OTA updates, for more information see OTA updates.

Options

How to use device type specific configuration

  • legacy: Set to false to disable the legacy integration (highly recommended), will change structure of the published payload (default true). The value must be true or false

Exposes

Action (enum)

Triggered action (e.g. a button click). Value can be found in the published state on the action property. It's not possible to read (/get) or write (/set) this value. The possible values are: toggle_s1, toggle_s2, toggle_s3, toggle_s4, on_s1, on_s2, on_s3, on_s4, off_s1, off_s2, off_s3, off_s4, recall_*_s1, recal_*_s2, recall_*_s3, recal_*_s4, brightness_move_up_s1, brightness_move_up_s2, brightness_move_up_s3, brightness_move_up_s4, brightness_move_down_s1, brightness_move_down_s2, brightness_move_down_s3, brightness_move_down_s4, brightness_stop_s1, brightness_stop_s2, brightness_stop_s3, brightness_stop_s4, cover_open_s5, cover_close_s5, cover_stop_s5, cover_open_s6, cover_close_s6, cover_stop_s6.

Linkquality (numeric)

Link quality (signal strength). Value can be found in the published state on the linkquality property. It's not possible to read (/get) or write (/set) this value. The minimal value is 0 and the maximum value is 255. The unit of this value is lqi.