2424#include < app-common/zap-generated/cluster-objects.h>
2525#include < app-common/zap-generated/ids/Attributes.h>
2626#include < app-common/zap-generated/ids/Clusters.h>
27- #include < app/AttributeAccessInterfaceRegistry.h>
2827#include < app/CommandHandler.h>
2928#include < app/ConcreteCommandPath.h>
3029#include < app/clusters/fan-control-server/fan-control-server.h>
@@ -390,7 +389,7 @@ void MatterFanControlClusterServerAttributeChangedCallback(const app::ConcreteAt
390389 // Plus 99 then integer divide by 100 instead of multiplying 0.01 to avoid floating point precision error
391390 uint8_t speedSetting = static_cast <uint8_t >((speedMax * percent + 99 ) / 100 );
392391
393- if (currentSpeedSetting != speedSetting )
392+ if (currentSpeedSetting. IsNull () || speedSetting != currentSpeedSetting. Value () )
394393 {
395394 status = SpeedSetting::Set (attributePath.mEndpointId , speedSetting);
396395 VerifyOrReturn (Status::Success == status,
@@ -414,75 +413,33 @@ void MatterFanControlClusterServerAttributeChangedCallback(const app::ConcreteAt
414413 ChipLogError (Zcl, " Failed to set FanMode to off with error: 0x%02x" , to_underlying (status)));
415414 }
416415
417- // Adjust PercentSetting from a speed value change for SpeedSetting only when the SpeedSetting change was received
418- // on a write command, not when it was changed by the server or the app logic. This avoids circular logic such as
419- // (with a SpeedMax of 10):
420- // 1. Client sets the PercetSetting to 25%
421- // 2. Server sets the SpeedSetting to 3 through the server callbackm, which sets the PercentSetting to 30%
422- // 3. Server sets the PercentSetting to 30% through the server callback
423- }
424- break ;
425- }
426- default :
427- break ;
428- }
429- }
430-
431- CHIP_ERROR FanControlAttributeAccessInterface::Write (const ConcreteDataAttributePath & aPath, AttributeValueDecoder & aDecoder)
432- {
433- Status status = Status::Success;
434- switch (aPath.mAttributeId )
435- {
436- case SpeedSetting::Id: {
437- DataModel::Nullable<uint8_t > speedSetting;
438- ReturnErrorOnFailure (aDecoder.Decode (speedSetting));
416+ // Adjust PercentSetting from a speed value change for SpeedSetting
417+ // percent = floor( speed/SpeedMax * 100 )
418+ uint8_t speedMax;
419+ status = SpeedMax::Get (attributePath.mEndpointId , &speedMax);
420+ VerifyOrReturn (Status::Success == status,
421+ ChipLogError (Zcl, " Failed to get SpeedMax with error: 0x%02x" , to_underlying (status)));
439422
440- DataModel::Nullable<uint8_t > currentSpeedSetting;
441- status = SpeedSetting::Get (aPath.mEndpointId , currentSpeedSetting);
442- ReturnLogErrorOnFailure (StatusIB (status).ToChipError ());
423+ DataModel::Nullable<Percent> currentPercentSetting;
424+ status = PercentSetting::Get (attributePath.mEndpointId , currentPercentSetting);
425+ VerifyOrReturn (Status::Success == status,
426+ ChipLogError (Zcl, " Failed to get PercentSetting with error: 0x%02x" , to_underlying (status)));
443427
444- if (speedSetting != currentSpeedSetting)
445- {
446- status = SpeedSetting::Set (aPath.mEndpointId , speedSetting);
447- ReturnLogErrorOnFailure (StatusIB (status).ToChipError ());
448- // Skip the last step if we are writing NULL
449- VerifyOrReturnValue (!speedSetting.IsNull (), CHIP_NO_ERROR);
428+ float speed = speedSetting.Value ();
429+ Percent percentSetting = static_cast <Percent>(speed / speedMax * 100 );
450430
451- if (SupportsMultiSpeed (aPath. mEndpointId ))
431+ if (currentPercentSetting. IsNull () || percentSetting != currentPercentSetting. Value ( ))
452432 {
453- // If SpeedSetting is set to 0, the server SHALL set the FanMode attribute value to Off.
454- if (speedSetting.Value () == 0 )
455- {
456- status = SetFanModeToOff (aPath.mEndpointId );
457- ReturnLogErrorOnFailure (StatusIB (status).ToChipError ());
458- }
459-
460- // Adjust PercentSetting from a speed value change for SpeedSetting
461- // percent = floor( speed/SpeedMax * 100 )
462- uint8_t speedMax;
463- status = SpeedMax::Get (aPath.mEndpointId , &speedMax);
464- ReturnLogErrorOnFailure (StatusIB (status).ToChipError ());
465-
466- DataModel::Nullable<Percent> currentPercentSetting;
467- status = PercentSetting::Get (aPath.mEndpointId , currentPercentSetting);
468- ReturnLogErrorOnFailure (StatusIB (status).ToChipError ());
469-
470- float speed = speedSetting.Value ();
471- Percent percentSetting = static_cast <Percent>(speed / speedMax * 100 );
472-
473- if (currentPercentSetting != percentSetting)
474- {
475- status = PercentSetting::Set (aPath.mEndpointId , percentSetting);
476- ReturnLogErrorOnFailure (StatusIB (status).ToChipError ());
477- }
433+ status = PercentSetting::Set (attributePath.mEndpointId , percentSetting);
434+ VerifyOrReturn (Status::Success == status,
435+ ChipLogError (Zcl, " Failed to set PercentSetting with error: 0x%02x" , to_underlying (status)));
478436 }
479437 }
480438 break ;
481439 }
482440 default :
483441 break ;
484442 }
485- return CHIP_NO_ERROR;
486443}
487444
488445bool emberAfFanControlClusterStepCallback (app::CommandHandler * commandObj, const app::ConcreteCommandPath & commandPath,
0 commit comments