This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

nRF52840 custom light bulb compatible with Hue and Alexa

Hello,

I am new to Nordic and quite new to ZigBee. Just had a short evaluation with Silabs so far.

My goal is developing a custom lamp for serial production that needs to be compatible with Hue Bridge & App, as well with Alexa.

I use PCA10056 and started with an example from the SDK but I did not come very far.

On a PCA10056 Board I run zigbee_light_bulb_pca10056 with SES but the lamp will not show up in the hue app using a Hue Bridge 2.1 when searching for lights.

Using PCA10059 Dongle as a sniffer I can see that there is a "transport key" package but the debug log keeps outputting:

<info> app: Network left (leave type: 0)
<info> app: Network steering was not successful (status: -1)

I read a lot here about hue keys, touch link and comissioning but still did not get it running and feel quite lost.

Nordic does not seem to support touch link and uses normal commisioning instead - what will the difference be like for the user?

How do I get this example working with Hue?

And in general - where to start to make this development process less scientific/tryanderror and more straingtforward instead? Where to get an overview about what you need from the beginning?

Thanks in advance!

Parents
  • Hi,

    Sorry for the late reply. 

    How do I get this example working with Hue?

    You're correct that Nordic does not support touchlink. Instead, I would recommend you try using the function zb_zdo_set_tc_standard_distributed_key() and call it before zb_start(), as is done in this reply. If you look at infocenter, you will find that there's no documentation for ZDO distributed security in the latest versions of the SDK. That's just an error in the documentation. The functions exist in the SDK, it's just been removed from the documentation by a mistake, so you should be able to use it as in the case I linked.

    what will the difference be like for the user?

    Normal commissioning uses network steering, formation, finding and binding. The commissioning mode is initiated by some action performed by the user, for instance a button press. The coordinator will then be in commissioning mode for 3 minutes, which is when routers and end-devices will be able to be commissioned to the network. Nodes that want to join a network scans for open networks and will attempt to join. If they are allowed to join, the node must be authenticated and receive the network key, which is often the Trust Center link key.

    Touchlink minimises how much the user has to do. When using touchlink, you don't need a coordinator for forming and joining networks. Instead, the nodes run a special commissioning application which is based on the ZLL Commissioning cluster. You have one initiator, which initiates the formation/joining of the network. If the initiator node is physically close to the node that should be included in the network, the procedure can be done by simply starting the commissioning, which can be done by pressing a button. Touchlink commissioning is performed in three steps:

    1. The initiator scans for ZLL nodes and gets a list of possible nodes. If there's more than one, the initiator has to decide which one to commission.
    2. The initiator sends a request to the node to get its network information, which it then receives from the node.
    3. The initiator requests the node to join the network, or to form a new one if no network already exists.
    where to start to make this development process less scientific/tryanderror and more straingtforward instead? Where to get an overview about what you need from the beginning?

    I would recommend reading the Zigbee 3.0 specification, as well as reading about the different cluster libraries relevant to your project, in order to better understand how everything works. In addition to that, you can take a look at our documentation for the SDK. There's also several examples there that you can look at in order to see how things can be implemented and used.

    If you're still having problems, could you please attach a sniffer log?

    Hope this helps you get going and that it answers your questions!

    Best regards,

    Marte

  • Hi,

    Thanks for your reply.

    I tried zb_zdo_set_tc_standard_distributed_key() before but I did not implement the other changes mentioned in that post.
    This time I changed all keys and also the security behaviour and it works with Hue!

    #define ZB_ZGP_DEFAULT_LINK_KEY "\x81< rest of key >
    #define ZB_ZGP_DEFAULT_SHARED_SECURITY_KEY_TYPE ZB_ZGP_SEC_KEY_TYPE_NWK
    #define ZB_ZGP_DEFAULT_SECURITY_LEVEL ZB_ZGP_SEC_LEVEL_FULL_WITH_ENC
    #define ZB_STANDARD_TC_KEY { 0x81, 0x42, < rest of key > };
    #define ZB_DISTRIBUTED_GLOBAL_KEY { 0x81, 0x42, , < rest of key > };
    #define ZB_TOUCHLINK_PRECONFIGURED_KEY { 0x81, 0x42, < rest of key > };

    calling this:
        zb_zdo_set_tc_standard_distributed_key(ZB_ZGP_DEFAULT_LINK_KEY);

    before the line with zboss_start_no_autostart in main.c

    Also changed #define IEEE_CHANNEL_MASK to 0x07fff800U and removed APP_BULB_USE_WS2812_LED_CHAIN.



    Thanks for explaining - Touchlink seems to be a dispensable feature for me now.



    Next to the ZigBee spec I'm also now reading a book on ZigBee as I really need to get deeper into this whole topic and things are already getting clearer.


    While Debugging this example I'm facing a new problem now:
    The debugger connection gets lost while doing ZigBee related things and eval board seems to reconnect itself.
    In the beginning this seemed to be directly related to ZigBee Events (after connection, when trying to change level).
    Now I cannot regularly reproduce it so it might also be related to sth else. During debug without touching the board the SES displays "Target connection has been lost" and the board reconnects (the virtual storage device pops up again and terminal on com-port is lost). Other times SES just hung up with no response until I disconnected the board manually.
    I thought it might be a power supply related thing but the board is set to SW9 VDD which should work fine?
    The attached screenshot shows where this happend the first and second time from the view of the serial ouput.

    Lost connection shortly after being discovered by Hue:

    Restarted the debugger and reconnected automatically to Hue - trying to enable/disable light and got lost again:

    This is all SES is saying:


    Thanks again for your support!
    Alex

  • Hi Marte,

    From what I found out so far it seems that only mandatory commands are fully processed by the library.

    As "Off with effect" is optional it is obviously not handled by the library - but already prepared for it. I would have to override the standard command handler, parse that command myself and e.g. hand it to my device callback.

    Maybe you can verify this with your Zigbee team so I am not making things harder than necessary.

    Thanks & best regards,

    Alex

  • Hi Alex,

    That's what I suspect as well, but I have asked the Zigbee team and will update you when I know more.

    Best regards,

    Marte

  • Hi Marte,

    I already tried to implement this but I did not come far.

    I tried to implement the handler as described here: https://infocenter.nordicsemi.com/topic/sdk_tz_v3.2.0/using_zigbee__z_c_l.html#process_zcl_cmd_implementing

    Now I am stuck again because several of the buffer handling macros and types are nowhere defined in the nRF SDK - e.g. ZB_BUF_FROM_REF and zb_buf_t 
    zb_buf_t *zcl_cmd_buf = (zb_buf_t *)ZB_BUF_FROM_REF(param);
    zb_zcl_parsed_hdr_t *cmd_info = ZB_GET_BUF_PARAM(zcl_cmd_buf, zb_zcl_parsed_hdr_t);

    The missing defines are documented online but the used low level functions are also nowhere accessible:
    So, please help...
    Thanks in advance,
    Alex

  • Found out it works better with the documentation of the matching SDK version ;-). Still a bit try & error but result is already good.

    https://infocenter.nordicsemi.com/topic/sdk_tz_v4.1.0/using_zigbee__z_c_l.html#process_zcl_cmd_implementing

  • Hi Alex,

    Great to hear that the results are good. I don't know how far you've come with implementing this now, but I finally got a response from the Zigbee team:

    Yes, this command is optional and may not be handled internally by the stack.

    To handle this command, register endpoint handler for the endpoint with the light bulb, using ZB_AF_SET_ENDPOINT_HANDLER() and the proper handler logic needs to be implemented.

    The handler itself can be implemented like below but it lacks the logic to handle Off with effect command:

    /* Handler function for incoming ZCL frames. */
    static zb_uint8_t light_bulb_ep_handler(zb_bufid_t bufid)
    {
        zb_zcl_parsed_hdr_t *p_cmd_info = ZB_BUF_GET_PARAM(bufid, zb_zcl_parsed_hdr_t);
     
        /* Make sure that received frame was sent with proper profile and to proper cluster. */
        if (p_cmd_info->cluster_id != ZB_ZCL_CLUSTER_ID_ON_OFF ||
            p_cmd_info->profile_id != ZB_AF_HA_PROFILE_ID)
        {
            return ZB_FALSE;
        }
     
        /* Check if the received command is OFF WITH EFFECT command. */
        if (p_cmd_info->cmd_id == ZB_ZCL_CMD_ON_OFF_OFF_WITH_EFFECT_ID)
        {
            zb_zcl_on_off_off_with_effect_req_t off_with_effect_payload;
            zb_zcl_parse_status_t status;
     
            ZB_ZCL_ON_OFF_GET_OFF_WITH_EFFECT_REQ(&off_with_effect_payload, param, status);
            if (status == ZB_ZCL_PARSE_STATUS_SUCCESS)
            {
                /* HERE - Implement logic to handle the OFF WITH EFFECT command.
                 * The "off_with_effect_payload" structure stores the command payload data.
                 */
     
                /* Once the command is handled, return ZB_TRUE to inform stack that the frame has already been processed. */
                return ZB_TRUE;
            }
        }
     
        return ZB_FALSE;
    }

    Hope this helps!

    Best regards,

    Marte

Reply
  • Hi Alex,

    Great to hear that the results are good. I don't know how far you've come with implementing this now, but I finally got a response from the Zigbee team:

    Yes, this command is optional and may not be handled internally by the stack.

    To handle this command, register endpoint handler for the endpoint with the light bulb, using ZB_AF_SET_ENDPOINT_HANDLER() and the proper handler logic needs to be implemented.

    The handler itself can be implemented like below but it lacks the logic to handle Off with effect command:

    /* Handler function for incoming ZCL frames. */
    static zb_uint8_t light_bulb_ep_handler(zb_bufid_t bufid)
    {
        zb_zcl_parsed_hdr_t *p_cmd_info = ZB_BUF_GET_PARAM(bufid, zb_zcl_parsed_hdr_t);
     
        /* Make sure that received frame was sent with proper profile and to proper cluster. */
        if (p_cmd_info->cluster_id != ZB_ZCL_CLUSTER_ID_ON_OFF ||
            p_cmd_info->profile_id != ZB_AF_HA_PROFILE_ID)
        {
            return ZB_FALSE;
        }
     
        /* Check if the received command is OFF WITH EFFECT command. */
        if (p_cmd_info->cmd_id == ZB_ZCL_CMD_ON_OFF_OFF_WITH_EFFECT_ID)
        {
            zb_zcl_on_off_off_with_effect_req_t off_with_effect_payload;
            zb_zcl_parse_status_t status;
     
            ZB_ZCL_ON_OFF_GET_OFF_WITH_EFFECT_REQ(&off_with_effect_payload, param, status);
            if (status == ZB_ZCL_PARSE_STATUS_SUCCESS)
            {
                /* HERE - Implement logic to handle the OFF WITH EFFECT command.
                 * The "off_with_effect_payload" structure stores the command payload data.
                 */
     
                /* Once the command is handled, return ZB_TRUE to inform stack that the frame has already been processed. */
                return ZB_TRUE;
            }
        }
     
        return ZB_FALSE;
    }

    Hope this helps!

    Best regards,

    Marte

Children
  • Hi Marte,

    Sorry for my late reply!

    Thanks for the code - it was helpful to see how this implementation is intended. My proof of concept is working quite well already.

    I am wondering about another thing now. I am receiving standard "get scene membership" commands. That command is mandatory. The example answers them with "default response" but I'd expect the answer to be a "scene membership response" command.

    In my application I also see these commands arriving in "zb_zcl_device_cb" with endpoint 0 instead of the real endpoint number - but in my own packet handler they arrive with the correct endpoint set.

    Can you help me figuring out why the default response is send and why no endpoint id is passed to the device callback?

    Thanks in advance,

    Alex

  • Hi Alex,

    Yes, from the Zigbee Cluster Library Specification, chapter 3.7.2.4.8, it's stated that the Get Scene Membership command shall generate an appropriate Get Scene Membership Response command from the device that received the first command, so you should get that instead of a default response. How was the command addressed? It shall only respond with the response if the command was addressed to a single device, or if an entry within the Scene Table corresponds to the Group ID.

    I will ask our Zigbee team internally about this. However, because of holiday season it might take some time to get a response from them, so please be patient.

    Best regards,

    Marte

  • Hi Marte,

    This is the request:

    Frame 85967: 48 bytes on wire (384 bits), 48 bytes captured (384 bits) on interface wireshark_extcap2892, id 0
    IEEE 802.15.4 Data, Dst: 0x0088, Src: 0x0001
        Frame Control Field: 0x8861, Frame Type: Data, Acknowledge Request, PAN ID Compression, Destination Addressing Mode: Short/16-bit, Frame Version: IEEE Std 802.15.4-2003, Source Addressing Mode: Short/16-bit
        Sequence Number: 158
        Destination PAN: 0x1174
        Destination: 0x0088
        Source: 0x0001
        [Extended Source: ......]
        [Origin: 1]
    ZigBee Network Layer Data, Dst: 0x0088, Src: 0x0001
        Frame Control Field: 0x0248, Frame Type: Data, Discover Route: Enable, Security Data
        Destination: 0x0088
        Source: 0x0001
        Radius: 30
        Sequence Number: 223
        [Extended Source: ......]
        [Origin: 1]
        ZigBee Security Header
    ZigBee Application Support Layer Data, Dst Endpt: 10, Src Endpt: 64
        Frame Control Field: Data (0x00)
        Destination Endpoint: 10
        Cluster: Scenes (0x0005)
        Profile: Home Automation (0x0104)
        Source Endpoint: 64
        Counter: 202
    ZigBee Cluster Library Frame
        Frame Control Field: Cluster-specific (0x01)
        Sequence Number: 224
        Command: Get Scene Membership (0x06)
        Payload
            Group ID: 0xf44c
    

    This is the wrong default response from the example (or slightly modified but similar application):

    Frame 85969: 64 bytes on wire (512 bits), 64 bytes captured (512 bits) on interface wireshark_extcap2892, id 0
    IEEE 802.15.4 Data, Dst: 0x0001, Src: 0x0088
    ZigBee Network Layer Data, Dst: 0x0001, Src: 0x0088
    ZigBee Application Support Layer Data, Dst Endpt: 64, Src Endpt: 10
        Frame Control Field: Data (0x40)
        Destination Endpoint: 64
        Cluster: Scenes (0x0005)
        Profile: Home Automation (0x0104)
        Source Endpoint: 10
        Counter: 68
    ZigBee Cluster Library Frame, Command: Default Response, Seq: 224
        Frame Control Field: Profile-wide (0x18)
        Sequence Number: 224
        Command: Default Response (0x0b)
        Response to Command: 0x06
        Status: Failure (0x01)
    

    This is what I would expect - captured from a certified device:

    Frame 382: 51 bytes on wire (408 bits), 51 bytes captured (408 bits) on interface wireshark_extcap1788, id 0
    IEEE 802.15.4 Data, Dst: 0x0001, Src: 0x007a
    ZigBee Network Layer Data, Dst: 0x0001, Src: 0x007a
    ZigBee Application Support Layer Data, Dst Endpt: 64, Src Endpt: 11
        Frame Control Field: Data (0x00)
        Destination Endpoint: 64
        Cluster: Scenes (0x0005)
        Profile: Home Automation (0x0104)
        Source Endpoint: 11
        Counter: 207
    ZigBee Cluster Library Frame
        Frame Control Field: Cluster-specific (0x19)
        Sequence Number: 160
        Command: Get Scene Membership Response (0x06)
        Payload
            Scenes Status: Success (0x00)
            Scene Capacity: 50
            Group ID: 0xf44c
            Scene Count: 0

    Looking forward to your response and have a nice Holiday!

    Best regards,

    Alex

  • Hi,

    I got a response from our Zigbee team now. They've implemented some scenes functionality:

    To handle Scenes in the application, Scene cluster related callback needs to be implemented and scene table needs to be managed. The required code is based on the SDK T&Z v4.1.0 and is included in the zip package: 5811.light_bulb_with_scenes.zip

    Package contains scene handlers and light bulb example, modified to use required handlers:

    • Added include header zcl_scenes.h
    • Added call to zcl_scenes_cb()
    • Added call to zcl_scenes_init()

    At this moment, it handles scenes for clusters: On/Off, Level control, Window covering.
    It supports only one endpoint, which needs to be defined in the zcl_scenes.h as ZCL_SCENES_ENDPOINT.

    If you have any other questions regarding this or the original case, please don't hesitate to ask here. If you have a new problem unrelated to this case, please open a new case with that issue, as this will make it easier for others later if they're experiencing a similar issue as yours, either the original one in this case or your new one.

    Best regards,

    Marte

Related