본문 바로가기

ESPRESSIF/ESP32-C6

[ESP32C6 xBee] Zigbee Gateway 제작 - 온도 센서 ZB End Device 붙이기

Adruino를 이용하여 입력에 해당하는 Zigbee 온도 센서 End Device를 제작 하였으니 Zigbee Gateway에 붙이는 코드도 작성해 보자

 

디바이스 바인딩은  ESP32C6 Light ZB End Device 붙이기 예제에서 처럼 simple_desc_cb 함수에 온도 센서 장치일 경우 바인딩 부분만 추가하면 쉽게 해결된다.

// Simple Descriptor 응답 처리 콜백
static void simple_desc_cb(esp_zb_zdp_status_t zdo_status,
                           esp_zb_af_simple_desc_1_1_t *simple_desc,
                           void *user_ctx)
{
    if (zdo_status != ESP_ZB_ZDP_STATUS_SUCCESS) {
        ESP_LOGW(TAG, "Simple desc request failed, status=%d", zdo_status);
        return;
    }

    esp_zb_zdo_signal_device_annce_params_t *dev = user_ctx;

    ESP_LOGI(TAG, "Simple desc: dev_short=0x%04X, dev_id=%d, ver=%d, profile=0x%X, ep=%d",
             dev->device_short_addr,
             simple_desc->app_device_id,
             simple_desc->app_device_version,
             simple_desc->app_profile_id,
             simple_desc->endpoint);

    switch (simple_desc->app_device_id) {
    case ESP_ZB_HA_ON_OFF_LIGHT_DEVICE_ID:
        ESP_LOGI(TAG, "Binding On/Off Light");
        bind_light_device(dev->device_short_addr, simple_desc->endpoint, user_ctx);
        break;

    case ESP_ZB_HA_TEMPERATURE_SENSOR_DEVICE_ID:
        ESP_LOGI(TAG, "Binding Temperature Sensor");
        bind_temperature_device(dev->device_short_addr, simple_desc->endpoint, user_ctx);
        break;

    case ESP_ZB_HA_IAS_ZONE_ID:
        ESP_LOGI(TAG, "Binding IAS Zone");
        bind_ias_device(dev->device_short_addr, simple_desc->endpoint, user_ctx);
        break;

    default:
        ESP_LOGW(TAG, "Unsupported device type: %d", simple_desc->app_device_id);
        break;
    }
}

 

 

프로그램 실행하고 End Device가 접속해오면 장치를 인식하고 온도 센서로 바인팅 하는것을 확인 할 수 있다.

 

I (1072) ESP_ZB_GATEWAY: ZDO signal: ZDO Device Update (0x30), status: ESP_OK

I (1082) ESP_ZB_GATEWAY: New device commissioned or rejoined (short: 0x8f29)

I (1102) ESP_ZB_GATEWAY: Bind temperature sensor

I (1112) ESP_ZB_GATEWAY: Successfully bind the temperature sensor from address(0x8f29) on endpoint(10)

I (1122) ESP_ZB_GATEWAY: The temperature sensor from address(0x8f29) on endpoint(10) successfully binds us


온도센서 End Device에서 보내는 데이터를 처리 하려면 esp_zb_task() 함수에 zb_action_handler 콜백 함수를 등록 해 주어야 한다.

    esp_zb_core_action_handler_register(zb_action_handler);


zb_action_handler()에서 각 디바이스 요청하는 리포트 메시지에 대한 처리를 해 주어야 한다.

/**
 * @brief Zigbee Core Action Callback 핸들러
 * 
 * Zigbee 스택에서 발생하는 ZCL(Attribute Report, Read Attribute Response, 
 * Configure Reporting Response 등) 액션 콜백을 처리하는 함수.
 */
static esp_err_t zb_action_handler(esp_zb_core_action_callback_id_t callback_id, const void *message)
{
    esp_err_t ret = ESP_OK;
    switch (callback_id) {
    case ESP_ZB_CORE_REPORT_ATTR_CB_ID:
        // ZCL Attribute Report(리포트 메시지) 수신 시 처리
        ret = zb_attribute_reporting_handler((esp_zb_zcl_report_attr_message_t *)message);
        break;
    case ESP_ZB_CORE_CMD_READ_ATTR_RESP_CB_ID:
        // Read Attribute Response 수신 시 처리
        ret = zb_read_attr_resp_handler((esp_zb_zcl_cmd_read_attr_resp_message_t *)message);
        break;
    case ESP_ZB_CORE_CMD_REPORT_CONFIG_RESP_CB_ID:
        // Configure Reporting Response 수신 시 처리
        ret = zb_configure_report_resp_handler((esp_zb_zcl_cmd_config_report_resp_message_t *)message);
        break;
    default:
        // 그 외 정의되지 않은 Callback ID 수신 시 경고 로그 출력
        ESP_LOGW(TAG, "Receive Zigbee action(0x%x) callback", callback_id);
        break;
    }
    return ret;
}

 

 

Zigbee End Device가 보내는 온도 데이터를 처리 하는 함수


/**
 * @brief Attribute Reporting 메시지 핸들러
 *
 * Zigbee 장치가 주기적으로 보내는 Attribute Report를 처리하는 함수
 *
 * @param message Attribute Report 메시지 포인터
 * @return esp_err_t 처리 결과
 */
static esp_err_t zb_attribute_reporting_handler(const esp_zb_zcl_report_attr_message_t *message)
{
    // 메시지 유효성 확인
    ESP_RETURN_ON_FALSE(message, ESP_FAIL, TAG, "Empty message");

    // 수신 상태가 정상인지 확인
    ESP_RETURN_ON_FALSE(message->status == ESP_ZB_ZCL_STATUS_SUCCESS,
                        ESP_ERR_INVALID_ARG, TAG,
                        "Received message: error status(%d)", message->status);

    // 수신한 리포트 정보 로그 출력
    ESP_LOGI(TAG, "Received report from address(0x%x) src endpoint(%d) to dst endpoint(%d) cluster(0x%x)",
             message->src_address.u.short_addr,  // 송신 장치의 네트워크 주소
             message->src_endpoint,              // 송신 엔드포인트
             message->dst_endpoint,              // 수신 엔드포인트
             message->cluster);                  // 속한 클러스터 ID

    // 클러스터와 Attribute 데이터를 애플리케이션 핸들러로 전달
    esp_app_zb_attribute_handler(message->cluster, &message->attribute);

    return ESP_OK;
}

 

 

이렇게  Attribute Report를 처리하는 함수를 추가 하게 되면 온도 Gateway에서 온도 값을 확인 할 수 있다.

 

I (27212) ESP_ZB_GATEWAY: Measured Value is 27.59 degrees Celsius

I (30212) ESP_ZB_GATEWAY: Received report from address(0x8f29) src endpoint(10) to dst endpoint(1) cluster(0x402)

I (30212) ESP_ZB_GATEWAY: Measured Value is 27.48 degrees Celsius

I (32212) ESP_ZB_GATEWAY: Received report from address(0x8f29) src endpoint(10) to dst endpoint(1) cluster(0x402)

I (32212) ESP_ZB_GATEWAY: Measured Value is 27.58 degrees Celsius

 

이제 Zigbee Gateway에서 송수신에 대한 처리를 해 주었으므로 다른 디바이스들도 분석해서 각 장치에 대한 처리를 해 주면 될것 같다.

반응형