diff --git a/examples/weather_station/CMakeLists.txt b/examples/weather_station/CMakeLists.txt index ad18bb41469aad..c785678652fdb2 100644 --- a/examples/weather_station/CMakeLists.txt +++ b/examples/weather_station/CMakeLists.txt @@ -47,6 +47,7 @@ target_include_directories(app PRIVATE target_sources(app PRIVATE src/app_task.cpp src/main.cpp + src/buzzer.cpp src/zap-generated/attribute-size.cpp src/zap-generated/IMClusterCommandHandler.cpp src/zap-generated/callback-stub.cpp diff --git a/examples/weather_station/configuration/thingy53_nrf5340_cpuapp/prj_ZDebug.conf b/examples/weather_station/configuration/thingy53_nrf5340_cpuapp/prj_ZDebug.conf index 8e4cb596c2a025..83aad25598b369 100644 --- a/examples/weather_station/configuration/thingy53_nrf5340_cpuapp/prj_ZDebug.conf +++ b/examples/weather_station/configuration/thingy53_nrf5340_cpuapp/prj_ZDebug.conf @@ -95,6 +95,7 @@ CONFIG_OBERON_MBEDTLS_AES_C=n # Add support for LEDs and buttons on Nordic development kits CONFIG_DK_LIBRARY=y CONFIG_DK_LIBRARY_INVERT_LEDS=n +CONFIG_PWM=y # Configure UART logging and shell CONFIG_LOG=y diff --git a/examples/weather_station/configuration/thingy53_nrf5340_cpuapp/prj_ZRelease.conf b/examples/weather_station/configuration/thingy53_nrf5340_cpuapp/prj_ZRelease.conf index 7ef2272bc85698..bb2c9bdabee13a 100644 --- a/examples/weather_station/configuration/thingy53_nrf5340_cpuapp/prj_ZRelease.conf +++ b/examples/weather_station/configuration/thingy53_nrf5340_cpuapp/prj_ZRelease.conf @@ -95,6 +95,7 @@ CONFIG_OBERON_MBEDTLS_AES_C=n # Add support for LEDs and buttons on Nordic development kits CONFIG_DK_LIBRARY=y CONFIG_DK_LIBRARY_INVERT_LEDS=n +CONFIG_PWM=y # Disable all debug features CONFIG_SHELL=n diff --git a/examples/weather_station/src/app_event.h b/examples/weather_station/src/app_event.h index a64cddee90d531..efd010f052d30d 100644 --- a/examples/weather_station/src/app_event.h +++ b/examples/weather_station/src/app_event.h @@ -16,9 +16,10 @@ struct AppEvent { FunctionRelease, FunctionTimer, MeasurementsTimer, + IdentifyTimer, }; - enum UpdateLedStateEventType : uint8_t { UpdateLedState = MeasurementsTimer + 1 }; + enum UpdateLedStateEventType : uint8_t { UpdateLedState = IdentifyTimer + 1 }; enum OtherEventType : uint8_t { #ifdef CONFIG_MCUMGR_SMP_BT diff --git a/examples/weather_station/src/app_task.cpp b/examples/weather_station/src/app_task.cpp index 4ccc5b9422de7d..c83bd27b910f09 100644 --- a/examples/weather_station/src/app_task.cpp +++ b/examples/weather_station/src/app_task.cpp @@ -6,6 +6,7 @@ #include "app_task.h" +#include "buzzer.h" #include "LEDWidget.h" #include @@ -18,7 +19,6 @@ #include #include - #include #include #include @@ -50,10 +50,16 @@ constexpr uint8_t kPressureMeasurementEndpointId = 3; constexpr int16_t kPressureMeasurementAttributeMaxValue = 0x7fff; constexpr int16_t kPressureMeasurementAttributeMinValue = 0x8001; constexpr int16_t kPressureMeasurementAttributeInvalidValue = 0x8000; +constexpr uint8_t kIdentifyEndpointId = 0; +/* It is recommended to toggle the signalled state with 0.5 s interval. */ +constexpr size_t kIdentifyTimerIntervalMs = 500; +/* The identify iime attribute SHALL be decremented every second. */ +constexpr size_t kIdentifyDecrementIntervalMs = 1000; K_MSGQ_DEFINE(sAppEventQueue, sizeof(AppEvent), kAppEventQueueSize, alignof(AppEvent)); k_timer sFunctionTimer; k_timer sMeasurementsTimer; +k_timer sIdentifyTimer; FunctionTimerMode sFunctionTimerMode = FunctionTimerMode::kDisabled; LEDWidget sRedLED; @@ -67,6 +73,12 @@ bool sHaveBLEConnections; LedState sLedState = LedState::kAlive; +static uint16_t sIdentifyDurationMs; +static uint16_t sIdentifyFullDurationTimeMs; +static Identify sIdentify = { + chip::EndpointId{ kIdentifyEndpointId }, AppTask::OnIdentifyStart, AppTask::OnIdentifyStop, EMBER_ZCL_IDENTIFY_IDENTIFY_TYPE_AUDIBLE_BEEP +}; + const device *kBme688SensorDev = device_get_binding(DT_LABEL(DT_INST(0, bosch_bme680))); } /* namespace */ @@ -96,6 +108,12 @@ int AppTask::Init() return -1; } + if (BuzzerInit()) + { + LOG_ERR("Buzzer init failed"); + return -1; + } + #ifdef CONFIG_MCUMGR_SMP_BT GetDFUOverSMP().Init(RequestSMPAdvertisingStart); GetDFUOverSMP().ConfirmNewImage(); @@ -109,6 +127,8 @@ int AppTask::Init() &sMeasurementsTimer, [](k_timer *) { sAppTask.PostEvent(AppEvent{ AppEvent::MeasurementsTimer }); }, nullptr); k_timer_start(&sMeasurementsTimer, K_MSEC(kMeasurementsIntervalMs), K_MSEC(kMeasurementsIntervalMs)); + k_timer_init(&sIdentifyTimer, [](k_timer *) { sAppTask.PostEvent(AppEvent{ AppEvent::IdentifyTimer }); }, + nullptr); /* Init ZCL Data Model and start server */ chip::Server::GetInstance().Init(); @@ -190,6 +210,9 @@ void AppTask::DispatchEvent(AppEvent &event) case AppEvent::MeasurementsTimer: MeasurementsTimerHandler(); break; + case AppEvent::IdentifyTimer: + IdentifyTimerHandler(); + break; case AppEvent::UpdateLedState: event.UpdateLedStateEvent.LedWidget->UpdateState(); break; @@ -254,6 +277,47 @@ void AppTask::MeasurementsTimerHandler() sAppTask.UpdateClusterState(); } +void AppTask::OnIdentifyStart(Identify *) +{ + uint16_t identifyTimeS; + EmberAfStatus status = emberAfReadAttribute(kIdentifyEndpointId, ZCL_IDENTIFY_CLUSTER_ID, ZCL_IDENTIFY_TIME_ATTRIBUTE_ID, CLUSTER_MASK_SERVER, reinterpret_cast(&identifyTimeS), sizeof(identifyTimeS), NULL); + if (status != EMBER_ZCL_STATUS_SUCCESS) { + LOG_ERR("Reading identify time failed %x", status); + return; + } + sIdentifyFullDurationTimeMs = identifyTimeS * 1000; + k_timer_start(&sIdentifyTimer, K_MSEC(kIdentifyIntervalMs), K_MSEC(kIdentifyIntervalMs)); +} + +void AppTask::OnIdentifyStop(Identify *) +{ + // empty +} + +void AppTask::IdentifyTimerHandler() +{ + sIdentifyDurationMs += kIdentifyIntervalMs; + /* Every second decrement IdentifyTime attribute value and update cluster state */ + if (sIdentifyDurationMs % kIdentifyDecrementIntervalMs == 0) { + EmberAfStatus status; + int timeLeft = sIdentifyFullDurationTimeMs - sIdentifyDurationMs; + uint16_t identifyTime = timeLeft > 0 ? timeLeft : 0; + status = emberAfWriteAttribute(kIdentifyEndpointId, ZCL_IDENTIFY_CLUSTER_ID, + ZCL_IDENTIFY_TIME_ATTRIBUTE_ID, CLUSTER_MASK_SERVER, + reinterpret_cast(&identifyTime), ZCL_INT16U_ATTRIBUTE_TYPE); + + if (status != EMBER_ZCL_STATUS_SUCCESS) { + LOG_ERR("Updating identify time failed %x", status); + } + + if (identifyTime == 0) { + k_timer_stop(&sIdentifyTimer); + } else { + BuzzerToggleState(); + } + } +} + void AppTask::UpdateClusterState() { struct sensor_value sTemperature, sPressure, sHumidity; diff --git a/examples/weather_station/src/app_task.h b/examples/weather_station/src/app_task.h index 90a26a86bccc68..e2107e3b9c30db 100644 --- a/examples/weather_station/src/app_task.h +++ b/examples/weather_station/src/app_task.h @@ -8,6 +8,7 @@ #include "app_event.h" +#include #include #ifdef CONFIG_MCUMGR_SMP_BT @@ -22,6 +23,9 @@ class AppTask { void PostEvent(const AppEvent &aEvent); void UpdateClusterState(); + // void UpdateIdentifyClusterState(uint16_t identifyTime); + static void OnIdentifyStart(Identify *); + static void OnIdentifyStop(Identify *); private: friend AppTask &GetAppTask(); @@ -38,6 +42,7 @@ class AppTask { static void ButtonReleaseHandler(); static void FunctionTimerHandler(); static void MeasurementsTimerHandler(); + static void IdentifyTimerHandler(); static void UpdateStatusLED(); static void LEDStateUpdateHandler(LEDWidget &ledWidget); static void ChipEventHandler(const chip::DeviceLayer::ChipDeviceEvent *event, intptr_t arg); diff --git a/examples/weather_station/src/buzzer.cpp b/examples/weather_station/src/buzzer.cpp new file mode 100644 index 00000000000000..1cf348779798da --- /dev/null +++ b/examples/weather_station/src/buzzer.cpp @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2021 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +#include "buzzer.h" + +#include + +#define BUZZER_PWM_NODE DT_ALIAS(buzzer_pwm) +#define BUZZER_PWM_NAME DT_LABEL(BUZZER_PWM_NODE) +#define BUZZER_PWM_PIN DT_PROP(BUZZER_PWM_NODE, ch0_pin) +#define BUZZER_PWM_FLAGS DT_PWMS_FLAGS(BUZZER_PWM_NODE) + +constexpr uint16_t kBuzzerPwmPeriodUs = 10000; +constexpr uint16_t kBuzzerPwmDutyCycleUs = 5000; + +const device *kBuzzerDevice; +static bool sBuzzerState; + +int BuzzerInit() { + kBuzzerDevice = device_get_binding(BUZZER_PWM_NAME); + if (!kBuzzerDevice) + { + return -ENODEV; + } + return 0; +} + +void BuzzerSetState(bool onOff) { + sBuzzerState = onOff; + pwm_pin_set_usec(kBuzzerDevice, BUZZER_PWM_PIN, kBuzzerPwmPeriodUs, sBuzzerState ? kBuzzerPwmDutyCycleUs : 0, + BUZZER_PWM_FLAGS); +} + +void BuzzerToggleState() { + sBuzzerState = !sBuzzerState; + pwm_pin_set_usec(kBuzzerDevice, BUZZER_PWM_PIN, kBuzzerPwmPeriodUs, sBuzzerState ? kBuzzerPwmDutyCycleUs : 0, + BUZZER_PWM_FLAGS); +} diff --git a/examples/weather_station/src/buzzer.h b/examples/weather_station/src/buzzer.h new file mode 100644 index 00000000000000..1f0fbffed56bcf --- /dev/null +++ b/examples/weather_station/src/buzzer.h @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2021 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +int BuzzerInit(); +void BuzzerSetState(bool onOff); +void BuzzerToggleState(); diff --git a/examples/weather_station/src/weather-station.zap b/examples/weather_station/src/weather-station.zap index 01652c3a097898..d92c580610088e 100644 --- a/examples/weather_station/src/weather-station.zap +++ b/examples/weather_station/src/weather-station.zap @@ -234,7 +234,7 @@ "mfgCode": null, "define": "IDENTIFY_CLUSTER", "side": "server", - "enabled": 0, + "enabled": 1, "commands": [ { "name": "IdentifyQueryResponse", @@ -255,12 +255,27 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "0x0000", + "defaultValue": "0", "reportable": 0, "minInterval": 0, "maxInterval": 65344, "reportableChange": 0 }, + { + "name": "identify type", + "code": 1, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "3", + "reportable": 0, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "ClusterRevision", "code": 65533, @@ -2629,7 +2644,7 @@ "commands": [], "attributes": [ { - "name": "measured value", + "name": "MeasuredValue", "code": 0, "mfgCode": null, "side": "server", @@ -2644,7 +2659,7 @@ "reportableChange": 0 }, { - "name": "min measured value", + "name": "MinMeasuredValue", "code": 1, "mfgCode": null, "side": "server", @@ -2659,7 +2674,7 @@ "reportableChange": 0 }, { - "name": "max measured value", + "name": "MaxMeasuredValue", "code": 2, "mfgCode": null, "side": "server", @@ -3557,7 +3572,7 @@ "commands": [], "attributes": [ { - "name": "measured value", + "name": "MeasuredValue", "code": 0, "mfgCode": null, "side": "server", @@ -3572,7 +3587,7 @@ "reportableChange": 0 }, { - "name": "min measured value", + "name": "MinMeasuredValue", "code": 1, "mfgCode": null, "side": "server", @@ -3587,7 +3602,7 @@ "reportableChange": 0 }, { - "name": "max measured value", + "name": "MaxMeasuredValue", "code": 2, "mfgCode": null, "side": "server", @@ -4485,7 +4500,7 @@ "commands": [], "attributes": [ { - "name": "measured value", + "name": "MeasuredValue", "code": 0, "mfgCode": null, "side": "server", @@ -4500,7 +4515,7 @@ "reportableChange": 0 }, { - "name": "min measured value", + "name": "MinMeasuredValue", "code": 1, "mfgCode": null, "side": "server", @@ -4515,7 +4530,7 @@ "reportableChange": 0 }, { - "name": "max measured value", + "name": "MaxMeasuredValue", "code": 2, "mfgCode": null, "side": "server", @@ -5525,7 +5540,7 @@ "commands": [], "attributes": [ { - "name": "measured value", + "name": "MeasuredValue", "code": 0, "mfgCode": null, "side": "server", @@ -5540,7 +5555,7 @@ "reportableChange": 0 }, { - "name": "min measured value", + "name": "MinMeasuredValue", "code": 1, "mfgCode": null, "side": "server", @@ -5555,7 +5570,7 @@ "reportableChange": 0 }, { - "name": "max measured value", + "name": "MaxMeasuredValue", "code": 2, "mfgCode": null, "side": "server", @@ -5622,7 +5637,7 @@ "commands": [], "attributes": [ { - "name": "measured value", + "name": "MeasuredValue", "code": 0, "mfgCode": null, "side": "server", @@ -5637,7 +5652,7 @@ "reportableChange": 0 }, { - "name": "min measured value", + "name": "MinMeasuredValue", "code": 1, "mfgCode": null, "side": "server", @@ -5652,7 +5667,7 @@ "reportableChange": 0 }, { - "name": "max measured value", + "name": "MaxMeasuredValue", "code": 2, "mfgCode": null, "side": "server", @@ -5667,7 +5682,7 @@ "reportableChange": 0 }, { - "name": "tolerance", + "name": "Tolerance", "code": 3, "mfgCode": null, "side": "server", @@ -5682,7 +5697,7 @@ "reportableChange": 0 }, { - "name": "scaled value", + "name": "ScaledValue", "code": 16, "mfgCode": null, "side": "server", @@ -5697,7 +5712,7 @@ "reportableChange": 0 }, { - "name": "scaled tolerance", + "name": "ScaledTolerance", "code": 19, "mfgCode": null, "side": "server", diff --git a/examples/weather_station/src/zap-generated/IMClusterCommandHandler.cpp b/examples/weather_station/src/zap-generated/IMClusterCommandHandler.cpp index 38bffc3922fccf..a04c17574e16e5 100644 --- a/examples/weather_station/src/zap-generated/IMClusterCommandHandler.cpp +++ b/examples/weather_station/src/zap-generated/IMClusterCommandHandler.cpp @@ -167,6 +167,54 @@ void DispatchServerCommand(CommandHandler * apCommandObj, const ConcreteCommandP } // namespace GeneralCommissioning +namespace Identify { + +void DispatchServerCommand(CommandHandler * apCommandObj, const ConcreteCommandPath & aCommandPath, TLV::TLVReader & aDataTlv) +{ + // We are using TLVUnpackError and TLVError here since both of them can be CHIP_END_OF_TLV + // When TLVError is CHIP_END_OF_TLV, it means we have iterated all of the items, which is not a real error. + // Any error value TLVUnpackError means we have received an illegal value. + // The following variables are used for all commands to save code size. + CHIP_ERROR TLVError = CHIP_NO_ERROR; + bool wasHandled = false; + { + switch (aCommandPath.mCommandId) + { + case Commands::Identify::Id: { + Commands::Identify::DecodableType commandData; + TLVError = DataModel::Decode(aDataTlv, commandData); + if (TLVError == CHIP_NO_ERROR) + { + wasHandled = emberAfIdentifyClusterIdentifyCallback(apCommandObj, aCommandPath, commandData); + } + break; + } + case Commands::IdentifyQuery::Id: { + Commands::IdentifyQuery::DecodableType commandData; + TLVError = DataModel::Decode(aDataTlv, commandData); + if (TLVError == CHIP_NO_ERROR) + { + wasHandled = emberAfIdentifyClusterIdentifyQueryCallback(apCommandObj, aCommandPath, commandData); + } + break; + } + default: { + // Unrecognized command ID, error status will apply. + ReportCommandUnsupported(apCommandObj, aCommandPath); + return; + } + } + } + + if (CHIP_NO_ERROR != TLVError || !wasHandled) + { + apCommandObj->AddStatus(aCommandPath, Protocols::InteractionModel::Status::InvalidCommand); + ChipLogProgress(Zcl, "Failed to dispatch command, TLVError=%" CHIP_ERROR_FORMAT, TLVError.Format()); + } +} + +} // namespace Identify + namespace NetworkCommissioning { void DispatchServerCommand(CommandHandler * apCommandObj, const ConcreteCommandPath & aCommandPath, TLV::TLVReader & aDataTlv) @@ -468,6 +516,9 @@ void DispatchSingleClusterCommand(const ConcreteCommandPath & aCommandPath, TLV: case Clusters::GeneralCommissioning::Id: Clusters::GeneralCommissioning::DispatchServerCommand(apCommandObj, aCommandPath, aReader); break; + case Clusters::Identify::Id: + Clusters::Identify::DispatchServerCommand(apCommandObj, aCommandPath, aReader); + break; case Clusters::NetworkCommissioning::Id: Clusters::NetworkCommissioning::DispatchServerCommand(apCommandObj, aCommandPath, aReader); break; diff --git a/examples/weather_station/src/zap-generated/PluginApplicationCallbacks.h b/examples/weather_station/src/zap-generated/PluginApplicationCallbacks.h index 9c16f88326d364..d535e4de771237 100644 --- a/examples/weather_station/src/zap-generated/PluginApplicationCallbacks.h +++ b/examples/weather_station/src/zap-generated/PluginApplicationCallbacks.h @@ -27,6 +27,7 @@ MatterDescriptorPluginServerInitCallback(); \ MatterGeneralCommissioningPluginServerInitCallback(); \ MatterGeneralDiagnosticsPluginServerInitCallback(); \ + MatterIdentifyPluginServerInitCallback(); \ MatterNetworkCommissioningPluginServerInitCallback(); \ MatterOperationalCredentialsPluginServerInitCallback(); \ MatterPressureMeasurementPluginServerInitCallback(); \ diff --git a/examples/weather_station/src/zap-generated/callback-stub.cpp b/examples/weather_station/src/zap-generated/callback-stub.cpp index 29f3d1a7b30345..000908479574d4 100644 --- a/examples/weather_station/src/zap-generated/callback-stub.cpp +++ b/examples/weather_station/src/zap-generated/callback-stub.cpp @@ -44,6 +44,9 @@ void emberAfClusterInitCallback(EndpointId endpoint, ClusterId clusterId) case ZCL_GENERAL_DIAGNOSTICS_CLUSTER_ID: emberAfGeneralDiagnosticsClusterInitCallback(endpoint); break; + case ZCL_IDENTIFY_CLUSTER_ID: + emberAfIdentifyClusterInitCallback(endpoint); + break; case ZCL_NETWORK_COMMISSIONING_CLUSTER_ID: emberAfNetworkCommissioningClusterInitCallback(endpoint); break; @@ -96,6 +99,11 @@ void __attribute__((weak)) emberAfGeneralDiagnosticsClusterInitCallback(Endpoint // To prevent warning (void) endpoint; } +void __attribute__((weak)) emberAfIdentifyClusterInitCallback(EndpointId endpoint) +{ + // To prevent warning + (void) endpoint; +} void __attribute__((weak)) emberAfNetworkCommissioningClusterInitCallback(EndpointId endpoint) { // To prevent warning diff --git a/examples/weather_station/src/zap-generated/endpoint_config.h b/examples/weather_station/src/zap-generated/endpoint_config.h index 8b467474909382..a73bb2d8dae0eb 100644 --- a/examples/weather_station/src/zap-generated/endpoint_config.h +++ b/examples/weather_station/src/zap-generated/endpoint_config.h @@ -643,12 +643,17 @@ #define ZAP_ATTRIBUTE_MASK(mask) ATTRIBUTE_MASK_##mask // This is an array of EmberAfAttributeMetadata structures. -#define GENERATED_ATTRIBUTE_COUNT 122 +#define GENERATED_ATTRIBUTE_COUNT 125 #define GENERATED_ATTRIBUTES \ { \ \ - /* Endpoint: 0, Cluster: Descriptor (server) */ \ - { 0x0000, ZAP_TYPE(ARRAY), 0, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), ZAP_EMPTY_DEFAULT() }, /* device list */ \ + /* Endpoint: 0, Cluster: Identify (server) */ \ + { 0x0000, ZAP_TYPE(INT16U), 2, ZAP_ATTRIBUTE_MASK(WRITABLE), ZAP_SIMPLE_DEFAULT(0) }, /* identify time */ \ + { 0x0001, ZAP_TYPE(ENUM8), 1, 0, ZAP_SIMPLE_DEFAULT(3) }, /* identify type */ \ + { 0xFFFD, ZAP_TYPE(INT16U), 2, 0, ZAP_SIMPLE_DEFAULT(2) }, /* ClusterRevision */ \ + \ + /* Endpoint: 0, Cluster: Descriptor (server) */ \ + { 0x0000, ZAP_TYPE(ARRAY), 0, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), ZAP_EMPTY_DEFAULT() }, /* device list */ \ { 0x0001, ZAP_TYPE(ARRAY), 0, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), ZAP_EMPTY_DEFAULT() }, /* server list */ \ { 0x0002, ZAP_TYPE(ARRAY), 0, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), ZAP_EMPTY_DEFAULT() }, /* client list */ \ { 0x0003, ZAP_TYPE(ARRAY), 0, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), ZAP_EMPTY_DEFAULT() }, /* parts list */ \ @@ -809,59 +814,71 @@ // Cluster function static arrays #define GENERATED_FUNCTION_ARRAYS \ + const EmberAfGenericClusterFunction chipFuncArrayIdentifyServer[] = { \ + (EmberAfGenericClusterFunction) emberAfIdentifyClusterServerInitCallback, \ + (EmberAfGenericClusterFunction) MatterIdentifyClusterServerAttributeChangedCallback, \ + }; \ const EmberAfGenericClusterFunction chipFuncArrayBasicServer[] = { \ (EmberAfGenericClusterFunction) emberAfBasicClusterServerInitCallback, \ }; #define ZAP_CLUSTER_MASK(mask) CLUSTER_MASK_##mask -#define GENERATED_CLUSTER_COUNT 15 +#define GENERATED_CLUSTER_COUNT 16 #define GENERATED_CLUSTERS \ { \ - { 0x001D, ZAP_ATTRIBUTE_INDEX(0), 5, 2, ZAP_CLUSTER_MASK(SERVER), NULL }, /* Endpoint: 0, Cluster: Descriptor (server) */ \ + { 0x0003, \ + ZAP_ATTRIBUTE_INDEX(0), \ + 3, \ + 5, \ + ZAP_CLUSTER_MASK(SERVER) | ZAP_CLUSTER_MASK(INIT_FUNCTION) | ZAP_CLUSTER_MASK(ATTRIBUTE_CHANGED_FUNCTION), \ + chipFuncArrayIdentifyServer }, /* Endpoint: 0, Cluster: Identify (server) */ \ + { \ + 0x001D, ZAP_ATTRIBUTE_INDEX(3), 5, 2, ZAP_CLUSTER_MASK(SERVER), NULL \ + }, /* Endpoint: 0, Cluster: Descriptor (server) */ \ { 0x0028, \ - ZAP_ATTRIBUTE_INDEX(5), \ + ZAP_ATTRIBUTE_INDEX(8), \ 12, \ 246, \ ZAP_CLUSTER_MASK(SERVER) | ZAP_CLUSTER_MASK(INIT_FUNCTION), \ chipFuncArrayBasicServer }, /* Endpoint: 0, Cluster: Basic (server) */ \ { \ - 0x0030, ZAP_ATTRIBUTE_INDEX(17), 3, 264, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x0030, ZAP_ATTRIBUTE_INDEX(20), 3, 264, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 0, Cluster: General Commissioning (server) */ \ { \ - 0x0031, ZAP_ATTRIBUTE_INDEX(20), 1, 2, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x0031, ZAP_ATTRIBUTE_INDEX(23), 1, 2, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 0, Cluster: Network Commissioning (server) */ \ { \ - 0x0033, ZAP_ATTRIBUTE_INDEX(21), 3, 258, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x0033, ZAP_ATTRIBUTE_INDEX(24), 3, 258, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 0, Cluster: General Diagnostics (server) */ \ { \ - 0x0034, ZAP_ATTRIBUTE_INDEX(24), 4, 26, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x0034, ZAP_ATTRIBUTE_INDEX(27), 4, 26, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 0, Cluster: Software Diagnostics (server) */ \ { \ - 0x0035, ZAP_ATTRIBUTE_INDEX(28), 61, 754, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x0035, ZAP_ATTRIBUTE_INDEX(31), 61, 754, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 0, Cluster: Thread Network Diagnostics (server) */ \ { \ - 0x003C, ZAP_ATTRIBUTE_INDEX(89), 1, 2, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x003C, ZAP_ATTRIBUTE_INDEX(92), 1, 2, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 0, Cluster: AdministratorCommissioning (server) */ \ { \ - 0x003E, ZAP_ATTRIBUTE_INDEX(90), 5, 724, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x003E, ZAP_ATTRIBUTE_INDEX(93), 5, 724, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 0, Cluster: Operational Credentials (server) */ \ { \ - 0x001D, ZAP_ATTRIBUTE_INDEX(95), 5, 2, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x001D, ZAP_ATTRIBUTE_INDEX(98), 5, 2, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 1, Cluster: Descriptor (server) */ \ { \ - 0x0402, ZAP_ATTRIBUTE_INDEX(100), 4, 8, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x0402, ZAP_ATTRIBUTE_INDEX(103), 4, 8, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 1, Cluster: Temperature Measurement (server) */ \ { \ - 0x001D, ZAP_ATTRIBUTE_INDEX(104), 5, 2, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x001D, ZAP_ATTRIBUTE_INDEX(107), 5, 2, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 2, Cluster: Descriptor (server) */ \ { \ - 0x0405, ZAP_ATTRIBUTE_INDEX(109), 4, 8, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x0405, ZAP_ATTRIBUTE_INDEX(112), 4, 8, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 2, Cluster: Relative Humidity Measurement (server) */ \ { \ - 0x001D, ZAP_ATTRIBUTE_INDEX(113), 5, 2, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x001D, ZAP_ATTRIBUTE_INDEX(116), 5, 2, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 3, Cluster: Descriptor (server) */ \ { \ - 0x0403, ZAP_ATTRIBUTE_INDEX(118), 4, 8, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x0403, ZAP_ATTRIBUTE_INDEX(121), 4, 8, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 3, Cluster: Pressure Measurement (server) */ \ } @@ -870,8 +887,8 @@ // This is an array of EmberAfEndpointType structures. #define GENERATED_ENDPOINT_TYPES \ { \ - { ZAP_CLUSTER_INDEX(0), 9, 2278 }, { ZAP_CLUSTER_INDEX(9), 2, 10 }, { ZAP_CLUSTER_INDEX(11), 2, 10 }, \ - { ZAP_CLUSTER_INDEX(13), 2, 10 }, \ + { ZAP_CLUSTER_INDEX(0), 10, 2283 }, { ZAP_CLUSTER_INDEX(10), 2, 10 }, { ZAP_CLUSTER_INDEX(12), 2, 10 }, \ + { ZAP_CLUSTER_INDEX(14), 2, 10 }, \ } // Largest attribute size is needed for various buffers @@ -881,7 +898,7 @@ #define ATTRIBUTE_SINGLETONS_SIZE (246) // Total size of attribute storage -#define ATTRIBUTE_MAX_SIZE (2308) +#define ATTRIBUTE_MAX_SIZE (2313) // Number of fixed endpoints #define FIXED_ENDPOINT_COUNT (4) diff --git a/examples/weather_station/src/zap-generated/gen_config.h b/examples/weather_station/src/zap-generated/gen_config.h index 5a04e920d9afb5..2555f314197328 100644 --- a/examples/weather_station/src/zap-generated/gen_config.h +++ b/examples/weather_station/src/zap-generated/gen_config.h @@ -34,6 +34,7 @@ #define EMBER_AF_DESCRIPTOR_CLUSTER_SERVER_ENDPOINT_COUNT (4) #define EMBER_AF_GENERAL_COMMISSIONING_CLUSTER_SERVER_ENDPOINT_COUNT (1) #define EMBER_AF_GENERAL_DIAGNOSTICS_CLUSTER_SERVER_ENDPOINT_COUNT (1) +#define EMBER_AF_IDENTIFY_CLUSTER_SERVER_ENDPOINT_COUNT (1) #define EMBER_AF_NETWORK_COMMISSIONING_CLUSTER_SERVER_ENDPOINT_COUNT (1) #define EMBER_AF_OPERATIONAL_CREDENTIALS_CLUSTER_SERVER_ENDPOINT_COUNT (1) #define EMBER_AF_PRESSURE_MEASUREMENT_CLUSTER_SERVER_ENDPOINT_COUNT (1) @@ -69,6 +70,11 @@ #define EMBER_AF_PLUGIN_GENERAL_DIAGNOSTICS_SERVER #define EMBER_AF_PLUGIN_GENERAL_DIAGNOSTICS +// Use this macro to check if the server side of the Identify cluster is included +#define ZCL_USING_IDENTIFY_CLUSTER_SERVER +#define EMBER_AF_PLUGIN_IDENTIFY_SERVER +#define EMBER_AF_PLUGIN_IDENTIFY + // Use this macro to check if the server side of the Network Commissioning cluster is included #define ZCL_USING_NETWORK_COMMISSIONING_CLUSTER_SERVER #define EMBER_AF_PLUGIN_NETWORK_COMMISSIONING_SERVER diff --git a/examples/weather_station/thingy53_nrf5340_cpuapp.overlay b/examples/weather_station/thingy53_nrf5340_cpuapp.overlay index b3f646aafa9f2d..920114042872c1 100644 --- a/examples/weather_station/thingy53_nrf5340_cpuapp.overlay +++ b/examples/weather_station/thingy53_nrf5340_cpuapp.overlay @@ -4,6 +4,12 @@ * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause */ +/ { + aliases { + buzzer-pwm = &pwm1; + }; +}; + &i2c1 { bme688@76 { compatible = "bosch,bme680";