Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Making use of the Supervision CC to set the thermostat mode. #2616

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 59 additions & 16 deletions cpp/src/command_classes/ThermostatMode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
//-----------------------------------------------------------------------------

#include "command_classes/CommandClasses.h"
#include "command_classes/Supervision.h"
#include "command_classes/ThermostatMode.h"
#include "Defs.h"
#include "Msg.h"
Expand Down Expand Up @@ -92,7 +93,7 @@ namespace OpenZWave

static char const* c_modeName[] =
{ "Off", "Heat", "Cool", "Auto", "Aux Heat", "Resume", "Fan Only", "Furnace", "Dry Air", "Moist Air", "Auto Changeover", "Heat Econ", "Cool Econ", "Away", "Unknown", "Full Power", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Manufacturer Specific" };


ThermostatMode::ThermostatMode(uint32 const _homeId, uint8 const _nodeId) :
CommandClass(_homeId, _nodeId),
Expand Down Expand Up @@ -323,6 +324,7 @@ namespace OpenZWave
}
}
}

/* at this stage, we don't know the Actual Mode of the Fan, so set it to the lowest
* value... If not, set to 0, which possibly could be invalid...
*/
Expand All @@ -341,29 +343,70 @@ namespace OpenZWave
return false;
}

void ThermostatMode::SupervisionSessionSuccess(uint8 _session_id, uint32 const _instance)
{
if (Node* node = GetNodeUnsafe())
{
uint32 index = node->GetSupervisionIndex(_session_id);

if (index != Internal::CC::Supervision::StaticNoIndex())
{
// We have received the confirmation for the thermostat mode from the Z-Wave device
if (Internal::VC::ValueList* valueList = static_cast<Internal::VC::ValueList*>(GetValue(_instance, ValueID_Index_ThermostatMode::Mode)))
{
valueList->ConfirmNewValue();
if (valueList->GetItem())
{
Log::Write(LogLevel_Info, GetNodeId(), "Confirmed thermostat mode: %s", valueList->GetItem()->m_label.c_str());
m_currentMode = valueList->GetItem()->m_value;
}
else
Log::Write(LogLevel_Warning, GetNodeId(), "Confirmed thermostat mode (No Item)");
valueList->Release();
}
}
else
{
Log::Write(LogLevel_Info, GetNodeId(), "Ignore unknown supervision session %d", _session_id);
}
}
}

//-----------------------------------------------------------------------------
// <ThermostatMode::SetValue>
// Set the device's thermostat mode
//-----------------------------------------------------------------------------
bool ThermostatMode::SetValue(Internal::VC::Value const& _value)
{
if (ValueID::ValueType_List == _value.GetID().GetType())

if (Node* node = GetNodeUnsafe())
{
Internal::VC::ValueList const* value = static_cast<Internal::VC::ValueList const*>(&_value);
if (value->GetItem() == NULL)
return false;
uint8 state = (uint8) value->GetItem()->m_value;
if (ValueID::ValueType_List == _value.GetID().GetType())
{
Internal::VC::ValueList const* value = static_cast<Internal::VC::ValueList const*>(&_value);
if (value->GetItem() == NULL)
return false;
uint8 state = (uint8)value->GetItem()->m_value;

uint8 index = value->GetID().GetIndex() & 0xFF;
uint8 supervision_session_id = node->CreateSupervisionSession(StaticGetCommandClassId(), index);
if (supervision_session_id == Internal::CC::Supervision::StaticNoSessionId())
{
Log::Write(LogLevel_Debug, GetNodeId(), "Supervision not supported, fall back to setpoint set/get");
}

Msg* msg = new Msg("ThermostatModeCmd_Set", GetNodeId(), REQUEST, FUNC_ID_ZW_SEND_DATA, true);
msg->SetInstance(this, _value.GetID().GetInstance());
msg->Append(GetNodeId());
msg->Append(3);
msg->Append(GetCommandClassId());
msg->Append(ThermostatModeCmd_Set);
msg->Append(state);
msg->Append(GetDriver()->GetTransmitOptions());
GetDriver()->SendMsg(msg, Driver::MsgQueue_Send);
return true;
Msg* msg = new Msg("ThermostatModeCmd_Set", GetNodeId(), REQUEST, FUNC_ID_ZW_SEND_DATA, true);
msg->SetInstance(this, _value.GetID().GetInstance());
msg->SetSupervision(supervision_session_id);
msg->Append(GetNodeId());
msg->Append(3);
msg->Append(GetCommandClassId());
msg->Append(ThermostatModeCmd_Set);
msg->Append(state);
msg->Append(GetDriver()->GetTransmitOptions());
GetDriver()->SendMsg(msg, Driver::MsgQueue_Send);
return true;
}
}

return false;
Expand Down
1 change: 1 addition & 0 deletions cpp/src/command_classes/ThermostatMode.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ namespace OpenZWave
{
return 3;
}
virtual void SupervisionSessionSuccess(uint8 _session_id, uint32 const _instance);

protected:
virtual void CreateVars(uint8 const _instance) override;
Expand Down
3 changes: 3 additions & 0 deletions cpp/src/value_classes/ValueList.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,9 @@ namespace OpenZWave
ValueList* tempValue = new ValueList(*this);
tempValue->m_valueIdx = _value;

// Save the new value to be stored when the device confirms the value was set successfully,
m_newValue = _value;

// Set the value in the device.
bool ret = ((Value*) tempValue)->Set();

Expand Down
5 changes: 5 additions & 0 deletions cpp/src/value_classes/ValueList.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@ namespace OpenZWave
bool SetByValue(int32 const _value);

void OnValueRefreshed(int32 const _valueIdx);
void ConfirmNewValue()
{
OnValueRefreshed(m_items[m_newValue].m_value);
};

// From Value
virtual string const GetAsString() const
Expand Down Expand Up @@ -98,6 +102,7 @@ namespace OpenZWave
vector<Item> m_items;
int32 m_valueIdx; // the current index in the m_items vector
int32 m_valueIdxCheck; // the previous index in the m_items vector (used for double-checking spurious value reads)
int32 m_newValue; // a new index to be set on the appropriate device (used by Supervision CC)
uint8 m_size;
int32 m_targetValue; // the Target Value, if the CC support it

Expand Down