Created
March 26, 2024 08:50
-
-
Save mnltake/9f02eb1c10480bbd8753b4ed170262ed to your computer and use it in GitHub Desktop.
Alexaに時刻を聞くボタン~M5Capluleで作るMatterデバイス
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
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