YOGYUI

[PROJ] Matter 이산화탄소 농도 측정 클러스터 개발 예제 (ESP32) 본문

PROJECT

[PROJ] Matter 이산화탄소 농도 측정 클러스터 개발 예제 (ESP32)

요겨 2024. 2. 18. 13:50
반응형

Matter - Carbon Dioxide Concentration Measurement Cluster Developing Example using ESP32 SoC

지난 글에서 대기 성분 농도 측정(Concentration Measurement) 센서 관련 클러스터들의 Matter 스펙에 대해 알아봤다

Matter Specification - Concentration Measurement Clusters

 

Matter Specification - Concentration Measurement Clusters

Matter :: Concentration Measurement Clusters The server cluster provides an interface to concentration measurement functionality. This cluster SHALL to be used via an alias to a specific substance (see Cluster IDs). 일산화탄소, 이산화탄소, 이산

yogyui.tistory.com

 

측정 대상 대기 성분은 Matter 1.2 버전에서는 아래와 같이 총 10종류를 지원한다

(일산화탄소, 이산화탄소, 이산화질소, 오존, 포름알데히드, TVOC, 라돈, 미세먼지 PM1/2.5/PM10)

 

이 글에서는 이산화탄소(Carbon Dioxide) 측정 클러스터를 구현하는 예제에 대해 다뤄보도록 한다

1. Hardware

1.1. Main Processor

  • ESP32-WROOM-32E-N4

이번 글에서도 역시 EspressIf사의 ESP32 모듈을 사용

1.2. Sensor Module

창고를 뒤져보니 Sensirion사에서 만든 이산화탄소 측정 센서 IC SCD41이 있길래 사용했다 (이전에 호기심에 사서 아두이노랑 한 번 연동해본 뒤로 창고행 ㅋㅋ)

SCD4x

SCD41 데이터시트: 링크

 

I2C 통신 인터페이스를 갖추고 있어 손쉽게 MCU에 연결할 수 있으며, 이산화탄소 뿐만 아니라 온도와 습도 센서까지 내장하고 있어 단일 IC로 하나의 완전한 실내 환경 센서를 구축할 수 있다

SCD41의 경우 이산화탄소 측정 범위는 400 ~ 5000ppm

2. Software

2.1. Software Development Kit (SDK)

ESP32로 Matter 관련 개발할 때는 위 3개 SDK를 사용하면 된다 (2024년 2월 9일 기준 최신 커밋)

2.2. SDK 수정

이번 예제를 제대로 돌리기 위해서는 2024년 2월 16일 기준 esp-matter SDK 소스코드 일부를 수정해야 한다

공기질 측정 관련 클러스터는 아직 많이들 개발하지 않는지, 아직 100% 완벽하게 구현이 되어 있지 않다.. (일단 어트리뷰트 데이터 타입부터 미스매치..)

 

예제를 구동할 정도로만 최소한으로 수정해야하는 사항은 아래와 같다

2.2.1. esp-matter/components/esp_matter/esp_matter_cluster.h

namespace carbon_dioxide_concentration_measurement {
typedef struct config {
    uint16_t cluster_revision;
    config() : cluster_revision(3) {}
} config_t;

// 아래 한줄 추가
cluster_t *create(endpoint_t *endpoint, config_t *config, uint8_t flags);
} /* carbon_dioxide_concentration_measurement */

 

2.2.2. esp-matter/components/esp_matter/esp_matter_attribute_utils.cpp

static esp_err_t get_attr_val_from_data(esp_matter_attr_val_t *val, EmberAfAttributeType attribute_type,
                                        uint16_t attribute_size, uint8_t *value,
                                        const EmberAfAttributeMetadata * attribute_metadata)
{
    switch (attribute_type) {
    /*
     * 기존 코드 유지
     */
     
    // 아래 블록 추가
    case ZCL_SINGLE_ATTRIBUTE_TYPE: {
        using Traits = chip::app::NumericAttributeTraits<float>;
        Traits::StorageType attribute_value;
        memcpy((float *)&attribute_value, value, sizeof(Traits::StorageType));
        if (attribute_metadata->IsNullable()) {
            if (Traits::IsNullValue(attribute_value)) {
                *val = esp_matter_nullable_float(nullable<float>());
            } else {
                *val = esp_matter_nullable_float(attribute_value);
            }
        } else {
            *val = esp_matter_float(attribute_value);
        }
        break;
    }
    
    default:
        *val = esp_matter_invalid(NULL);
        break;
    }

    return ESP_OK;
}

 

Pull Request할까 생각했는데, 한 번 손대면 이산화탄소 측정 클러스터 말고도 손봐야될게 많아 일단 이슈로만 던져뒀다 ㅋㅋ 알아서들 고치겠지 뭐~

https://github.com/espressif/esp-matter/issues/843

 

Missing `single` data type attribute value handling. (CON-1051) · Issue #843 · espressif/esp-matter

Is your feature request related to a problem? Please describe. When updating attribute value which data type is single (single precision floating point), error occurred. Describe the solution you'd...

github.com

2.3. 소스코드 커밋

언제나처럼 소스코드는 깃허브에 커밋 완료

https://github.com/YOGYUI/matter-esp32-scd41

 

GitHub - YOGYUI/matter-esp32-scd41: Matter carbon dioxide concentration measurement sensor (ESP32 + SCD41) example

Matter carbon dioxide concentration measurement sensor (ESP32 + SCD41) example - YOGYUI/matter-esp32-scd41

github.com

2.4. I2C 통신 클래스 구현

I2C 통신 클래스는 지난번 온습도 센서 클러스터 예제 프로젝트할 때 구현해뒀던 클래스를 그대로 사용~

[PROJ] Matter 온도/상대습도 측정 클러스터 개발 예제 (ESP32)

 

[PROJ] Matter 온도/상대습도 측정 클러스터 개발 예제 (ESP32)

Matter - Temperature, Relative Humidity Measurement Cluster Developing Example using ESP32 SoC 지난번 글에서Temperature Measurement(온도 측정)와 Relative Humidity Measurement(상대 습도 측정)두 Matter Cluster에 대한 Specification을 알

yogyui.tistory.com

2.5.  CO2 센서(SCD41) 클래스 구현

SCD41 센서의 측정 시작, 측정 데이터 읽기, 데이터 준비 상태 등을 I2C 인터페이스로 통신하는 클래스 CScd41Ctrl을 다음과 같이 구현해줬다

#include "scd41.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include <inttypes.h>

#define SCD4X_I2C_ADDR                      0x62    /**< SCD4X I2C address */
#define SCD4X_START_PERIODIC_MEASURE        0x21B1  /**< start periodic measurement, signal update interval is 5 seconds. */
#define SCD4X_READ_MEASUREMENT              0xEC05  /**< read measurement */
#define SCD4X_STOP_PERIODIC_MEASURE         0x3F86  /**< stop periodic measurement command */
#define SCD4X_MEASURE_SINGLE_SHOT           0x219D   ///< measure single shot */
#define SCD4X_MEASURE_SINGLE_SHOT_RHT_ONLY  0x2196   ///< measure single shot rht only */
#define SCD4X_POWER_DOWN                    0x36E0   ///< Put the sensor from idle to sleep to reduce current consumption. */
#define SCD4X_WAKE_UP                       0x36F6   ///< Wake up the sensor from sleep mode into idle mode. */

CScd41Ctrl::CScd41Ctrl()
{
    m_i2c_master = nullptr;
}

bool CScd41Ctrl::initialize(CI2CMaster *i2c_master, bool self_test/*=false*/)
{
    m_i2c_master = i2c_master;

    wakeup_module();
    stop_periodic_measure();

    GetLogger(eLogType::Info)->Log("Initialized");
    return true;
}

bool CScd41Ctrl::wakeup_module()
{
    uint8_t data_write[2] = {
        (uint8_t)(SCD4X_WAKE_UP >> 8),
        (uint8_t)(SCD4X_WAKE_UP & 0xFF)
    };
    if (!m_i2c_master->write_bytes(SCD4X_I2C_ADDR, data_write, sizeof(data_write))) {
        return false;
    }
    vTaskDelay(20 / portTICK_PERIOD_MS);

    return true;
}

bool CScd41Ctrl::sleep_module()
{
    uint8_t data_write[2] = {
        (uint8_t)(SCD4X_POWER_DOWN >> 8),
        (uint8_t)(SCD4X_POWER_DOWN & 0xFF)
    };
    if (!m_i2c_master->write_bytes(SCD4X_I2C_ADDR, data_write, sizeof(data_write))) {
        return false;
    }

    return true;
}

bool CScd41Ctrl::start_periodic_measure()
{
    uint8_t data_write[2] = {
        (uint8_t)(SCD4X_START_PERIODIC_MEASURE >> 8),
        (uint8_t)(SCD4X_START_PERIODIC_MEASURE & 0xFF)
    };
    if (!m_i2c_master->write_bytes(SCD4X_I2C_ADDR, data_write, sizeof(data_write))) {
        return false;
    }

    return true;
}

bool CScd41Ctrl::stop_periodic_measure()
{
    uint8_t data_write[2] = {
        (uint8_t)(SCD4X_STOP_PERIODIC_MEASURE >> 8),
        (uint8_t)(SCD4X_STOP_PERIODIC_MEASURE & 0xFF)
    };
    if (!m_i2c_master->write_bytes(SCD4X_I2C_ADDR, data_write, sizeof(data_write))) {
        return false;
    }
    vTaskDelay(500 / portTICK_PERIOD_MS);

    return true;
}

bool CScd41Ctrl::measure_single_shot()
{
    uint8_t data_write[2] = {
        (uint8_t)(SCD4X_MEASURE_SINGLE_SHOT >> 8),
        (uint8_t)(SCD4X_MEASURE_SINGLE_SHOT & 0xFF)
    };
    if (!m_i2c_master->write_bytes(SCD4X_I2C_ADDR, data_write, sizeof(data_write))) {
        return false;
    }
    vTaskDelay(5000 / portTICK_PERIOD_MS);

    return true;
}

bool CScd41Ctrl::read_measurement(uint16_t *co2ppm, float *temperature, float *humidity)
{
    uint8_t data_write[2] = {
        (uint8_t)(SCD4X_READ_MEASUREMENT >> 8),
        (uint8_t)(SCD4X_READ_MEASUREMENT & 0xFF)
    };
    uint8_t data_read[9] = {0, };
    if (!m_i2c_master->write_and_read_bytes(SCD4X_I2C_ADDR, data_write, sizeof(data_write), data_read, sizeof(data_read)))
        return false;
    
    if (co2ppm) {
        *co2ppm = ((uint16_t)data_read[0] << 8) | (uint16_t)data_read[1];
    }

    if (temperature) {
        uint16_t temp1 = ((uint16_t)data_read[3] << 8) | (uint16_t)data_read[4];
        *temperature = -45.f + 175.f * (float)temp1 / (float)((uint32_t)1 << 16);
    }

    if (humidity) {
        uint16_t temp2 = ((uint16_t)data_read[6] << 8) | (uint16_t)data_read[7];
        *humidity = 100.f * (float)temp2 / (float)((uint32_t)1 << 16);
    }

    return true;
}

bool CScd41Ctrl::is_measurement_data_ready()
{
    uint8_t data_write[2] = {
        (uint8_t)(SCD4X_GET_DATA_READY_STATUS >> 8),
        (uint8_t)(SCD4X_GET_DATA_READY_STATUS & 0xFF)
    };
    uint8_t data_read[3] = {0, };
    if (!m_i2c_master->write_and_read_bytes(SCD4X_I2C_ADDR, data_write, sizeof(data_write), data_read, sizeof(data_read)))
        return false;

    uint16_t result = ((uint16_t)data_read[0] << 8) | (uint16_t)data_read[1];
    if ((result & 0x07FF) == 0x0000)
        return false;

    return true;
}

2.6. 공기질 센서 엔드포인트 생성

Matter 스펙에 따르면 농도 측정 클러스터는 Air Quality 디바이스 타입을 가진 엔드포인트에 추가해야 한다

Identity와 Air Quality 클러스터는 필수(mandatory)로 추가해야 하며, 온도/습도 측정 클러스터 및 10종의 농도 측정 클러스터는 선택적(optional)으로 추가할 수 있다

 

Air Quality 엔드포인트는 esp-matter의 API로 손쉽게 추가할 수 있다

(Air Quality 클러스터도 자동으로 추가해준다)

esp_matter::node_t *root = GetSystem()->get_root_node();
esp_matter::endpoint::air_quality_sensor::config_t config_endpoint;
uint8_t flags = esp_matter::ENDPOINT_FLAG_DESTROYABLE;
esp_matter::endpoint::air_quality_sensor::create(root, &config_endpoint, flags, nullptr);

추가된 엔드포인트에 이산화탄소 측정 클러스터를 수동으로 다음과 같이 추가해주면 된다

esp_matter::cluster_t *cluster = esp_matter::cluster::carbon_dioxide_concentration_measurement::create(m_endpoint, &cfg_cluster, esp_matter::cluster_flags::CLUSTER_FLAG_SERVER);

 

이제 추가된 엔드포인트에 필수 어트리뷰트를 추가해줘야 한다

구현하고자 하는 특성(Feature)에 따라 필수로 구현해야 하는 어트리뷰트의 종류가 달라진며, 사용할 수 있는 특성은 다음과 같다

SCD41은 이산화탄소 측정 결과를 ppm 단위의 수치 데이터로 제공하므로 사용하는 Feature는 NumericMeasurement를 활성화해 사용하기로 했으며, 따라서 필수로 추가해야 하는 어트리뷰트는 MeasuredValue, MinMeasuredValue, MaxMeasuredValue, MeasurementUnit 4개이며 다음과 같이 위에서 추가한 클러스터에 추가해주면 된다

uint32_t attribute_id;
uint8_t flags = esp_matter::attribute_flags::ATTRIBUTE_FLAG_NULLABLE;

// create <Measured Value> attribute
attribute_id = chip::app::Clusters::CarbonDioxideConcentrationMeasurement::Attributes::MeasuredValue::Id;
esp_matter::attribute::create(cluster, attribute_id, flags, esp_matter_nullable_float(nullable<float>()));

// create <Min Measured Value> attribute & set value
attribute_id = chip::app::Clusters::CarbonDioxideConcentrationMeasurement::Attributes::MinMeasuredValue::Id;
attribute = esp_matter::attribute::create(cluster, attribute_id, flags, esp_matter_nullable_float(nullable<float>()));

// create <Max Measured Value> attribute & set value
attribute_id = chip::app::Clusters::CarbonDioxideConcentrationMeasurement::Attributes::MaxMeasuredValue::Id;
attribute = esp_matter::attribute::create(cluster, attribute_id, flags, esp_matter_nullable_float(nullable<float>()));

// create <Measurement Unit> attribute & set value
attribute_id = chip::app::Clusters::CarbonDioxideConcentrationMeasurement::Attributes::MeasurementUnit::Id;
attribute = esp_matter::attribute::create(cluster, attribute_id, flags, esp_matter_enum8(0));   // PPM

 

그리고 마지막으로 FeatureMap의 Bit 0를 1로 값을 설정해준다

esp_matter_attr_val_t val;

// set feature map
attribute = esp_matter::attribute::get(cluster, chip::app::Clusters::Globals::Attributes::FeatureMap::Id);
if (attribute) {
    esp_matter::attribute::get_val(attribute, &val);
    val.val.u32 |= 0x1; // MEA, Cluster supports numeric measurement of substance
    esp_matter::attribute::set_val(attribute, &val);
}

결과적으로 구현되는 Matter 디바이스 정보는 다음과 같다 (엔드포인트 ID는 1로 추가된다)

  • Device Type ID: 0x002C
  • 구현 클러스터
    • Identify (ID: 0x0003)
    • Air Quality (ID: 0x005B)
      • Attribute - Air Quality (ID: 0x0000)
    • Carbon Dioxide Concentration Measurement (ID: 0x040D)
      • Attribute - Measured Value (ID: 0x0000)
      • Attribute - Min Measured Value (ID: 0x0001)
      • Attribute - Max Measured Value (ID: 0x0002)
      • Attribute - Measurement Unit (ID: 0x0008)

Matter 관련 CO2 센서 객체의 전체 구현 결과는 소스코드의 co2sensor.cpp에 구현해 둔 CCO2Sensor 클래스를 참고하면 된다

2.7. Measurement Task 생성

주기적으로 센서에서 값을 측정한 뒤 어트리뷰트 값 갱신을 위해 FreeRTOS 태스크(Task)를 아래와 같이 구현했다

#include "system.h"
#include "scd41.h"
#include "co2sensor.h"

#define TASK_TIMER_STACK_DEPTH  3072
#define TASK_TIMER_PRIORITY     5
#define MEASURE_PERIOD_US       10000000

CSystem::CSystem() 
{
    xTaskCreate(task_timer_function, "TASK_TIMER", TASK_TIMER_STACK_DEPTH, this, TASK_TIMER_PRIORITY, &m_task_timer_handle);
}

void CSystem::task_timer_function(void *param)
{
    CSystem *obj = static_cast<CSystem *>(param);
    int64_t current_tick_us;
    int64_t last_tick_us = 0;
    CDevice * dev;
    uint16_t co2ppm = 0;
    float temperature = 0.f;
    float humidity = 0.f;
    bool measure_shot = false;

    while (1) {
        if (!measure_shot) {
            current_tick_us = esp_timer_get_time();
            if (current_tick_us - last_tick_us >= MEASURE_PERIOD_US) {
                GetScd41Ctrl()->measure_single_shot();
                measure_shot = true;
                last_tick_us = current_tick_us;
            }
        } else {
            if (!GetScd41Ctrl()->is_measurement_data_ready()) {
                vTaskDelay(pdMS_TO_TICKS(100));
                current_tick_us = esp_timer_get_time();
                if (current_tick_us - last_tick_us >= MEASURE_PERIOD_US) {
                    measure_shot = false;
                    last_tick_us = current_tick_us;
                }
                continue;
            }

            if (GetScd41Ctrl()->read_measurement(&co2ppm, &temperature, &humidity)) {
                dev = obj->find_device_by_endpoint_id(1);
                dev->update_measured_value((float)co2ppm);
                dev = obj->find_device_by_endpoint_id(2);
                dev->update_measured_value(temperature);
                dev = obj->find_device_by_endpoint_id(3);
                dev->update_measured_value(humidity);
            }
            measure_shot = false;
        }
    }

    vTaskDelay(pdMS_TO_TICKS(50));
    }
    vTaskDelete(nullptr);
}

3. DEMO

3.1.  홈 IoT 플랫폼 액세서리 추가

안타깝게도 Air Quality 디바이스가 2024년 2월 현재 Apple Home과 Google Home 모두 액세서리가 제대로 등록되지 않는다.. (커미셔닝은 되는데 액세서리가 지원이 되지 않는다 ㅠ)

※ iOS 17.3.1 버전, Google Home 3.12.1.6 버전 기준

 

참고로 Air Quality 디바이스 타입은 지난 2023년 10월 23일 릴리즈된 Matter 1.2버전에 새로 추가되었다

https://csa-iot.org/newsroom/matter-1-2-arrives-with-nine-new-device-types-improvements-across-the-board/

 

아마 Matter 1.2에 추가된 디바이스 타입에 대해서는 아직 공식적으로 지원하지 않는 것 같다 (뇌피셜 ㅎㅎ)

 

Apple, Google 개발자 커뮤니티에 해당 문제에 대한 질문을 올렸지만 아직 대답이 없다 ㅠ

앞으로 iOS나 Google Home 버전이 업데이트될 때마다 꾸준히 모니터링해볼 예정

3.2. CHIP-TOOL로 센서 측정값 읽기

Ubuntu 22.04가 설치된 랩탑에서 connectedhomeip SDK의 매터 유틸리티 앱인 CHIP-TOOL을 사용해 디바이스를 커미셔닝하고 이산화탄소 측정 클러스터의 어트리뷰트 값을 읽어보자

 

chip-tool이 설치된 디렉터리 (connectedhomeip sdk 경로의 /out/host)를 PATH 환경변수에 추가해준다

$ export PATH="$PATH:~/tools/esp-matter/connectedhomeip/connectedhomeip/out/host"

 

chip-tool로 커미셔닝 (BLE + WiFi 2.4G)

$ chip-tool pairing ble-wifi {node_id} {wifi_ssid} {wifi_passwd} {passcode} {discriminator}
  • node_id: 16비트 정수를 헥사 형태로 아무 값이나 넣어준다 (ex: 0x7283)
  • wifi_ssid, wifi_passwd: WiFi 2.4G SSID와 비밀번호
  • passcode: 20222023
  • discriminator: 3841

chip-tool 어트리뷰트 값 읽기

% chip-tool carbondioxideconcentrationmeasurement read measured-value {node_id} {endpoint_id}
  • node_id: 페이링 시 지정한 fabric node id
  • endpoint:id: 1 

chip-tool로 co2 농도 측정 클러스터의 measured-value 어트리뷰트 값을 읽는 명령을 날린 뒤 로그를 살펴보자


chip-tool carbondioxideconcentrationmeasurement read measured-value 0x7283 1

// 디바이스 접속 관련 로그 생략

[801304:801306] CHIP:EM: Rxd Ack; Removing MessageCounter:165306232 from Retrans Table on exchange 51550i
[1708229934.367952][801304:801306] CHIP:DMG: ReportDataMessage =
[1708229934.367977][801304:801306] CHIP:DMG: {
[1708229934.367997][801304:801306] CHIP:DMG:    AttributeReportIBs =
[1708229934.368028][801304:801306] CHIP:DMG:    [
[1708229934.368049][801304:801306] CHIP:DMG:            AttributeReportIB =
[1708229934.368079][801304:801306] CHIP:DMG:            {
[1708229934.368100][801304:801306] CHIP:DMG:                    AttributeDataIB =
[1708229934.368124][801304:801306] CHIP:DMG:                    {
[1708229934.368149][801304:801306] CHIP:DMG:                            DataVersion = 0x22f2c549,
[1708229934.368172][801304:801306] CHIP:DMG:                            AttributePathIB =
[1708229934.368197][801304:801306] CHIP:DMG:                            {
[1708229934.368221][801304:801306] CHIP:DMG:                                    Endpoint = 0x1,
[1708229934.368246][801304:801306] CHIP:DMG:                                    Cluster = 0x40d,
[1708229934.368271][801304:801306] CHIP:DMG:                                    Attribute = 0x0000_0000,
[1708229934.368295][801304:801306] CHIP:DMG:                            }
[1708229934.368321][801304:801306] CHIP:DMG: 
[1708229934.368356][801304:801306] CHIP:DMG:                            Data = 727.000000, 
[1708229934.368379][801304:801306] CHIP:DMG:                    },
[1708229934.368407][801304:801306] CHIP:DMG: 
[1708229934.368429][801304:801306] CHIP:DMG:            },
[1708229934.368457][801304:801306] CHIP:DMG: 
[1708229934.368477][801304:801306] CHIP:DMG:    ],
[1708229934.368506][801304:801306] CHIP:DMG: 
[1708229934.368528][801304:801306] CHIP:DMG:    SuppressResponse = true, 
[1708229934.368550][801304:801306] CHIP:DMG:    InteractionModelRevision = 11
[1708229934.368570][801304:801306] CHIP:DMG: }
[1708229934.368762][801304:801306] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_040D Attribute 0x0000_0000 DataVersion: 586335561
[1708229934.368935][801304:801306] CHIP:TOO:   MeasuredValue: 727.000000
[1708229934.369176][801304:801306] CHIP:EM: <<< [E:51550i S:14845 M:165306233 (Ack:85969258)] (S) Msg TX to 1:0000000000007283 [C7C2] [UDP:[fe80::dabc:38ff:fe40:97b0%enx106530b918ca]:5540] --- Type 0000:10 (SecureChannel:StandaloneAck)


Endpoint 1, Cluster 0x040D의 Attribute 0x0000 의 single floating 데이터 값 727.0 ppm 을 제대로 읽는 것을 확인할 수 있다

3.3. ESP32 로그

chip-tool로만 페어링된 상태에서는 matter 관련 로그가 꽤 단촐해진다 ㅎㅎ (attribute value write 함수만 로깅)


I (779358) logger: [CSystem::task_timer_function] CO2 PPM: 748, Temperature: 20.7585, Humidity: 58.3221 [system.cpp:480]
I (789368) logger: [CCO2Sensor::update_measured_value] Update measured CO2 concentration value as 774 [co2sensor.cpp:165]
I (789368) esp_matter_attribute: ********** W : Endpoint 0x0001's Cluster 0x0000040D's Attribute 0x00000000 is 774.000000 **********
I (789378) logger: [CSystem::task_timer_function] CO2 PPM: 774, Temperature: 20.7745, Humidity: 58.3252 [system.cpp:480]
I (799388) logger: [CCO2Sensor::update_measured_value] Update measured CO2 concentration value as 748 [co2sensor.cpp:165]
I (799388) esp_matter_attribute: ********** W : Endpoint 0x0001's Cluster 0x0000040D's Attribute 0x00000000 is 748.000000 **********
I (799398) logger: [CSystem::task_timer_function] CO2 PPM: 748, Temperature: 20.7692, Humidity: 58.287 [system.cpp:480]
I (809408) logger: [CCO2Sensor::update_measured_value] Update measured CO2 concentration value as 729 [co2sensor.cpp:165]
I (809408) esp_matter_attribute: ********** W : Endpoint 0x0001's Cluster 0x0000040D's Attribute 0x00000000 is 729.000000 **********



홈 IoT 플랫폼들이 Matter 1.2의 신규 디바이스를 아직 제대로 지원하지 않아 약간 아쉬운 마무리..

이번 글의 의의는 esp-matter sdk에서 디폴트로 구현되어 있는 클러스터 외에 개발자가 임의로 클러스터를 추가하여 커스텀 엔드포인트를 만드는 방법에 대해 알아본 것이랄까? ㅎㅎ (구현되어 있는 API만 조합하면 누구나 쉽게 커스터마이즈할 수 있는 것이 Matter의 큰 장점.. 물론 IoT 플랫폼이 지원을 해야 써먹을 수 있다는 문제는 있지만~)

 

Matter 생태계가 꽤 빠른 속도로 확장하고 있기 때문에 조만간 신규 디바이스들도 지원되리라 기대하며 다른 센서 모듈을 찾으러 창고로 출발해본다 ㅋㅋ

반응형
Comments