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

Thermostat cluster enable issue

Hi All,

I am developing product using nRF52840 and SDK nRF5_SDK_for_Thread_and_Zigbee_v3.0.0_d310e71.

This product is basically, using the Thermostat cluster and Zigbee protocol to communicate with the Zigbee gateway.

So, I referred light_bulb example and followed steps to enable "Thermostat cluster and attributes".

I have included the respective files also but I am unable to execute the below callback function case statement,

static zb_void_t zcl_device_cb(zb_uint8_t param)
{
    zb_uint8_t                       cluster_id;
    zb_uint8_t                       attr_id;
    zb_buf_t                       * p_buffer = ZB_BUF_FROM_REF(param);
    zb_zcl_device_callback_param_t * p_device_cb_param =
                     ZB_GET_BUF_PARAM(p_buffer, zb_zcl_device_callback_param_t);

    NRF_LOG_INFO("zcl_device_cb id %hd", p_device_cb_param->device_cb_id);

    /* Set default response value. */
    p_device_cb_param->status = RET_OK;

    switch (p_device_cb_param->device_cb_id)
    {
        case ZB_ZCL_SET_ATTR_VALUE_CB_ID:
            cluster_id = p_device_cb_param->cb_param.set_attr_value_param.cluster_id;
            attr_id    = p_device_cb_param->cb_param.set_attr_value_param.attr_id;

            if (cluster_id == ZB_ZCL_CLUSTER_ID_THERMOSTAT)
            {
                uint16_t value = p_device_cb_param->cb_param.set_attr_value_param.values.data16;

                NRF_LOG_INFO("thermostat local temperature: %d", value);
                if (attr_id == ZB_ZCL_ATTR_THERMOSTAT_LOCAL_TEMPERATURE_ID)
                {
                    local_temperature_value(value);
                }
            }
            else
            {
                /* Other clusters can be processed here */
                NRF_LOG_INFO("Unhandled cluster attribute id: %d", cluster_id);
            }
        break;

        default:
            p_device_cb_param->status = RET_ERROR;
            break;
    }

    NRF_LOG_INFO("zcl_device_cb status: %hd", p_device_cb_param->status);
}

Also, I am attaching code for reference please let me know what else I forgot to enable the functions. It is urgent for me to solve this issue.

Radiator_nRF_v0.9.0.zip

And, with these attributes, for some of the commands, I need to implement custom attributes so if you share how to add custom attributes to this cluster.

Thanks in advance.

Regards,

Rohit R

Parents
  • Hi Marte,

    Thank you for the details, 

    As of now, sending custom command is pending. I will work on this in some time. 

    But current requirement I am trying to enabled the required attributes list. With reference to your code and other I have created extended list also. 

    But unoccupied, min and max, local_calibration and etc are not getting highlighted from thermostat cluster. And also Battery percentage attribute also facing same problem. they are not getting highlighted and these are must attributes (mandatory ids). 

    I have tested in SDK 3.0 I am getting highlighted below points but in SDK 4.1 i am facing this issue. Let me know why?

    Below is the image attached for both cluster. And also my thermostat.h file please check what is wrong. Why I am not getting these attributes highlighted. 

    0508.zb_zcl_thermostat.h

    5807.zb_zcl_power_config.h

    Thanks and regards

    Rohit 

  • Hi Marte, 

    Any update on this. 

    Urgent!

    Is there any difference in my file. 

    Thanks and Regards

    Rohit R

  • Hi Marte, 

    Thanks for the response. 

     I have already answered this, and explained that this is not possible with SED. With devices that are not SED, this will happen by default if you are using zb_osif_wait_for_event() to reduce power.

    - My point here is, I want less current consumption for my device it should be 30uA. As per your suggestion we tried SED because zb_osif_wait_for_event(); Didn't worked. It gave us current 3.9mA. 

    So, Till we get developer feedback on waking up device using Zigbee command. We tried SED config. And it gave us some better result around 1mA. But again this huge my target is 30uA. 

    - That's why asked any update from Developer for this? If the waking up device using Zigbee command gives us better result in current consumption I will definitely use that not SED. On other hand after configuring SED if would resulted me in uA (micro Ampear) then I would go ahead with. I didn't bother for waking up on Zigbee command. 

    - Point is, using SED or zb_osif_wait_for_event() not gave me less current. In document typical value mentioned. Also, some points regarding System ON, no ram retention but how to do that no explanation. System Off also same. Only wakeup on reset or GPIO interrupt that also not help me here. 

    Then how to reduce current?? We trying different different ways but still same result. Current not reducing below mA. 

     As this feature is only available in v4.1.0, you must implement it yourself in v3.0.0. As I stated before you should look at the function zigbee_power_down_unused_ram() in zigbee_helpers.c in v4.1.0 to see how this can be done. After implementing the function, you should call it right after setting SED with zb_set_rx_on_when_idle() in main().

    - I saw some post and suggestion followed below to configure the same. 

    NRF_POWER->RAM[0].POWERCLR = 0x3;
    NRF_POWER->RAM[1].POWERCLR = 0x3;
    NRF_POWER->RAM[2].POWERCLR = 0x3;
    NRF_POWER->RAM[3].POWERCLR = 0x3;
    NRF_POWER->RAM[4].POWERCLR = 0x3;
    NRF_POWER->RAM[5].POWERCLR = 0x3;
    NRF_POWER->RAM[6].POWERCLR = 0x3;
    NRF_POWER->RAM[7].POWERCLR = 0x3;
    NRF_POWER->RAM[8].POWERCLR = 0x3F;
    - As per our study I commented RAM[0], RAM[1] and RAM[2] and set RAM[8] = 0x3 then able to run my code. 
    - And, if i just comment RAM[0] and RAM[8] = 0x3F as per one of nrf engineer post, I am not able to run code. IT enters into hardfault. 
    - Okay, I will follows your steps. Use 4.1 to port in 3.0 SDK. 
    I will come back to you regarding this.

    - Yes, please I will wait. 

    Thanks and Regards

    Rohit R

  • Hi Rohit,

    So, Till we get developer feedback on waking up device using Zigbee command. We tried SED config. And it gave us some better result around 1mA. But again this huge my target is 30uA. 

    Can you please give some more information about what your project is doing when you are measuring the current and how you are measuring it? You say the device has joined the network, but is it performing any other actions while you are measuring the current consumption?

    You can also check out our guide Measuring current, and I recommend reading the note further down on that page. Additionally, it is suggested to cut SB40 to put P22 in series with the load, as explained in Preparing the DK. You should also set SW6 to "nRF only".

    When performing current consumption tests earlier, our developers have managed to get sleep current consumption down to 1.6-3.3 µA, depending on the amount of RAM retention. This was when the device had joined and was not performing additional actions, but being in sleep mode. However, it is difficult to compare with your results without knowing more about your test setup.

    That's why asked any update from Developer for this? If the waking up device using Zigbee command gives us better result in current consumption I will definitely use that not SED. On other hand after configuring SED if would resulted me in uA (micro Ampear) then I would go ahead with. I didn't bother for waking up on Zigbee command.

    Please read what I wrote in my previous reply about this. If you want to get the lowest possible current consumption, you should use SED. You will not get lower current consumption when not using SED. The difference between SED and non sleepy devices is that with SED the radio is turned off and does not receive or send packets. This greatly reduces current consumption.

    If you are using SED but does not see a significant impact on the current consumption, then it is possible the device does not go to sleep as it should, or that it wakes up very often.

    Also, the current consumption in SED applications is further optimized in v4.1.0 of the SDK, so you it is very likely you would get a lower current consumption using that version.

    Also, some points regarding System ON, no ram retention but how to do that no explanation.

    Please read my previous replies. I explained clearly what the parts of this configuration means:

    • System ON: This means that the chip is in system ON, and not in system OFF, which means that the chip is in a regular state ready to run, and that the CPU is in sleep mode. The CPU is in a WFE (waitinf for event) call, and will wake when there is an interrupt. This interrupt is typically the RTC clock, but with 1 μA. the RTC is not in use.
    • no RAM retention: this means that the RAM is not conserved, and will practically mean that there is no code running on the chip.

    You get System ON when the CPU is in sleep mode, so either when a SED goes to sleep, or when calling zb_osif_wait_for_event(). You must have some RAM retention, as without it, your application cannot run, but you can power down unused parts of RAM, as I have explained previously.

    And also, I would like to know can we use system off in sleepy end device and wake up on GPIO interrupt.

    In both the case of SED and non-SED devices, the stack calls zb_osif_wait_for_event(), which will behave like a single call of __WFE() instruction, from a functional point of view. So if an interrupt occurs between zb_osif_wait_for_event() calls, the device will wake up. Thus, you can implement GPIO interrupts in the same way as you would with WFE (wait for event). You must enable GPIO, configure a pin for input, and configure it to give an interrupt on pin change. An example of how you can do this is to create a gpio_init functions as follows:

    static void gpio_init(void)
    {
        ret_code_t err_code;
        
        err_code = nrf_drv_gpiote_init();
        APP_ERROR_CHECK(err_code);
        
        nrf_drv_gpiote_in_config_t in_config = GPIOTE_CONFIG_IN_SENSE_TOGGLE(false);
        in_config.pull = NRF_GPIO_PIN_PULLUP;
        
        err_code = nrf_drv_gpiote_in_init(PIN_IN, &in_config, in_pin_handler);
        APP_ERROR_CHECK(err_code);
        
        nrf_drv_gpiote_in_event_enable(PIN_IN, true);
    }

    Then you can call this function in main() during initialization. You must remember to define PIN_IN as the pin you want to use for interrupts. You can also check out the GPIOTE driver for more information.

    Best regards,

    Marte

  • Hi Marte, 

    Thank you so much for the response. 

    Please find my attached document and explanation for your question, setup images. 

    Also, I have attached code which I used to check the current. 

    Go through my comments and let me know your feedback on my comments as early as possible. 

    nRF52840 setup and comments.docx

    main. cfile. 

    /**
     * Copyright (c) 2018 - 2019, Nordic Semiconductor ASA
     *
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without modification,
     * are permitted provided that the following conditions are met:
     *
     * 1. Redistributions of source code must retain the above copyright notice, this
     *    list of conditions and the following disclaimer.
     *
     * 2. Redistributions in binary form, except as embedded into a Nordic
     *    Semiconductor ASA integrated circuit in a product or a software update for
     *    such product, must reproduce the above copyright notice, this list of
     *    conditions and the following disclaimer in the documentation and/or other
     *    materials provided with the distribution.
     *
     * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
     *    contributors may be used to endorse or promote products derived from this
     *    software without specific prior written permission.
     *
     * 4. This software, with or without modification, must only be used with a
     *    Nordic Semiconductor ASA integrated circuit.
     *
     * 5. Any software provided in binary form under this license must not be reverse
     *    engineered, decompiled, modified and/or disassembled.
     *
     * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
     * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
     * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
     * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
     * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
     * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     *
     */
    /** @file
     *
     * @defgroup zigbee_examples_light_bulb main.c
     * @{
     * @ingroup zigbee_examples
     * @brief Dimmable light sample (HA profile)
     */
    
    #include "sdk_config.h"
    #include "zboss_api.h"
    #include "zb_mem_config_med.h"
    #include "zb_error_handler.h"
    #include "zb_nrf52840_internal.h"
    #include "zigbee_helpers.h"
    
    #include "bsp.h"
    #include "boards.h"
    #include "app_timer.h"
    
    #include "nrf_log.h"
    #include "nrf_log_ctrl.h"
    #include "nrf_log_default_backends.h"
    
    #include "app_uart.h"
    #include "app_error.h"
    #include "nrf_delay.h"
    #include "nrf.h"
    
    /**User Include file*********/
    #include "uart_config.h"
    #include "gpio_config.h"
    #include "timer_config.h"
    #include "commands.h" 
    #include "uart_statemachine.h" 
    #include "app_flash_memory.h"
    
    #include "zb_custom1_thermostat.h"
    #include "custom_app_event.h"
    
    
                                    
    /**< Scan only one, predefined channel to find the coordinator. */
    #define IEEE_CHANNEL_MASK                (ZB_TRANSCEIVER_ALL_CHANNELS_MASK)    // (1l << ZIGBEE_CHANNEL)
    
    #define ERASE_PERSISTENT_CONFIG           ZB_FALSE                              /**< Do not erase NVRAM to save the network parameters after device reboot or power-off. */
    
    
    #define ZIGBEE_NETWORK_STATE_LED          BSP_BOARD_LED_2                       /**< LED indicating that light switch successfully joind ZigBee network. */
    
    
    #if !defined ZB_ED_ROLE
    #error Define ZB_ED_ROLE to compile End Device source code.
    #endif
    
    
    
    /******************************************************************
    * GLOBAL VARIABLES
    *
    *******************************************************************/
    uint16_t ui16CurrentTemp =0, ui16OccupiedHeatSetpoint = 0, ui16UnOccupiedHeatSetpoint = 0;
    uint8_t  ui8LocalTemperatureCalibration = 0;
    uint32_t ui32HostflagsData = 0;
    
    bool boolSetTemperature = false;
    bool boolGetStatus = false;
    bool boolSetHostflags = false;
    bool boolSendDeviceConfig = false;
    /******************************************************************************************
    *EXTERNAL VARIABLES
    *
    *******************************************************************************************/
    extern bool boolReady;
    extern bool boolMCUInterrupt;
    extern bool boolSetCommand;
    extern uint8_t ui8SendDeviceConfig[BUFFER_SIZE];
    
    extern App_tsEventUart sAppUartEvent;
    extern E_StateMachineThermostat e_StateMachineThermostat;
    /******************************************************************************************
    *FUNCTIONS 
    *
    *******************************************************************************************/
    /* Declare attribute list for Basic cluster. */
    ZB_ZCL_DECLARE_BASIC_ATTRIB_LIST_EXT(basic_attr_list,
                                         &m_dev_ctx.basic_attr.zcl_version,
                                         &m_dev_ctx.basic_attr.app_version,
                                         &m_dev_ctx.basic_attr.stack_version,
                                         &m_dev_ctx.basic_attr.hw_version,
                                         m_dev_ctx.basic_attr.mf_name,
                                         m_dev_ctx.basic_attr.model_id,
                                         m_dev_ctx.basic_attr.date_code,
                                         &m_dev_ctx.basic_attr.power_source,
                                         m_dev_ctx.basic_attr.location_id,
                                         &m_dev_ctx.basic_attr.ph_env,
                                         m_dev_ctx.basic_attr.sw_ver);
    
    /* Declare attribute list for Identify cluster. */
    ZB_ZCL_DECLARE_IDENTIFY_ATTRIB_LIST(identify_attr_list,
                                        &m_dev_ctx.identify_attr.identify_time);
    
    /**power attributes**/
    ZB_ZCL_DECLARE_POWER_CONFIG_BATTERY_ATTRIB_LIST_EXT(power_config_attr_list,
                                            &m_dev_ctx.power_attr.battery_voltage,
                                            &m_dev_ctx.power_attr.battery_size,
                                            &m_dev_ctx.power_attr.battery_quantity,
                                            &m_dev_ctx.power_attr.battery_rated_voltage,
                                            &m_dev_ctx.power_attr.battery_alarm_mask,
                                            &m_dev_ctx.power_attr.battery_voltage_min_threshold,
                                            &m_dev_ctx.power_attr.battery_percentage_remaining,
                                            &m_dev_ctx.power_attr.battery_voltage_threshold1,
                                            &m_dev_ctx.power_attr.battery_voltage_threshold2,
                                            &m_dev_ctx.power_attr.battery_voltage_threshold3,
                                            &m_dev_ctx.power_attr.battery_percentage_min_threshold,
                                            &m_dev_ctx.power_attr.battery_percentage_threshold1,
                                            &m_dev_ctx.power_attr.battery_percentage_threshold2,
                                            &m_dev_ctx.power_attr.battery_percentage_threshold3,
                                            &m_dev_ctx.power_attr.battery_alarm_state);
    
    ZB_ZCL_DECLARE_TIME_ATTRIB_LIST(time_attr_list,
                                    &m_dev_ctx.time_attr.timeId,
                                    &m_dev_ctx.time_attr.time_status,
                                    &m_dev_ctx.time_attr.time_zone,
                                    &m_dev_ctx.time_attr.dst_start,
                                    &m_dev_ctx.time_attr.dst_end,
                                    &m_dev_ctx.time_attr.dst_shift,
                                    &m_dev_ctx.time_attr.standard_time,
                                    &m_dev_ctx.time_attr.local_time,
                                    &m_dev_ctx.time_attr.last_settime,
                                    &m_dev_ctx.time_attr.valid_untilTime);
    
    /* Declare extended attribute list for Thermostat cluster. */
    ZB_ZCL_DECLARE_THERMOSTAT_ATTRIB_LIST_EXT(thermostat_attr_list,
                                              &m_dev_ctx.thermostat_attr.local_temperature,
                                              &m_dev_ctx.thermostat_attr.local_temperature_calibration,
                                              &m_dev_ctx.thermostat_attr.occupied_heating_setpoint,
                                              &m_dev_ctx.thermostat_attr.unoccupied_heating_setpoint,
                                              &m_dev_ctx.thermostat_attr.pi_heating_demand,
                                              &m_dev_ctx.thermostat_attr.min_heating_setpoint_limit,
                                              &m_dev_ctx.thermostat_attr.max_heating_setpoint_limit,
                                              &m_dev_ctx.thermostat_attr.remote_sensing,
                                              &m_dev_ctx.thermostat_attr.control_seq_of_operation,
                                              &m_dev_ctx.thermostat_attr.system_mode,
                                              &m_dev_ctx.thermostat_attr.trv_mode,
                                              &m_dev_ctx.thermostat_attr.set_valve_position,
                                              &m_dev_ctx.thermostat_attr.error,
                                              &m_dev_ctx.thermostat_attr.current_setpoint,
                                              &m_dev_ctx.thermostat_attr.host_flags);
    
    /* Declare cluster list for Thermostat device (Basic, Identify, Thermostat, Fan Control, Thermostat UI). */
    ZB_DECLARE_CUSTOM_THERMOSTAT_CLUSTER_LIST(thermostat_clusters,
                                          basic_attr_list,
                                          identify_attr_list,
                                          power_config_attr_list,
                                          thermostat_attr_list,
                                          time_attr_list);
    
    
    ZB_HA_DECLARE_CUSTOM_THERMOSTAT_EP(thermostat_ep,
                                   THERMOSTAT_SENSOR_ENDPOINT,
                                   thermostat_clusters);
    
    ZB_HA_DECLARE_CUSTOM_THERMOSTAT_CTX(thermostat_ctx, thermostat_ep);
    
    /**@brief Function for initializing the application timer.
     */
    static void timer_init(void)
    {
        uint32_t error_code = app_timer_init();
        APP_ERROR_CHECK(error_code);
    }
    
    /**@brief Function for initializing the nrf log module.
     */
    static void log_init(void)
    {
        ret_code_t err_code = NRF_LOG_INIT(NULL);
        APP_ERROR_CHECK(err_code);
    
        NRF_LOG_DEFAULT_BACKENDS_INIT();
    }
    
    
    /**@brief Function for initializing LEDs.
     */
    static void leds_init(void)
    {
        bsp_board_init(BSP_INIT_LEDS);
    }
    
    /**@brief Function for initializing all clusters attributes.
    */
    static void thermostat_clusters_attr_init(void)
    {
         /* Basic cluster attributes data */
         m_dev_ctx.basic_attr.zcl_version = ZB_ZCL_VERSION;
         m_dev_ctx.basic_attr.app_version = THERMOSTAT_INIT_BASIC_APP_VERSION;
         m_dev_ctx.basic_attr.stack_version = THERMOSTAT_INIT_BASIC_STACK_VERSION;
         m_dev_ctx.basic_attr.hw_version = THERMOSTAT_INIT_BASIC_HW_VERSION;
       
        /* Use ZB_ZCL_SET_STRING_VAL to set strings, because the first byte should
         * contain string length without trailing zero.
         *
         * For example "test" string wil be encoded as:
         *   [(0x4), 't', 'e', 's', 't']
         */
          ZB_ZCL_SET_STRING_VAL(m_dev_ctx.basic_attr.mf_name,
                              THERMOSTAT_INIT_BASIC_MANUF_NAME,
                              ZB_ZCL_STRING_CONST_SIZE(THERMOSTAT_INIT_BASIC_MANUF_NAME));
    
          ZB_ZCL_SET_STRING_VAL(m_dev_ctx.basic_attr.model_id,
                              THERMOSTAT_INIT_BASIC_MODEL_ID,
                              ZB_ZCL_STRING_CONST_SIZE(THERMOSTAT_INIT_BASIC_MODEL_ID));
    
          ZB_ZCL_SET_STRING_VAL(m_dev_ctx.basic_attr.date_code,
                              THERMOSTAT_INIT_BASIC_DATE_CODE,
                              ZB_ZCL_STRING_CONST_SIZE(THERMOSTAT_INIT_BASIC_DATE_CODE));
    
          m_dev_ctx.basic_attr.power_source = THERMOSTAT_INIT_BASIC_POWER_SOURCE;
    
          ZB_ZCL_SET_STRING_VAL(m_dev_ctx.basic_attr.location_id,
                              THERMOSTAT_INIT_BASIC_LOCATION_DESC,
                              ZB_ZCL_STRING_CONST_SIZE(THERMOSTAT_INIT_BASIC_LOCATION_DESC));
    
    
          m_dev_ctx.basic_attr.ph_env = THERMOSTAT_INIT_BASIC_PH_ENV;
          //m_dev_ctx.basic_attr.sw_ver = "00000000";
          memcpy( m_dev_ctx.basic_attr.sw_ver,"00000000", 8);
        
        /* Identify cluster attributes data */
        m_dev_ctx.identify_attr.identify_time        = ZB_ZCL_IDENTIFY_IDENTIFY_TIME_DEFAULT_VALUE;
    
    //    /**power configuration attributes data**/
        m_dev_ctx.power_attr.battery_percentage_remaining = 0x02;
        m_dev_ctx.power_attr.battery_quantity = ZB_POWER_CONFIG_BATTERY_QUANTITY;
        m_dev_ctx.power_attr.battery_size = ZB_ZCL_POWER_CONFIG_BATTERY_SIZE_AA;
    
       /* Thermostat cluster attributes data */
        m_dev_ctx.thermostat_attr.local_temperature             = 0x07D0;
        m_dev_ctx.thermostat_attr.local_temperature_calibration = 0x00;
        m_dev_ctx.thermostat_attr.pi_heating_demand             = 0xFF;
        m_dev_ctx.thermostat_attr.occupied_heating_setpoint     = 0x07D0;
        m_dev_ctx.thermostat_attr.unoccupied_heating_setpoint   = 0x07D0;
        m_dev_ctx.thermostat_attr.min_heating_setpoint_limit    = 0x01F4;
        m_dev_ctx.thermostat_attr.max_heating_setpoint_limit    = 0x0BB8;
        m_dev_ctx.thermostat_attr.control_seq_of_operation      = ZB_ZCL_THERMOSTAT_CONTROL_SEQ_OF_OPERATION_HEATING_ONLY;
        m_dev_ctx.thermostat_attr.system_mode                   = ZB_ZCL_THERMOSTAT_SYSTEM_MODE_HEAT;
        m_dev_ctx.thermostat_attr.current_setpoint             = 0x0898;
        m_dev_ctx.thermostat_attr.trv_mode                     = ZB_ZCL_THERMOSTAT_TRV_MODE_DEFAULT_VALUE;
        m_dev_ctx.thermostat_attr.set_valve_position           = 0;
        m_dev_ctx.thermostat_attr.error                        = 0;
    
             /***time cluster attributes data**/
        m_dev_ctx.time_attr.timeId = ZB_ZCL_TIME_TIME_DEFAULT_VALUE;
        m_dev_ctx.time_attr.time_status = ZB_ZCL_TIME_TIME_STATUS_DEFAULT_VALUE;
    
        /*local temperature set attribute**/
       ZB_ZCL_SET_ATTRIBUTE(THERMOSTAT_SENSOR_ENDPOINT,
                            ZB_ZCL_CLUSTER_ID_THERMOSTAT,
                            ZB_ZCL_CLUSTER_SERVER_ROLE,
                            ZB_ZCL_ATTR_THERMOSTAT_LOCAL_TEMPERATURE_ID,
                            (zb_uint8_t *)&m_dev_ctx.thermostat_attr.local_temperature,
                            ZB_FALSE);
     
        ZB_ZCL_SET_ATTRIBUTE(THERMOSTAT_SENSOR_ENDPOINT,
                            ZB_ZCL_CLUSTER_ID_THERMOSTAT,
                            ZB_ZCL_CLUSTER_SERVER_ROLE,
                            ZB_ZCL_ATTR_THERMOSTAT_OCCUPIED_HEATING_SETPOINT_ID,
                            (zb_uint8_t *)&m_dev_ctx.thermostat_attr.occupied_heating_setpoint,
                            ZB_FALSE);
    
        ZB_ZCL_SET_ATTRIBUTE(THERMOSTAT_SENSOR_ENDPOINT,
                            ZB_ZCL_CLUSTER_ID_THERMOSTAT,
                            ZB_ZCL_CLUSTER_SERVER_ROLE,
                            ZB_ZCL_ATTR_THERMOSTAT_UNOCCUPIED_HEATING_SETPOINT_ID,
                            (zb_uint8_t *)&m_dev_ctx.thermostat_attr.unoccupied_heating_setpoint,
                            ZB_FALSE);
    
        ZB_ZCL_SET_ATTRIBUTE(THERMOSTAT_SENSOR_ENDPOINT, 
                             ZB_ZCL_CLUSTER_ID_THERMOSTAT, 
                             ZB_ZCL_CLUSTER_SERVER_ROLE, 
                             ZB_ZCL_ATTR_THERMOSTAT_HOST_FLAG_ID, 
                             (zb_uint8_t *)&m_dev_ctx.thermostat_attr.host_flags, 
                             ZB_FALSE);
    
        ZB_ZCL_SET_ATTRIBUTE(THERMOSTAT_SENSOR_ENDPOINT, 
                             ZB_ZCL_CLUSTER_ID_THERMOSTAT, 
                             ZB_ZCL_CLUSTER_SERVER_ROLE, 
                             ZB_ZCL_ATTR_THERMOSTAT_TRV_MODE_ID, 
                             (zb_uint8_t *)& m_dev_ctx.thermostat_attr.trv_mode, 
                             ZB_FALSE);
    
       /**Battery percentage value**/
       ZB_ZCL_SET_ATTRIBUTE(THERMOSTAT_SENSOR_ENDPOINT,
                            ZB_ZCL_CLUSTER_ID_POWER_CONFIG,
                            ZB_ZCL_CLUSTER_SERVER_ROLE,
                            ZB_ZCL_ATTR_POWER_CONFIG_BATTERY_REMAINING_ID,
                            (zb_uint8_t *)&m_dev_ctx.power_attr.battery_percentage_remaining,
                            ZB_FALSE);  
                                      
       ZB_ZCL_SET_ATTRIBUTE(THERMOSTAT_SENSOR_ENDPOINT,
                            ZB_ZCL_CLUSTER_ID_POWER_CONFIG,
                            ZB_ZCL_CLUSTER_SERVER_ROLE,
                            ZB_ZCL_ATTR_POWER_CONFIG_BATTERY_QUANTITY_ID,
                            (zb_uint8_t *)&m_dev_ctx.power_attr.battery_quantity,
                            ZB_FALSE);
    }
    
    /**@brief Function for local temperature
     *
     * @param[in]   new_value local temp value
     */
    void localTemperatureValue(zb_uint16_t ui16local_tempvalue)
    {
       zb_zcl_status_t zcl_status;
    
       zcl_status = zb_zcl_set_attr_val(THERMOSTAT_SENSOR_ENDPOINT, 
                                         ZB_ZCL_CLUSTER_ID_THERMOSTAT, 
                                         ZB_ZCL_CLUSTER_SERVER_ROLE, 
                                         ZB_ZCL_ATTR_THERMOSTAT_LOCAL_TEMPERATURE_ID, 
                                         (zb_uint8_t *)&ui16local_tempvalue , 
                                         ZB_FALSE);
       if(zcl_status != ZB_ZCL_STATUS_SUCCESS)
       {
          NRF_LOG_INFO("Set local temperature value fail. zcl_status: %d", zcl_status);
       }
    }
    void CurrentSetpointChangeValue(zb_uint16_t ui16CurrentSetpoint)
    {
       zb_zcl_status_t zcl_status;
       zcl_status = zb_zcl_set_attr_val(THERMOSTAT_SENSOR_ENDPOINT,
                                        ZB_ZCL_CLUSTER_ID_THERMOSTAT,
                                        ZB_ZCL_CLUSTER_SERVER_ROLE,
                                        ZB_ZCL_ATTR_THERMOSTAT_CURRENT_SETPOINT_CHANGE_ID,
                                        (zb_uint8_t *)&ui16CurrentSetpoint,
                                        ZB_FALSE);
       
       if(zcl_status != ZB_ZCL_STATUS_SUCCESS)
       {
          NRF_LOG_INFO("Setc current set point temperature value fail. zcl_status: %d", zcl_status);
       }
    
       
       if(ui16CurrentSetpoint != 0xFFFF)
       {
          ui16CurrentTemp = ui16CurrentSetpoint;
       }
       else
       {
          ui16CurrentTemp = 0xFFFF;
       }
    
    }
    
    /**
    **function to read/write the occupied heating setpoint 
    **Any change in occupied heating value will automatically copied to set point change attribute
    **
    **/
    void OccupiedHeatingSetpoint(zb_uint16_t ui16OccupiedSetpoint)
    {
       zb_zcl_status_t zcl_status;
    
       zcl_status = zb_zcl_set_attr_val(THERMOSTAT_SENSOR_ENDPOINT,
                                        ZB_ZCL_CLUSTER_ID_THERMOSTAT,
                                        ZB_ZCL_CLUSTER_SERVER_ROLE,
                                        ZB_ZCL_ATTR_THERMOSTAT_OCCUPIED_HEATING_SETPOINT_ID,
                                        (zb_uint8_t *)&ui16OccupiedSetpoint,
                                        ZB_FALSE);
       
         
       if(ui16OccupiedSetpoint != 0xFFFF)
       {
          ui16OccupiedHeatSetpoint = ui16OccupiedSetpoint;
          ui16CurrentTemp = ui16OccupiedSetpoint;
          CurrentSetpointChangeValue(ui16CurrentTemp);
       }
       else
       {
          ui16OccupiedHeatSetpoint == 0xFFFF;
       }
       if(zcl_status != ZB_ZCL_STATUS_SUCCESS)
       {
          NRF_LOG_INFO("Set occupied heating setpoint temperature value fail. zcl_status: %d", zcl_status);
       }
    }
    
    void ReadOccupiedHeatingSetpoint(zb_uint16_t ui16ReadOccupiedSetpoint)
    {
       zb_zcl_status_t zcl_status;
    
       zcl_status = zb_zcl_set_attr_val(THERMOSTAT_SENSOR_ENDPOINT,
                                        ZB_ZCL_CLUSTER_ID_THERMOSTAT,
                                        ZB_ZCL_CLUSTER_SERVER_ROLE,
                                        ZB_ZCL_ATTR_THERMOSTAT_OCCUPIED_HEATING_SETPOINT_ID,
                                        (zb_uint8_t *)&ui16ReadOccupiedSetpoint,
                                        ZB_FALSE);
    
       if(zcl_status != ZB_ZCL_STATUS_SUCCESS)
       {
          NRF_LOG_INFO("Set occupied heating setpoint temperature value fail. zcl_status: %d", zcl_status);
       }
    }
    /**
    **function to read/write the unoccupied heating setpoint 
    **Any change in unoccupied heating value will automatically copied to set point change attribute
    **
    **/
    void UnOccupiedHeatingSetpoint(zb_uint16_t ui16UnOccupiedSetpoint)
    {
       zb_zcl_status_t zcl_status;
    
       zcl_status = zb_zcl_set_attr_val(THERMOSTAT_SENSOR_ENDPOINT,
                                        ZB_ZCL_CLUSTER_ID_THERMOSTAT,
                                        ZB_ZCL_CLUSTER_SERVER_ROLE,
                                        ZB_ZCL_ATTR_THERMOSTAT_UNOCCUPIED_HEATING_SETPOINT_ID,
                                        (zb_uint8_t *)&ui16UnOccupiedSetpoint,
                                        ZB_FALSE);
       
       if(ui16UnOccupiedSetpoint != 0xFFFF)
       {
         ui16UnOccupiedHeatSetpoint = ui16UnOccupiedSetpoint;
         ui16CurrentTemp = ui16UnOccupiedSetpoint;
         CurrentSetpointChangeValue(ui16CurrentTemp);
       }
       else
       {
         ui16UnOccupiedHeatSetpoint =  0xFFFF;
       }
       if(zcl_status != ZB_ZCL_STATUS_SUCCESS)
       {
          NRF_LOG_INFO("Set unoccupied heating setpoint temperature value fail. zcl_status: %d", zcl_status);
       }
    }
    
    /**
    **function to read value of pi heating demand
    **Any change in valve position value will be copied to PI heating demand attribute which only read attribute
    **
    **/
    static void PIHeatingDemand (zb_uint8_t ui8PiHeatingDemand)
    {
       zb_zcl_status_t zcl_status;
    
       zcl_status = zb_zcl_set_attr_val(THERMOSTAT_SENSOR_ENDPOINT,
                                        ZB_ZCL_CLUSTER_ID_THERMOSTAT,
                                        ZB_ZCL_CLUSTER_SERVER_ROLE,
                                        ZB_ZCL_ATTR_THERMOSTAT_PI_HEATING_DEMAND_ID,
                                        &ui8PiHeatingDemand,
                                        ZB_FALSE);
       
    
       if(zcl_status != ZB_ZCL_STATUS_SUCCESS)
       {
          NRF_LOG_INFO("read pi heating demand value fail. zcl_status: %d", zcl_status);
       }
    }
    /**
    **function for read/write local temperature calibration
    **Any change in local temperature attribute then add this value to D11 and D12 of set temperature command
    **
    **/
    static void LocalTemperatureCalibration(zb_uint8_t ui8localTempCalibration)
    {
       zb_zcl_status_t zcl_status;
    
       zcl_status = zb_zcl_set_attr_val(THERMOSTAT_SENSOR_ENDPOINT,
                                        ZB_ZCL_CLUSTER_ID_THERMOSTAT,
                                        ZB_ZCL_CLUSTER_SERVER_ROLE,
                                        ZB_ZCL_ATTR_THERMOSTAT_LOCAL_TEMPERATURE_CALIBRATION_ID,
                                        &ui8localTempCalibration,
                                        ZB_FALSE);
       
       ui8LocalTemperatureCalibration = ui8localTempCalibration;
    
       if(zcl_status != ZB_ZCL_STATUS_SUCCESS)
       {
          NRF_LOG_INFO("local temperature calibration value fail. zcl_status: %d", zcl_status);
       }
    }
    /**
    **function to read/write the valve position
    **Any change in valve position value will be copied to PI heating demand attribute which only read attribute
    **
    **/
    void SetValvePosition(zb_uint8_t ui8ValvePosition)
    {
       zb_zcl_status_t zcl_status;
    
       zcl_status = zb_zcl_set_attr_val(THERMOSTAT_SENSOR_ENDPOINT,
                                        ZB_ZCL_CLUSTER_ID_THERMOSTAT,
                                        ZB_ZCL_CLUSTER_SERVER_ROLE,
                                        ZB_ZCL_ATTR_THERMOSTAT_SET_VALVE_POSITION_ID,
                                        &ui8ValvePosition,
                                        ZB_FALSE);
       
       PIHeatingDemand(ui8ValvePosition);
    
       if(zcl_status != ZB_ZCL_STATUS_SUCCESS)
       {
          NRF_LOG_INFO("Set valve position value fail. zcl_status: %d", zcl_status);
       }
    }
    
    void SetTRVMode (zb_uint8_t ui8TRVMode)
    {
       zb_zcl_status_t zcl_status;
    
       zcl_status = zb_zcl_set_attr_val(THERMOSTAT_SENSOR_ENDPOINT,
                                        ZB_ZCL_CLUSTER_ID_THERMOSTAT,
                                        ZB_ZCL_CLUSTER_SERVER_ROLE,
                                        ZB_ZCL_ATTR_THERMOSTAT_TRV_MODE_ID,
                                        &ui8TRVMode,
                                        ZB_FALSE);
       
       
    
       if(zcl_status != ZB_ZCL_STATUS_SUCCESS)
       {
          NRF_LOG_INFO("Set trv mode value fail. zcl_status: %d", zcl_status);
       }
    }
    /**@brief Function for remaining battery percentage 
     *
     * @param[in]   new_value local temp value
     */
    void ReadRemainigBatteryPercentage(zb_uint8_t ui8BatteryPercentage)
    {
       zb_zcl_status_t zcl_status;
    
       zcl_status = zb_zcl_set_attr_val(THERMOSTAT_SENSOR_ENDPOINT, 
                                         ZB_ZCL_CLUSTER_ID_POWER_CONFIG, 
                                         ZB_ZCL_CLUSTER_SERVER_ROLE, 
                                         ZB_ZCL_ATTR_POWER_CONFIG_BATTERY_REMAINING_ID, 
                                         &ui8BatteryPercentage , 
                                         ZB_FALSE);
       if(zcl_status != ZB_ZCL_STATUS_SUCCESS)
       {
          NRF_LOG_INFO("Set Battery percentage value fail. zcl_status: %d", zcl_status);
       }
    }
    /**
    **function to read the error status for different valve status 
    **Any change in valve status respective error state copied to Error attribute which is read only attribute
    **
    **/
    void ReadErrorStatus(zb_uint8_t ui8ErrorStatus)
    {
       zb_zcl_status_t zcl_status;
    
       zcl_status = zb_zcl_set_attr_val(THERMOSTAT_SENSOR_ENDPOINT, 
                                         ZB_ZCL_CLUSTER_ID_THERMOSTAT, 
                                         ZB_ZCL_CLUSTER_SERVER_ROLE, 
                                         ZB_ZCL_ATTR_THERMOSTAT_ERROR_ID, 
                                         &ui8ErrorStatus , 
                                         ZB_FALSE);
       if(zcl_status != ZB_ZCL_STATUS_SUCCESS)
       {
          NRF_LOG_INFO("read error status fail. zcl_status: %d", zcl_status);
       }
    }
    /**
    **function to read/write the flag status for different operation 
    **
    **
    **/
    void HostFlagStatus(zb_uint32_t ui32HostFlagsStatus)
    {
       zb_zcl_status_t zcl_status;
    
       zcl_status = zb_zcl_set_attr_val(THERMOSTAT_SENSOR_ENDPOINT, 
                                         ZB_ZCL_CLUSTER_ID_THERMOSTAT, 
                                         ZB_ZCL_CLUSTER_SERVER_ROLE, 
                                         ZB_ZCL_ATTR_THERMOSTAT_HOST_FLAG_ID, 
                                         (zb_uint8_t *)&ui32HostFlagsStatus, 
                                         ZB_FALSE);
       ui32HostflagsData = ui32HostFlagsStatus;
    
        //Rotate LCD by 180
        if((ui32HostflagsData & 0x000002)== 0x02)
        {    
          boolSetHostflags = false;
    
          boolSendDeviceConfig = true;
          if((ui8SendDeviceConfig[5] ^ DEVICE_CONFIG_BYTE_3_LCD_ROTATION) & DEVICE_CONFIG_BYTE_3_LCD_ROTATION ) 
          {
            ui8SendDeviceConfig[5] |= DEVICE_CONFIG_BYTE_3_LCD_ROTATION;        
          }
        }
        //LCD in default position
        if((ui32HostflagsData ^ 0x000002) & 0x02 )
        {
          boolSetHostflags = false;
          boolSendDeviceConfig = true;
          if(ui8SendDeviceConfig[5]  & DEVICE_CONFIG_BYTE_3_LCD_ROTATION) 
          {
            ui8SendDeviceConfig[5]  &= ui8SendDeviceConfig[5] ^ DEVICE_CONFIG_BYTE_3_LCD_ROTATION;		        
          }
        }
    
       if(zcl_status != ZB_ZCL_STATUS_SUCCESS)
       {
          NRF_LOG_INFO("Host flag status fail. zcl_status: %d", zcl_status);
       }
    }
    
    /**@brief Callback function for handling ZCL commands.
     *
     * @param[in]   param   Reference to ZigBee stack buffer used to pass received data.
     */
    static zb_void_t zcl_device_cb(zb_uint8_t param)
    {
        zb_uint16_t                cluster_id;
        zb_uint16_t                attr_id;
        zb_buf_t                       * p_buffer = ZB_BUF_FROM_REF(param);
        zb_zcl_device_callback_param_t * p_device_cb_param =
                         ZB_GET_BUF_PARAM(p_buffer, zb_zcl_device_callback_param_t);
    
        NRF_LOG_INFO("zcl_device_cb id %hd", p_device_cb_param->device_cb_id);
    
        /* Set default response value. */
        p_device_cb_param->status = RET_OK;
    
        switch (p_device_cb_param->device_cb_id)
        {
            case ZB_ZCL_SET_ATTR_VALUE_CB_ID:
                   cluster_id = p_device_cb_param->cb_param.set_attr_value_param.cluster_id;
                   attr_id = p_device_cb_param->cb_param.set_attr_value_param.attr_id;
    
                 if (cluster_id == ZB_ZCL_CLUSTER_ID_THERMOSTAT)
                 {
                      if (attr_id == ZB_ZCL_ATTR_THERMOSTAT_OCCUPIED_HEATING_SETPOINT_ID)
                      {
                          zb_int16_t value = p_device_cb_param->cb_param.set_attr_value_param.values.data16;
                          OccupiedHeatingSetpoint(value);
                           boolSetTemperature = true;
                           boolReady = true;
                           boolMCUInterrupt = false; 
                          
                      }
                      else if (attr_id == ZB_ZCL_ATTR_THERMOSTAT_UNOCCUPIED_HEATING_SETPOINT_ID)
                      {
                          zb_int16_t value = p_device_cb_param->cb_param.set_attr_value_param.values.data16;
                          UnOccupiedHeatingSetpoint(value);
                           boolSetTemperature = true;
                           boolReady = true;
                           boolMCUInterrupt = false; 
                         
                      }
                      else if (attr_id ==ZB_ZCL_ATTR_THERMOSTAT_CURRENT_SETPOINT_CHANGE_ID)
                      {
                          zb_int16_t value = p_device_cb_param->cb_param.set_attr_value_param.values.data16;
                          CurrentSetpointChangeValue(value);
                           boolSetTemperature = true;
                           boolReady = true;
                           boolMCUInterrupt = false; 
                           
                      }
                      else if(attr_id ==ZB_ZCL_ATTR_THERMOSTAT_LOCAL_TEMPERATURE_CALIBRATION_ID)
                      {
                          zb_uint8_t value = p_device_cb_param->cb_param.set_attr_value_param.values.data8;
                          LocalTemperatureCalibration(value);
                      }
                      else if (attr_id ==ZB_ZCL_ATTR_THERMOSTAT_SET_VALVE_POSITION_ID)
                      {
                          zb_uint8_t value = p_device_cb_param->cb_param.set_attr_value_param.values.data8;
                          SetValvePosition(value);
                      }
                      else if(attr_id == ZB_ZCL_ATTR_THERMOSTAT_HOST_FLAG_ID)
                      {
                         zb_uint32_t value = p_device_cb_param->cb_param.set_attr_value_param.values.data32;
                         HostFlagStatus(value);
                         boolSetHostflags  = true; 
                         boolReady = true;
                         boolMCUInterrupt = false; 
                      }
                      else if(attr_id == ZB_ZCL_ATTR_THERMOSTAT_TRV_MODE_ID)
                      {
                         zb_uint8_t value = p_device_cb_param->cb_param.set_attr_value_param.values.data8;
                         SetTRVMode(value);
                      }
                 }
                  
              break;
    
    
            default:
                p_device_cb_param->status = RET_ERROR;
                break;
        }
    
        NRF_LOG_INFO("zcl_device_cb status: %hd", p_device_cb_param->status);
    }
    
    /**@brief ZigBee stack event handler.
     *
     * @param[in]   param   Reference to ZigBee stack buffer used to pass arguments (signal).
     */
    void zboss_signal_handler(zb_uint8_t param)
    {
        zb_zdo_app_signal_hdr_t  * p_sg_p = NULL;
        zb_zdo_app_signal_type_t   sig    = zb_get_app_signal(param, &p_sg_p);
        zb_ret_t                   status = ZB_GET_APP_SIGNAL_STATUS(param);
        zb_bool_t                  comm_status;
    
        switch (sig)
        {
            case ZB_BDB_SIGNAL_DEVICE_FIRST_START:
            case ZB_BDB_SIGNAL_DEVICE_REBOOT:
                if (status == RET_OK)
                {
                    NRF_LOG_INFO("Joined network successfully");
                    bsp_board_led_on(ZIGBEE_NETWORK_STATE_LED);                
                    boolSetCommand  = true; 
                    boolReady = true;
                    boolGetStatus = true;
    //                zb_zdo_pim_set_long_poll_interval(ZB_PIM_DEFAULT_LONG_POLL_INTERVAL);
                }
                else
                {
                    NRF_LOG_ERROR("Failed to join network. Status: %d", status);
                    bsp_board_led_off(ZIGBEE_NETWORK_STATE_LED);
                    comm_status = bdb_start_top_level_commissioning(ZB_BDB_NETWORK_STEERING);
                    ZB_COMM_STATUS_CHECK(comm_status);
                }
                break;
    
            case ZB_ZDO_SIGNAL_PRODUCTION_CONFIG_READY:
                if (status != RET_OK)
                {
                    NRF_LOG_WARNING("Production config is not present or invalid");
                }
                break;
    
            case ZB_COMMON_SIGNAL_CAN_SLEEP:
                {
                    zb_sleep_now(); //when receiving the signal ZB_COMMON_SIGNAL_CAN_SLEEP call sleep_now()
                }
                break;
    
            case ZB_ZDO_SIGNAL_LEAVE:
                if (status == RET_OK)
                {
                    bsp_board_led_off(ZIGBEE_NETWORK_STATE_LED);
    
                    zb_zdo_signal_leave_params_t * p_leave_params = ZB_ZDO_SIGNAL_GET_PARAMS(p_sg_p, zb_zdo_signal_leave_params_t);
                    NRF_LOG_INFO("Network left. Leave type: %d", p_leave_params->leave_type);
                }
                else
                {
                    NRF_LOG_ERROR("Unable to leave network. Status: %d", status);
                }
                break;
    
            default:
                /* Unhandled signal. For more information see: zb_zdo_app_signal_type_e and zb_ret_e */
                NRF_LOG_INFO("Unhandled signal %d. Status: %d", sig, status);
                break;
        }
    
        if (param)
        {
            ZB_FREE_BUF_BY_REF(param);
        }
    }
    
    
    /**@brief Function for application main entry.
     */
    void main(void)
    {
        zb_ret_t       zb_err_code;
        zb_ieee_addr_t ieee_addr;
    
        nrf_delay_ms(1500);
    
        /* Initialize logging system and GPIOs. */
        timer_init();
        log_init();
    
        leds_init();
    
        Uart_Init_Func();    
    
        timer_config_func();
    
        ulp_input_pin_configuration();
     
        Flashinitialization();
    
        /* Set ZigBee stack logging level and traffic dump subsystem. */
        ZB_SET_TRACE_LEVEL(ZIGBEE_TRACE_LEVEL);
        ZB_SET_TRACE_MASK(ZIGBEE_TRACE_MASK);
        ZB_SET_TRAF_DUMP_OFF();
    
        /* Initialize Zigbee stack. */
        ZB_INIT("thermostat");
    
        /* Set device address to the value read from FICR registers. */
        zb_osif_get_ieee_eui64(ieee_addr);
        zb_set_long_address(ieee_addr);
    
        /* Set static long IEEE address. */
        zb_set_network_ed_role(IEEE_CHANNEL_MASK);
        zigbee_erase_persistent_storage(ERASE_PERSISTENT_CONFIG);
    
        zb_set_ed_timeout(ED_AGING_TIMEOUT_64MIN);
        zb_set_keepalive_timeout(ZB_MILLISECONDS_TO_BEACON_INTERVAL(3000));
        zb_set_rx_on_when_idle(ZB_FALSE); // This enables sleepy behavior and makes your device act as a Sleepy End Device.
    
        NRF_POWER->RAM[3].POWERCLR = 0x3;
        NRF_POWER->RAM[4].POWERCLR = 0x3;
        NRF_POWER->RAM[5].POWERCLR = 0x3;
        NRF_POWER->RAM[6].POWERCLR = 0x3;
        NRF_POWER->RAM[7].POWERCLR = 0x3;
        NRF_POWER->RAM[8].POWERCLR = 0x3;
    
        zb_set_node_descriptor_manufacturer_code(ZB_ZCL_MANF_CODE);
    
        /* Initialize application context structure. */
        UNUSED_RETURN_VALUE(ZB_MEMSET(&m_dev_ctx, 0, sizeof(m_dev_ctx)));
    
        /* Register callback for handling ZCL commands. */
        ZB_ZCL_REGISTER_DEVICE_CB(zcl_device_cb);
    
        /* Register thermostat device context (endpoints). */
        ZB_AF_REGISTER_DEVICE_CTX(&thermostat_ctx);
    
        thermostat_clusters_attr_init();
    
        /** Start Zigbee Stack. */
        zb_err_code = zboss_start();
        ZB_ERROR_CHECK(zb_err_code);   
         
       
        CommandBootloader();  //get bootloader command 
    
        while(1)
        {
           zboss_main_loop_iteration();
           UNUSED_RETURN_VALUE(NRF_LOG_PROCESS());
    
            CommunicationStateExecution();   //MCU and NP communication state     
            DataProcessing();                //Flag bit processing
            UARTStateStateMachine();    
        }
    }
    
    
    /**
     * @}
     */
    

    Hi, 

    Just now I tried with zigbee_power_down_unused_ram() function. As suggested ported the function from SDK4.1 to SDK3.0. And as per your suggestion called the function after zb_set_rx_on_when_idle(ZB_FALSE); in main file but still current remains same 1mA. 

    Along, with multi meter we used power profile kit to measure the current. In both tool we are getting avg current = 1mA.

    Hi Marte, 

    One more update from my end. We tested our code using power profile Kit as said previously. And this is what we observed on power profile Kit. 

    Setup is same Radiator plus Nrf devkit as shown in document. 

    We see that there are spike in every 2.5sec. please find attached image of the same for reference. This might help us to narrow down the sleep issue. 

    My observation - In idle state, the power profiler show the current consumption in ampere. Average we see is around 1mA. But after every 2.5msec we see a spike of around 19msecs. This means that controller is either waking up every 2.5msec or it is not sleeping at all from start. 

    Let me know your feedback on this. 

    lasted main. c file with power down unused ram section as per SDK4.1. function. 

    /**
     * Copyright (c) 2018 - 2019, Nordic Semiconductor ASA
     *
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without modification,
     * are permitted provided that the following conditions are met:
     *
     * 1. Redistributions of source code must retain the above copyright notice, this
     *    list of conditions and the following disclaimer.
     *
     * 2. Redistributions in binary form, except as embedded into a Nordic
     *    Semiconductor ASA integrated circuit in a product or a software update for
     *    such product, must reproduce the above copyright notice, this list of
     *    conditions and the following disclaimer in the documentation and/or other
     *    materials provided with the distribution.
     *
     * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
     *    contributors may be used to endorse or promote products derived from this
     *    software without specific prior written permission.
     *
     * 4. This software, with or without modification, must only be used with a
     *    Nordic Semiconductor ASA integrated circuit.
     *
     * 5. Any software provided in binary form under this license must not be reverse
     *    engineered, decompiled, modified and/or disassembled.
     *
     * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
     * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
     * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
     * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
     * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
     * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     *
     */
    /** @file
     *
     * @defgroup zigbee_examples_light_bulb main.c
     * @{
     * @ingroup zigbee_examples
     * @brief Dimmable light sample (HA profile)
     */
    
    #include "sdk_config.h"
    #include "zboss_api.h"
    #include "zb_mem_config_med.h"
    #include "zb_error_handler.h"
    #include "zb_nrf52840_internal.h"
    #include "zigbee_helpers.h"
    
    #include "bsp.h"
    #include "boards.h"
    #include "app_timer.h"
    
    #include "nrf_log.h"
    #include "nrf_log_ctrl.h"
    #include "nrf_log_default_backends.h"
    
    #include "app_uart.h"
    #include "app_error.h"
    #include "nrf_delay.h"
    #include "nrf.h"
    #include "nrfx_power.h"
    
    /**User Include file*********/
    #include "uart_config.h"
    #include "gpio_config.h"
    #include "timer_config.h"
    #include "commands.h" 
    #include "uart_statemachine.h" 
    #include "app_flash_memory.h"
    
    #include "zb_custom1_thermostat.h"
    #include "custom_app_event.h"
    
    
                                    
    /**< Scan only one, predefined channel to find the coordinator. */
    #define IEEE_CHANNEL_MASK                (ZB_TRANSCEIVER_ALL_CHANNELS_MASK)    // (1l << ZIGBEE_CHANNEL)
    
    #define ERASE_PERSISTENT_CONFIG           ZB_FALSE                              /**< Do not erase NVRAM to save the network parameters after device reboot or power-off. */
    
    
    #define ZIGBEE_NETWORK_STATE_LED          BSP_BOARD_LED_2                       /**< LED indicating that light switch successfully joind ZigBee network. */
    
    #define RAM_START_ADDRESS           0x20000000UL                                    /**< Start address of RAM. */
    #define RAM_BANK_0_7_SECTION_SIZE   0x1000                                          /**< Size of RAM section for banks 0-7. */
    #define RAM_BANK_0_7_SECTIONS_NBR   2                                               /**< Number of sections in banks 0-7. */
    #define RAM_BANK_8_SECTION_SIZE     0x8000                                          /**< Size of RAM section for bank 8. */
    #define RAM_BANK_8_SECTIONS_NBR     6                                               /**< Number of sections in bank 8. */
    
    /* Define address of RAM region which can be used by application.
     * GCC, SES compiler and Keil compiler has memory layout
     * with stack being placed at the end of the RAM.
     * For those compilers end of RAM can be determined by top of the stack.
     * IAR has different layout and address of end of RAM
     * is determined by linker symbol.
     */
    #if defined ( __ICCARM__ )
    #define RAM_END_ADDRESS ((uint32_t)&__ICFEDIT_region_RAM_end__)
    
    extern char __ICFEDIT_region_RAM_end__;
    #else
    #define RAM_END_ADDRESS ((uint32_t)STACK_TOP)
    #endif /* defined __ICCARM__ */
    
    #if !defined ZB_ED_ROLE
    #error Define ZB_ED_ROLE to compile End Device source code.
    #endif
    
    
    
    /******************************************************************
    * GLOBAL VARIABLES
    *
    *******************************************************************/
    uint16_t ui16CurrentTemp =0, ui16OccupiedHeatSetpoint = 0, ui16UnOccupiedHeatSetpoint = 0;
    uint8_t  ui8LocalTemperatureCalibration = 0;
    uint32_t ui32HostflagsData = 0;
    
    bool boolSetTemperature = false;
    bool boolGetStatus = false;
    bool boolSetHostflags = false;
    bool boolSendDeviceConfig = false;
    /******************************************************************************************
    *EXTERNAL VARIABLES
    *
    *******************************************************************************************/
    extern bool boolReady;
    extern bool boolMCUInterrupt;
    extern bool boolSetCommand;
    extern uint8_t ui8SendDeviceConfig[BUFFER_SIZE];
    
    extern App_tsEventUart sAppUartEvent;
    extern E_StateMachineThermostat e_StateMachineThermostat;
    /******************************************************************************************
    *FUNCTIONS 
    *
    *******************************************************************************************/
    /* Declare attribute list for Basic cluster. */
    ZB_ZCL_DECLARE_BASIC_ATTRIB_LIST_EXT(basic_attr_list,
                                         &m_dev_ctx.basic_attr.zcl_version,
                                         &m_dev_ctx.basic_attr.app_version,
                                         &m_dev_ctx.basic_attr.stack_version,
                                         &m_dev_ctx.basic_attr.hw_version,
                                         m_dev_ctx.basic_attr.mf_name,
                                         m_dev_ctx.basic_attr.model_id,
                                         m_dev_ctx.basic_attr.date_code,
                                         &m_dev_ctx.basic_attr.power_source,
                                         m_dev_ctx.basic_attr.location_id,
                                         &m_dev_ctx.basic_attr.ph_env,
                                         m_dev_ctx.basic_attr.sw_ver);
    
    /* Declare attribute list for Identify cluster. */
    ZB_ZCL_DECLARE_IDENTIFY_ATTRIB_LIST(identify_attr_list,
                                        &m_dev_ctx.identify_attr.identify_time);
    
    /**power attributes**/
    ZB_ZCL_DECLARE_POWER_CONFIG_BATTERY_ATTRIB_LIST_EXT(power_config_attr_list,
                                            &m_dev_ctx.power_attr.battery_voltage,
                                            &m_dev_ctx.power_attr.battery_size,
                                            &m_dev_ctx.power_attr.battery_quantity,
                                            &m_dev_ctx.power_attr.battery_rated_voltage,
                                            &m_dev_ctx.power_attr.battery_alarm_mask,
                                            &m_dev_ctx.power_attr.battery_voltage_min_threshold,
                                            &m_dev_ctx.power_attr.battery_percentage_remaining,
                                            &m_dev_ctx.power_attr.battery_voltage_threshold1,
                                            &m_dev_ctx.power_attr.battery_voltage_threshold2,
                                            &m_dev_ctx.power_attr.battery_voltage_threshold3,
                                            &m_dev_ctx.power_attr.battery_percentage_min_threshold,
                                            &m_dev_ctx.power_attr.battery_percentage_threshold1,
                                            &m_dev_ctx.power_attr.battery_percentage_threshold2,
                                            &m_dev_ctx.power_attr.battery_percentage_threshold3,
                                            &m_dev_ctx.power_attr.battery_alarm_state);
    
    ZB_ZCL_DECLARE_TIME_ATTRIB_LIST(time_attr_list,
                                    &m_dev_ctx.time_attr.timeId,
                                    &m_dev_ctx.time_attr.time_status,
                                    &m_dev_ctx.time_attr.time_zone,
                                    &m_dev_ctx.time_attr.dst_start,
                                    &m_dev_ctx.time_attr.dst_end,
                                    &m_dev_ctx.time_attr.dst_shift,
                                    &m_dev_ctx.time_attr.standard_time,
                                    &m_dev_ctx.time_attr.local_time,
                                    &m_dev_ctx.time_attr.last_settime,
                                    &m_dev_ctx.time_attr.valid_untilTime);
    
    /* Declare extended attribute list for Thermostat cluster. */
    ZB_ZCL_DECLARE_THERMOSTAT_ATTRIB_LIST_EXT(thermostat_attr_list,
                                              &m_dev_ctx.thermostat_attr.local_temperature,
                                              &m_dev_ctx.thermostat_attr.local_temperature_calibration,
                                              &m_dev_ctx.thermostat_attr.occupied_heating_setpoint,
                                              &m_dev_ctx.thermostat_attr.unoccupied_heating_setpoint,
                                              &m_dev_ctx.thermostat_attr.pi_heating_demand,
                                              &m_dev_ctx.thermostat_attr.min_heating_setpoint_limit,
                                              &m_dev_ctx.thermostat_attr.max_heating_setpoint_limit,
                                              &m_dev_ctx.thermostat_attr.remote_sensing,
                                              &m_dev_ctx.thermostat_attr.control_seq_of_operation,
                                              &m_dev_ctx.thermostat_attr.system_mode,
                                              &m_dev_ctx.thermostat_attr.trv_mode,
                                              &m_dev_ctx.thermostat_attr.set_valve_position,
                                              &m_dev_ctx.thermostat_attr.error,
                                              &m_dev_ctx.thermostat_attr.current_setpoint,
                                              &m_dev_ctx.thermostat_attr.host_flags);
    
    /* Declare cluster list for Thermostat device (Basic, Identify, Thermostat, Fan Control, Thermostat UI). */
    ZB_DECLARE_CUSTOM_THERMOSTAT_CLUSTER_LIST(thermostat_clusters,
                                          basic_attr_list,
                                          identify_attr_list,
                                          power_config_attr_list,
                                          thermostat_attr_list,
                                          time_attr_list);
    
    
    ZB_HA_DECLARE_CUSTOM_THERMOSTAT_EP(thermostat_ep,
                                   THERMOSTAT_SENSOR_ENDPOINT,
                                   thermostat_clusters);
    
    ZB_HA_DECLARE_CUSTOM_THERMOSTAT_CTX(thermostat_ctx, thermostat_ep);
    
    /**@brief Function for initializing the application timer.
     */
    static void timer_init(void)
    {
        uint32_t error_code = app_timer_init();
        APP_ERROR_CHECK(error_code);
    }
    
    /**@brief Function for initializing the nrf log module.
     */
    static void log_init(void)
    {
        ret_code_t err_code = NRF_LOG_INIT(NULL);
        APP_ERROR_CHECK(err_code);
    
        NRF_LOG_DEFAULT_BACKENDS_INIT();
    }
    
    
    /**@brief Function for initializing LEDs.
     */
    static void leds_init(void)
    {
        bsp_board_init(BSP_INIT_LEDS);
    }
    
    /**@bried Calculate bottom addresss of RAM bank with given id.
     *
     * @param[in] bank_id  ID of RAM bank to get start address of.
     *
     * @return    Start address of RAM bank.
     */
    static inline uint32_t ram_bank_bottom_addr(uint8_t bank_id)
    {
        return RAM_START_ADDRESS + bank_id * RAM_BANK_0_7_SECTION_SIZE * RAM_BANK_0_7_SECTIONS_NBR;
    }
    
    /* Function for powering down unused RAM. */
    static void zigbee_power_down_unused_ram(void)
    {
    #if defined(NRF52811_XXAA) || defined(NRF52833_XXAA) || defined(NRF52840_XXAA)
    
        /* ID of top RAM bank */
    #if defined(NRF52811_XXAA)
        uint8_t     bank_id                 = 3;
    #elif defined(NRF52833_XXAA) || defined(NRF52840_XXAA)
        uint8_t     bank_id                 = 8;
    #endif
        uint8_t     section_id              = 5;
        uint32_t    section_size            = 0;
        /* Mask to power down whole RAM bank */
        uint32_t    ram_bank_power_off_mask = 0xFFFFFFFF;
    
        /* Power off banks with unused RAM only */
        while (RAM_END_ADDRESS <= ram_bank_bottom_addr(bank_id))
        {
            NRF_LOG_DEBUG("Powering off bank: %d.", bank_id);
    #ifdef SOFTDEVICE_PRESENT
            ret_code_t ret_val;
    
            ret_val = sd_power_ram_power_clr(bank_id, ram_bank_power_off_mask);
            APP_ERROR_CHECK(ret_val);
    #else
            nrf_power_rampower_mask_off(bank_id, ram_bank_power_off_mask);
    #endif /* defined SOFTDEVICE_PRESENT*/
            bank_id--;
        }
    
        /* Set id of top section and section size for given bank */
        section_id = (bank_id == 8) ? (RAM_BANK_8_SECTIONS_NBR - 1) : (RAM_BANK_0_7_SECTIONS_NBR - 1);
        section_size = (bank_id == 8) ? RAM_BANK_8_SECTION_SIZE : RAM_BANK_0_7_SECTION_SIZE;
    
        /* Power off remaining sections of unused RAM */
        while (RAM_END_ADDRESS <= (ram_bank_bottom_addr(bank_id) + section_id * section_size))
        {
            NRF_LOG_DEBUG("Powering off section %d of bank %d.", section_id, bank_id);
    #ifdef SOFTDEVICE_PRESENT
            ret_code_t ret_val;
    
            ret_val = sd_power_ram_power_clr(bank_id, ((NRF_POWER_RAMPOWER_S0POWER << section_id) |
                                                       (NRF_POWER_RAMPOWER_S0RETENTION << section_id)));
            APP_ERROR_CHECK(ret_val);
    #else
            nrf_power_rampower_mask_off(bank_id, ((NRF_POWER_RAMPOWER_S0POWER << section_id) |
                                                  (NRF_POWER_RAMPOWER_S0RETENTION << section_id)));
    #endif /* defined SOFTDEVICE_PRESENT*/
    
            section_id--;
        }
    
    #else
    #warning "Unsupported MCU - No RAM is powered down"
    #endif /* defined NRF52811_XXAA || defined NRF52833_XXAA || defined NRF52840_XXAA */
    }
    
    /**@brief Function for initializing all clusters attributes.
    */
    static void thermostat_clusters_attr_init(void)
    {
         /* Basic cluster attributes data */
         m_dev_ctx.basic_attr.zcl_version = ZB_ZCL_VERSION;
         m_dev_ctx.basic_attr.app_version = THERMOSTAT_INIT_BASIC_APP_VERSION;
         m_dev_ctx.basic_attr.stack_version = THERMOSTAT_INIT_BASIC_STACK_VERSION;
         m_dev_ctx.basic_attr.hw_version = THERMOSTAT_INIT_BASIC_HW_VERSION;
       
        /* Use ZB_ZCL_SET_STRING_VAL to set strings, because the first byte should
         * contain string length without trailing zero.
         *
         * For example "test" string wil be encoded as:
         *   [(0x4), 't', 'e', 's', 't']
         */
          ZB_ZCL_SET_STRING_VAL(m_dev_ctx.basic_attr.mf_name,
                              THERMOSTAT_INIT_BASIC_MANUF_NAME,
                              ZB_ZCL_STRING_CONST_SIZE(THERMOSTAT_INIT_BASIC_MANUF_NAME));
    
          ZB_ZCL_SET_STRING_VAL(m_dev_ctx.basic_attr.model_id,
                              THERMOSTAT_INIT_BASIC_MODEL_ID,
                              ZB_ZCL_STRING_CONST_SIZE(THERMOSTAT_INIT_BASIC_MODEL_ID));
    
          ZB_ZCL_SET_STRING_VAL(m_dev_ctx.basic_attr.date_code,
                              THERMOSTAT_INIT_BASIC_DATE_CODE,
                              ZB_ZCL_STRING_CONST_SIZE(THERMOSTAT_INIT_BASIC_DATE_CODE));
    
          m_dev_ctx.basic_attr.power_source = THERMOSTAT_INIT_BASIC_POWER_SOURCE;
    
          ZB_ZCL_SET_STRING_VAL(m_dev_ctx.basic_attr.location_id,
                              THERMOSTAT_INIT_BASIC_LOCATION_DESC,
                              ZB_ZCL_STRING_CONST_SIZE(THERMOSTAT_INIT_BASIC_LOCATION_DESC));
    
    
          m_dev_ctx.basic_attr.ph_env = THERMOSTAT_INIT_BASIC_PH_ENV;
          //m_dev_ctx.basic_attr.sw_ver = "00000000";
          memcpy( m_dev_ctx.basic_attr.sw_ver,"00000000", 8);
        
        /* Identify cluster attributes data */
        m_dev_ctx.identify_attr.identify_time        = ZB_ZCL_IDENTIFY_IDENTIFY_TIME_DEFAULT_VALUE;
    
    //    /**power configuration attributes data**/
        m_dev_ctx.power_attr.battery_percentage_remaining = 0x02;
        m_dev_ctx.power_attr.battery_quantity = ZB_POWER_CONFIG_BATTERY_QUANTITY;
        m_dev_ctx.power_attr.battery_size = ZB_ZCL_POWER_CONFIG_BATTERY_SIZE_AA;
    
       /* Thermostat cluster attributes data */
        m_dev_ctx.thermostat_attr.local_temperature             = 0x07D0;
        m_dev_ctx.thermostat_attr.local_temperature_calibration = 0x00;
        m_dev_ctx.thermostat_attr.pi_heating_demand             = 0xFF;
        m_dev_ctx.thermostat_attr.occupied_heating_setpoint     = 0x07D0;
        m_dev_ctx.thermostat_attr.unoccupied_heating_setpoint   = 0x07D0;
        m_dev_ctx.thermostat_attr.min_heating_setpoint_limit    = 0x01F4;
        m_dev_ctx.thermostat_attr.max_heating_setpoint_limit    = 0x0BB8;
        m_dev_ctx.thermostat_attr.control_seq_of_operation      = ZB_ZCL_THERMOSTAT_CONTROL_SEQ_OF_OPERATION_HEATING_ONLY;
        m_dev_ctx.thermostat_attr.system_mode                   = ZB_ZCL_THERMOSTAT_SYSTEM_MODE_HEAT;
        m_dev_ctx.thermostat_attr.current_setpoint             = 0x0898;
        m_dev_ctx.thermostat_attr.trv_mode                     = ZB_ZCL_THERMOSTAT_TRV_MODE_DEFAULT_VALUE;
        m_dev_ctx.thermostat_attr.set_valve_position           = 0;
        m_dev_ctx.thermostat_attr.error                        = 0;
    
             /***time cluster attributes data**/
        m_dev_ctx.time_attr.timeId = ZB_ZCL_TIME_TIME_DEFAULT_VALUE;
        m_dev_ctx.time_attr.time_status = ZB_ZCL_TIME_TIME_STATUS_DEFAULT_VALUE;
    
        /*local temperature set attribute**/
       ZB_ZCL_SET_ATTRIBUTE(THERMOSTAT_SENSOR_ENDPOINT,
                            ZB_ZCL_CLUSTER_ID_THERMOSTAT,
                            ZB_ZCL_CLUSTER_SERVER_ROLE,
                            ZB_ZCL_ATTR_THERMOSTAT_LOCAL_TEMPERATURE_ID,
                            (zb_uint8_t *)&m_dev_ctx.thermostat_attr.local_temperature,
                            ZB_FALSE);
     
        ZB_ZCL_SET_ATTRIBUTE(THERMOSTAT_SENSOR_ENDPOINT,
                            ZB_ZCL_CLUSTER_ID_THERMOSTAT,
                            ZB_ZCL_CLUSTER_SERVER_ROLE,
                            ZB_ZCL_ATTR_THERMOSTAT_OCCUPIED_HEATING_SETPOINT_ID,
                            (zb_uint8_t *)&m_dev_ctx.thermostat_attr.occupied_heating_setpoint,
                            ZB_FALSE);
    
        ZB_ZCL_SET_ATTRIBUTE(THERMOSTAT_SENSOR_ENDPOINT,
                            ZB_ZCL_CLUSTER_ID_THERMOSTAT,
                            ZB_ZCL_CLUSTER_SERVER_ROLE,
                            ZB_ZCL_ATTR_THERMOSTAT_UNOCCUPIED_HEATING_SETPOINT_ID,
                            (zb_uint8_t *)&m_dev_ctx.thermostat_attr.unoccupied_heating_setpoint,
                            ZB_FALSE);
    
        ZB_ZCL_SET_ATTRIBUTE(THERMOSTAT_SENSOR_ENDPOINT, 
                             ZB_ZCL_CLUSTER_ID_THERMOSTAT, 
                             ZB_ZCL_CLUSTER_SERVER_ROLE, 
                             ZB_ZCL_ATTR_THERMOSTAT_HOST_FLAG_ID, 
                             (zb_uint8_t *)&m_dev_ctx.thermostat_attr.host_flags, 
                             ZB_FALSE);
    
        ZB_ZCL_SET_ATTRIBUTE(THERMOSTAT_SENSOR_ENDPOINT, 
                             ZB_ZCL_CLUSTER_ID_THERMOSTAT, 
                             ZB_ZCL_CLUSTER_SERVER_ROLE, 
                             ZB_ZCL_ATTR_THERMOSTAT_TRV_MODE_ID, 
                             (zb_uint8_t *)& m_dev_ctx.thermostat_attr.trv_mode, 
                             ZB_FALSE);
    
       /**Battery percentage value**/
       ZB_ZCL_SET_ATTRIBUTE(THERMOSTAT_SENSOR_ENDPOINT,
                            ZB_ZCL_CLUSTER_ID_POWER_CONFIG,
                            ZB_ZCL_CLUSTER_SERVER_ROLE,
                            ZB_ZCL_ATTR_POWER_CONFIG_BATTERY_REMAINING_ID,
                            (zb_uint8_t *)&m_dev_ctx.power_attr.battery_percentage_remaining,
                            ZB_FALSE);  
                                      
       ZB_ZCL_SET_ATTRIBUTE(THERMOSTAT_SENSOR_ENDPOINT,
                            ZB_ZCL_CLUSTER_ID_POWER_CONFIG,
                            ZB_ZCL_CLUSTER_SERVER_ROLE,
                            ZB_ZCL_ATTR_POWER_CONFIG_BATTERY_QUANTITY_ID,
                            (zb_uint8_t *)&m_dev_ctx.power_attr.battery_quantity,
                            ZB_FALSE);
    }
    
    /**@brief Function for local temperature
     *
     * @param[in]   new_value local temp value
     */
    void localTemperatureValue(zb_uint16_t ui16local_tempvalue)
    {
       zb_zcl_status_t zcl_status;
    
       zcl_status = zb_zcl_set_attr_val(THERMOSTAT_SENSOR_ENDPOINT, 
                                         ZB_ZCL_CLUSTER_ID_THERMOSTAT, 
                                         ZB_ZCL_CLUSTER_SERVER_ROLE, 
                                         ZB_ZCL_ATTR_THERMOSTAT_LOCAL_TEMPERATURE_ID, 
                                         (zb_uint8_t *)&ui16local_tempvalue , 
                                         ZB_FALSE);
       if(zcl_status != ZB_ZCL_STATUS_SUCCESS)
       {
          NRF_LOG_INFO("Set local temperature value fail. zcl_status: %d", zcl_status);
       }
    }
    void CurrentSetpointChangeValue(zb_uint16_t ui16CurrentSetpoint)
    {
       zb_zcl_status_t zcl_status;
       zcl_status = zb_zcl_set_attr_val(THERMOSTAT_SENSOR_ENDPOINT,
                                        ZB_ZCL_CLUSTER_ID_THERMOSTAT,
                                        ZB_ZCL_CLUSTER_SERVER_ROLE,
                                        ZB_ZCL_ATTR_THERMOSTAT_CURRENT_SETPOINT_CHANGE_ID,
                                        (zb_uint8_t *)&ui16CurrentSetpoint,
                                        ZB_FALSE);
       
       if(zcl_status != ZB_ZCL_STATUS_SUCCESS)
       {
          NRF_LOG_INFO("Setc current set point temperature value fail. zcl_status: %d", zcl_status);
       }
    
       
       if(ui16CurrentSetpoint != 0xFFFF)
       {
          ui16CurrentTemp = ui16CurrentSetpoint;
       }
       else
       {
          ui16CurrentTemp = 0xFFFF;
       }
    
    }
    
    /**
    **function to read/write the occupied heating setpoint 
    **Any change in occupied heating value will automatically copied to set point change attribute
    **
    **/
    void OccupiedHeatingSetpoint(zb_uint16_t ui16OccupiedSetpoint)
    {
       zb_zcl_status_t zcl_status;
    
       zcl_status = zb_zcl_set_attr_val(THERMOSTAT_SENSOR_ENDPOINT,
                                        ZB_ZCL_CLUSTER_ID_THERMOSTAT,
                                        ZB_ZCL_CLUSTER_SERVER_ROLE,
                                        ZB_ZCL_ATTR_THERMOSTAT_OCCUPIED_HEATING_SETPOINT_ID,
                                        (zb_uint8_t *)&ui16OccupiedSetpoint,
                                        ZB_FALSE);
       
         
       if(ui16OccupiedSetpoint != 0xFFFF)
       {
          ui16OccupiedHeatSetpoint = ui16OccupiedSetpoint;
          ui16CurrentTemp = ui16OccupiedSetpoint;
          CurrentSetpointChangeValue(ui16CurrentTemp);
       }
       else
       {
          ui16OccupiedHeatSetpoint == 0xFFFF;
       }
       if(zcl_status != ZB_ZCL_STATUS_SUCCESS)
       {
          NRF_LOG_INFO("Set occupied heating setpoint temperature value fail. zcl_status: %d", zcl_status);
       }
    }
    
    void ReadOccupiedHeatingSetpoint(zb_uint16_t ui16ReadOccupiedSetpoint)
    {
       zb_zcl_status_t zcl_status;
    
       zcl_status = zb_zcl_set_attr_val(THERMOSTAT_SENSOR_ENDPOINT,
                                        ZB_ZCL_CLUSTER_ID_THERMOSTAT,
                                        ZB_ZCL_CLUSTER_SERVER_ROLE,
                                        ZB_ZCL_ATTR_THERMOSTAT_OCCUPIED_HEATING_SETPOINT_ID,
                                        (zb_uint8_t *)&ui16ReadOccupiedSetpoint,
                                        ZB_FALSE);
    
       if(zcl_status != ZB_ZCL_STATUS_SUCCESS)
       {
          NRF_LOG_INFO("Set occupied heating setpoint temperature value fail. zcl_status: %d", zcl_status);
       }
    }
    /**
    **function to read/write the unoccupied heating setpoint 
    **Any change in unoccupied heating value will automatically copied to set point change attribute
    **
    **/
    void UnOccupiedHeatingSetpoint(zb_uint16_t ui16UnOccupiedSetpoint)
    {
       zb_zcl_status_t zcl_status;
    
       zcl_status = zb_zcl_set_attr_val(THERMOSTAT_SENSOR_ENDPOINT,
                                        ZB_ZCL_CLUSTER_ID_THERMOSTAT,
                                        ZB_ZCL_CLUSTER_SERVER_ROLE,
                                        ZB_ZCL_ATTR_THERMOSTAT_UNOCCUPIED_HEATING_SETPOINT_ID,
                                        (zb_uint8_t *)&ui16UnOccupiedSetpoint,
                                        ZB_FALSE);
       
       if(ui16UnOccupiedSetpoint != 0xFFFF)
       {
         ui16UnOccupiedHeatSetpoint = ui16UnOccupiedSetpoint;
         ui16CurrentTemp = ui16UnOccupiedSetpoint;
         CurrentSetpointChangeValue(ui16CurrentTemp);
       }
       else
       {
         ui16UnOccupiedHeatSetpoint =  0xFFFF;
       }
       if(zcl_status != ZB_ZCL_STATUS_SUCCESS)
       {
          NRF_LOG_INFO("Set unoccupied heating setpoint temperature value fail. zcl_status: %d", zcl_status);
       }
    }
    
    /**
    **function to read value of pi heating demand
    **Any change in valve position value will be copied to PI heating demand attribute which only read attribute
    **
    **/
    static void PIHeatingDemand (zb_uint8_t ui8PiHeatingDemand)
    {
       zb_zcl_status_t zcl_status;
    
       zcl_status = zb_zcl_set_attr_val(THERMOSTAT_SENSOR_ENDPOINT,
                                        ZB_ZCL_CLUSTER_ID_THERMOSTAT,
                                        ZB_ZCL_CLUSTER_SERVER_ROLE,
                                        ZB_ZCL_ATTR_THERMOSTAT_PI_HEATING_DEMAND_ID,
                                        &ui8PiHeatingDemand,
                                        ZB_FALSE);
       
    
       if(zcl_status != ZB_ZCL_STATUS_SUCCESS)
       {
          NRF_LOG_INFO("read pi heating demand value fail. zcl_status: %d", zcl_status);
       }
    }
    /**
    **function for read/write local temperature calibration
    **Any change in local temperature attribute then add this value to D11 and D12 of set temperature command
    **
    **/
    static void LocalTemperatureCalibration(zb_uint8_t ui8localTempCalibration)
    {
       zb_zcl_status_t zcl_status;
    
       zcl_status = zb_zcl_set_attr_val(THERMOSTAT_SENSOR_ENDPOINT,
                                        ZB_ZCL_CLUSTER_ID_THERMOSTAT,
                                        ZB_ZCL_CLUSTER_SERVER_ROLE,
                                        ZB_ZCL_ATTR_THERMOSTAT_LOCAL_TEMPERATURE_CALIBRATION_ID,
                                        &ui8localTempCalibration,
                                        ZB_FALSE);
       
       ui8LocalTemperatureCalibration = ui8localTempCalibration;
    
       if(zcl_status != ZB_ZCL_STATUS_SUCCESS)
       {
          NRF_LOG_INFO("local temperature calibration value fail. zcl_status: %d", zcl_status);
       }
    }
    /**
    **function to read/write the valve position
    **Any change in valve position value will be copied to PI heating demand attribute which only read attribute
    **
    **/
    void SetValvePosition(zb_uint8_t ui8ValvePosition)
    {
       zb_zcl_status_t zcl_status;
    
       zcl_status = zb_zcl_set_attr_val(THERMOSTAT_SENSOR_ENDPOINT,
                                        ZB_ZCL_CLUSTER_ID_THERMOSTAT,
                                        ZB_ZCL_CLUSTER_SERVER_ROLE,
                                        ZB_ZCL_ATTR_THERMOSTAT_SET_VALVE_POSITION_ID,
                                        &ui8ValvePosition,
                                        ZB_FALSE);
       
       PIHeatingDemand(ui8ValvePosition);
    
       if(zcl_status != ZB_ZCL_STATUS_SUCCESS)
       {
          NRF_LOG_INFO("Set valve position value fail. zcl_status: %d", zcl_status);
       }
    }
    
    void SetTRVMode (zb_uint8_t ui8TRVMode)
    {
       zb_zcl_status_t zcl_status;
    
       zcl_status = zb_zcl_set_attr_val(THERMOSTAT_SENSOR_ENDPOINT,
                                        ZB_ZCL_CLUSTER_ID_THERMOSTAT,
                                        ZB_ZCL_CLUSTER_SERVER_ROLE,
                                        ZB_ZCL_ATTR_THERMOSTAT_TRV_MODE_ID,
                                        &ui8TRVMode,
                                        ZB_FALSE);
       
       
    
       if(zcl_status != ZB_ZCL_STATUS_SUCCESS)
       {
          NRF_LOG_INFO("Set trv mode value fail. zcl_status: %d", zcl_status);
       }
    }
    /**@brief Function for remaining battery percentage 
     *
     * @param[in]   new_value local temp value
     */
    void ReadRemainigBatteryPercentage(zb_uint8_t ui8BatteryPercentage)
    {
       zb_zcl_status_t zcl_status;
    
       zcl_status = zb_zcl_set_attr_val(THERMOSTAT_SENSOR_ENDPOINT, 
                                         ZB_ZCL_CLUSTER_ID_POWER_CONFIG, 
                                         ZB_ZCL_CLUSTER_SERVER_ROLE, 
                                         ZB_ZCL_ATTR_POWER_CONFIG_BATTERY_REMAINING_ID, 
                                         &ui8BatteryPercentage , 
                                         ZB_FALSE);
       if(zcl_status != ZB_ZCL_STATUS_SUCCESS)
       {
          NRF_LOG_INFO("Set Battery percentage value fail. zcl_status: %d", zcl_status);
       }
    }
    /**
    **function to read the error status for different valve status 
    **Any change in valve status respective error state copied to Error attribute which is read only attribute
    **
    **/
    void ReadErrorStatus(zb_uint8_t ui8ErrorStatus)
    {
       zb_zcl_status_t zcl_status;
    
       zcl_status = zb_zcl_set_attr_val(THERMOSTAT_SENSOR_ENDPOINT, 
                                         ZB_ZCL_CLUSTER_ID_THERMOSTAT, 
                                         ZB_ZCL_CLUSTER_SERVER_ROLE, 
                                         ZB_ZCL_ATTR_THERMOSTAT_ERROR_ID, 
                                         &ui8ErrorStatus , 
                                         ZB_FALSE);
       if(zcl_status != ZB_ZCL_STATUS_SUCCESS)
       {
          NRF_LOG_INFO("read error status fail. zcl_status: %d", zcl_status);
       }
    }
    /**
    **function to read/write the flag status for different operation 
    **
    **
    **/
    void HostFlagStatus(zb_uint32_t ui32HostFlagsStatus)
    {
       zb_zcl_status_t zcl_status;
    
       zcl_status = zb_zcl_set_attr_val(THERMOSTAT_SENSOR_ENDPOINT, 
                                         ZB_ZCL_CLUSTER_ID_THERMOSTAT, 
                                         ZB_ZCL_CLUSTER_SERVER_ROLE, 
                                         ZB_ZCL_ATTR_THERMOSTAT_HOST_FLAG_ID, 
                                         (zb_uint8_t *)&ui32HostFlagsStatus, 
                                         ZB_FALSE);
       ui32HostflagsData = ui32HostFlagsStatus;
    
        //Rotate LCD by 180
        if((ui32HostflagsData & 0x000002)== 0x02)
        {    
          boolSetHostflags = false;
    
          boolSendDeviceConfig = true;
          if((ui8SendDeviceConfig[5] ^ DEVICE_CONFIG_BYTE_3_LCD_ROTATION) & DEVICE_CONFIG_BYTE_3_LCD_ROTATION ) 
          {
            ui8SendDeviceConfig[5] |= DEVICE_CONFIG_BYTE_3_LCD_ROTATION;        
          }
        }
        //LCD in default position
        if((ui32HostflagsData ^ 0x000002) & 0x02 )
        {
          boolSetHostflags = false;
          boolSendDeviceConfig = true;
          if(ui8SendDeviceConfig[5]  & DEVICE_CONFIG_BYTE_3_LCD_ROTATION) 
          {
            ui8SendDeviceConfig[5]  &= ui8SendDeviceConfig[5] ^ DEVICE_CONFIG_BYTE_3_LCD_ROTATION;		        
          }
        }
    
       if(zcl_status != ZB_ZCL_STATUS_SUCCESS)
       {
          NRF_LOG_INFO("Host flag status fail. zcl_status: %d", zcl_status);
       }
    }
    
    /**@brief Callback function for handling ZCL commands.
     *
     * @param[in]   param   Reference to ZigBee stack buffer used to pass received data.
     */
    static zb_void_t zcl_device_cb(zb_uint8_t param)
    {
        zb_uint16_t                cluster_id;
        zb_uint16_t                attr_id;
        zb_buf_t                       * p_buffer = ZB_BUF_FROM_REF(param);
        zb_zcl_device_callback_param_t * p_device_cb_param =
                         ZB_GET_BUF_PARAM(p_buffer, zb_zcl_device_callback_param_t);
    
        NRF_LOG_INFO("zcl_device_cb id %hd", p_device_cb_param->device_cb_id);
    
        /* Set default response value. */
        p_device_cb_param->status = RET_OK;
    
        switch (p_device_cb_param->device_cb_id)
        {
            case ZB_ZCL_SET_ATTR_VALUE_CB_ID:
                   cluster_id = p_device_cb_param->cb_param.set_attr_value_param.cluster_id;
                   attr_id = p_device_cb_param->cb_param.set_attr_value_param.attr_id;
    
                 if (cluster_id == ZB_ZCL_CLUSTER_ID_THERMOSTAT)
                 {
                      if (attr_id == ZB_ZCL_ATTR_THERMOSTAT_OCCUPIED_HEATING_SETPOINT_ID)
                      {
                          zb_int16_t value = p_device_cb_param->cb_param.set_attr_value_param.values.data16;
                          OccupiedHeatingSetpoint(value);
                           boolSetTemperature = true;
                           boolReady = true;
                           boolMCUInterrupt = false; 
                          
                      }
                      else if (attr_id == ZB_ZCL_ATTR_THERMOSTAT_UNOCCUPIED_HEATING_SETPOINT_ID)
                      {
                          zb_int16_t value = p_device_cb_param->cb_param.set_attr_value_param.values.data16;
                          UnOccupiedHeatingSetpoint(value);
                           boolSetTemperature = true;
                           boolReady = true;
                           boolMCUInterrupt = false; 
                         
                      }
                      else if (attr_id ==ZB_ZCL_ATTR_THERMOSTAT_CURRENT_SETPOINT_CHANGE_ID)
                      {
                          zb_int16_t value = p_device_cb_param->cb_param.set_attr_value_param.values.data16;
                          CurrentSetpointChangeValue(value);
                           boolSetTemperature = true;
                           boolReady = true;
                           boolMCUInterrupt = false; 
                           
                      }
                      else if(attr_id ==ZB_ZCL_ATTR_THERMOSTAT_LOCAL_TEMPERATURE_CALIBRATION_ID)
                      {
                          zb_uint8_t value = p_device_cb_param->cb_param.set_attr_value_param.values.data8;
                          LocalTemperatureCalibration(value);
                      }
                      else if (attr_id ==ZB_ZCL_ATTR_THERMOSTAT_SET_VALVE_POSITION_ID)
                      {
                          zb_uint8_t value = p_device_cb_param->cb_param.set_attr_value_param.values.data8;
                          SetValvePosition(value);
                      }
                      else if(attr_id == ZB_ZCL_ATTR_THERMOSTAT_HOST_FLAG_ID)
                      {
                         zb_uint32_t value = p_device_cb_param->cb_param.set_attr_value_param.values.data32;
                         HostFlagStatus(value);
                         boolSetHostflags  = true; 
                         boolReady = true;
                         boolMCUInterrupt = false; 
                      }
                      else if(attr_id == ZB_ZCL_ATTR_THERMOSTAT_TRV_MODE_ID)
                      {
                         zb_uint8_t value = p_device_cb_param->cb_param.set_attr_value_param.values.data8;
                         SetTRVMode(value);
                      }
                 }
                  
              break;
    
    
            default:
                p_device_cb_param->status = RET_ERROR;
                break;
        }
    
        NRF_LOG_INFO("zcl_device_cb status: %hd", p_device_cb_param->status);
    }
    
    /**@brief ZigBee stack event handler.
     *
     * @param[in]   param   Reference to ZigBee stack buffer used to pass arguments (signal).
     */
    void zboss_signal_handler(zb_uint8_t param)
    {
        zb_zdo_app_signal_hdr_t  * p_sg_p = NULL;
        zb_zdo_app_signal_type_t   sig    = zb_get_app_signal(param, &p_sg_p);
        zb_ret_t                   status = ZB_GET_APP_SIGNAL_STATUS(param);
        zb_bool_t                  comm_status;
    
        switch (sig)
        {
            case ZB_BDB_SIGNAL_DEVICE_FIRST_START:
            case ZB_BDB_SIGNAL_DEVICE_REBOOT:
                if (status == RET_OK)
                {
                    NRF_LOG_INFO("Joined network successfully");
                    bsp_board_led_on(ZIGBEE_NETWORK_STATE_LED);                
                    boolSetCommand  = true; 
                    boolReady = true;
                    boolGetStatus = true;
    //                zb_zdo_pim_set_long_poll_interval(ZB_PIM_DEFAULT_LONG_POLL_INTERVAL);
                }
                else
                {
                    NRF_LOG_ERROR("Failed to join network. Status: %d", status);
                    bsp_board_led_off(ZIGBEE_NETWORK_STATE_LED);
                    comm_status = bdb_start_top_level_commissioning(ZB_BDB_NETWORK_STEERING);
                    ZB_COMM_STATUS_CHECK(comm_status);
                }
                break;
    
            case ZB_ZDO_SIGNAL_PRODUCTION_CONFIG_READY:
                if (status != RET_OK)
                {
                    NRF_LOG_WARNING("Production config is not present or invalid");
                }
                break;
    
            case ZB_COMMON_SIGNAL_CAN_SLEEP:
                {
                    zb_sleep_now(); //when receiving the signal ZB_COMMON_SIGNAL_CAN_SLEEP call sleep_now()
                }
                break;
    
            case ZB_ZDO_SIGNAL_LEAVE:
                if (status == RET_OK)
                {
                    bsp_board_led_off(ZIGBEE_NETWORK_STATE_LED);
    
                    zb_zdo_signal_leave_params_t * p_leave_params = ZB_ZDO_SIGNAL_GET_PARAMS(p_sg_p, zb_zdo_signal_leave_params_t);
                    NRF_LOG_INFO("Network left. Leave type: %d", p_leave_params->leave_type);
                }
                else
                {
                    NRF_LOG_ERROR("Unable to leave network. Status: %d", status);
                }
                break;
    
            default:
                /* Unhandled signal. For more information see: zb_zdo_app_signal_type_e and zb_ret_e */
                NRF_LOG_INFO("Unhandled signal %d. Status: %d", sig, status);
                break;
        }
    
        if (param)
        {
            ZB_FREE_BUF_BY_REF(param);
        }
    }
    
    
    /**@brief Function for application main entry.
     */
    void main(void)
    {
        zb_ret_t       zb_err_code;
        zb_ieee_addr_t ieee_addr;
    
        nrf_delay_ms(1500);
    
        /* Initialize logging system and GPIOs. */
        timer_init();
        log_init();
    
        leds_init();
    
        Uart_Init_Func();    
    
        timer_config_func();
    
        ulp_input_pin_configuration();
     
        Flashinitialization();
    
        /* Set ZigBee stack logging level and traffic dump subsystem. */
        ZB_SET_TRACE_LEVEL(ZIGBEE_TRACE_LEVEL);
        ZB_SET_TRACE_MASK(ZIGBEE_TRACE_MASK);
        ZB_SET_TRAF_DUMP_OFF();
    
        /* Initialize Zigbee stack. */
        ZB_INIT("thermostat");
    
        /* Set device address to the value read from FICR registers. */
        zb_osif_get_ieee_eui64(ieee_addr);
        zb_set_long_address(ieee_addr);
    
        /* Set static long IEEE address. */
        zb_set_network_ed_role(IEEE_CHANNEL_MASK);
        zigbee_erase_persistent_storage(ERASE_PERSISTENT_CONFIG);
    
        zb_set_ed_timeout(ED_AGING_TIMEOUT_64MIN);
        zb_set_keepalive_timeout(ZB_MILLISECONDS_TO_BEACON_INTERVAL(3000));
        zb_set_rx_on_when_idle(ZB_FALSE); // This enables sleepy behavior and makes your device act as a Sleepy End Device.
        zigbee_power_down_unused_ram();
    
        zb_set_node_descriptor_manufacturer_code(ZB_ZCL_MANF_CODE);
    
        /* Initialize application context structure. */
        UNUSED_RETURN_VALUE(ZB_MEMSET(&m_dev_ctx, 0, sizeof(m_dev_ctx)));
    
        /* Register callback for handling ZCL commands. */
        ZB_ZCL_REGISTER_DEVICE_CB(zcl_device_cb);
    
        /* Register thermostat device context (endpoints). */
        ZB_AF_REGISTER_DEVICE_CTX(&thermostat_ctx);
    
        thermostat_clusters_attr_init();
    
        /** Start Zigbee Stack. */
        zb_err_code = zboss_start();
        ZB_ERROR_CHECK(zb_err_code);   
         
       
        CommandBootloader();  //get bootloader command 
    
        while(1)
        {
           zboss_main_loop_iteration();
           UNUSED_RETURN_VALUE(NRF_LOG_PROCESS());
    
            CommunicationStateExecution();   //MCU and NP communication state     
            DataProcessing();                //Flag bit processing
            UARTStateStateMachine();    
        }
    }
    
    
    /**
     * @}
     */
    

    Thanks and Regards

    Rohit R

  • Hi Rohit,

    Thank you for providing detailed explanations of your project and set up. I have tried to look into it, but current consumption is not my field of expertise, so I have been unable to solve this so far. Most of the Zigbee team is out of office right now, so I have not been able to ask them more about expected current consumption in your scenario. I have asked some of our experts on current consumption to take a look. They have not been able to do so yet, but they will look into it next week. 

    I will be out of office the next few weeks, so someone else will take care of your case. Since this ticket has become rather long and the problem you have now is not directly related to the original topic of the ticket, can you please create a new ticket with your current problem? Please explain the problem you are having now in detail in the other ticket, and provide the information you shared in your last replies here. This will make it easier for the engineer responsible for your case to help you.

    Best regards,

    Marte

  • Hi Marte, 

    Okay, I will post in new and if you get any suggestion let me know. 

    Also, as per your suggestion we ported our functions into SDK4.1 but still we are getting same result in current 1mA avg. 

    Do not close this ticket, I need some points in new ticket as a reference. Once done I will only close.

    Thanks and Regards

    Rohit R

  • Reply Children
    No Data
    Related