From 8e0a8faf3d13f96a3644424185ffe26348424909 Mon Sep 17 00:00:00 2001 From: eve-cxrp <80681009+eve-cxrp@users.noreply.github.com> Date: Tue, 14 Dec 2021 14:52:23 +0100 Subject: [PATCH] Add feature map support to window covering cluster (#12937) * fix feature map xml defintion * add feature map support to window-covering cluster * Restyled by whitespace * fix typo * remove wrong code * fix emberAfWindowCoveringClusterStopMotionCallback endpointid * fix HasFeature conversion * use new feature map approach * regen all * Restyled by clang-format Co-authored-by: Restyled.io --- .../window-covering-server.cpp | 131 ++++++++++++------ .../window-covering-server.h | 7 - .../zcl/data-model/chip/window-covering.xml | 19 ++- .../zap-generated/cluster-objects.h | 10 ++ .../app-common/zap-generated/enums.h | 10 ++ 5 files changed, 123 insertions(+), 54 deletions(-) diff --git a/src/app/clusters/window-covering-server/window-covering-server.cpp b/src/app/clusters/window-covering-server/window-covering-server.cpp index 5f06bc6607d241..04a65368ba72eb 100644 --- a/src/app/clusters/window-covering-server/window-covering-server.cpp +++ b/src/app/clusters/window-covering-server/window-covering-server.cpp @@ -58,9 +58,18 @@ using namespace chip::app::Clusters::WindowCovering; #define WC_PERCENT100THS_MAX 10000 -static bool HasFeature(chip::EndpointId endpoint, Features feature) +static bool HasFeature(chip::EndpointId endpoint, WindowCoveringFeature feature) { - return true; + uint32_t FeatureMap = 0; + if (EMBER_ZCL_STATUS_SUCCESS == + emberAfReadServerAttribute(endpoint, chip::app::Clusters::WindowCovering::Id, + chip::app::Clusters::WindowCovering::Attributes::FeatureMap::Id, + reinterpret_cast(&FeatureMap), sizeof(FeatureMap))) + { + return (FeatureMap & chip::to_underlying(feature)) != 0; + } + + return false; } static uint16_t ValueToPercent100ths(uint16_t openLimit, uint16_t closedLimit, uint16_t value) @@ -158,26 +167,42 @@ bool IsOpen(chip::EndpointId endpoint) uint16_t liftLimit = 0; uint16_t tiltPosition = 0; uint16_t tiltLimit = 0; + bool isOpen = false; + + if (HasFeature(endpoint, WindowCoveringFeature::kLift) && HasFeature(endpoint, WindowCoveringFeature::kPositionAwareLift) && + HasFeature(endpoint, WindowCoveringFeature::kAbsolutePosition) && + EMBER_ZCL_STATUS_SUCCESS == Attributes::TargetPositionLiftPercent100ths::Get(endpoint, &liftPosition) && + EMBER_ZCL_STATUS_SUCCESS == Attributes::InstalledOpenLimitLift::Get(endpoint, &liftLimit)) + { + isOpen = liftPosition == liftLimit; + } + else if (HasFeature(endpoint, WindowCoveringFeature::kLift) && + HasFeature(endpoint, WindowCoveringFeature::kPositionAwareLift) && + EMBER_ZCL_STATUS_SUCCESS == Attributes::TargetPositionLiftPercent100ths::Get(endpoint, &liftPosition)) + { + isOpen = 0 == liftPosition; + } + + if (HasFeature(endpoint, WindowCoveringFeature::kTilt) && HasFeature(endpoint, WindowCoveringFeature::kPositionAwareTilt) && + HasFeature(endpoint, WindowCoveringFeature::kAbsolutePosition) && + EMBER_ZCL_STATUS_SUCCESS == Attributes::TargetPositionTiltPercent100ths::Get(endpoint, &tiltPosition) && + EMBER_ZCL_STATUS_SUCCESS == Attributes::InstalledOpenLimitTilt::Get(endpoint, &tiltLimit)) + { + isOpen = isOpen && tiltPosition == tiltLimit; + } + else if (HasFeature(endpoint, WindowCoveringFeature::kTilt) && + HasFeature(endpoint, WindowCoveringFeature::kPositionAwareTilt) && + EMBER_ZCL_STATUS_SUCCESS == Attributes::TargetPositionTiltPercent100ths::Get(endpoint, &tiltPosition)) + { + isOpen = isOpen && 0 == tiltPosition; + } - Attributes::TargetPositionLiftPercent100ths::Get(endpoint, &liftPosition); - Attributes::InstalledOpenLimitLift::Get(endpoint, &liftLimit); - Attributes::TargetPositionTiltPercent100ths::Get(endpoint, &tiltPosition); - Attributes::InstalledOpenLimitTilt::Get(endpoint, &tiltLimit); - return liftPosition == liftLimit && tiltPosition == tiltLimit; + return isOpen; } bool IsClosed(chip::EndpointId endpoint) { - uint16_t liftPosition = 0; - uint16_t liftLimit = 0; - uint16_t tiltPosition = 0; - uint16_t tiltLimit = 0; - - Attributes::TargetPositionLiftPercent100ths::Get(endpoint, &liftPosition); - Attributes::InstalledClosedLimitLift::Get(endpoint, &liftLimit); - Attributes::TargetPositionTiltPercent100ths::Get(endpoint, &tiltPosition); - Attributes::InstalledClosedLimitTilt::Get(endpoint, &tiltLimit); - return liftPosition == liftLimit && tiltPosition == tiltLimit; + return !IsOpen(endpoint); } void TypeSet(chip::EndpointId endpoint, EmberAfWcType type) @@ -194,9 +219,15 @@ EmberAfWcType TypeGet(chip::EndpointId endpoint) void ConfigStatusSet(chip::EndpointId endpoint, const ConfigStatus & status) { - uint8_t value = (status.operational ? 0x01 : 0) | (status.online ? 0x02 : 0) | (status.liftIsReversed ? 0x04 : 0) | - (status.liftIsPA ? 0x08 : 0) | (status.tiltIsPA ? 0x10 : 0) | (status.liftIsEncoderControlled ? 0x20 : 0) | - (status.tiltIsEncoderControlled ? 0x40 : 0); + /* clang-format off */ + uint8_t value = (status.operational ? 0x01 : 0) + | (status.online ? 0x02 : 0) + | (status.liftIsReversed ? 0x04 : 0) + | (status.liftIsPA ? 0x08 : 0) + | (status.tiltIsPA ? 0x10 : 0) + | (status.liftIsEncoderControlled ? 0x20 : 0) + | (status.tiltIsEncoderControlled ? 0x40 : 0); + /* clang-format on */ Attributes::ConfigStatus::Set(endpoint, value); } @@ -271,12 +302,19 @@ const Mode ModeGet(chip::EndpointId endpoint) void SafetyStatusSet(chip::EndpointId endpoint, SafetyStatus & status) { - uint16_t value = (status.remoteLockout ? 0x0001 : 0) | (status.tamperDetection ? 0x0002 : 0) | - (status.failedCommunication ? 0x0004 : 0) | (status.positionFailure ? 0x0008 : 0) | - (status.thermalProtection ? 0x0010 : 0) | (status.obstacleDetected ? 0x0020 : 0) | (status.powerIssue ? 0x0040 : 0) | - (status.stopInput ? 0x0080 : 0); - value |= (uint16_t)(status.motorJammed ? 0x0100 : 0) | (uint16_t)(status.hardwareFailure ? 0x0200 : 0) | - (uint16_t)(status.manualOperation ? 0x0400 : 0); + /* clang-format off */ + uint16_t value = (status.remoteLockout ? 0x0001 : 0) + | (status.tamperDetection ? 0x0002 : 0) + | (status.failedCommunication ? 0x0004 : 0) + | (status.positionFailure ? 0x0008 : 0) + | (status.thermalProtection ? 0x0010 : 0) + | (status.obstacleDetected ? 0x0020 : 0) + | (status.powerIssue ? 0x0040 : 0) + | (status.stopInput ? 0x0080 : 0); + value |= (uint16_t) (status.motorJammed ? 0x0100 : 0) + | (uint16_t) (status.hardwareFailure ? 0x0200 : 0) + | (uint16_t) (status.manualOperation ? 0x0400 : 0); + /* clang-format on */ Attributes::SafetyStatus::Set(endpoint, value); } @@ -387,11 +425,11 @@ bool emberAfWindowCoveringClusterUpOrOpenCallback(app::CommandHandler * commandO EndpointId endpoint = commandPath.mEndpointId; emberAfWindowCoveringClusterPrint("UpOrOpen command received"); - if (HasFeature(endpoint, Features::Lift)) + if (HasFeature(endpoint, WindowCoveringFeature::kLift)) { Attributes::TargetPositionLiftPercent100ths::Set(endpoint, 0); } - if (HasFeature(endpoint, Features::Tilt)) + if (HasFeature(endpoint, WindowCoveringFeature::kTilt)) { Attributes::TargetPositionTiltPercent100ths::Set(endpoint, 0); } @@ -408,11 +446,11 @@ bool emberAfWindowCoveringClusterDownOrCloseCallback(app::CommandHandler * comma EndpointId endpoint = commandPath.mEndpointId; emberAfWindowCoveringClusterPrint("DownOrClose command received"); - if (HasFeature(endpoint, Features::Lift)) + if (HasFeature(endpoint, WindowCoveringFeature::kLift)) { Attributes::TargetPositionLiftPercent100ths::Set(endpoint, WC_PERCENT100THS_MAX); } - if (HasFeature(endpoint, Features::Tilt)) + if (HasFeature(endpoint, WindowCoveringFeature::kTilt)) { Attributes::TargetPositionTiltPercent100ths::Set(endpoint, WC_PERCENT100THS_MAX); } @@ -428,9 +466,22 @@ emberAfWindowCoveringClusterStopMotionCallback(app::CommandHandler * commandObj, const Commands::StopMotion::DecodableType & fields) { emberAfWindowCoveringClusterPrint("StopMotion command received"); + uint16_t current = 0; + chip::EndpointId endpoint = commandPath.mEndpointId; - emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_SUCCESS); - return true; + if (HasFeature(endpoint, WindowCoveringFeature::kLift) && HasFeature(endpoint, WindowCoveringFeature::kPositionAwareLift)) + { + (void) Attributes::CurrentPositionLiftPercent100ths::Get(endpoint, ¤t); + (void) Attributes::TargetPositionLiftPercent100ths::Set(endpoint, current); + } + + if (HasFeature(endpoint, WindowCoveringFeature::kTilt) && HasFeature(endpoint, WindowCoveringFeature::kPositionAwareTilt)) + { + (void) Attributes::CurrentPositionTiltPercent100ths::Get(endpoint, ¤t); + (void) Attributes::TargetPositionTiltPercent100ths::Set(endpoint, current); + } + + return EMBER_SUCCESS == emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_SUCCESS); } /** @@ -444,8 +495,8 @@ bool emberAfWindowCoveringClusterGoToLiftValueCallback(app::CommandHandler * com EndpointId endpoint = commandPath.mEndpointId; - bool hasLift = HasFeature(endpoint, Features::Lift); - bool isPositionAware = HasFeature(endpoint, Features::PositionAware); + bool hasLift = HasFeature(endpoint, WindowCoveringFeature::kLift); + bool isPositionAware = HasFeature(endpoint, WindowCoveringFeature::kPositionAwareLift); emberAfWindowCoveringClusterPrint("GoToLiftValue Value command received"); if (hasLift && isPositionAware) @@ -473,8 +524,8 @@ bool emberAfWindowCoveringClusterGoToLiftPercentageCallback(app::CommandHandler EndpointId endpoint = commandPath.mEndpointId; - bool hasLift = HasFeature(endpoint, Features::Lift); - bool isPositionAware = HasFeature(endpoint, Features::PositionAware); + bool hasLift = HasFeature(endpoint, WindowCoveringFeature::kLift); + bool isPositionAware = HasFeature(endpoint, WindowCoveringFeature::kPositionAwareLift); emberAfWindowCoveringClusterPrint("GoToLiftPercentage Percentage command received"); if (hasLift && isPositionAware) @@ -502,8 +553,8 @@ bool emberAfWindowCoveringClusterGoToTiltValueCallback(app::CommandHandler * com EndpointId endpoint = commandPath.mEndpointId; - bool hasTilt = HasFeature(endpoint, Features::Tilt); - bool isPositionAware = HasFeature(endpoint, Features::PositionAware); + bool hasTilt = HasFeature(endpoint, WindowCoveringFeature::kTilt); + bool isPositionAware = HasFeature(endpoint, WindowCoveringFeature::kPositionAwareTilt); emberAfWindowCoveringClusterPrint("GoToTiltValue command received"); if (hasTilt && isPositionAware) @@ -531,8 +582,8 @@ bool emberAfWindowCoveringClusterGoToTiltPercentageCallback(app::CommandHandler EndpointId endpoint = commandPath.mEndpointId; - bool hasTilt = HasFeature(endpoint, Features::Tilt); - bool isPositionAware = HasFeature(endpoint, Features::PositionAware); + bool hasTilt = HasFeature(endpoint, WindowCoveringFeature::kTilt); + bool isPositionAware = HasFeature(endpoint, WindowCoveringFeature::kPositionAwareTilt); emberAfWindowCoveringClusterPrint("GoToTiltPercentage command received"); if (hasTilt && isPositionAware) diff --git a/src/app/clusters/window-covering-server/window-covering-server.h b/src/app/clusters/window-covering-server/window-covering-server.h index 2ef7302fa47e84..d0db0bff505b93 100644 --- a/src/app/clusters/window-covering-server/window-covering-server.h +++ b/src/app/clusters/window-covering-server/window-covering-server.h @@ -26,13 +26,6 @@ namespace app { namespace Clusters { namespace WindowCovering { -enum class Features -{ - Lift = 0x01, - Tilt = 0x02, - PositionAware = 0x04 -}; - struct Mode { uint8_t motorDirReversed : 1; // bit 0 diff --git a/src/app/zap-templates/zcl/data-model/chip/window-covering.xml b/src/app/zap-templates/zcl/data-model/chip/window-covering.xml index 6040c52a31bad7..eeff24927ab8a2 100644 --- a/src/app/zap-templates/zcl/data-model/chip/window-covering.xml +++ b/src/app/zap-templates/zcl/data-model/chip/window-covering.xml @@ -23,14 +23,9 @@ limitations under the License. true - + - - true - false - false - false - + Type @@ -178,4 +173,14 @@ limitations under the License. + + + + + + + + + + diff --git a/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h b/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h index 5bdd9efe2fbdc5..b8b2a224b1dc3e 100644 --- a/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h +++ b/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h @@ -18999,6 +18999,16 @@ enum class WcSafetyStatus : uint16_t kProtection = 0x800, }; +// Bitmap for WindowCoveringFeature +enum class WindowCoveringFeature : uint32_t +{ + kLift = 0x1, + kTilt = 0x2, + kPositionAwareLift = 0x4, + kAbsolutePosition = 0x8, + kPositionAwareTilt = 0x10, +}; + namespace Commands { // Forward-declarations so we can reference these later. diff --git a/zzz_generated/app-common/app-common/zap-generated/enums.h b/zzz_generated/app-common/app-common/zap-generated/enums.h index 41423ccfbc687c..70ce299d265bf8 100644 --- a/zzz_generated/app-common/app-common/zap-generated/enums.h +++ b/zzz_generated/app-common/app-common/zap-generated/enums.h @@ -1342,3 +1342,13 @@ enum EmberAfWiFiVersionType : uint8_t #define EMBER_AF_WI_FI_NETWORK_DIAGNOSTICS_FEATURE_PACKET_COUNTS_OFFSET (0) #define EMBER_AF_WI_FI_NETWORK_DIAGNOSTICS_FEATURE_ERROR_COUNTS (2) #define EMBER_AF_WI_FI_NETWORK_DIAGNOSTICS_FEATURE_ERROR_COUNTS_OFFSET (1) +#define EMBER_AF_WINDOW_COVERING_FEATURE_LIFT (1) +#define EMBER_AF_WINDOW_COVERING_FEATURE_LIFT_OFFSET (0) +#define EMBER_AF_WINDOW_COVERING_FEATURE_TILT (2) +#define EMBER_AF_WINDOW_COVERING_FEATURE_TILT_OFFSET (1) +#define EMBER_AF_WINDOW_COVERING_FEATURE_POSITION_AWARE_LIFT (4) +#define EMBER_AF_WINDOW_COVERING_FEATURE_POSITION_AWARE_LIFT_OFFSET (2) +#define EMBER_AF_WINDOW_COVERING_FEATURE_ABSOLUTE_POSITION (8) +#define EMBER_AF_WINDOW_COVERING_FEATURE_ABSOLUTE_POSITION_OFFSET (3) +#define EMBER_AF_WINDOW_COVERING_FEATURE_POSITION_AWARE_TILT (16) +#define EMBER_AF_WINDOW_COVERING_FEATURE_POSITION_AWARE_TILT_OFFSET (4)