blob: 31ff5098869680f71cd8d6239b679d3007a0feec [file] [log] [blame]
/*
*
* Copyright (c) 2022 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 "controller/InvokeInteraction.h"
#include "controller/ReadInteraction.h"
#include <app/clusters/bindings/bindings.h>
#if CONFIG_ENABLE_CHIP_SHELL
#include "lib/shell/Engine.h"
#include "lib/shell/commands/Help.h"
#endif // ENABLE_CHIP_SHELL
using namespace chip;
using namespace chip::app;
#if CONFIG_ENABLE_CHIP_SHELL
using Shell::Engine;
using Shell::shell_command_t;
using Shell::streamer_get;
using Shell::streamer_printf;
Engine sShellSwitchThermostatSubCommands;
Engine sShellSwitchThermostatReadSubCommands;
Engine sShellSwitchGroupsThermostatSubCommands;
#endif // defined(ENABLE_CHIP_SHELL)
void ProcessThermostatUnicastBindingRead(BindingCommandData * data, const EmberBindingTableEntry & binding,
OperationalDeviceProxy * peer_device)
{
auto onSuccess = [](const ConcreteDataAttributePath & attributePath, const auto & dataResponse) {
ChipLogProgress(NotSpecified, "Read Thermostat attribute succeeds");
};
auto onFailure = [](const ConcreteDataAttributePath * attributePath, CHIP_ERROR error) {
ChipLogError(NotSpecified, "Read Thermostat attribute failed: %" CHIP_ERROR_FORMAT, error.Format());
};
VerifyOrDie(peer_device != nullptr && peer_device->ConnectionReady());
switch (data->attributeId)
{
case Clusters::Thermostat::Attributes::AttributeList::Id:
Controller::ReadAttribute<Clusters::Thermostat::Attributes::AttributeList::TypeInfo>(
peer_device->GetExchangeManager(), peer_device->GetSecureSession().Value(), binding.remote, onSuccess, onFailure);
break;
case Clusters::Thermostat::Attributes::LocalTemperature::Id:
Controller::ReadAttribute<Clusters::Thermostat::Attributes::LocalTemperature::TypeInfo>(
peer_device->GetExchangeManager(), peer_device->GetSecureSession().Value(), binding.remote, onSuccess, onFailure);
break;
case Clusters::Thermostat::Attributes::AbsMinHeatSetpointLimit::Id:
Controller::ReadAttribute<Clusters::Thermostat::Attributes::AbsMinHeatSetpointLimit::TypeInfo>(
peer_device->GetExchangeManager(), peer_device->GetSecureSession().Value(), binding.remote, onSuccess, onFailure);
break;
case Clusters::Thermostat::Attributes::AbsMaxHeatSetpointLimit::Id:
Controller::ReadAttribute<Clusters::Thermostat::Attributes::AbsMaxHeatSetpointLimit::TypeInfo>(
peer_device->GetExchangeManager(), peer_device->GetSecureSession().Value(), binding.remote, onSuccess, onFailure);
break;
case Clusters::Thermostat::Attributes::AbsMinCoolSetpointLimit::Id:
Controller::ReadAttribute<Clusters::Thermostat::Attributes::AbsMinCoolSetpointLimit::TypeInfo>(
peer_device->GetExchangeManager(), peer_device->GetSecureSession().Value(), binding.remote, onSuccess, onFailure);
break;
case Clusters::Thermostat::Attributes::AbsMaxCoolSetpointLimit::Id:
Controller::ReadAttribute<Clusters::Thermostat::Attributes::AbsMaxCoolSetpointLimit::TypeInfo>(
peer_device->GetExchangeManager(), peer_device->GetSecureSession().Value(), binding.remote, onSuccess, onFailure);
break;
case Clusters::Thermostat::Attributes::PICoolingDemand::Id:
Controller::ReadAttribute<Clusters::Thermostat::Attributes::PICoolingDemand::TypeInfo>(
peer_device->GetExchangeManager(), peer_device->GetSecureSession().Value(), binding.remote, onSuccess, onFailure);
break;
case Clusters::Thermostat::Attributes::PIHeatingDemand::Id:
Controller::ReadAttribute<Clusters::Thermostat::Attributes::PIHeatingDemand::TypeInfo>(
peer_device->GetExchangeManager(), peer_device->GetSecureSession().Value(), binding.remote, onSuccess, onFailure);
break;
case Clusters::Thermostat::Attributes::OccupiedCoolingSetpoint::Id:
Controller::ReadAttribute<Clusters::Thermostat::Attributes::OccupiedCoolingSetpoint::TypeInfo>(
peer_device->GetExchangeManager(), peer_device->GetSecureSession().Value(), binding.remote, onSuccess, onFailure);
break;
case Clusters::Thermostat::Attributes::OccupiedHeatingSetpoint::Id:
Controller::ReadAttribute<Clusters::Thermostat::Attributes::OccupiedHeatingSetpoint::TypeInfo>(
peer_device->GetExchangeManager(), peer_device->GetSecureSession().Value(), binding.remote, onSuccess, onFailure);
break;
case Clusters::Thermostat::Attributes::MinHeatSetpointLimit::Id:
Controller::ReadAttribute<Clusters::Thermostat::Attributes::MinHeatSetpointLimit::TypeInfo>(
peer_device->GetExchangeManager(), peer_device->GetSecureSession().Value(), binding.remote, onSuccess, onFailure);
break;
case Clusters::Thermostat::Attributes::MaxHeatSetpointLimit::Id:
Controller::ReadAttribute<Clusters::Thermostat::Attributes::MaxHeatSetpointLimit::TypeInfo>(
peer_device->GetExchangeManager(), peer_device->GetSecureSession().Value(), binding.remote, onSuccess, onFailure);
break;
case Clusters::Thermostat::Attributes::MinCoolSetpointLimit::Id:
Controller::ReadAttribute<Clusters::Thermostat::Attributes::MinCoolSetpointLimit::TypeInfo>(
peer_device->GetExchangeManager(), peer_device->GetSecureSession().Value(), binding.remote, onSuccess, onFailure);
break;
case Clusters::Thermostat::Attributes::MaxCoolSetpointLimit::Id:
Controller::ReadAttribute<Clusters::Thermostat::Attributes::MaxCoolSetpointLimit::TypeInfo>(
peer_device->GetExchangeManager(), peer_device->GetSecureSession().Value(), binding.remote, onSuccess, onFailure);
break;
case Clusters::Thermostat::Attributes::ControlSequenceOfOperation::Id:
Controller::ReadAttribute<Clusters::Thermostat::Attributes::ControlSequenceOfOperation::TypeInfo>(
peer_device->GetExchangeManager(), peer_device->GetSecureSession().Value(), binding.remote, onSuccess, onFailure);
break;
case Clusters::Thermostat::Attributes::SystemMode::Id:
Controller::ReadAttribute<Clusters::Thermostat::Attributes::SystemMode::TypeInfo>(
peer_device->GetExchangeManager(), peer_device->GetSecureSession().Value(), binding.remote, onSuccess, onFailure);
break;
}
}
void ProcessThermostatUnicastBindingCommand(BindingCommandData * data, const EmberBindingTableEntry & binding,
OperationalDeviceProxy * peer_device)
{
auto onSuccess = [](const ConcreteCommandPath & commandPath, const StatusIB & status, const auto & dataResponse) {
ChipLogProgress(NotSpecified, "Thermostat command succeeds");
};
auto onFailure = [](CHIP_ERROR error) {
ChipLogError(NotSpecified, "Thermostat command failed: %" CHIP_ERROR_FORMAT, error.Format());
};
VerifyOrDie(peer_device != nullptr && peer_device->ConnectionReady());
Clusters::Thermostat::Commands::SetpointRaiseLower::Type setpointRaiseLowerCommand;
switch (data->commandId)
{
case Clusters::Thermostat::Commands::SetpointRaiseLower::Id:
setpointRaiseLowerCommand.mode = static_cast<Clusters::Thermostat::SetpointAdjustMode>(data->args[0]);
setpointRaiseLowerCommand.amount = static_cast<int8_t>(data->args[1]);
Controller::InvokeCommandRequest(peer_device->GetExchangeManager(), peer_device->GetSecureSession().Value(), binding.remote,
setpointRaiseLowerCommand, onSuccess, onFailure);
break;
}
}
void ProcessThermostatGroupBindingCommand(BindingCommandData * data, const EmberBindingTableEntry & binding)
{
Messaging::ExchangeManager & exchangeMgr = Server::GetInstance().GetExchangeManager();
Clusters::Thermostat::Commands::SetpointRaiseLower::Type setpointRaiseLowerCommand;
switch (data->commandId)
{
case Clusters::Thermostat::Commands::SetpointRaiseLower::Id:
setpointRaiseLowerCommand.mode = static_cast<Clusters::Thermostat::SetpointAdjustMode>(data->args[0]);
setpointRaiseLowerCommand.amount = static_cast<int8_t>(data->args[1]);
Controller::InvokeGroupCommandRequest(&exchangeMgr, binding.fabricIndex, binding.groupId, setpointRaiseLowerCommand);
break;
}
}
#if CONFIG_ENABLE_CHIP_SHELL
/********************************************************
* Thermostat switch shell functions
*********************************************************/
CHIP_ERROR ThermostatHelpHandler(int argc, char ** argv)
{
sShellSwitchThermostatSubCommands.ForEachCommand(Shell::PrintCommandHelp, nullptr);
return CHIP_NO_ERROR;
}
CHIP_ERROR ThermostatSwitchCommandHandler(int argc, char ** argv)
{
if (argc == 0)
{
return ThermostatHelpHandler(argc, argv);
}
return sShellSwitchThermostatSubCommands.ExecCommand(argc, argv);
}
CHIP_ERROR SetpointRaiseLowerSwitchCommandHandler(int argc, char ** argv)
{
if (argc != 2)
{
return ThermostatHelpHandler(argc, argv);
}
BindingCommandData * data = Platform::New<BindingCommandData>();
data->commandId = Clusters::Thermostat::Commands::SetpointRaiseLower::Id;
data->clusterId = Clusters::Thermostat::Id;
data->args[0] = atoi(argv[0]);
data->args[1] = atoi(argv[1]);
DeviceLayer::PlatformMgr().ScheduleWork(SwitchWorkerFunction, reinterpret_cast<intptr_t>(data));
return CHIP_NO_ERROR;
}
/********************************************************
* Thermostat Read switch shell functions
*********************************************************/
CHIP_ERROR ThermostatReadHelpHandler(int argc, char ** argv)
{
sShellSwitchThermostatReadSubCommands.ForEachCommand(Shell::PrintCommandHelp, nullptr);
return CHIP_NO_ERROR;
}
CHIP_ERROR ThermostatRead(int argc, char ** argv)
{
if (argc == 0)
{
return ThermostatReadHelpHandler(argc, argv);
}
return sShellSwitchThermostatReadSubCommands.ExecCommand(argc, argv);
}
CHIP_ERROR ThermostatReadAttributeList(int argc, char ** argv)
{
BindingCommandData * data = Platform::New<BindingCommandData>();
data->attributeId = Clusters::Thermostat::Attributes::AttributeList::Id;
data->clusterId = Clusters::Thermostat::Id;
data->isReadAttribute = true;
DeviceLayer::PlatformMgr().ScheduleWork(SwitchWorkerFunction, reinterpret_cast<intptr_t>(data));
return CHIP_NO_ERROR;
}
CHIP_ERROR ThermostatReadLocalTemperature(int argc, char ** argv)
{
BindingCommandData * data = Platform::New<BindingCommandData>();
data->attributeId = Clusters::Thermostat::Attributes::LocalTemperature::Id;
data->clusterId = Clusters::Thermostat::Id;
data->isReadAttribute = true;
DeviceLayer::PlatformMgr().ScheduleWork(SwitchWorkerFunction, reinterpret_cast<intptr_t>(data));
return CHIP_NO_ERROR;
}
CHIP_ERROR ThermostatReadAbsMinHeatSetpointLimit(int argc, char ** argv)
{
BindingCommandData * data = Platform::New<BindingCommandData>();
data->attributeId = Clusters::Thermostat::Attributes::AbsMinHeatSetpointLimit::Id;
data->clusterId = Clusters::Thermostat::Id;
data->isReadAttribute = true;
DeviceLayer::PlatformMgr().ScheduleWork(SwitchWorkerFunction, reinterpret_cast<intptr_t>(data));
return CHIP_NO_ERROR;
}
CHIP_ERROR ThermostatReadAbsMaxHeatSetpointLimit(int argc, char ** argv)
{
BindingCommandData * data = Platform::New<BindingCommandData>();
data->attributeId = Clusters::Thermostat::Attributes::AbsMaxHeatSetpointLimit::Id;
data->clusterId = Clusters::Thermostat::Id;
data->isReadAttribute = true;
DeviceLayer::PlatformMgr().ScheduleWork(SwitchWorkerFunction, reinterpret_cast<intptr_t>(data));
return CHIP_NO_ERROR;
}
CHIP_ERROR ThermostatReadAbsMinCoolSetpointLimit(int argc, char ** argv)
{
BindingCommandData * data = Platform::New<BindingCommandData>();
data->attributeId = Clusters::Thermostat::Attributes::AbsMinCoolSetpointLimit::Id;
data->clusterId = Clusters::Thermostat::Id;
data->isReadAttribute = true;
DeviceLayer::PlatformMgr().ScheduleWork(SwitchWorkerFunction, reinterpret_cast<intptr_t>(data));
return CHIP_NO_ERROR;
}
CHIP_ERROR ThermostatReadAbsMaxCoolSetpointLimit(int argc, char ** argv)
{
BindingCommandData * data = Platform::New<BindingCommandData>();
data->attributeId = Clusters::Thermostat::Attributes::AbsMaxCoolSetpointLimit::Id;
data->clusterId = Clusters::Thermostat::Id;
data->isReadAttribute = true;
DeviceLayer::PlatformMgr().ScheduleWork(SwitchWorkerFunction, reinterpret_cast<intptr_t>(data));
return CHIP_NO_ERROR;
}
CHIP_ERROR ThermostatReadPiCoolingDemand(int argc, char ** argv)
{
BindingCommandData * data = Platform::New<BindingCommandData>();
data->attributeId = Clusters::Thermostat::Attributes::PICoolingDemand::Id;
data->clusterId = Clusters::Thermostat::Id;
data->isReadAttribute = true;
DeviceLayer::PlatformMgr().ScheduleWork(SwitchWorkerFunction, reinterpret_cast<intptr_t>(data));
return CHIP_NO_ERROR;
}
CHIP_ERROR ThermostatReadPiHeatingDemand(int argc, char ** argv)
{
BindingCommandData * data = Platform::New<BindingCommandData>();
data->attributeId = Clusters::Thermostat::Attributes::PIHeatingDemand::Id;
data->clusterId = Clusters::Thermostat::Id;
data->isReadAttribute = true;
DeviceLayer::PlatformMgr().ScheduleWork(SwitchWorkerFunction, reinterpret_cast<intptr_t>(data));
return CHIP_NO_ERROR;
}
CHIP_ERROR ThermostatReadOccupiedCoolingSetpoint(int argc, char ** argv)
{
BindingCommandData * data = Platform::New<BindingCommandData>();
data->attributeId = Clusters::Thermostat::Attributes::OccupiedCoolingSetpoint::Id;
data->clusterId = Clusters::Thermostat::Id;
data->isReadAttribute = true;
DeviceLayer::PlatformMgr().ScheduleWork(SwitchWorkerFunction, reinterpret_cast<intptr_t>(data));
return CHIP_NO_ERROR;
}
CHIP_ERROR ThermostatReadOccupiedHeatingSetpoint(int argc, char ** argv)
{
BindingCommandData * data = Platform::New<BindingCommandData>();
data->attributeId = Clusters::Thermostat::Attributes::OccupiedHeatingSetpoint::Id;
data->clusterId = Clusters::Thermostat::Id;
data->isReadAttribute = true;
DeviceLayer::PlatformMgr().ScheduleWork(SwitchWorkerFunction, reinterpret_cast<intptr_t>(data));
return CHIP_NO_ERROR;
}
CHIP_ERROR ThermostatReadMinHeatSetpointLimit(int argc, char ** argv)
{
BindingCommandData * data = Platform::New<BindingCommandData>();
data->attributeId = Clusters::Thermostat::Attributes::MinHeatSetpointLimit::Id;
data->clusterId = Clusters::Thermostat::Id;
data->isReadAttribute = true;
DeviceLayer::PlatformMgr().ScheduleWork(SwitchWorkerFunction, reinterpret_cast<intptr_t>(data));
return CHIP_NO_ERROR;
}
CHIP_ERROR ThermostatReadMaxHeatSetpointLimit(int argc, char ** argv)
{
BindingCommandData * data = Platform::New<BindingCommandData>();
data->attributeId = Clusters::Thermostat::Attributes::MaxHeatSetpointLimit::Id;
data->clusterId = Clusters::Thermostat::Id;
data->isReadAttribute = true;
DeviceLayer::PlatformMgr().ScheduleWork(SwitchWorkerFunction, reinterpret_cast<intptr_t>(data));
return CHIP_NO_ERROR;
}
CHIP_ERROR ThermostatReadMinCoolSetpointLimit(int argc, char ** argv)
{
BindingCommandData * data = Platform::New<BindingCommandData>();
data->attributeId = Clusters::Thermostat::Attributes::MinCoolSetpointLimit::Id;
data->clusterId = Clusters::Thermostat::Id;
data->isReadAttribute = true;
DeviceLayer::PlatformMgr().ScheduleWork(SwitchWorkerFunction, reinterpret_cast<intptr_t>(data));
return CHIP_NO_ERROR;
}
CHIP_ERROR ThermostatReadMaxCoolSetpointLimit(int argc, char ** argv)
{
BindingCommandData * data = Platform::New<BindingCommandData>();
data->attributeId = Clusters::Thermostat::Attributes::MaxCoolSetpointLimit::Id;
data->clusterId = Clusters::Thermostat::Id;
data->isReadAttribute = true;
DeviceLayer::PlatformMgr().ScheduleWork(SwitchWorkerFunction, reinterpret_cast<intptr_t>(data));
return CHIP_NO_ERROR;
}
CHIP_ERROR ThermostatReadControlSequenceOfOperation(int argc, char ** argv)
{
BindingCommandData * data = Platform::New<BindingCommandData>();
data->attributeId = Clusters::Thermostat::Attributes::ControlSequenceOfOperation::Id;
data->clusterId = Clusters::Thermostat::Id;
data->isReadAttribute = true;
DeviceLayer::PlatformMgr().ScheduleWork(SwitchWorkerFunction, reinterpret_cast<intptr_t>(data));
return CHIP_NO_ERROR;
}
CHIP_ERROR ThermostatReadSystemMode(int argc, char ** argv)
{
BindingCommandData * data = Platform::New<BindingCommandData>();
data->attributeId = Clusters::Thermostat::Attributes::SystemMode::Id;
data->clusterId = Clusters::Thermostat::Id;
data->isReadAttribute = true;
DeviceLayer::PlatformMgr().ScheduleWork(SwitchWorkerFunction, reinterpret_cast<intptr_t>(data));
return CHIP_NO_ERROR;
}
/********************************************************
* Groups Thermostat switch shell functions
*********************************************************/
CHIP_ERROR GroupsThermostatHelpHandler(int argc, char ** argv)
{
sShellSwitchGroupsThermostatSubCommands.ForEachCommand(Shell::PrintCommandHelp, nullptr);
return CHIP_NO_ERROR;
}
CHIP_ERROR GroupsThermostatSwitchCommandHandler(int argc, char ** argv)
{
if (argc == 0)
{
return GroupsThermostatHelpHandler(argc, argv);
}
return sShellSwitchGroupsThermostatSubCommands.ExecCommand(argc, argv);
}
CHIP_ERROR GroupsSetpointRaiseLowerSwitchCommandHandler(int argc, char ** argv)
{
BindingCommandData * data = Platform::New<BindingCommandData>();
data->commandId = Clusters::Thermostat::Commands::SetpointRaiseLower::Id;
data->clusterId = Clusters::Thermostat::Id;
data->isGroup = true;
DeviceLayer::PlatformMgr().ScheduleWork(SwitchWorkerFunction, reinterpret_cast<intptr_t>(data));
return CHIP_NO_ERROR;
}
#endif // CONFIG_ENABLE_CHIP_SHELL