Deconz-rest-plugin: Device setup cluster on Ubisys D1 dimmer

Created on 13 Jan 2018  路  15Comments  路  Source: dresden-elektronik/deconz-rest-plugin

The Ubisys D1 dimmer shows up nicely as a light and switch(es), but is there a way to change attributes on the manufacturer-specific device setup cluster? There are 2 attributes (InputConfigurations and InputActions) to configure the way the buttons work work. Included the technical reference. They both seem to be arrays, but unfortunately that isn't supported by the ZCLDB in the deCONZ GUI.
ubisys-d1-technical-reference.pdf

stale

Most helpful comment

I have added PR #919 to configure the S1 from the Rest API.

All 15 comments

No, the deCONZ GUI cannot interact with manufacturer-specific attributes, see https://github.com/dresden-elektronik/deconz-rest-plugin/issues/20#issuecomment-324121358. I'm afraid you'll need the ubisys gateway to configure these, or write your own deCONZ plugin in C/C++.

The switches are exposed to the REST API - where you can attach any (REST) commands to them using rules. Of course, deCONZ needs to be up and running for these commands to be executed.

In a nutshell you need to create a deCONZ plugin based on the example deCONZ C++ API example plugin. https://github.com/dresden-elektronik/basic-aps-plugin

The following code snippet sends a manufacturer specific ZCL attribute request.

/*! Send ZCL Attribute Request ProfileCommand (Read / Write / Report configuration)
 *  with or without Manufacturer Specific Attributes
   \return true if request was added to queue
 */
bool BasicApsPlugin::sendZclAttributeGenericRequest(int shortaddr, int ep, int cluster, QByteArray payload, int manu) {
    char strtmp[TMP_STR];
    int rc = -1;

    if (m_apsCtrl->networkState() != deCONZ::InNetwork) {
        return false;
    }
    DBG_Printf(DBG_INFO, "-------------> sendZclReadAttributeRequest\n");

    // generate and remember a new ZDP transaction sequence number
    m_zclSeq = (uint8_t) qrand();

    uint8_t zclattrcmd = payload.at(0); // first byte is commandId
    payload.remove(0,1);                // remaining bytes are payload

    deCONZ::ZclFrame zclReq;
    uint8_t framecontrol = deCONZ::ZclFCProfileCommand;
    if (manu > 0) {
        framecontrol |= deCONZ::ZclFCManufacturerSpecific;
        DBG_Printf(DBG_INFO, "framecontrol = %02x\n", framecontrol);
        zclReq.setManufacturerCode(manu);

    }
    zclReq.setFrameControl(framecontrol);
    zclReq.setSequenceNumber(m_zclSeq);
    zclReq.setCommandId(zclattrcmd); // for example deCONZ::ZclReadAttributesId

    // prepare ZCL payload
    zclReq.setPayload(payload);

    deCONZ::ApsDataRequest apsReq;

    // set destination addressing
    apsReq.setDstAddressMode(deCONZ::ApsNwkAddress);
    apsReq.dstAddress().setNwk(shortaddr);
    apsReq.setDstEndpoint(ep);
    apsReq.setSrcEndpoint(0x01);  // Source Endpoint 0x01
    apsReq.setProfileId(HA_PROFILE_ID);
    apsReq.setClusterId(cluster);

    // prepare APS payload
    QDataStream stream(&apsReq.asdu(), QIODevice::WriteOnly);
    stream.setByteOrder(QDataStream::LittleEndian);

    zclReq.writeToStream(stream);

    unsigned int length = apsReq.asdu().length();
    int strlen = length * 3;  // print each byte in hex (2 bytes) and white space
    char rawstr[strlen+1];
    memset(rawstr, '\0', strlen + 1);

    QDataStream asdustream(apsReq.asdu());
    asdustream.setByteOrder(QDataStream::LittleEndian);
    uint8_t asdudata;
    while (!asdustream.atEnd()) {
        asdustream >> asdudata;
        char rawtmp[4];
        memset(rawtmp, '\0', 4);
        snprintf(rawtmp, 4, "%02X ", asdudata);
        strcat(rawstr, rawtmp);
    }
    DBG_Printf(DBG_INFO, "APS Req id 0x%02X %d profile 0x%04X %s, shortaddr = 0x%04X, ep = %d\n",
            apsReq.id(), length, apsReq.profileId(), rawstr, shortaddr, ep);

    if (m_apsCtrl && ((rc = m_apsCtrl->apsdeDataRequest(apsReq)) == deCONZ::Success)) {
        // remember request
        m_apsReqQueue.push_back(apsReq);
        return true;
    } else {
        //    Success = 0,       //!< Success
        //    ErrorNotConnected, //!< Not connected (device or network)
        //    ErrorQueueIsFull,  //!< Queue is full
        //    ErrorNodeIsZombie, //!< Node is not reachable
        //    ErrorNotFound      //!< Not found
        switch(rc) {
            case -1: snprintf(strtmp, TMP_STR, "controller not connected "); break;
            case deCONZ::ErrorNotConnected: snprintf(strtmp, TMP_STR, " ErrorNotConnected "); break;
            case deCONZ::ErrorQueueIsFull: snprintf(strtmp, TMP_STR, " ErrorQueueIsFull "); break;
            case deCONZ::ErrorNodeIsZombie: snprintf(strtmp, TMP_STR, " ErrorNodeIsZombie "); break;
            case deCONZ::ErrorNotFound: snprintf(strtmp, TMP_STR, " ErrorNotFound "); break;
            default: snprintf(strtmp, TMP_STR, " Error %d ", rc);

        }

    }

    return false;
}

/*! Send ZCL Attribute Manufacturer Specific Request ProfileCommand (Read / Write / Report configuration)
   \return true if request was added to queue
 */
bool BasicApsPlugin::sendZclAttributeManuSpecRequest(int shortaddr, int ep, int cluster, QByteArray payload, int manu) {
    return sendZclAttributeGenericRequest(shortaddr, ep, cluster, payload, manu);
}

I have configured my ubisys switch S2 buttons this way.

Thanks for the quick replies! Will try it as soon as I can.

In addition to my previous comment. The buttons on the ubisys inputs are configured on the Device Setup cluster 0xFC00 on Endpoint 232.

That cluster 0xFC00 is a manufacturer specific _cluster_, but the _attributes_ on cluster 0xFC00 are not manufacturer specific, so you should be able to read and write the InputActions attribute id 0x0001, type array (ZCL data type 0x48) of raw binary data (ZCL data type 0x41) without a custom plug-in.

the attributes on cluster 0xFC00 are not manufacturer specific

Ah, didn't realise that. Then it should be sufficient to add the cluster and the attributes to /usr/share/deCONZ/zcl/general.xml for the deCONZ GUI to generate the _Cluster Info_ panel.

I have added the cluster to the general.xml file but I'm stuck how to define the data type of the two attributes. According to the Ubisys tech. reference for the D1 the data types are

  • array (ZCL data type 0x48) of 8-bit data (ZCL data type 0x08) for InputConfigurations attr.
  • array (ZCL data type 0x48) of raw binary data (ZCL data type 0x41) for InputActions attr.

All of these data types are "declared" in the general.xml, but what is the way to define "array of ..." as type for an attribute child element of a clusters server?

This is the XML I have added to the general.xml (The attributes show up in the GUI, but read returns nothing and I didn't dare to try writing something yet ;) )

<cluster id="0xFC00" name="Device Setup">
    <description>...</description>
    <server>
        <attribute id="0x0000" name="InputConfigurations" type="array" access="rw" required="o" default="0x00"></attribute>
        <attribute id="0x0001" name="InputActions" type="array" access="rw" required="o" default="0x00"></attribute>
    </server>
    <client>
    </client>
</cluster>

This is where I got stuck as well. There's no instances of these data types being used anywhere in the general.xml file.

I ran into the same Problem with a Ubisys S1 switch. I would like to change the InputConfigurations value, but the deConz indicates that this field is read only.

Has someone found a solution without having to buy the Ubisys Zigbee stick and software?

You might try the deCONZ command line plugin, https://github.com/ma-ca/deconz-cli-plugin, see #540.

I have added PR #919 to configure the S1 from the Rest API.

Using the deconz-cli-plugin I could Also configue my Ubisys D1. Thanks for that contribution :)

Using the deconz-cli-plugin I could Also configue my Ubisys D1. Thanks for that contribution :)

How did you configure your D1 with the deconz-cli-plugin? Could you write a short tutorial on what commands you used? That would be great! Did you compile the plugin yourself?

Basically I just followed instructions in den Readme of the deconz-cli-plugin plus some try and error finding the correct value to set for the inputconfigurations on the D1.
I compiled the plugin myself, for me it worked exactly as described in the readme. (Deconz dev package was already installed - my OS is openahbian, i.e. Raspbian Stretch)
After copying the compiled plugin to the deconz plugin dir and restarting deconz-service (the headless version) I could connect tho the "shell" with
nc localhost 5008
Now first I send a match descriptor request with profile ZHA (0x0104) and Ubisys Device Setup cluster (0xFC00) to get the shortaddress of my D1
m 0x0104 0xFC00
That returned the match
<-ZDP match 0x001FEE0000000F60 0x5808 232 0xFC00 0x0104
The shortaddress is the fourth string, in this case "0x5808"
With
zclattr 0x5808 232 0xFC00 000100
you can read the current configuration of the D1; it might be worth saving (copy&paste) this in case you set a config that the dimmer can't work with (like I did ;) ) - however the standard config can also be found in the D1 technical reference document on the Ubisys website.
In my scenario, I just wanted to be able to switch the dimmer on an of with a rocker switch (two stable positions). I do dimming only via app or an IKEA Tradfri Remote. The Readme of the deconz-cli-plugin has an example config for exactly this for the S1, I just had to adapt the endpoints - which are different for the D1. Finally I set my config with
zclattr 0x5808 232 0xFC00 0201004841040006000D0206000206010D020600020600030206000206010302060002
The "payload" start with the "4841..." it is described in detail in the D1 tech.-ref. what each byte means - and what you need to set depends on what exactly you want to achieve.
One more thing: the 2nd physical input of the D1 is not connected in my case, so I can only state that this config works for the 1st input.

Just for reference, here's the command I used to configure my D1 to use both switches. As the D1 reference manual states:

The following example shows the input action micro-code for using two push-buttons to control a
target dimmer (whether it be the local output or a remote device) in an up/down manner, i.e. one button
is used to turn the light(s) on and dim brighter, the other one to turn the light(s) off and dim darker.

zclattr <shortaddr> 232 0xFC00 020100484106000600070206000108000602080005003206000B020800070601070206000008010602080005013206010B02080007

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

salopette picture salopette  路  4Comments

tenholde picture tenholde  路  3Comments

Thomas-Vos picture Thomas-Vos  路  4Comments

flex-0 picture flex-0  路  4Comments

ScharV picture ScharV  路  5Comments