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

Zigbee Smart Home demo

Hello,
I came across this twitter clip by Marjeris showing a Thingy 52 relaying temp info to Alexa.
How was this done? by mqtt? or as gadget?
thank-you,

Parents
  • Hi Simon,

    Sorry for the late reply. We used the BLE Thingy and Zigbee Color Light Bulb example as the starting point and modified it by adding Zigbee Temperature sensor cluster and in this case, updated the temperature attribute of the cluster everytime we got a new temperature reading from the Thingy temperature characteristic. I have tried to write down some steps you can follow if you want to try to add temperature readings to the BLE thingy and Zigbee Color Light bulb example:

    Declare a new endpoint with Zigbee temperature sensor cluster (you can use the Zigbee Multisensor example as a guideline).

    In ble_thingy_master.c we updated some structures to include updates of the temperature characteristic from the Thingy:

    /* Thingy device events passed to the main application. */
    typedef enum
    {
        THINGY_BUTTON_PRESSED,
        THINGY_BUTTON_RELEASED,
        THINGY_CONNECTED,
        THINGY_DISCONNECTED,
        THINGY_TEMPERATURE_UPDATE,
    } thingy_evt_t;
    
    /* Structure to contain characteristic for discovery purpose */
    typedef struct
    {
        uint8_t                     name[20];
        uint16_t                    handle;
    } characteristic_t;
    
    /* Structure for storing used Thingy's characteristic's */
    typedef struct
    {
        characteristic_t            battery_level;
        characteristic_t            led;
        characteristic_t            button;
        characteristic_t            button_cccd;
        characteristic_t            temp;
        characteristic_t            temp_cccd;
        uint16_t                    conn_handle;
        bool                        frame_lock;
    } thingy_device_t;
    
    /**@brief Callback definition for intercepting thingy device events. */
    typedef void (*thingy_evt_handler_t)(thingy_device_t * p_thingy, thingy_evt_t evt, ble_evt_t const * p_ble_evt);

    And we added a new case for THINGY_TEMPERATURE_UPDATE inside the thingy_event_handler() in main.c to store the new temperature inside a variable and set a flag to update temperature cluster.

    case THINGY_TEMPERATURE_UPDATE:
                new_temperature = (zb_int16_t)p_ble_evt->evt.gattc_evt.params.hvx.data[0];
                if (new_temperature != m_temperature)
                {
                    m_temperature = new_temperature;
                    NRF_LOG_INFO("main temperature update %d", p_ble_evt->evt.gattc_evt.params.hvx.data[0]);
                    m_update_temperature_flag = true;
                }
                else
                {
                    NRF_LOG_INFO("same temperature (%d)", new_temperature);
                }
                break;

    Then called update_temperature() function from main loop to update the ZCL temperature cluster using zb_zcl_set_attr_val() for a new temperature reading:

    static void update_temperature(zb_int16_t temperature)
    {
        zb_zcl_status_t zcl_status;
        static zb_int16_t new_temp_value;
        
        /* Get new temperature measured value */
        new_temp_value = temperature;
        new_temp_value = new_temp_value * 100;
        zcl_status = zb_zcl_set_attr_val(MULTI_SENSOR_ENDPOINT,
                                         ZB_ZCL_CLUSTER_ID_TEMP_MEASUREMENT,
                                         ZB_ZCL_CLUSTER_SERVER_ROLE,
                                         ZB_ZCL_ATTR_TEMP_MEASUREMENT_VALUE_ID,
                                         (zb_uint8_t *)&new_temp_value,
                                         ZB_FALSE);
        if (zcl_status != ZB_ZCL_STATUS_SUCCESS)
        {
            NRF_LOG_INFO("Set temperature value fail. zcl_status &d", zcl_status);
        }
        else
        {
            NRF_LOG_INFO("Set temperature value success, val: 0x%04x, %d", new_temp_value, new_temp_value);
        }
    }

    Main loop at the end of main():

        /* Enter main loop */
        for (;;)
        {
            if(m_update_temperature_flag)
            {
                m_update_temperature_flag = false;
                update_temperature(m_temperature);
            }
            zboss_main_loop_iteration();
            UNUSED_RETURN_VALUE(NRF_LOG_PROCESS());
        }

    Links to the infocenter pages for the Zigbee examples that were used:

    BLE Thingy and Zigbee multiprotocol example: https://infocenter.nordicsemi.com/topic/sdk_tz_v4.1.0/zigbee_multi_dynamic_color_light_sed_thingy_master.html

    Zigbee multisensor example: https://infocenter.nordicsemi.com/topic/sdk_tz_v4.1.0/zigbee_multi_sensor_example.html

    Best regards,

    Marjeris

Reply
  • Hi Simon,

    Sorry for the late reply. We used the BLE Thingy and Zigbee Color Light Bulb example as the starting point and modified it by adding Zigbee Temperature sensor cluster and in this case, updated the temperature attribute of the cluster everytime we got a new temperature reading from the Thingy temperature characteristic. I have tried to write down some steps you can follow if you want to try to add temperature readings to the BLE thingy and Zigbee Color Light bulb example:

    Declare a new endpoint with Zigbee temperature sensor cluster (you can use the Zigbee Multisensor example as a guideline).

    In ble_thingy_master.c we updated some structures to include updates of the temperature characteristic from the Thingy:

    /* Thingy device events passed to the main application. */
    typedef enum
    {
        THINGY_BUTTON_PRESSED,
        THINGY_BUTTON_RELEASED,
        THINGY_CONNECTED,
        THINGY_DISCONNECTED,
        THINGY_TEMPERATURE_UPDATE,
    } thingy_evt_t;
    
    /* Structure to contain characteristic for discovery purpose */
    typedef struct
    {
        uint8_t                     name[20];
        uint16_t                    handle;
    } characteristic_t;
    
    /* Structure for storing used Thingy's characteristic's */
    typedef struct
    {
        characteristic_t            battery_level;
        characteristic_t            led;
        characteristic_t            button;
        characteristic_t            button_cccd;
        characteristic_t            temp;
        characteristic_t            temp_cccd;
        uint16_t                    conn_handle;
        bool                        frame_lock;
    } thingy_device_t;
    
    /**@brief Callback definition for intercepting thingy device events. */
    typedef void (*thingy_evt_handler_t)(thingy_device_t * p_thingy, thingy_evt_t evt, ble_evt_t const * p_ble_evt);

    And we added a new case for THINGY_TEMPERATURE_UPDATE inside the thingy_event_handler() in main.c to store the new temperature inside a variable and set a flag to update temperature cluster.

    case THINGY_TEMPERATURE_UPDATE:
                new_temperature = (zb_int16_t)p_ble_evt->evt.gattc_evt.params.hvx.data[0];
                if (new_temperature != m_temperature)
                {
                    m_temperature = new_temperature;
                    NRF_LOG_INFO("main temperature update %d", p_ble_evt->evt.gattc_evt.params.hvx.data[0]);
                    m_update_temperature_flag = true;
                }
                else
                {
                    NRF_LOG_INFO("same temperature (%d)", new_temperature);
                }
                break;

    Then called update_temperature() function from main loop to update the ZCL temperature cluster using zb_zcl_set_attr_val() for a new temperature reading:

    static void update_temperature(zb_int16_t temperature)
    {
        zb_zcl_status_t zcl_status;
        static zb_int16_t new_temp_value;
        
        /* Get new temperature measured value */
        new_temp_value = temperature;
        new_temp_value = new_temp_value * 100;
        zcl_status = zb_zcl_set_attr_val(MULTI_SENSOR_ENDPOINT,
                                         ZB_ZCL_CLUSTER_ID_TEMP_MEASUREMENT,
                                         ZB_ZCL_CLUSTER_SERVER_ROLE,
                                         ZB_ZCL_ATTR_TEMP_MEASUREMENT_VALUE_ID,
                                         (zb_uint8_t *)&new_temp_value,
                                         ZB_FALSE);
        if (zcl_status != ZB_ZCL_STATUS_SUCCESS)
        {
            NRF_LOG_INFO("Set temperature value fail. zcl_status &d", zcl_status);
        }
        else
        {
            NRF_LOG_INFO("Set temperature value success, val: 0x%04x, %d", new_temp_value, new_temp_value);
        }
    }

    Main loop at the end of main():

        /* Enter main loop */
        for (;;)
        {
            if(m_update_temperature_flag)
            {
                m_update_temperature_flag = false;
                update_temperature(m_temperature);
            }
            zboss_main_loop_iteration();
            UNUSED_RETURN_VALUE(NRF_LOG_PROCESS());
        }

    Links to the infocenter pages for the Zigbee examples that were used:

    BLE Thingy and Zigbee multiprotocol example: https://infocenter.nordicsemi.com/topic/sdk_tz_v4.1.0/zigbee_multi_dynamic_color_light_sed_thingy_master.html

    Zigbee multisensor example: https://infocenter.nordicsemi.com/topic/sdk_tz_v4.1.0/zigbee_multi_sensor_example.html

    Best regards,

    Marjeris

Children
Related