diff --git a/examples/all-devices-app/all-devices-common/device-factory/DeviceFactory.h b/examples/all-devices-app/all-devices-common/device-factory/DeviceFactory.h index dd22486d8b02..0d37529b8b15 100644 --- a/examples/all-devices-app/all-devices-common/device-factory/DeviceFactory.h +++ b/examples/all-devices-app/all-devices-common/device-factory/DeviceFactory.h @@ -242,7 +242,7 @@ class DeviceFactory void RegisterCreator(const std::string & deviceTypeArg, DeviceCreator && creator) { - if (mDefaultDevice.empty()) + if (mDefaultDevice.empty() && deviceTypeArg != "aggregator" && deviceTypeArg != "bridged-node") { mDefaultDevice = deviceTypeArg; } @@ -254,7 +254,24 @@ class DeviceFactory RegisterCreator(deviceTypeArg, [c = std::move(creator)](const std::string &) { return c(); }); } - const std::string & GetDefaultDevice() const { return mDefaultDevice; } + const std::string & GetDefaultDevice() const + { + static const std::string kDimmableLight = "dimmable-light"; + if (mRegistry.find(kDimmableLight) != mRegistry.end()) + { + return kDimmableLight; + } + if (!mDefaultDevice.empty()) + { + return mDefaultDevice; + } + if (!mRegistry.empty()) + { + return mRegistry.begin()->first; + } + static const std::string kEmptyString; + return kEmptyString; + } bool IsValidDevice(const std::string & deviceTypeArg) const { return mRegistry.find(deviceTypeArg) != mRegistry.end(); } diff --git a/examples/all-devices-app/esp32/CMakeLists.txt b/examples/all-devices-app/esp32/CMakeLists.txt index 69cf800b4423..89cac814ea75 100644 --- a/examples/all-devices-app/esp32/CMakeLists.txt +++ b/examples/all-devices-app/esp32/CMakeLists.txt @@ -31,9 +31,14 @@ include(${CMAKE_CURRENT_LIST_DIR}/third_party/connectedhomeip/examples/common/cm # - config/esp32/components: Provides the 'chip' component (GN build wrapper) set(EXTRA_COMPONENT_DIRS "${CMAKE_CURRENT_LIST_DIR}/third_party/connectedhomeip/config/esp32/components" + "${CMAKE_CURRENT_LIST_DIR}/third_party/connectedhomeip/examples/common" "${CMAKE_CURRENT_LIST_DIR}/third_party/connectedhomeip/examples/platform/esp32/led_widget" ) +if(${IDF_TARGET} STREQUAL "esp32") + list(APPEND EXTRA_COMPONENT_DIRS "${CMAKE_CURRENT_LIST_DIR}/third_party/connectedhomeip/examples/common/m5stack-tft/repo/components") +endif() + # Compute project (output binary) name from the device selection. # ALL_DEVICES_ENABLED_DEVICES and ALL_DEVICES_APP_NAME may be passed as -D flags; # this mirrors the three-way logic in enabled_devices.cmake / enabled_devices.gni. diff --git a/examples/all-devices-app/esp32/main/CMakeLists.txt b/examples/all-devices-app/esp32/main/CMakeLists.txt index 1e801fe417df..bcab1ec4e3b7 100644 --- a/examples/all-devices-app/esp32/main/CMakeLists.txt +++ b/examples/all-devices-app/esp32/main/CMakeLists.txt @@ -34,6 +34,14 @@ set(PRIV_INCLUDE_DIRS_LIST ${ALL_DEVICES_EXTRA_INCLUDE_DIRS} ) +if (CONFIG_HAVE_DISPLAY) + list(APPEND PRIV_INCLUDE_DIRS_LIST + "${CMAKE_CURRENT_LIST_DIR}/display" + "${CHIP_ROOT}/examples/common/screen-framework/include" + "${CHIP_ROOT}/examples/common/QRCode/repo/c" + ) +endif() + # Keep top-level src/app files explicit to avoid pulling unrelated src/app/*.cpp. set(APP_TOPLEVEL_EXTRA_SRCS "${CHIP_ROOT}/src/app/SafeAttributePersistenceProvider.cpp" @@ -57,6 +65,12 @@ set(SRC_DIRS_LIST "${CHIP_ROOT}/src/app/server-cluster" ) +if (CONFIG_HAVE_DISPLAY) + list(APPEND SRC_DIRS_LIST + "${CMAKE_CURRENT_LIST_DIR}/display" + ) +endif() + idf_component_register(PRIV_INCLUDE_DIRS ${PRIV_INCLUDE_DIRS_LIST} SRC_DIRS ${SRC_DIRS_LIST}) diff --git a/examples/all-devices-app/esp32/main/DeviceShellCommands.cpp b/examples/all-devices-app/esp32/main/DeviceShellCommands.cpp index 209c28367a1d..9898c66453ef 100644 --- a/examples/all-devices-app/esp32/main/DeviceShellCommands.cpp +++ b/examples/all-devices-app/esp32/main/DeviceShellCommands.cpp @@ -1,6 +1,6 @@ /* * - * Copyright (c) 2025 Project CHIP Authors + * Copyright (c) 2025-2026 Project CHIP Authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,11 +16,12 @@ */ #include +#include #include #include // Forward declaration of the function defined in main.cpp -void InitServerWithDeviceType(std::string deviceType); +void SetDeviceTypeAndRestart(const std::string & deviceType); namespace chip { namespace Shell { @@ -47,7 +48,9 @@ CHIP_ERROR DeviceCommands::SetDeviceTypeHandler(int argc, char ** argv) const auto supportedDeviceTypes = chip::app::NoHooksDeviceFactory::GetInstance().SupportedDeviceTypes(); streamer_printf(streamer_get(), "Usage: devtype set \r\n"); streamer_printf(streamer_get(), "Example: devtype set contact-sensor\r\n"); + streamer_printf(streamer_get(), "Example: devtype set * (all bridged devices)\r\n"); streamer_printf(streamer_get(), "Supported device types:\r\n"); + streamer_printf(streamer_get(), " - *\r\n"); for (const auto & deviceType : supportedDeviceTypes) { streamer_printf(streamer_get(), " - %s\r\n", deviceType.c_str()); @@ -57,9 +60,15 @@ CHIP_ERROR DeviceCommands::SetDeviceTypeHandler(int argc, char ** argv) const char * deviceType = argv[0]; - streamer_printf(streamer_get(), "Device type set to: %s\r\n", deviceType); + if (strcmp(deviceType, "*") != 0 && !chip::app::NoHooksDeviceFactory::GetInstance().IsValidDevice(deviceType)) + { + streamer_printf(streamer_get(), "Unknown device type: %s\r\n", deviceType); + return CHIP_ERROR_INVALID_ARGUMENT; + } + + streamer_printf(streamer_get(), "Device type set to: %s. Restarting...\r\n", deviceType); - InitServerWithDeviceType(std::string(deviceType)); + SetDeviceTypeAndRestart(std::string(deviceType)); return CHIP_NO_ERROR; } diff --git a/examples/all-devices-app/esp32/main/Kconfig.projbuild b/examples/all-devices-app/esp32/main/Kconfig.projbuild index fcb15edd5cf0..8916ace437d6 100644 --- a/examples/all-devices-app/esp32/main/Kconfig.projbuild +++ b/examples/all-devices-app/esp32/main/Kconfig.projbuild @@ -1,5 +1,5 @@ # -# Copyright (c) 2025 Project CHIP Authors +# Copyright (c) 2025-2026 Project CHIP Authors # All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -20,11 +20,128 @@ menu "Demo" + choice + prompt "Device Type" + default DEVICE_TYPE_ESP32_DEVKITC if IDF_TARGET_ESP32 + default DEVICE_TYPE_ESP32_C3_DEVKITM if IDF_TARGET_ESP32C3 + default DEVICE_TYPE_ESP32_C2_DEVKITM if IDF_TARGET_ESP32C2 + default DEVICE_TYPE_ESP32_C6_DEVKITC if IDF_TARGET_ESP32C6 + default DEVICE_TYPE_ESP32_S31_DEVKITC if IDF_TARGET_ESP32S31 + default DEVICE_TYPE_ESP32_H2_DEVKITM if IDF_TARGET_ESP32H2 + default DEVICE_TYPE_ESP32_H21_DEVKITM if IDF_TARGET_ESP32H21 + default DEVICE_TYPE_ESP32_H4_DEVKITM if IDF_TARGET_ESP32H4 + default DEVICE_TYPE_ESP32_P4_FUNCTION_EV_BOARD if IDF_TARGET_ESP32P4 + help + Specifies the type of ESP32 device. + + Note that the "ESP32-DevKitC" choice is compatible with a number of clone devices + available from third-party manufacturers. + + config DEVICE_TYPE_ESP32_DEVKITC + bool "ESP32-DevKitC" + depends on IDF_TARGET_ESP32 + config DEVICE_TYPE_ESP32_WROVER_KIT + bool "ESP32-WROVER-KIT_V4.1" + depends on IDF_TARGET_ESP32 + config DEVICE_TYPE_M5STACK + bool "M5Stack" + depends on IDF_TARGET_ESP32 + config DEVICE_TYPE_ESP32_C3_DEVKITM + bool "ESP32C3-DevKitM" + depends on IDF_TARGET_ESP32C3 + config DEVICE_TYPE_ESP32_C2_DEVKITM + bool "ESP32C2-DevKitM" + depends on IDF_TARGET_ESP32C2 + config DEVICE_TYPE_ESP32_C6_DEVKITC + bool "ESP32C6-DevKitC" + depends on IDF_TARGET_ESP32C6 + config DEVICE_TYPE_ESP32_S31_DEVKITC + bool "ESP32S31-DevKitC" + depends on IDF_TARGET_ESP32S31 + config DEVICE_TYPE_ESP32_H2_DEVKITM + bool "ESP32H2-DevKitM" + depends on IDF_TARGET_ESP32H2 + config DEVICE_TYPE_ESP32_H21_DEVKITM + bool "ESP32H21-DevKitM" + depends on IDF_TARGET_ESP32H21 + config DEVICE_TYPE_ESP32_H4_DEVKITM + bool "ESP32H4-DevKitM" + depends on IDF_TARGET_ESP32H4 + config DEVICE_TYPE_ESP32_P4_FUNCTION_EV_BOARD + bool "ESP32P4 Function EV Board" + depends on IDF_TARGET_ESP32P4 + endchoice + + choice + prompt "Rendezvous Mode" + default RENDEZVOUS_MODE_BLE if BT_ENABLED + default RENDEZVOUS_MODE_SOFTAP + help + Specifies the Rendezvous mode of the peripheral. + + config RENDEZVOUS_MODE_SOFTAP + bool "Soft-AP" + select ESP_WIFI_SOFTAP_SUPPORT + config RENDEZVOUS_MODE_BLE + bool "BLE" + depends on BT_ENABLED + config RENDEZVOUS_MODE_ON_NETWORK + bool "On-Network" + config RENDEZVOUS_MODE_THREAD_MESHCOP + bool "Thread MeshCoP" + depends on CHIP_DEVICE_ENABLE_THREAD_MESHCOP + config RENDEZVOUS_MODE_SOFTAP_ON_NETWORK + bool "Soft-AP / On-Network" + select ESP_WIFI_SOFTAP_SUPPORT + config RENDEZVOUS_MODE_BLE_ON_NETWORK + bool "BLE / On-Network" + endchoice + + config TFT_PREDEFINED_DISPLAY_TYPE + int + range 0 5 + default 0 if DEVICE_TYPE_ESP32_DEVKITC || DEVICE_TYPE_ESP32_H2_DEVKITM || DEVICE_TYPE_ESP32_H21_DEVKITM || DEVICE_TYPE_ESP32_H4_DEVKITM || DEVICE_TYPE_ESP32_P4_FUNCTION_EV_BOARD + default 0 if DEVICE_TYPE_ESP32_C3_DEVKITM || DEVICE_TYPE_ESP32_C2_DEVKITM || DEVICE_TYPE_ESP32_C6_DEVKITC || DEVICE_TYPE_ESP32_S31_DEVKITC + default 3 if DEVICE_TYPE_M5STACK + default 4 if DEVICE_TYPE_ESP32_WROVER_KIT + + config HAVE_DISPLAY + bool + default y if DEVICE_TYPE_M5STACK || DEVICE_TYPE_ESP32_WROVER_KIT + default n if !(DEVICE_TYPE_M5STACK || DEVICE_TYPE_ESP32_WROVER_KIT) + + config RENDEZVOUS_MODE + int + range 0 63 + default 1 if RENDEZVOUS_MODE_SOFTAP + default 2 if RENDEZVOUS_MODE_BLE + default 4 if RENDEZVOUS_MODE_ON_NETWORK + default 32 if RENDEZVOUS_MODE_THREAD_MESHCOP + default 5 if RENDEZVOUS_MODE_SOFTAP_ON_NETWORK + default 6 if RENDEZVOUS_MODE_BLE_ON_NETWORK + + config DISPLAY_AUTO_OFF + bool "Automatically turn off the M5Stack's Display after a few seconds" + default "y" + depends on DEVICE_TYPE_M5STACK + help + To reduce wear and heat the M5Stack's Display is automatically switched off after a few seconds + + config STATUS_LED_GPIO_NUM + int + range 0 40 + default 2 if DEVICE_TYPE_ESP32_DEVKITC #Use LED1 (blue LED) as status LED on DevKitC + default 8 if DEVICE_TYPE_ESP32_C3_DEVKITM || DEVICE_TYPE_ESP32_C2_DEVKITM || DEVICE_TYPE_ESP32_C6_DEVKITC || DEVICE_TYPE_ESP32_S31_DEVKITC || DEVICE_TYPE_ESP32_H2_DEVKITM || DEVICE_TYPE_ESP32_H21_DEVKITM || DEVICE_TYPE_ESP32_H4_DEVKITM || DEVICE_TYPE_ESP32_P4_FUNCTION_EV_BOARD + default 26 if DEVICE_TYPE_ESP32_WROVER_KIT + default 40 if DEVICE_TYPE_M5STACK + help + Each board has a status led, define its pin number. + config ALL_DEVICES_ENDPOINT int "Device Endpoint ID" default 1 range 1 254 help - The endpoint ID to use for the device. + The endpoint ID to use for the single device mode. endmenu diff --git a/examples/all-devices-app/esp32/main/display/Button.cpp b/examples/all-devices-app/esp32/main/display/Button.cpp new file mode 100644 index 000000000000..1b71db7b0c87 --- /dev/null +++ b/examples/all-devices-app/esp32/main/display/Button.cpp @@ -0,0 +1,99 @@ +/* + * + * Copyright (c) 2026 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Button.h" +#include "Display.h" +#include "ScreenManager.h" +#include +#include + +#define APP_BUTTON_PRESSED 0 +#define APP_BUTTON_RELEASED 1 + +static const char TAG[] = "Button"; + +void IRAM_ATTR button_isr_handler(void * arg) +{ + auto * button = static_cast