diff --git a/src/app/clusters/smoke-co-alarm-server/smoke-co-alarm-server.cpp b/src/app/clusters/smoke-co-alarm-server/smoke-co-alarm-server.cpp index e1700db3a19e32..d00cd7831d873c 100644 --- a/src/app/clusters/smoke-co-alarm-server/smoke-co-alarm-server.cpp +++ b/src/app/clusters/smoke-co-alarm-server/smoke-co-alarm-server.cpp @@ -46,42 +46,51 @@ SmokeCoAlarmServer & SmokeCoAlarmServer::Instance() void SmokeCoAlarmServer::SetExpressedStateByPriority(EndpointId endpointId, const std::array & priorityOrder) { - AlarmStateEnum alarmState = AlarmStateEnum::kNormal; - EndOfServiceEnum endOfServiceState = EndOfServiceEnum::kNormal; - bool active = false; - for (ExpressedStateEnum priority : priorityOrder) { + AlarmStateEnum alarmState = AlarmStateEnum::kNormal; + EndOfServiceEnum endOfServiceState = EndOfServiceEnum::kNormal; + bool active = false; + switch (priority) { case ExpressedStateEnum::kSmokeAlarm: - GetSmokeState(endpointId, alarmState); + VerifyOrReturn(GetAttribute(endpointId, SmokeState::Id, SmokeState::Get, alarmState) || mUnsupportedStatus); break; case ExpressedStateEnum::kCOAlarm: - GetCOState(endpointId, alarmState); + VerifyOrReturn(GetAttribute(endpointId, COState::Id, COState::Get, alarmState) || mUnsupportedStatus); break; case ExpressedStateEnum::kBatteryAlert: - GetBatteryAlert(endpointId, alarmState); + VerifyOrReturn(GetAttribute(endpointId, BatteryAlert::Id, BatteryAlert::Get, alarmState) || mUnsupportedStatus); break; case ExpressedStateEnum::kTesting: - GetTestInProgress(endpointId, active); + VerifyOrReturn(GetAttribute(endpointId, TestInProgress::Id, TestInProgress::Get, active) || mUnsupportedStatus); break; case ExpressedStateEnum::kHardwareFault: - GetHardwareFaultAlert(endpointId, active); + VerifyOrReturn(GetAttribute(endpointId, HardwareFaultAlert::Id, HardwareFaultAlert::Get, active) || mUnsupportedStatus); break; case ExpressedStateEnum::kEndOfService: - GetEndOfServiceAlert(endpointId, endOfServiceState); + VerifyOrReturn(GetAttribute(endpointId, EndOfServiceAlert::Id, EndOfServiceAlert::Get, endOfServiceState) || + mUnsupportedStatus); break; case ExpressedStateEnum::kInterconnectSmoke: - GetInterconnectSmokeAlarm(endpointId, alarmState); + VerifyOrReturn(GetAttribute(endpointId, InterconnectSmokeAlarm::Id, InterconnectSmokeAlarm::Get, alarmState) || + mUnsupportedStatus); break; case ExpressedStateEnum::kInterconnectCO: - GetInterconnectCOAlarm(endpointId, alarmState); + VerifyOrReturn(GetAttribute(endpointId, InterconnectCOAlarm::Id, InterconnectCOAlarm::Get, alarmState) || + mUnsupportedStatus); break; default: break; } + // Skip if attribute is not supported + if (mUnsupportedStatus) + { + continue; + } + if ((alarmState != AlarmStateEnum::kNormal) || (endOfServiceState != EndOfServiceEnum::kNormal) || active) { SetExpressedState(endpointId, priority); @@ -186,20 +195,25 @@ bool SmokeCoAlarmServer::SetDeviceMuted(EndpointId endpointId, MuteStateEnum new { AlarmStateEnum alarmState; - GetAttribute(endpointId, SmokeState::Id, SmokeState::Get, alarmState); - VerifyOrReturnValue(alarmState != AlarmStateEnum::kCritical, false); + // If the attribute is supported and the attribute is Critical, return false + + VerifyOrReturnValue(GetAttribute(endpointId, SmokeState::Id, SmokeState::Get, alarmState) || mUnsupportedStatus, false); + VerifyOrReturnValue(mUnsupportedStatus || alarmState != AlarmStateEnum::kCritical, false); - GetAttribute(endpointId, COState::Id, COState::Get, alarmState); - VerifyOrReturnValue(alarmState != AlarmStateEnum::kCritical, false); + VerifyOrReturnValue(GetAttribute(endpointId, COState::Id, COState::Get, alarmState) || mUnsupportedStatus, false); + VerifyOrReturnValue(mUnsupportedStatus || alarmState != AlarmStateEnum::kCritical, false); - GetAttribute(endpointId, BatteryAlert::Id, BatteryAlert::Get, alarmState); - VerifyOrReturnValue(alarmState != AlarmStateEnum::kCritical, false); + VerifyOrReturnValue(GetAttribute(endpointId, BatteryAlert::Id, BatteryAlert::Get, alarmState) || mUnsupportedStatus, false); + VerifyOrReturnValue(mUnsupportedStatus || alarmState != AlarmStateEnum::kCritical, false); - GetAttribute(endpointId, InterconnectSmokeAlarm::Id, InterconnectSmokeAlarm::Get, alarmState); - VerifyOrReturnValue(alarmState != AlarmStateEnum::kCritical, false); + VerifyOrReturnValue(GetAttribute(endpointId, InterconnectSmokeAlarm::Id, InterconnectSmokeAlarm::Get, alarmState) || + mUnsupportedStatus, + false); + VerifyOrReturnValue(mUnsupportedStatus || alarmState != AlarmStateEnum::kCritical, false); - GetAttribute(endpointId, InterconnectCOAlarm::Id, InterconnectCOAlarm::Get, alarmState); - VerifyOrReturnValue(alarmState != AlarmStateEnum::kCritical, false); + VerifyOrReturnValue( + GetAttribute(endpointId, InterconnectCOAlarm::Id, InterconnectCOAlarm::Get, alarmState) || mUnsupportedStatus, false); + VerifyOrReturnValue(mUnsupportedStatus || alarmState != AlarmStateEnum::kCritical, false); } VerifyOrReturnValue(SetAttribute(endpointId, DeviceMuted::Id, DeviceMuted::Set, newDeviceMuted), false); @@ -464,12 +478,14 @@ void SmokeCoAlarmServer::SendEvent(EndpointId endpointId, T & event) template bool SmokeCoAlarmServer::GetAttribute(EndpointId endpointId, AttributeId attributeId, - EmberAfStatus (*getFn)(EndpointId endpointId, T * value), T & value) const + EmberAfStatus (*getFn)(EndpointId endpointId, T * value), T & value) { EmberAfStatus status = getFn(endpointId, &value); bool success = (EMBER_ZCL_STATUS_SUCCESS == status); + mUnsupportedStatus = (EMBER_ZCL_STATUS_UNSUPPORTED_ATTRIBUTE == status); - if (!success && EMBER_ZCL_STATUS_UNSUPPORTED_ATTRIBUTE != status) + // Ignore error logs for unsupported attributes + if (!success && !mUnsupportedStatus) { ChipLogError(Zcl, "Failed to read SmokeCOAlarm attribute: attribute=" ChipLogFormatMEI ", status=0x%x", ChipLogValueMEI(attributeId), to_underlying(status)); diff --git a/src/app/clusters/smoke-co-alarm-server/smoke-co-alarm-server.h b/src/app/clusters/smoke-co-alarm-server/smoke-co-alarm-server.h index 9a41c88f282831..0fa1d45e06cf48 100644 --- a/src/app/clusters/smoke-co-alarm-server/smoke-co-alarm-server.h +++ b/src/app/clusters/smoke-co-alarm-server/smoke-co-alarm-server.h @@ -129,17 +129,17 @@ class SmokeCoAlarmServer /** * @brief Get generic attribute value * - * @tparam T attribute value type - * @param endpointId endpoint where SmokeCoAlarmServer is running - * @param attributeId attribute Id (used for logging only) - * @param getFn attribute getter function as defined in - * @param value actual attribute value on success - * @return true on success (value is set to the actual attribute value) - * @return false if attribute reading failed (value is kept unchanged) + * @tparam T attribute value type + * @param endpointId endpoint where SmokeCoAlarmServer is running + * @param attributeId attribute Id (used for logging only) + * @param getFn attribute getter function as defined in + * @param value actual attribute value on success + * @return true on success (value is set to the actual attribute value) + * @return false if attribute reading failed (value is kept unchanged) */ template bool GetAttribute(chip::EndpointId endpointId, chip::AttributeId attributeId, - EmberAfStatus (*getFn)(chip::EndpointId endpointId, T * value), T & value) const; + EmberAfStatus (*getFn)(chip::EndpointId endpointId, T * value), T & value); /** * @brief Set generic attribute value @@ -160,6 +160,8 @@ class SmokeCoAlarmServer chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, const chip::app::Clusters::SmokeCoAlarm::Commands::SelfTestRequest::DecodableType & commandData); + bool mUnsupportedStatus; // Used with GetAttribute() to determine whether an attribute is supported or not + static SmokeCoAlarmServer sInstance; };