Skip to content

Instantly share code, notes, and snippets.

@mnltake
Created March 26, 2024 08:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mnltake/9f02eb1c10480bbd8753b4ed170262ed to your computer and use it in GitHub Desktop.
Save mnltake/9f02eb1c10480bbd8753b4ed170262ed to your computer and use it in GitHub Desktop.
Alexaに時刻を聞くボタン~M5Capluleで作るMatterデバイス
/*
ESP32 board version 2.0.14 (M5Stack でなく esp32 by Espressif Systems の方で)
Turn on C++17 support for Arduino. https://github.com/Yacubane/esp32-arduino-matter?tab=readme-ov-file#enabling-c17-on-arduino-ide
import library into Arduino IDE. https://github.com/Yacubane/esp32-arduino-matter/releases/download/v1.0.0-beta.7/esp32-arduino-matter.zip
ツール > ボード > esp32 > ESP32S3 Dev Module (STAMP-S3だとうまくいかない)
ツール > Erase Flash Before Sketch Upload > Enable
ツール > Partition Scheme > Minimal SPIFFS(1.9MB APP with OTA/190KB SPIFF)
起動時にシリアルモニタに出る  https://project-chip.github.io/connectedhomeip/qrcode.html?data=M・・・ 
をブラウザで開いてQRコードをAlexアプリ等でデバイス登録
*/
#include "Matter.h"
#include <app/server/OnboardingCodesUtil.h>
#include <credentials/examples/DeviceAttestationCredsExample.h>
using namespace chip;
using namespace chip::app::Clusters;
using namespace esp_matter;
using namespace esp_matter::endpoint;
#define CONTACT_SENSOR_STATE_OPEN false
#define CONTACT_SENSOR_STATE_CLOSE true
/**
* The original sample code was made by Yacubane.
* https://github.com/Yacubane/esp32-arduino-matter/tree/master
* 日本語解説 by @wanko_in_lunch
* https://qiita.com/wanko_in_lunch/items/70ec071083d3c5172880
**/
// M5 Capsul
const int TOGGLE_BUTTON_PIN = 42;
const int HOLD_PIN = 46;
// Debounce for toggle button
const int DEBOUNCE_DELAY = 500;
int last_toggle;
// 接触センサのクラスターIDと接触状態のアトリビュートID
const uint32_t CLUSTER_ID = BooleanState::Id;
const uint32_t ATTRIBUTE_ID = BooleanState::Attributes::StateValue::Id;
// Endpoint and attribute ref that will be assigned to Matter device
uint16_t contact_sensor_endpoint_id_1 = 0;
uint16_t contact_sensor_endpoint_id_2 = 0;
attribute_t *attribute_ref_1;
attribute_t *attribute_ref_2;
// There is possibility to listen for various device events, related for example
// to setup process. Leaved as empty for simplicity.
static void on_device_event(const ChipDeviceEvent *event, intptr_t arg) {}
static esp_err_t on_identification(identification::callback_type_t type,
uint16_t endpoint_id, uint8_t effect_id,
uint8_t effect_variant, void *priv_data) {
return ESP_OK;
}
// Listener on attribute update requests.
// In this example, when update is requested, path (endpoint, cluster and attribute) is checked
static esp_err_t on_attribute_update(attribute::callback_type_t type,
uint16_t endpoint_id, uint32_t cluster_id,
uint32_t attribute_id,
esp_matter_attr_val_t *val,
void *priv_data) {
if (type == attribute::PRE_UPDATE && cluster_id == CLUSTER_ID && attribute_id == ATTRIBUTE_ID) {
// センサーはデバイスから外部から操作できないので何もしない
}
return ESP_OK;
}
void setup() {
Serial.begin(115200);
pinMode(TOGGLE_BUTTON_PIN, INPUT);
pinMode(HOLD_PIN, OUTPUT);
digitalWrite(HOLD_PIN, HIGH);
// デバッグレベルの設定(ただし、プリコンパイルされてるライブラリ側で設定済みのためここで変更しても反映されない)
esp_log_level_set("*", ESP_LOG_INFO);
// Nodeをセットアップ
// node_labelを設定すると、Alexaでデバイスを登録した時に表示される。設定しない場合は「◯番目コンタクトセンサー」という名前になる
// 2バイト文字はうまくいかないみたい?
// HomeKitではHomeKit認定済みデバイス出ない場合は問答無用で「Matter Accessory」という名前で表示される
node::config_t node_config;
snprintf(node_config.root_node.basic_information.node_label, sizeof(node_config.root_node.basic_information.node_label), "M5 Capsule");
node_t *node_1 = node::create(&node_config, on_attribute_update, on_identification);
// 接触センサのendpoint / cluster / attributesをデフォルト値でセットアップ
// 接触センサのRequirement clusterはidentifyとboolean_state
contact_sensor::config_t contact_sensor_config;
contact_sensor_config.boolean_state.state_value = CONTACT_SENSOR_STATE_OPEN;
contact_sensor_config.identify.cluster_revision = 4;
contact_sensor_config.identify.identify_time = 0;
contact_sensor_config.identify.identify_type = 0;
// endpointを作成
endpoint_t *endpoint_1 = contact_sensor::create(node_1, &contact_sensor_config, ENDPOINT_FLAG_NONE, NULL);
// センサー状態のAttributeを取得
attribute_ref_1 = attribute::get(cluster::get(endpoint_1, CLUSTER_ID), ATTRIBUTE_ID);
// endpointのIDを取得
contact_sensor_endpoint_id_1 = endpoint::get_id(endpoint_1);
// Setup DAC (this is good place to also set custom commission data, passcodes etc.)
esp_matter::set_custom_dac_provider(chip::Credentials::Examples::GetExampleDACProvider());
// Start Matter device
esp_matter::start(on_device_event);
// QRコードを出力
PrintOnboardingCodes(chip::RendezvousInformationFlags(chip::RendezvousInformationFlag::kBLE));
delay(1000);
// 起動時に一度開閉
esp_matter_attr_val_t contact_value_1 = get_boolean_attribute_value(attribute_ref_1);
contact_value_1.val.b = CONTACT_SENSOR_STATE_CLOSE;
Serial.print("contact_state1 : ");
Serial.println(contact_value_1.val.b);
set_boolean_attribute_value(&contact_value_1, contact_sensor_endpoint_id_1);
delay(5000);
contact_value_1 = get_boolean_attribute_value(attribute_ref_1);
contact_value_1.val.b = CONTACT_SENSOR_STATE_OPEN;
Serial.print("contact_state1 : ");
Serial.println(contact_value_1.val.b);
set_boolean_attribute_value(&contact_value_1, contact_sensor_endpoint_id_1);
delay(2000);
//USBで給電時以外はここで電源断
digitalWrite(HOLD_PIN, LOW);
}
// 接触センサの状態を取得する関数
esp_matter_attr_val_t get_boolean_attribute_value(esp_matter::attribute_t *att_ref) {
esp_matter_attr_val_t boolean_value = esp_matter_invalid(NULL);
attribute::get_val(att_ref, &boolean_value);
return boolean_value;
}
// 接触センサの状態をセットする関数
void set_boolean_attribute_value(esp_matter_attr_val_t *boolean_value, uint16_t endpoint_id) {
attribute::update(endpoint_id, CLUSTER_ID, ATTRIBUTE_ID, boolean_value);
}
//
void loop() {
// ボタンでセンサ1をトグル
if ((millis() - last_toggle) > DEBOUNCE_DELAY) {
if (digitalRead(TOGGLE_BUTTON_PIN) == LOW) {
last_toggle = millis();
// 接触センサの状態を取得、反転してセット
esp_matter_attr_val_t contact_value_1 = get_boolean_attribute_value(attribute_ref_1);
contact_value_1.val.b = !contact_value_1.val.b;
Serial.print("contact_state1 : ");
Serial.println(contact_value_1.val.b);
set_boolean_attribute_value(&contact_value_1, contact_sensor_endpoint_id_1);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment