Skip to content

Commit

Permalink
Add feature map support to window covering cluster (#12937)
Browse files Browse the repository at this point in the history
* 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 <[email protected]>
  • Loading branch information
2 people authored and pull[bot] committed Jan 26, 2022
1 parent b04c43e commit 1750988
Show file tree
Hide file tree
Showing 5 changed files with 123 additions and 54 deletions.
131 changes: 91 additions & 40 deletions src/app/clusters/window-covering-server/window-covering-server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<uint8_t *>(&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)
Expand Down Expand Up @@ -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)
Expand All @@ -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);
}

Expand Down Expand Up @@ -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);
}

Expand Down Expand Up @@ -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);
}
Expand All @@ -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);
}
Expand All @@ -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, &current);
(void) Attributes::TargetPositionLiftPercent100ths::Set(endpoint, current);
}

if (HasFeature(endpoint, WindowCoveringFeature::kTilt) && HasFeature(endpoint, WindowCoveringFeature::kPositionAwareTilt))
{
(void) Attributes::CurrentPositionTiltPercent100ths::Get(endpoint, &current);
(void) Attributes::TargetPositionTiltPercent100ths::Set(endpoint, current);
}

return EMBER_SUCCESS == emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_SUCCESS);
}

/**
Expand All @@ -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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
19 changes: 12 additions & 7 deletions src/app/zap-templates/zcl/data-model/chip/window-covering.xml
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,9 @@ limitations under the License.
<server tick="false" init="false">true</server>
<tag name="LF" description="Lift Control"/>
<tag name="TL" description="Tilt Control"/>
<tag name="PA" description="Position Aware"/>
<tag name="PA_LF" description="Position Aware lift control"/>
<tag name="ABS" description="Absolute Positioning"/>
<globalAttribute side="server" code="0xFFFC" value="0x0001">
<featureBit tag="LF" bit="0">true</featureBit>
<featureBit tag="TL" bit="1">false</featureBit>
<featureBit tag="PA" bit="2">false</featureBit>
<featureBit tag="ABS" bit="3">false</featureBit>
</globalAttribute>
<tag name="PA_TL" description="Position Aware tilt control"/>
<globalAttribute side="either" code="0xFFFD" value="5"/>
<!-- Window Covering Information Attribute Set -->
<attribute side="server" writable="false" code="0x0000" define="WC_TYPE" type="ENUM8" min="0x00" max="0x09" default="0x00" optional="false">Type</attribute>
Expand Down Expand Up @@ -178,4 +173,14 @@ limitations under the License.
<field mask="0x0400" name="ManualOperation"/>
<field mask="0x0800" name="Protection"/>
</bitmap>

<bitmap name="WindowCoveringFeature" type="BITMAP32">
<cluster code="0x0102"/>
<field name="Lift" mask="0x1"/>
<field name="Tilt" mask="0x2"/>
<field name="PositionAwareLift" mask="0x4"/>
<field name="AbsolutePosition" mask="0x8"/>
<field name="PositionAwareTilt" mask="0x10"/>
</bitmap>

</configurator>

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions zzz_generated/app-common/app-common/zap-generated/enums.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 1750988

Please sign in to comment.