
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에서 송수신에 대한 처리를 해 주었으므로 다른 디바이스들도 분석해서 각 장치에 대한 처리를 해 주면 될것 같다.