| /* |
| * |
| * Copyright (c) 2021 Project CHIP Authors |
| * All rights reserved. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #include <app/util/af.h> |
| |
| #include <app-common/zap-generated/af-structs.h> |
| #include <app-common/zap-generated/attribute-id.h> |
| #include <app-common/zap-generated/attribute-type.h> |
| #include <app-common/zap-generated/cluster-id.h> |
| #include <app-common/zap-generated/command-id.h> |
| |
| using namespace chip; |
| using namespace chip::app::Clusters; |
| #define MAX_LEVEL 99 |
| #define MIN_LEVEL 1 |
| |
| typedef struct |
| { |
| CommandId commandId; |
| uint16_t storedLevel; |
| bool increasing; |
| } EmberAfLevelControlState; |
| |
| static EmberAfLevelControlState stateTable[EMBER_AF_LEVEL_CONTROL_CLUSTER_SERVER_ENDPOINT_COUNT]; |
| |
| static EmberAfLevelControlState * getState(EndpointId endpoint) |
| { |
| uint8_t ep = emberAfFindClusterServerEndpointIndex(endpoint, ZCL_LEVEL_CONTROL_CLUSTER_ID); |
| return (ep == 0xFF ? NULL : &stateTable[ep]); |
| } |
| |
| static void stepHandler(CommandId commandId, uint8_t stepMode, uint8_t stepSize, pp::DataModel::Nullable<uint16_t> transitionTimeDs, |
| BitMask<LevelControl::LevelControlOptions> optionMask, |
| BitMask<LevelControl::LevelControlOptions> optionOverride) |
| { |
| |
| EndpointId endpoint = emberAfCurrentEndpoint(); |
| EmberAfLevelControlState * state = getState(endpoint); |
| EmberAfStatus status; |
| app::DataModel::Nullable<uint8_t> nullableCurrentLevel; |
| uint8_t currentLevel; |
| |
| status = Attributes::CurrentLevel::Get(endpoint, nullableCurrentLevel); |
| if (status != EMBER_ZCL_STATUS_SUCCESS) |
| { |
| emberAfLevelControlClusterPrintln("ERR: reading current level %x", status); |
| goto send_default_response; |
| } |
| |
| if (nullableCurrentLevel.IsNull()) |
| { |
| emberAfLevelControlClusterPrintln("ERR: Current Level is null"); |
| status = EMBER_ZCL_STATUS_FAILURE; |
| |
| goto send_default_response; |
| } |
| |
| currentLevel = nullableCurrentLevel.Value(); |
| |
| switch (stepMode) |
| { |
| case EMBER_ZCL_STEP_MODE_UP: |
| state->increasing = true; |
| if (MAX_LEVEL >= currentLevel + stepSize) |
| { |
| currentLevel = currentLevel + stepSize; |
| } |
| break; |
| case EMBER_ZCL_STEP_MODE_DOWN: |
| state->increasing = false; |
| if (MIN_LEVEL <= currentLevel - stepSize) |
| { |
| currentLevel = currentLevel - stepSize; |
| } |
| break; |
| default: |
| status = EMBER_ZCL_STATUS_INVALID_FIELD; |
| goto send_default_response; |
| } |
| |
| if (currentLevel != state->storedLevel) |
| { |
| int volumeIncrementCount = abs(currentLevel - state->storedLevel); |
| for (int i = 0; i < volumeIncrementCount; ++i) |
| { |
| if (state->increasing) |
| { |
| ChipLogProgress(Zcl, "Volume UP"); |
| // TODO: Insert your code here to send volume up command |
| } |
| else |
| { |
| ChipLogProgress(Zcl, "Volume DOWN"); |
| // TODO: Insert your code here to send volume down command |
| } |
| } |
| |
| nullableCurrentLevel.SetNonNull(currentLevel); |
| status = Attributes::CurrentLevel::Set(endpoint, nullableCurrentLevel); |
| |
| state->storedLevel = currentLevel; |
| ChipLogProgress(Zcl, "Setting volume to new level %d", state->storedLevel); |
| } |
| |
| send_default_response: |
| if (emberAfCurrentCommand()->apsFrame->clusterId == ZCL_LEVEL_CONTROL_CLUSTER_ID) |
| { |
| emberAfSendImmediateDefaultResponse(status); |
| } |
| } |
| |
| bool emberAfLevelControlClusterStepCallback(uint8_t stepMode, uint8_t stepSize, pp::DataModel::Nullable<uint8_t> transitionTime, |
| BitMask<LevelControl::LevelControlOptions> optionMask, |
| BitMask<LevelControl::LevelControlOptions> optionOverride) |
| { |
| stepHandler(ZCL_STEP_COMMAND_ID, stepMode, stepSize, transitionTime, optionMask, optionOverride); |
| return true; |
| } |
| |
| bool emberAfLevelControlClusterMoveCallback(unsigned char, unsigned char, unsigned char, unsigned char) |
| { |
| ChipLogProgress(Zcl, "Not supported"); |
| return true; |
| } |
| |
| bool emberAfLevelControlClusterMoveToLevelCallback(unsigned char, unsigned short, unsigned char, unsigned char) |
| { |
| ChipLogProgress(Zcl, "Not supported"); |
| return true; |
| } |
| |
| bool emberAfLevelControlClusterMoveToLevelWithOnOffCallback(unsigned char, unsigned short) |
| { |
| ChipLogProgress(Zcl, "Not supported"); |
| return true; |
| } |
| |
| bool emberAfLevelControlClusterMoveWithOnOffCallback(unsigned char, unsigned char) |
| { |
| ChipLogProgress(Zcl, "Not supported"); |
| return true; |
| } |
| |
| bool emberAfLevelControlClusterStopCallback(unsigned char, unsigned char) |
| { |
| ChipLogProgress(Zcl, "Not supported"); |
| return true; |
| } |
| |
| bool emberAfLevelControlClusterStopWithOnOffCallback() |
| { |
| ChipLogProgress(Zcl, "Not supported"); |
| return true; |
| } |
| |
| bool emberAfOnOffClusterLevelControlEffectCallback(unsigned char, bool) |
| { |
| ChipLogProgress(Zcl, "Not supported"); |
| return true; |
| } |
| |
| bool emberAfLevelControlClusterServerInitCallback(unsigned char) |
| { |
| ChipLogProgress(Zcl, "Not supported"); |
| return true; |
| } |
| |
| bool emberAfLevelControlClusterStepWithOnOffCallback(unsigned char, unsigned char, unsigned short) |
| { |
| ChipLogProgress(Zcl, "Not supported"); |
| return true; |
| } |
| |
| bool emberAfLevelControlClusterServerTickCallback(unsigned char) |
| { |
| ChipLogProgress(Zcl, "Not supported"); |
| return true; |
| } |