update esppilight lib

content of the library is not filtered on 433mhz only
This commit is contained in:
Florian committed 2018-11-28 20:41:37 +01:00
1 parent a275e48ee1
commit 67dd7ac078
1030 files changed
+203335 -116

No files matched your search

@@ -0,0 +1,6 @@
project(openzwave_value_classes)
file(GLOB ${PROJECT_NAME}_sources "${PROJECT_SOURCE_DIR}/*.cpp")
file(GLOB ${PROJECT_NAME}_headers "${PROJECT_SOURCE_DIR}/*.h")
set(${PROJECT_NAME}_files ${${PROJECT_NAME}_sources} ${${PROJECT_NAME}_headers} CACHE INTERNAL "")
@@ -0,0 +1,723 @@
//-----------------------------------------------------------------------------
//
// Value.cpp
//
// Base class for all OpenZWave Value Classes
//
// Copyright (c) 2010 Mal Lansell <openzwave@lansell.org>
//
// SOFTWARE NOTICE AND LICENSE
//
// This file is part of OpenZWave.
//
// OpenZWave is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation, either version 3 of the License,
// or (at your option) any later version.
//
// OpenZWave is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenZWave. If not, see <http://www.gnu.org/licenses/>.
//
//-----------------------------------------------------------------------------
#include "../tinyxml.h"
#include "../Manager.h"
#include "../Driver.h"
#include "../Node.h"
#include "../Notification.h"
#include "../Msg.h"
#include "Value.h"
#include "../platform/Log.h"
#include "../command_classes/CommandClass.h"
#include <ctime>
#include "../Options.h"
using namespace OpenZWave;
static char const* c_genreName[] =
{
"basic",
"user",
"config",
"system",
"invalid"
};
static char const* c_typeName[] =
{
"bool",
"byte",
"decimal",
"int",
"list",
"schedule",
"short",
"string",
"button",
"raw"
};
//-----------------------------------------------------------------------------
// <Value::Value>
// Constructor
//-----------------------------------------------------------------------------
Value::Value
(
uint32 const _homeId,
uint8 const _nodeId,
ValueID::ValueGenre const _genre,
uint8 const _commandClassId,
uint8 const _instance,
uint8 const _index,
ValueID::ValueType const _type,
string const& _label,
string const& _units,
bool const _readOnly,
bool const _writeOnly,
bool const _isSet,
uint8 const _pollIntensity
):
m_min( 0 ),
m_max( 0 ),
m_refreshTime(0),
m_verifyChanges( false ),
m_id( _homeId, _nodeId, _genre, _commandClassId, _instance, _index, _type ),
m_label( _label ),
m_units( _units ),
m_help( "" ),
m_readOnly( _readOnly ),
m_writeOnly( _writeOnly ),
m_isSet( _isSet ),
m_affectsLength( 0 ),
m_affects(),
m_affectsAll( false ),
m_checkChange( false ),
m_pollIntensity( _pollIntensity )
{
}
//-----------------------------------------------------------------------------
// <Value::Value>
// Constructor (from XML)
//-----------------------------------------------------------------------------
Value::Value
(
):
m_min( 0 ),
m_max( 0 ),
m_refreshTime(0),
m_verifyChanges( false ),
m_readOnly( false ),
m_writeOnly( false ),
m_isSet( false ),
m_affectsLength( 0 ),
m_affects(),
m_affectsAll( false ),
m_checkChange( false ),
m_pollIntensity( 0 )
{
}
//-----------------------------------------------------------------------------
// <Value::~Value>
// Destructor
//-----------------------------------------------------------------------------
Value::~Value
(
)
{
if( m_affectsLength > 0 )
{
delete [] m_affects;
}
}
//-----------------------------------------------------------------------------
// <Value::ReadXML>
// Apply settings from XML
//-----------------------------------------------------------------------------
void Value::ReadXML
(
uint32 const _homeId,
uint8 const _nodeId,
uint8 const _commandClassId,
TiXmlElement const* _valueElement
)
{
int intVal;
ValueID::ValueGenre genre = Value::GetGenreEnumFromName( _valueElement->Attribute( "genre" ) );
ValueID::ValueType type = Value::GetTypeEnumFromName( _valueElement->Attribute( "type" ) );
uint8 instance = 1;
if( TIXML_SUCCESS == _valueElement->QueryIntAttribute( "instance", &intVal ) )
{
instance = (uint8)intVal;
}
uint8 index = 0;
if( TIXML_SUCCESS == _valueElement->QueryIntAttribute( "index", &intVal ) )
{
index = (uint8)intVal;
}
m_id = ValueID( _homeId, _nodeId, genre, _commandClassId, instance, index, type );
char const* label = _valueElement->Attribute( "label" );
if( label )
{
m_label = label;
}
char const* units = _valueElement->Attribute( "units" );
if( units )
{
m_units = units;
}
char const* readOnly = _valueElement->Attribute( "read_only" );
if( readOnly )
{
m_readOnly = !strcmp( readOnly, "true" );
}
char const* writeOnly = _valueElement->Attribute( "write_only" );
if( writeOnly )
{
m_writeOnly = !strcmp( writeOnly, "true" );
}
if( TIXML_SUCCESS == _valueElement->QueryIntAttribute( "poll_intensity", &intVal ) )
{
m_pollIntensity = (uint8)intVal;
}
char const* affects = _valueElement->Attribute( "affects" );
if( affects )
{
if ( m_affectsLength != 0 )
{
delete [] m_affects;
}
m_affectsLength = 0;
if( !strcmp( affects, "all" ) )
{
m_affectsAll = true;
}
else
{
size_t len = strlen( affects );
if( len > 0 )
{
for( size_t i = 0; i < len; i++ )
{
if( affects[i] == ',' )
{
m_affectsLength++;
}
else if(affects[i] < '0' || affects[i] > '9')
{
Log::Write( LogLevel_Info, "Improperly formatted affects data: \"%s\"", affects);
break;
}
}
m_affectsLength++;
m_affects = new uint8[m_affectsLength];
unsigned int j = 0;
for( int i = 0; i < m_affectsLength; i++ )
{
m_affects[i] = atoi( &affects[j] );
while( j < len && affects[j] != ',' )
{
j++;
}
j++;
}
}
}
}
char const* verifyChanges = _valueElement->Attribute( "verify_changes" );
if( verifyChanges )
{
m_verifyChanges = !strcmp( verifyChanges, "true" );
}
if( TIXML_SUCCESS == _valueElement->QueryIntAttribute( "min", &intVal ) )
{
m_min = intVal;
}
if( TIXML_SUCCESS == _valueElement->QueryIntAttribute( "max", &intVal ) )
{
m_max = intVal;
}
TiXmlElement const* helpElement = _valueElement->FirstChildElement();
while( helpElement )
{
char const* str = helpElement->Value();
if( str && !strcmp( str, "Help" ) )
{
str = helpElement->GetText();
if( str )
{
m_help = str;
}
break;
}
helpElement = helpElement->NextSiblingElement();
}
}
//-----------------------------------------------------------------------------
// <Value::WriteXML>
// Write ourselves to an XML document
//-----------------------------------------------------------------------------
void Value::WriteXML
(
TiXmlElement* _valueElement
)
{
char str[16];
_valueElement->SetAttribute( "type", GetTypeNameFromEnum(m_id.GetType()) );
_valueElement->SetAttribute( "genre", GetGenreNameFromEnum(m_id.GetGenre()) );
snprintf( str, sizeof(str), "%d", m_id.GetInstance() );
_valueElement->SetAttribute( "instance", str );
snprintf( str, sizeof(str), "%d", m_id.GetIndex() );
_valueElement->SetAttribute( "index", str );
_valueElement->SetAttribute( "label", m_label.c_str() );
_valueElement->SetAttribute( "units", m_units.c_str() );
_valueElement->SetAttribute( "read_only", m_readOnly ? "true" : "false" );
_valueElement->SetAttribute( "write_only", m_writeOnly ? "true" : "false" );
_valueElement->SetAttribute( "verify_changes", m_verifyChanges ? "true" : "false" );
snprintf( str, sizeof(str), "%d", m_pollIntensity );
_valueElement->SetAttribute( "poll_intensity", str );
snprintf( str, sizeof(str), "%d", m_min );
_valueElement->SetAttribute( "min", str );
snprintf( str, sizeof(str), "%d", m_max );
_valueElement->SetAttribute( "max", str );
if( m_affectsAll )
{
_valueElement->SetAttribute( "affects", "all" );
}
else if( m_affectsLength > 0 )
{
string s;
for( int i = 0; i < m_affectsLength; i++ )
{
snprintf( str, sizeof(str), "%d", m_affects[i] );
s = s + str;
if( i + 1 < m_affectsLength )
{
s = s + ",";
}
}
_valueElement->SetAttribute( "affects", s.c_str() );
}
if( m_help.length() > 0 )
{
TiXmlElement* helpElement = new TiXmlElement( "Help" );
_valueElement->LinkEndChild( helpElement );
TiXmlText* textElement = new TiXmlText( m_help.c_str() );
helpElement->LinkEndChild( textElement );
}
}
//-----------------------------------------------------------------------------
// <Value::Set>
// Set a new value in the device
//-----------------------------------------------------------------------------
bool Value::Set
(
)
{
// nothing to do if this is a read-only value (return false to indicate an error)
if( IsReadOnly() )
{
return false;
}
// retrieve the driver, node and commandclass object for this value
bool res = false;
Node* node = NULL;
if( Driver* driver = Manager::Get()->GetDriver( m_id.GetHomeId() ) )
{
node = driver->GetNodeUnsafe( m_id.GetNodeId() );
if( node != NULL )
{
if( CommandClass* cc = node->GetCommandClass( m_id.GetCommandClassId() ) )
{
// flag value as set and queue a "Set Value" message for transmission to the device
res = cc->SetValue( *this );
if( res )
{
if( !IsWriteOnly() )
{
// queue a "RequestValue" message to update the value
cc->RequestValue( 0, m_id.GetIndex(), m_id.GetInstance(), Driver::MsgQueue_Send );
}
else
{
// There is a "bug" here in that write only values
// never send a notification about the value changing.
// For sleeping devices it may not change until the
// device wakes up at some point in the future.
// So when is the right time to change it?
if( m_affectsAll )
{
node->RequestAllConfigParams( 0 );
}
else if( m_affectsLength > 0 )
{
for( int i = 0; i < m_affectsLength; i++ )
{
node->RequestConfigParam( m_affects[i] );
}
}
}
}
}
}
}
return res;
}
//-----------------------------------------------------------------------------
// <Value::OnValueRefreshed>
// A value in a device has been refreshed
//-----------------------------------------------------------------------------
void Value::OnValueRefreshed
(
)
{
if( IsWriteOnly() )
{
return;
}
if( Driver* driver = Manager::Get()->GetDriver( m_id.GetHomeId() ) )
{
m_isSet = true;
bool bSuppress;
Options::Get()->GetOptionAsBool( "SuppressValueRefresh", &bSuppress );
if( !bSuppress )
{
// Notify the watchers
Notification* notification = new Notification( Notification::Type_ValueRefreshed );
notification->SetValueId( m_id );
driver->QueueNotification( notification );
}
}
}
//-----------------------------------------------------------------------------
// <Value::OnValueChanged>
// A value in a device has changed
//-----------------------------------------------------------------------------
void Value::OnValueChanged
(
)
{
if( IsWriteOnly() )
{
return;
}
if( Driver* driver = Manager::Get()->GetDriver( m_id.GetHomeId() ) )
{
m_isSet = true;
// Notify the watchers
Notification* notification = new Notification( Notification::Type_ValueChanged );
notification->SetValueId( m_id );
driver->QueueNotification( notification );
}
/* Call Back to the Command Class that this Value has changed, so we can search the
* TriggerRefreshValue vector to see if we should request any other values to be
* refreshed.
*/
Node* node = NULL;
if( Driver* driver = Manager::Get()->GetDriver( m_id.GetHomeId() ) )
{
node = driver->GetNodeUnsafe( m_id.GetNodeId() );
if( node != NULL )
{
if( CommandClass* cc = node->GetCommandClass( m_id.GetCommandClassId() ) )
{
cc->CheckForRefreshValues(this);
}
}
}
}
//-----------------------------------------------------------------------------
// <Value::GetGenreEnumFromName>
// Static helper to get a genre enum from a string
//-----------------------------------------------------------------------------
ValueID::ValueGenre Value::GetGenreEnumFromName
(
char const* _name
)
{
ValueID::ValueGenre genre = ValueID::ValueGenre_System;
if( _name )
{
for( int i=0; i<(int)ValueID::ValueGenre_Count; ++i )
{
if( !strcmp( _name, c_genreName[i] ) )
{
genre = (ValueID::ValueGenre)i;
break;
}
}
}
return genre;
}
//-----------------------------------------------------------------------------
// <Value::GetGenreNameFromEnum>
// Static helper to get a genre enum as a string
//-----------------------------------------------------------------------------
char const* Value::GetGenreNameFromEnum
(
ValueID::ValueGenre _genre
)
{
return c_genreName[_genre];
}
//-----------------------------------------------------------------------------
// <Value::GetTypeEnumFromName>
// Static helper to get a type enum from a string
//-----------------------------------------------------------------------------
ValueID::ValueType Value::GetTypeEnumFromName
(
char const* _name
)
{
ValueID::ValueType type = ValueID::ValueType_Bool;
if( _name )
{
for( int i=0; i<=(int)ValueID::ValueType_Max; ++i )
{
if( !strcmp( _name, c_typeName[i] ) )
{
type = (ValueID::ValueType)i;
break;
}
}
}
return type;
}
//-----------------------------------------------------------------------------
// <Value::GetTypeNameFromEnum>
// Static helper to get a type enum as a string
//-----------------------------------------------------------------------------
char const* Value::GetTypeNameFromEnum
(
ValueID::ValueType _type
)
{
return c_typeName[_type];
}
//-----------------------------------------------------------------------------
// <Value::VerifyRefreshedValue>
// Check a refreshed value
//-----------------------------------------------------------------------------
int Value::VerifyRefreshedValue
(
void* _originalValue,
void* _checkValue,
void* _newValue,
int _type,
int _length // = 0
)
{
// TODO: this is pretty rough code, but it's reused by each value type. It would be
// better if the actions were taken (m_value = _value, etc.) in this code rather than
// in the calling routine as a result of the return value. In particular, it's messy
// to be setting these values after the refesh or notification is sent. With some
// focus on the actual variable storage, we should be able to accomplish this with
// memory functions. It's really the strings that make things complicated(?).
// if this is the first read of a value, assume it is valid (and notify as a change)
if( !IsSet() )
{
Log::Write( LogLevel_Detail, m_id.GetNodeId(), "Initial read of value" );
Value::OnValueChanged();
return 2; // confirmed change of value
}
else
{
switch( _type )
{
case 1: // string
{
Log::Write( LogLevel_Detail, m_id.GetNodeId(), "Refreshed Value: old value=%s, new value=%s, type=%s", ((string*)_originalValue)->c_str(), ((string*)_newValue)->c_str(), "string" );
break;
}
case 2: // short
{
Log::Write( LogLevel_Detail, m_id.GetNodeId(), "Refreshed Value: old value=%d, new value=%d, type=%s", *((short*)_originalValue), *((short*)_newValue), "short");
break;
}
case 3: // int32
{
Log::Write( LogLevel_Detail, m_id.GetNodeId(), "Refreshed Value: old value=%d, new value=%d, type=%s", *((int32*)_originalValue), *((int32*)_newValue), "int32" );
break;
}
case 4: // uint8
{
Log::Write( LogLevel_Detail, m_id.GetNodeId(), "Refreshed Value: old value=%d, new value=%d, type=%s", *((uint8*)_originalValue), *((uint8*)_newValue), "uint8" );
break;
}
case 5: // bool
{
Log::Write( LogLevel_Detail, m_id.GetNodeId(), "Refreshed Value: old value=%s, new value=%s, type=%s", *((bool*)_originalValue)?"true":"false", *((uint8*)_newValue)?"true":"false", "bool" );
break;
}
case 6: // raw
{
Log::Write( LogLevel_Detail, m_id.GetNodeId(), "Refreshed Value: old value=%x, new value=%x, type=raw", _originalValue, _newValue );
break;
}
default:
{
break;
}
}
}
m_refreshTime = time( NULL ); // update value refresh time
// check whether changes in this value should be verified (since some devices will report values that always
// change, where confirming changes is difficult or impossible)
Log::Write( LogLevel_Detail, m_id.GetNodeId(), "Changes to this value are %sverified", m_verifyChanges ? "" : "not " );
if( !m_verifyChanges )
{
// since we're not checking changes in this value, notify ValueChanged (to be on the safe side)
Value::OnValueChanged();
return 2; // confirmed change of value
}
// see if the value has changed (result is used whether checking change or not)
bool bOriginalEqual = false;
switch( _type )
{
case 1: // string
bOriginalEqual = ( strcmp( ((string*)_originalValue)->c_str(), ((string*)_newValue)->c_str() ) == 0 );
break;
case 2: // short
bOriginalEqual = ( *((short*)_originalValue) == *((short*)_newValue) );
break;
case 3: // int32
bOriginalEqual = ( *((int32*)_originalValue) == *((int32*)_newValue) );
break;
case 4: // uint8
bOriginalEqual = ( *((uint8*)_originalValue) == *((uint8*)_newValue) );
break;
case 5: // bool
bOriginalEqual = ( *((bool*)_originalValue) == *((bool*)_newValue) );
break;
case 6: // raw
bOriginalEqual = ( memcmp( _originalValue, _newValue, _length ) == 0 );
break;
}
// if this is the first refresh of the value, test to see if the value has changed
if( !IsCheckingChange() )
{
if( bOriginalEqual )
{
// values are the same, so signal a refresh and return
Value::OnValueRefreshed();
return 0; // value hasn't changed
}
// values are different, so flag this as a verification refresh and queue it
Log::Write( LogLevel_Info, m_id.GetNodeId(), "Changed value (possible)--rechecking" );
SetCheckingChange( true );
Manager::Get()->RefreshValue( GetID() );
return 1; // value has changed (to be confirmed)
}
else // IsCheckingChange is true if this is the second read of a potentially changed value
{
// if the second read is the same as the first read, the value really changed
bool bCheckEqual = false;
switch( _type )
{
case 1: // string
bCheckEqual = ( strcmp( ((string*)_checkValue)->c_str(), ((string*)_newValue)->c_str() ) == 0 );
break;
case 2: // short
bCheckEqual = ( *((short*)_checkValue) == *((short*)_newValue) );
break;
case 3: // int32
bCheckEqual = ( *((int32*)_checkValue) == *((int32*)_newValue) );
break;
case 4: // uint8
bCheckEqual = ( *((uint8*)_checkValue) == *((uint8*)_newValue) );
break;
case 5: // bool
bCheckEqual = ( *((bool*)_checkValue) == *((bool*)_newValue) );
break;
case 6:
bCheckEqual = ( memcmp( _checkValue, _newValue, _length ) == 0 );
break;
}
if( bCheckEqual )
{
Log::Write( LogLevel_Info, m_id.GetNodeId(), "Changed value--confirmed" );
SetCheckingChange( false );
// update the saved value and send notification
Value::OnValueChanged();
return 2;
}
// if the second read is the same as the original value, the first read is assumed to have been in error
// log this situation, but don't change the value or send a ValueChanged Notification
if( bOriginalEqual )
{
Log::Write( LogLevel_Info, m_id.GetNodeId(), "Spurious value change was noted." );
SetCheckingChange( false );
Value::OnValueRefreshed();
return 0;
}
// the second read is different than both the original value and the checked value...retry
// keep trying until we get the same value twice
Log::Write( LogLevel_Info, m_id.GetNodeId(), "Changed value (changed again)--rechecking" );
SetCheckingChange( true );
// save a temporary copy of value and re-read value from device
Manager::Get()->RefreshValue( GetID() );
return 1;
}
}
@@ -0,0 +1,127 @@
//-----------------------------------------------------------------------------
//
// Value.h
//
// Base class for all OpenZWave Value Classes
//
// Copyright (c) 2010 Mal Lansell <openzwave@lansell.org>
//
// SOFTWARE NOTICE AND LICENSE
//
// This file is part of OpenZWave.
//
// OpenZWave is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation, either version 3 of the License,
// or (at your option) any later version.
//
// OpenZWave is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenZWave. If not, see <http://www.gnu.org/licenses/>.
//
//-----------------------------------------------------------------------------
#ifndef _Value_H
#define _Value_H
#include <string>
#include <sys/time.h>
#include "../Defs.h"
#include "../platform/Ref.h"
#include "ValueID.h"
class TiXmlElement;
namespace OpenZWave
{
class Node;
/** \brief Base class for values associated with a node.
*/
class Value: public Ref
{
friend class Driver;
friend class ValueStore;
public:
Value( uint32 const _homeId, uint8 const _nodeId, ValueID::ValueGenre const _genre, uint8 const _commandClassId, uint8 const _instance, uint8 const _index, ValueID::ValueType const _type, string const& _label, string const& _units, bool const _readOnly, bool const _writeOnly, bool const _isset, uint8 const _pollIntensity );
Value();
virtual void ReadXML( uint32 const _homeId, uint8 const _nodeId, uint8 const _commandClassId, TiXmlElement const* _valueElement );
virtual void WriteXML( TiXmlElement* _valueElement );
ValueID const& GetID()const{ return m_id; }
bool IsReadOnly()const{ return m_readOnly; }
bool IsWriteOnly()const{ return m_writeOnly; }
bool IsSet()const{ return m_isSet; }
bool IsPolled()const{ return m_pollIntensity != 0; }
string const& GetLabel()const{ return m_label; }
void SetLabel( string const& _label ){ m_label = _label; }
string const& GetUnits()const{ return m_units; }
void SetUnits( string const& _units ){ m_units = _units; }
string const& GetHelp()const{ return m_help; }
void SetHelp( string const& _help ){ m_help = _help; }
uint8 const& GetPollIntensity()const{ return m_pollIntensity; }
void SetPollIntensity( uint8 const& _intensity ){ m_pollIntensity = _intensity; }
int32 GetMin()const{ return m_min; }
int32 GetMax()const{ return m_max; }
void SetChangeVerified( bool _verify ){ m_verifyChanges = _verify; }
virtual string const GetAsString() const { return ""; }
virtual bool SetFromString( string const& _value ) { return false; }
bool Set(); // For the user to change a value in a device
// Helpers
static ValueID::ValueGenre GetGenreEnumFromName( char const* _name );
static char const* GetGenreNameFromEnum( ValueID::ValueGenre _genre );
static ValueID::ValueType GetTypeEnumFromName( char const* _name );
static char const* GetTypeNameFromEnum( ValueID::ValueType _type );
protected:
virtual ~Value();
// void SetIsSet() { m_isSet = true; } // TODO: consider removing this...it's never called since m_isSet is set in ValueChanged and ValueRefreshed
bool IsCheckingChange()const{ return m_checkChange; }
void SetCheckingChange( bool _check ) { m_checkChange = _check; }
void OnValueRefreshed(); // A value in a device has been refreshed
void OnValueChanged(); // The refreshed value actually changed
int VerifyRefreshedValue( void* _originalValue, void* _checkValue, void* _newValue, int _type, int _length = 0 );
int32 m_min;
int32 m_max;
time_t m_refreshTime; // time_t identifying when this value was last refreshed
bool m_verifyChanges; // if true, apparent changes are verified; otherwise, they're not
private:
ValueID m_id;
string m_label;
string m_units;
string m_help;
bool m_readOnly;
bool m_writeOnly;
bool m_isSet;
uint8 m_affectsLength;
uint8* m_affects;
bool m_affectsAll;
bool m_checkChange;
uint8 m_pollIntensity;
};
} // namespace OpenZWave
#endif
@@ -0,0 +1,161 @@
//-----------------------------------------------------------------------------
//
// ValueBool.cpp
//
// Represents a boolean value
//
// Copyright (c) 2010 Mal Lansell <openzwave@lansell.org>
//
// SOFTWARE NOTICE AND LICENSE
//
// This file is part of OpenZWave.
//
// OpenZWave is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation, either version 3 of the License,
// or (at your option) any later version.
//
// OpenZWave is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenZWave. If not, see <http://www.gnu.org/licenses/>.
//
//-----------------------------------------------------------------------------
#include "../tinyxml.h"
#include "ValueBool.h"
#include "../Driver.h"
#include "../Node.h"
#include "../platform/Log.h"
#include "../Manager.h"
#include <ctime>
using namespace OpenZWave;
//-----------------------------------------------------------------------------
// <ValueBool::ValueBool>
// Constructor
//-----------------------------------------------------------------------------
ValueBool::ValueBool
(
uint32 const _homeId,
uint8 const _nodeId,
ValueID::ValueGenre const _genre,
uint8 const _commandClassId,
uint8 const _instance,
uint8 const _index,
string const& _label,
string const& _units,
bool const _readOnly,
bool const _writeOnly,
bool const _value,
uint8 const _pollIntensity
):
Value( _homeId, _nodeId, _genre, _commandClassId, _instance, _index, ValueID::ValueType_Bool, _label, _units, _readOnly, _writeOnly, false, _pollIntensity ),
m_value( _value ),
m_valueCheck( false ),
m_newValue( false )
{
}
bool ValueBool::SetFromString
(
string const& _value
)
{
if ( !strcasecmp( "true", _value.c_str() ) ) {
return Set( true );
}
else if ( !strcasecmp( "false", _value.c_str() ) ) {
return Set( false );
}
return false;
}
//-----------------------------------------------------------------------------
// <ValueBool::ReadXML>
// Apply settings from XML
//-----------------------------------------------------------------------------
void ValueBool::ReadXML
(
uint32 const _homeId,
uint8 const _nodeId,
uint8 const _commandClassId,
TiXmlElement const* _valueElement
)
{
Value::ReadXML( _homeId, _nodeId, _commandClassId, _valueElement );
char const* str = _valueElement->Attribute( "value" );
if( str )
{
m_value = !strcmp( str, "True" );
}
else
{
Log::Write( LogLevel_Info, "Missing default boolean value from xml configuration: node %d, class 0x%02x, instance %d, index %d", _nodeId, _commandClassId, GetID().GetInstance(), GetID().GetIndex() );
}
}
//-----------------------------------------------------------------------------
// <ValueBool::WriteXML>
// Write ourselves to an XML document
//-----------------------------------------------------------------------------
void ValueBool::WriteXML
(
TiXmlElement* _valueElement
)
{
Value::WriteXML( _valueElement );
_valueElement->SetAttribute( "value", m_value ? "True" : "False" );
}
//-----------------------------------------------------------------------------
// <ValueBool::Set>
// Set a new value in the device
//-----------------------------------------------------------------------------
bool ValueBool::Set
(
bool const _value
)
{
// create a temporary copy of this value to be submitted to the Set() call and set its value to the function param
ValueBool* tempValue = new ValueBool( *this );
tempValue->m_value = _value;
// Set the value in the device.
bool ret = ((Value*)tempValue)->Set();
// clean up the temporary value
delete tempValue;
return ret;
}
//-----------------------------------------------------------------------------
// <ValueBool::OnValueRefreshed>
// A value in a device has been refreshed
//-----------------------------------------------------------------------------
void ValueBool::OnValueRefreshed
(
bool const _value
)
{
switch( VerifyRefreshedValue( (void*) &m_value, (void*) &m_valueCheck, (void*) &_value, 5) )
{
case 0: // value hasn't changed, nothing to do
break;
case 1: // value has changed (not confirmed yet), save _value in m_valueCheck
m_valueCheck = _value;
break;
case 2: // value has changed (confirmed), save _value in m_value
m_value = _value;
break;
case 3: // all three values are different, so wait for next refresh to try again
break;
}
}
@@ -0,0 +1,74 @@
//-----------------------------------------------------------------------------
//
// ValueBool.h
//
// Represents a boolean value
//
// Copyright (c) 2010 Mal Lansell <openzwave@lansell.org>
//
// SOFTWARE NOTICE AND LICENSE
//
// This file is part of OpenZWave.
//
// OpenZWave is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation, either version 3 of the License,
// or (at your option) any later version.
//
// OpenZWave is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenZWave. If not, see <http://www.gnu.org/licenses/>.
//
//-----------------------------------------------------------------------------
#ifndef _ValueBool_H
#define _ValueBool_H
#include <string>
#include "../Defs.h"
#include "Value.h"
class TiXmlElement;
namespace OpenZWave
{
class Msg;
class Node;
class CommandClass;
/** \brief Boolean value sent to/received from a node.
*/
class ValueBool: public Value
{
public:
ValueBool( uint32 const _homeId, uint8 const _nodeId, ValueID::ValueGenre const _genre, uint8 const _commandClassId, uint8 const _instance, uint8 const _index, string const& _label, string const& _units, bool const _readOnly, bool const _writeOnly, bool const _value, uint8 const _pollIntensity );
ValueBool(){}
virtual ~ValueBool(){}
bool Set( bool const _value );
void OnValueRefreshed( bool const _value );
// From Value
virtual string const GetAsString() const { return ( GetValue() ? "True" : "False" ); }
virtual bool SetFromString( string const& _value );
virtual void ReadXML( uint32 const _homeId, uint8 const _nodeId, uint8 const _commandClassId, TiXmlElement const* _valueElement );
virtual void WriteXML( TiXmlElement* _valueElement );
bool GetValue()const{ return m_value; }
private:
bool m_value; // the current index in the m_items vector
bool m_valueCheck; // the previous value (used for double-checking spurious value reads)
bool m_newValue; // a new value to be set on the appropriate device
};
} // namespace OpenZWave
#endif
@@ -0,0 +1,120 @@
//-----------------------------------------------------------------------------
//
// ValueButton.h
//
// Represents a write-only value that triggers activity in a device
//
// Copyright (c) 2010 Mal Lansell <openzwave@lansell.org>
//
// SOFTWARE NOTICE AND LICENSE
//
// This file is part of OpenZWave.
//
// OpenZWave is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation, either version 3 of the License,
// or (at your option) any later version.
//
// OpenZWave is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenZWave. If not, see <http://www.gnu.org/licenses/>.
//
//-----------------------------------------------------------------------------
#include "../tinyxml.h"
#include "ValueButton.h"
#include "../Manager.h"
#include "../Driver.h"
#include "../Node.h"
#include "../platform/Log.h"
using namespace OpenZWave;
//-----------------------------------------------------------------------------
// <ValueButton::ValueButton>
// Constructor
//-----------------------------------------------------------------------------
ValueButton::ValueButton
(
uint32 const _homeId,
uint8 const _nodeId,
ValueID::ValueGenre const _genre,
uint8 const _commandClassId,
uint8 const _instance,
uint8 const _index,
string const& _label,
uint8 const _pollIntensity
):
Value( _homeId, _nodeId, _genre, _commandClassId, _instance, _index, ValueID::ValueType_Button, _label, "", false, true, true, _pollIntensity ),
m_pressed( false )
{
}
//-----------------------------------------------------------------------------
// <ValueButton::ReadXML>
// Apply settings from XML
//-----------------------------------------------------------------------------
void ValueButton::ReadXML
(
uint32 const _homeId,
uint8 const _nodeId,
uint8 const _commandClassId,
TiXmlElement const* _valueElement
)
{
Value::ReadXML( _homeId, _nodeId, _commandClassId, _valueElement );
}
//-----------------------------------------------------------------------------
// <ValueButton::WriteXML>
// Write ourselves to an XML document
//-----------------------------------------------------------------------------
void ValueButton::WriteXML
(
TiXmlElement* _valueElement
)
{
Value::WriteXML( _valueElement );
}
//-----------------------------------------------------------------------------
// <ValueButton::PressButton>
// Start an activity in a device
//-----------------------------------------------------------------------------
bool ValueButton::PressButton
(
)
{
// Set the value in the device.
m_pressed = true;
return Value::Set();
}
//-----------------------------------------------------------------------------
// <ValueButton::ReleaseButton>
// Stop an activity in a device
//-----------------------------------------------------------------------------
bool ValueButton::ReleaseButton
(
)
{
// Set the value in the device.
m_pressed = false;
bool res = Value::Set();
if( Driver* driver = Manager::Get()->GetDriver( GetID().GetHomeId() ) )
{
if( Node* node = driver->GetNodeUnsafe( GetID().GetNodeId() ) )
{
node->RequestDynamicValues();
}
}
return res;
}
@@ -0,0 +1,70 @@
//-----------------------------------------------------------------------------
//
// ValueButton.h
//
// Represents a write-only value that triggers activity in a device
//
// Copyright (c) 2010 Mal Lansell <openzwave@lansell.org>
//
// SOFTWARE NOTICE AND LICENSE
//
// This file is part of OpenZWave.
//
// OpenZWave is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation, either version 3 of the License,
// or (at your option) any later version.
//
// OpenZWave is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenZWave. If not, see <http://www.gnu.org/licenses/>.
//
//-----------------------------------------------------------------------------
#ifndef _ValueButton_H
#define _ValueButton_H
#include <string>
#include "../Defs.h"
#include "Value.h"
class TiXmlElement;
namespace OpenZWave
{
class Msg;
class Node;
class CommandClass;
/** \brief Button value ???.
*/
class ValueButton: public Value
{
public:
ValueButton( uint32 const _homeId, uint8 const _nodeId, ValueID::ValueGenre const _genre, uint8 const _commandClassId, uint8 const _instance, uint8 const _index, string const& _label, uint8 const _pollIntensity );
ValueButton(): m_pressed( false ){}
virtual ~ValueButton(){}
bool PressButton();
bool ReleaseButton();
// From Value
virtual void ReadXML( uint32 const _homeId, uint8 const _nodeId, uint8 const _commandClassId, TiXmlElement const* _valueElement );
virtual void WriteXML( TiXmlElement* _valueElement );
bool IsPressed()const{ return m_pressed; }
private:
bool m_pressed;
};
} // namespace OpenZWave
#endif
@@ -0,0 +1,186 @@
//-----------------------------------------------------------------------------
//
// ValueByte.cpp
//
// Represents an 8-bit value
//
// Copyright (c) 2010 Mal Lansell <openzwave@lansell.org>
//
// SOFTWARE NOTICE AND LICENSE
//
// This file is part of OpenZWave.
//
// OpenZWave is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation, either version 3 of the License,
// or (at your option) any later version.
//
// OpenZWave is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenZWave. If not, see <http://www.gnu.org/licenses/>.
//
//-----------------------------------------------------------------------------
#include <sstream>
#include "../tinyxml.h"
#include "ValueByte.h"
#include "../Msg.h"
#include "../platform/Log.h"
#include "../Manager.h"
#include <ctime>
using namespace OpenZWave;
//-----------------------------------------------------------------------------
// <ValueByte::ValueByte>
// Constructor
//-----------------------------------------------------------------------------
ValueByte::ValueByte
(
uint32 const _homeId,
uint8 const _nodeId,
ValueID::ValueGenre const _genre,
uint8 const _commandClassId,
uint8 const _instance,
uint8 const _index,
string const& _label,
string const& _units,
bool const _readOnly,
bool const _writeOnly,
uint8 const _value,
uint8 const _pollIntensity
):
Value( _homeId, _nodeId, _genre, _commandClassId, _instance, _index, ValueID::ValueType_Byte, _label, _units, _readOnly, _writeOnly, false, _pollIntensity ),
m_value( _value ),
m_valueCheck( false ),
m_newValue( false )
{
m_min = 0;
m_max = 255;
}
//-----------------------------------------------------------------------------
// <ValueByte::ValueByte>
// Constructor (from XML)
//-----------------------------------------------------------------------------
ValueByte::ValueByte
(
)
{
m_min = 0;
m_max = 255;
}
string const ValueByte::GetAsString
(
) const
{
stringstream ss;
ss << GetValue();
return ss.str();
}
bool ValueByte::SetFromString
(
string const& _value
)
{
uint32 val = (uint32)atoi( _value.c_str() );
if( val < 256 )
{
return Set( (uint8)val );
}
return false;
}
//-----------------------------------------------------------------------------
// <ValueByte::ReadXML>
// Apply settings from XML
//-----------------------------------------------------------------------------
void ValueByte::ReadXML
(
uint32 const _homeId,
uint8 const _nodeId,
uint8 const _commandClassId,
TiXmlElement const* _valueElement
)
{
Value::ReadXML( _homeId, _nodeId, _commandClassId, _valueElement );
int intVal;
if( TIXML_SUCCESS == _valueElement->QueryIntAttribute( "value", &intVal ) )
{
m_value = (uint8)intVal;
}
else
{
Log::Write( LogLevel_Info, "Missing default byte value from xml configuration: node %d, class 0x%02x, instance %d, index %d", _nodeId, _commandClassId, GetID().GetInstance(), GetID().GetIndex() );
}
}
//-----------------------------------------------------------------------------
// <ValueByte::WriteXML>
// Write ourselves to an XML document
//-----------------------------------------------------------------------------
void ValueByte::WriteXML
(
TiXmlElement* _valueElement
)
{
Value::WriteXML( _valueElement );
char str[8];
snprintf( str, sizeof(str), "%d", m_value );
_valueElement->SetAttribute( "value", str );
}
//-----------------------------------------------------------------------------
// <ValueByte::Set>
// Set a new value in the device
//-----------------------------------------------------------------------------
bool ValueByte::Set
(
uint8 const _value
)
{
// create a temporary copy of this value to be submitted to the Set() call and set its value to the function param
ValueByte* tempValue = new ValueByte( *this );
tempValue->m_value = _value;
// Set the value in the device.
bool ret = ((Value*)tempValue)->Set();
// clean up the temporary value
delete tempValue;
return ret;
}
//-----------------------------------------------------------------------------
// <ValueByte::OnValueRefreshed>
// A value in a device has been refreshed
//-----------------------------------------------------------------------------
void ValueByte::OnValueRefreshed
(
uint8 const _value
)
{
switch( VerifyRefreshedValue( (void*) &m_value, (void*) &m_valueCheck, (void*) &_value, 4) )
{
case 0: // value hasn't changed, nothing to do
break;
case 1: // value has changed (not confirmed yet), save _value in m_valueCheck
m_valueCheck = _value;
break;
case 2: // value has changed (confirmed), save _value in m_value
m_value = _value;
break;
case 3: // all three values are different, so wait for next refresh to try again
break;
}
}
@@ -0,0 +1,73 @@
//-----------------------------------------------------------------------------
//
// ValueByte.h
//
// Represents an 8-bit value
//
// Copyright (c) 2010 Mal Lansell <openzwave@lansell.org>
//
// SOFTWARE NOTICE AND LICENSE
//
// This file is part of OpenZWave.
//
// OpenZWave is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation, either version 3 of the License,
// or (at your option) any later version.
//
// OpenZWave is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenZWave. If not, see <http://www.gnu.org/licenses/>.
//
//-----------------------------------------------------------------------------
#ifndef _ValueByte_H
#define _ValueByte_H
#include <string>
#include "../Defs.h"
#include "Value.h"
class TiXmlElement;
namespace OpenZWave
{
class Msg;
class Node;
/** \brief Byte value sent to/received from a node.
*/
class ValueByte: public Value
{
public:
ValueByte( uint32 const _homeId, uint8 const _nodeId, ValueID::ValueGenre const _genre, uint8 const _commandClassId, uint8 const _instance, uint8 const _index, string const& _label, string const& _units, bool const _readOnly, bool const _writeOnly, uint8 const _value, uint8 const _pollIntensity );
ValueByte();
virtual ~ValueByte(){}
bool Set( uint8 const _value );
void OnValueRefreshed( uint8 const _value );
// From Value
virtual string const GetAsString() const;
virtual bool SetFromString( string const& _value );
virtual void ReadXML( uint32 const _homeId, uint8 const _nodeId, uint8 const _commandClassId, TiXmlElement const* _valueElement );
virtual void WriteXML( TiXmlElement* _valueElement );
uint8 GetValue()const{ return m_value; }
private:
uint8 m_value; // the current value
uint8 m_valueCheck; // the previous value (used for double-checking spurious value reads)
uint8 m_newValue; // a new value to be set on the appropriate device
};
} // namespace OpenZWave
#endif
@@ -0,0 +1,147 @@
//-----------------------------------------------------------------------------
//
// ValueDecimal.cpp
//
// Represents a value that may have a fractional component
//
// Copyright (c) 2010 Mal Lansell <openzwave@lansell.org>
//
// SOFTWARE NOTICE AND LICENSE
//
// This file is part of OpenZWave.
//
// OpenZWave is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation, either version 3 of the License,
// or (at your option) any later version.
//
// OpenZWave is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenZWave. If not, see <http://www.gnu.org/licenses/>.
//
//-----------------------------------------------------------------------------
#include "../tinyxml.h"
#include "ValueDecimal.h"
#include "../Msg.h"
#include "../platform/Log.h"
#include "../Manager.h"
#include <ctime>
using namespace OpenZWave;
//-----------------------------------------------------------------------------
// <ValueDecimal::ValueDecimal>
// Constructor
//-----------------------------------------------------------------------------
ValueDecimal::ValueDecimal
(
uint32 const _homeId,
uint8 const _nodeId,
ValueID::ValueGenre const _genre,
uint8 const _commandClassId,
uint8 const _instance,
uint8 const _index,
string const& _label,
string const& _units,
bool const _readOnly,
bool const _writeOnly,
string const& _value,
uint8 const _pollIntensity
):
Value( _homeId, _nodeId, _genre, _commandClassId, _instance, _index, ValueID::ValueType_Decimal, _label, _units, _readOnly, _writeOnly, false, _pollIntensity ),
m_value( _value ),
m_valueCheck( "" ),
m_newValue( "" ),
m_precision( 0 )
{
}
//-----------------------------------------------------------------------------
// <ValueDecimal::ReadXML>
// Apply settings from XML
//-----------------------------------------------------------------------------
void ValueDecimal::ReadXML
(
uint32 const _homeId,
uint8 const _nodeId,
uint8 const _commandClassId,
TiXmlElement const* _valueElement
)
{
Value::ReadXML( _homeId, _nodeId, _commandClassId, _valueElement );
char const* str = _valueElement->Attribute( "value" );
if( str )
{
m_value = str;
}
else
{
Log::Write( LogLevel_Info, "Missing default decimal value from xml configuration: node %d, class 0x%02x, instance %d, index %d", _nodeId, _commandClassId, GetID().GetInstance(), GetID().GetIndex() );
}
}
//-----------------------------------------------------------------------------
// <ValueDecimal::WriteXML>
// Write ourselves to an XML document
//-----------------------------------------------------------------------------
void ValueDecimal::WriteXML
(
TiXmlElement* _valueElement
)
{
Value::WriteXML( _valueElement );
_valueElement->SetAttribute( "value", m_value.c_str() );
}
//-----------------------------------------------------------------------------
// <ValueDecimal::Set>
// Set a new value in the device
//-----------------------------------------------------------------------------
bool ValueDecimal::Set
(
string const& _value
)
{
// create a temporary copy of this value to be submitted to the Set() call and set its value to the function param
ValueDecimal* tempValue = new ValueDecimal( *this );
tempValue->m_value = _value;
// Set the value in the device.
bool ret = ((Value*)tempValue)->Set();
// clean up the temporary value
delete tempValue;
return ret;
}
//-----------------------------------------------------------------------------
// <ValueDecimal::OnValueRefreshed>
// A value in a device has been refreshed
//-----------------------------------------------------------------------------
void ValueDecimal::OnValueRefreshed
(
string const& _value
)
{
switch( VerifyRefreshedValue( (void*) &m_value, (void*) &m_valueCheck, (void*) &_value, 1) )
{
case 0: // value hasn't changed, nothing to do
break;
case 1: // value has changed (not confirmed yet), save _value in m_valueCheck
m_valueCheck = _value;
break;
case 2: // value has changed (confirmed), save _value in m_value
m_value = _value;
break;
case 3: // all three values are different, so wait for next refresh to try again
break;
}
}
@@ -0,0 +1,82 @@
//-----------------------------------------------------------------------------
//
// ValueDecimal.h
//
// Represents a value that may have a fractional component
//
// Copyright (c) 2010 Mal Lansell <openzwave@lansell.org>
//
// SOFTWARE NOTICE AND LICENSE
//
// This file is part of OpenZWave.
//
// OpenZWave is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation, either version 3 of the License,
// or (at your option) any later version.
//
// OpenZWave is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenZWave. If not, see <http://www.gnu.org/licenses/>.
//
//-----------------------------------------------------------------------------
#ifndef _ValueDecimal_H
#define _ValueDecimal_H
#include <string>
#include "../Defs.h"
#include "Value.h"
class TiXmlElement;
namespace OpenZWave
{
class Msg;
class Node;
/** \brief Decimal value sent to/received from a node.
*/
class ValueDecimal: public Value
{
friend class EnergyProduction;
friend class Meter;
friend class SensorMultilevel;
friend class ThermostatSetpoint;
public:
ValueDecimal( uint32 const _homeId, uint8 const _nodeId, ValueID::ValueGenre const _genre, uint8 const _commandClassId, uint8 const _instance, uint8 const _index, string const& _label, string const& _units, bool const _readOnly, bool const _writeOnly, string const& _value, uint8 const _pollIntensity );
ValueDecimal(): m_precision( 0 ){}
virtual ~ValueDecimal(){}
bool Set( string const& _value );
void OnValueRefreshed( string const& _value );
// From Value
virtual string const GetAsString() const { return GetValue(); }
virtual bool SetFromString( string const& _value ) { return Set( _value ); }
virtual void ReadXML( uint32 const _homeId, uint8 const _nodeId, uint8 const _commandClassId, TiXmlElement const* _valueElement );
virtual void WriteXML( TiXmlElement* _valueElement );
string GetValue()const{ return m_value; }
uint8 GetPrecision()const{ return m_precision; }
private:
void SetPrecision( uint8 _precision ){ m_precision = _precision; }
string m_value; // the current value
string m_valueCheck; // the previous value (used for double-checking spurious value reads)
string m_newValue; // a new value to be set on the appropriate device
uint8 m_precision;
};
} // namespace OpenZWave
#endif
@@ -0,0 +1,310 @@
//-----------------------------------------------------------------------------
//
// ValueID.h
//
// Unique identifier for a Value object
//
// Copyright (c) 2010 Mal Lansell <openzwave@lansell.org>
//
// SOFTWARE NOTICE AND LICENSE
//
// This file is part of OpenZWave.
//
// OpenZWave is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation, either version 3 of the License,
// or (at your option) any later version.
//
// OpenZWave is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenZWave. If not, see <http://www.gnu.org/licenses/>.
//
//-----------------------------------------------------------------------------
#ifndef _ValueID_H
#define _ValueID_H
#include <string>
#include <assert.h>
#include "../Defs.h"
class TiXmlElement;
namespace OpenZWave
{
/** \brief Provides a unique ID for a value reported by a Z-Wave device.
*
* The ValueID is used to uniquely identify a value reported by a
* Z-Wave device.
* <p>
* The ID is built by packing various identifying characteristics into a single
* 32-bit number - the Z-Wave driver index, device node ID, the command class and
* command class instance that handles the value, plus an index for the value
* to distinguish it among all the other values managed by that command class
* instance. The type (bool, byte, string etc) of the value is also stored.
* <p>
* The packing of the ID is such that a list of Values sorted by ValueID
* will be in a sensible order for display to the user.
*/
class OPENZWAVE_EXPORT ValueID
{
friend class Manager;
friend class Driver;
friend class Node;
friend class Group;
friend class CommandClass;
friend class Value;
friend class ValueStore;
friend class Notification;
friend class ManufacturerSpecific;
public:
/**
* Value Genres
* The classification of a value to enable low level system or configuration parameters to be filtered by the application.
* \see GetGenre
*/
enum ValueGenre
{
ValueGenre_Basic = 0, /**< The 'level' as controlled by basic commands. Usually duplicated by another command class. */
ValueGenre_User, /**< Basic values an ordinary user would be interested in. */
ValueGenre_Config, /**< Device-specific configuration parameters. These cannot be automatically discovered via Z-Wave, and are usually described in the user manual instead. */
ValueGenre_System, /**< Values of significance only to users who understand the Z-Wave protocol */
ValueGenre_Count /**< A count of the number of genres defined. Not to be used as a genre itself. */
};
/**
* Value Types
* The type of data represented by the value object.
* \see GetType
*/
enum ValueType
{
ValueType_Bool = 0, /**< Boolean, true or false */
ValueType_Byte, /**< 8-bit unsigned value */
ValueType_Decimal, /**< Represents a non-integer value as a string, to avoid floating point accuracy issues. */
ValueType_Int, /**< 32-bit signed value */
ValueType_List, /**< List from which one item can be selected */
ValueType_Schedule, /**< Complex type used with the Climate Control Schedule command class */
ValueType_Short, /**< 16-bit signed value */
ValueType_String, /**< Text string */
ValueType_Button, /**< A write-only value that is the equivalent of pressing a button to send a command to a device */
ValueType_Raw, /**< A collection of bytes */
ValueType_Max = ValueType_Raw /**< The highest-number type defined. Not to be used as a type itself. */
};
/**
* Get the Home ID of the driver that controls the node containing the value.
* \return the Home ID.
*/
uint32 GetHomeId()const{ return m_homeId; }
/**
* Get the Home ID of the driver that controls the node containing the value.
* \return the node id.
*/
uint8 GetNodeId()const{ return( (uint8)( (m_id & 0xff000000) >> 24 ) ); }
/**
* Get the genre of the value. The genre classifies a value to enable
* low-level system or configuration parameters to be filtered out by the application
* \return the value's genre.
* \see ValueGenre
*/
ValueGenre GetGenre()const{ return( (ValueGenre)( (m_id & 0x00c00000) >> 22 ) ); }
/**
* Get the Z-Wave command class that created and manages this value. Knowledge of
* command classes is not required to use OpenZWave, but this information is
* exposed in case it is of interest.
* \return the value's command class.
*/
uint8 GetCommandClassId()const{ return( (uint8)( (m_id & 0x003fc000) >> 14 ) ); }
/**
* Get the command class instance of this value. It is possible for there to be
* multiple instances of a command class, although currently it appears that
* only the SensorMultilevel command class ever does this. Knowledge of
* instances and command classes is not required to use OpenZWave, but this
* information is exposed in case it is of interest.
* \return the instance of the value's command class.
*/
uint8 GetInstance()const{ return( (uint8)( ( (m_id1 & 0xff000000) ) >> 24 ) ); }
/**
* Get the value index. The index is used to identify one of multiple
* values created and managed by a command class. In the case of configurable
* parameters (handled by the configuration command class), the index is the
* same as the parameter ID. Knowledge of command classes is not required
* to use OpenZWave, but this information is exposed in case it is of interest.
* \return the value index within the command class.
*/
uint8 GetIndex()const{ return( (uint8)( (m_id & 0x00000ff0) >> 4 ) ); }
/**
* Get the type of the value. The type describes the data held by the value
* and enables the user to select the correct value accessor method in the
* Manager class.
* \return the value's type.
* \see ValueType, Manager::GetValueAsBool, Manager::GetValueAsByte, Manager::GetValueAsFloat, Manager::GetValueAsInt, Manager::GetValueAsShort, Manager::GetValueAsString, Manager::GetValueListSelection.
*/
ValueType GetType()const{ return( (ValueType)( m_id & 0x0000000f ) ); }
/**
* Get a 64Bit Integer that represents this ValueID. This Integer is not guaranteed to be valid
* across restarts of OpenZWave.
* \return a uint64 integer
*/
uint64 GetId()const{ return (uint64) ( ( (uint64)m_id1 << 32 ) | m_id );}
// Comparison Operators
bool operator == ( ValueID const& _other )const{ return( ( m_homeId == _other.m_homeId ) && ( m_id == _other.m_id ) && ( m_id1 == _other.m_id1 ) ); }
bool operator != ( ValueID const& _other )const{ return( ( m_homeId != _other.m_homeId ) || ( m_id != _other.m_id ) || ( m_id1 != _other.m_id1 ) ); }
bool operator < ( ValueID const& _other )const
{
if( m_homeId == _other.m_homeId )
{
if( m_id == _other.m_id )
{
return( m_id1 < _other.m_id1 );
}
else
{
return( m_id < _other.m_id );
}
}
else
{
return( m_homeId < _other.m_homeId );
}
}
bool operator > ( ValueID const& _other )const
{
if( m_homeId == _other.m_homeId )
{
if( m_id == _other.m_id )
{
return( m_id1 > _other.m_id1 );
}
else
{
return( m_id > _other.m_id );
}
}
else
{
return( m_homeId > _other.m_homeId );
}
}
/**
* Construct a value ID from its component parts.
* This method is public only to allow ValueIDs to be saved and recreated by the application.
* Only ValueIDs that have been reported by OpenZWave notifications should ever be used.
* \param _homeId Home ID of the PC Z-Wave Controller that manages the device.
* \param _nodeId Node ID of the device reporting the value.
* \param _genre classification of the value to enable low level system or configuration parameters to be filtered out.
* \param _commandClassId ID of command class that creates and manages this value.
* \param _instance Instance index of the command class.
* \param _valueIndex Index of the value within all the values created by the command class instance.
* \param _type Type of value (bool, byte, string etc).
* \return The ValueID.
* \see ValueID
*/
ValueID
(
uint32 const _homeId,
uint8 const _nodeId,
ValueGenre const _genre,
uint8 const _commandClassId,
uint8 const _instance,
uint8 const _valueIndex,
ValueType const _type
):
m_homeId( _homeId )
{
m_id = (((uint32)_nodeId)<<24)
| (((uint32)_genre)<<22)
| (((uint32)_commandClassId)<<14)
| (((uint32)_valueIndex)<<4)
| ((uint32)_type);
m_id1 = (((uint32)_instance)<<24);
}
/* construct a ValueID based on the HomeID and the unit64 returned from GetID
* \param _homeId - The HomeID
* \param id - The ID returned from ValueID::GetID
* \see ValueID::GetId
*/
ValueID
(
uint32 _homeId,
uint64 id
):
m_homeId(_homeId)
{
m_id = ((uint32)(id & 0xFFFFFFFF));
m_id1 = (uint32)(id >> 32);
}
private:
// Construct a value id for use in notifications
ValueID( uint32 const _homeId, uint8 const _nodeId ): m_id1( 0 ),m_homeId( _homeId ){ m_id = ((uint32)_nodeId)<<24; }
ValueID( uint32 const _homeId, uint8 const _nodeId, uint32 const _instance ):
m_homeId( _homeId )
{
m_id = (((uint32)_nodeId)<<24);
m_id1 = (((uint32)_instance)<<24);
}
// Default constructor
ValueID():m_id(0),m_id1(0),m_homeId(0){}
// Not all parts of the ValueID are necessary to uniquely identify the value. In the case of a
// Node's ValueStore, we can ignore the home ID, node ID, genre and type and still be left with
// a unique integer than can be used as a key to look up values. The two GetValueStoreKey methods
// below are helpers to enable command classes to easily access their values from the ValueStore.
// Get the key from our own m_id
uint32 GetValueStoreKey()const
{
return ( ( m_id & 0x003ffff0 ) | ( m_id1 & 0xff000000 ) );
}
// Generate a key from its component parts
static uint32 GetValueStoreKey( uint8 const _commandClassId, uint8 const _instance, uint8 const _valueIndex )
{
uint32 key = (((uint32)_instance)<<24)
| (((uint32)_commandClassId)<<14)
| (((uint32)_valueIndex)<<4);
return key;
}
// ID Packing:
// Bits
// 24-31: 8 bits. Node ID of device
// 22-23: 2 bits. genre of value (see ValueGenre enum).
// 14-21: 8 bits. ID of command class that created and manages this value.
// 12-13: 2 bits. Unused.
// 04-11: 8 bits. Index of value within all the value created by the command class
// instance (in configuration parameters, this is also the parameter ID).
// 00-03: 4 bits. Type of value (bool, byte, string etc).
uint32 m_id;
// ID1 Packing:
// Bits
// 24-31 8 bits. Instance Index of the command class.
uint32 m_id1;
// Unique PC interface identifier
uint32 m_homeId;
};
} // namespace OpenZWave
#endif
@@ -0,0 +1,188 @@
//-----------------------------------------------------------------------------
//
// ValueInt.cpp
//
// Represents a 32-bit value
//
// Copyright (c) 2010 Mal Lansell <openzwave@lansell.org>
//
// SOFTWARE NOTICE AND LICENSE
//
// This file is part of OpenZWave.
//
// OpenZWave is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation, either version 3 of the License,
// or (at your option) any later version.
//
// OpenZWave is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenZWave. If not, see <http://www.gnu.org/licenses/>.
//
//-----------------------------------------------------------------------------
#include <sstream>
#include <limits.h>
#include "../tinyxml.h"
#include "ValueInt.h"
#include "../Msg.h"
#include "../platform/Log.h"
#include "../Manager.h"
#include <ctime>
using namespace OpenZWave;
//-----------------------------------------------------------------------------
// <ValueInt::ValueInt>
// Constructor
//-----------------------------------------------------------------------------
ValueInt::ValueInt
(
uint32 const _homeId,
uint8 const _nodeId,
ValueID::ValueGenre const _genre,
uint8 const _commandClassId,
uint8 const _instance,
uint8 const _index,
string const& _label,
string const& _units,
bool const _readOnly,
bool const _writeOnly,
int32 const _value,
uint8 const _pollIntensity
):
Value( _homeId, _nodeId, _genre, _commandClassId, _instance, _index, ValueID::ValueType_Int, _label, _units, _readOnly, _writeOnly, false, _pollIntensity ),
m_value( _value ),
m_valueCheck( 0 ),
m_newValue( 0 )
{
m_min = INT_MIN;
m_max = INT_MAX;
}
//-----------------------------------------------------------------------------
// <ValueInt::ValueInt>
// Constructor (from XML)
//-----------------------------------------------------------------------------
ValueInt::ValueInt
(
):
Value(),
m_value( 0 ),
m_valueCheck( 0 ),
m_newValue( 0 )
{
m_min = INT_MIN;
m_max = INT_MAX;
}
string const ValueInt::GetAsString
(
) const
{
stringstream ss;
ss << GetValue();
return ss.str();
}
bool ValueInt::SetFromString
(
string const& _value
)
{
int32 val = atoi( _value.c_str() );
return Set( val );
}
//-----------------------------------------------------------------------------
// <ValueInt::ReadXML>
// Apply settings from XML
//-----------------------------------------------------------------------------
void ValueInt::ReadXML
(
uint32 const _homeId,
uint8 const _nodeId,
uint8 const _commandClassId,
TiXmlElement const* _valueElement
)
{
Value::ReadXML( _homeId, _nodeId, _commandClassId, _valueElement );
int intVal;
if( TIXML_SUCCESS == _valueElement->QueryIntAttribute( "value", &intVal ) )
{
m_value = (int32)intVal;
}
else
{
Log::Write( LogLevel_Info, "Missing default integer value from xml configuration: node %d, class 0x%02x, instance %d, index %d", _nodeId, _commandClassId, GetID().GetInstance(), GetID().GetIndex() );
}
}
//-----------------------------------------------------------------------------
// <ValueInt::WriteXML>
// Write ourselves to an XML document
//-----------------------------------------------------------------------------
void ValueInt::WriteXML
(
TiXmlElement* _valueElement
)
{
Value::WriteXML( _valueElement );
char str[16];
snprintf( str, sizeof(str), "%d", m_value );
_valueElement->SetAttribute( "value", str );
}
//-----------------------------------------------------------------------------
// <ValueInt::Set>
// Set a new value in the device
//-----------------------------------------------------------------------------
bool ValueInt::Set
(
int32 const _value
)
{
// create a temporary copy of this value to be submitted to the Set() call and set its value to the function param
ValueInt* tempValue = new ValueInt( *this );
tempValue->m_value = _value;
// Set the value in the device.
bool ret = ((Value*)tempValue)->Set();
// clean up the temporary value
delete tempValue;
return ret;
}
//-----------------------------------------------------------------------------
// <ValueInt::OnValueRefreshed>
// A value in a device has been refreshed
//-----------------------------------------------------------------------------
void ValueInt::OnValueRefreshed
(
int32 const _value
)
{
switch( VerifyRefreshedValue( (void*) &m_value, (void*) &m_valueCheck, (void*) &_value, 3) )
{
case 0: // value hasn't changed, nothing to do
break;
case 1: // value has changed (not confirmed yet), save _value in m_valueCheck
m_valueCheck = _value;
break;
case 2: // value has changed (confirmed), save _value in m_value
m_value = _value;
break;
case 3: // all three values are different, so wait for next refresh to try again
break;
}
}
@@ -0,0 +1,70 @@
//-----------------------------------------------------------------------------
//
// ValueInt.h
//
// Represents a 32-bit value
//
// Copyright (c) 2010 Mal Lansell <openzwave@lansell.org>
//
// SOFTWARE NOTICE AND LICENSE
//
// This file is part of OpenZWave.
//
// OpenZWave is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation, either version 3 of the License,
// or (at your option) any later version.
//
// OpenZWave is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenZWave. If not, see <http://www.gnu.org/licenses/>.
//
//-----------------------------------------------------------------------------
#ifndef _ValueInt_H
#define _ValueInt_H
#include <string>
#include "../Defs.h"
#include "Value.h"
class TiXmlElement;
namespace OpenZWave
{
class Msg;
class Node;
/** \brief Integer value sent to/received from a node.
*/
class ValueInt: public Value
{
public:
ValueInt( uint32 const _homeId, uint8 const _nodeId, ValueID::ValueGenre const _genre, uint8 const _commandClassId, uint8 const _instance, uint8 const _index, string const& _label, string const& _units, bool const _readOnly, bool const _writeOnly, int32 const _value, uint8 const _pollIntensity );
ValueInt();
virtual ~ValueInt(){}
bool Set( int32 const _value );
void OnValueRefreshed( int32 const _value );
// From Value
virtual string const GetAsString() const;
virtual bool SetFromString( string const& _value );
virtual void ReadXML( uint32 const _homeId, uint8 const _nodeId, uint8 const _commandClassId, TiXmlElement const* _valueElement );
virtual void WriteXML( TiXmlElement* _valueElement );
int32 GetValue()const{ return m_value; }
private:
int32 m_value; // the current value
int32 m_valueCheck; // the previous value (used for double-checking spurious value reads)
int32 m_newValue; // a new value to be set on the appropriate device
};
} // namespace OpenZWave
#endif
@@ -0,0 +1,358 @@
//-----------------------------------------------------------------------------
//
// ValueList.cpp
//
// Represents a list of items
//
// Copyright (c) 2010 Mal Lansell <openzwave@lansell.org>
//
// SOFTWARE NOTICE AND LICENSE
//
// This file is part of OpenZWave.
//
// OpenZWave is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation, either version 3 of the License,
// or (at your option) any later version.
//
// OpenZWave is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenZWave. If not, see <http://www.gnu.org/licenses/>.
//
//-----------------------------------------------------------------------------
#include "../tinyxml.h"
#include "ValueList.h"
#include "../Msg.h"
#include "../platform/Log.h"
#include "../Manager.h"
#include <ctime>
using namespace OpenZWave;
//-----------------------------------------------------------------------------
// <ValueList::ValueList>
// Constructor
//-----------------------------------------------------------------------------
ValueList::ValueList
(
uint32 const _homeId,
uint8 const _nodeId,
ValueID::ValueGenre const _genre,
uint8 const _commandClassId,
uint8 const _instance,
uint8 const _index,
string const& _label,
string const& _units,
bool const _readOnly,
bool const _writeOnly,
vector<Item> const& _items,
int32 const _valueIdx,
uint8 const _pollIntensity,
uint8 const _size // = 4
):
Value( _homeId, _nodeId, _genre, _commandClassId, _instance, _index, ValueID::ValueType_List, _label, _units, _readOnly, _writeOnly, false, _pollIntensity ),
m_items( _items ),
m_valueIdx( _valueIdx ),
m_valueIdxCheck( 0 ),
m_newValueIdx( 0 ),
m_size( _size )
{
}
//-----------------------------------------------------------------------------
// <ValueList::ValueList>
// Constructor
//-----------------------------------------------------------------------------
ValueList::ValueList
(
):
Value(),
m_items( ),
m_valueIdx(),
m_valueIdxCheck( 0 ),
m_newValueIdx( 0 ),
m_size(0)
{
}
//-----------------------------------------------------------------------------
// <ValueList::ReadXML>
// Apply settings from XML
//-----------------------------------------------------------------------------
void ValueList::ReadXML
(
uint32 const _homeId,
uint8 const _nodeId,
uint8 const _commandClassId,
TiXmlElement const* _valueElement
)
{
Value::ReadXML( _homeId, _nodeId, _commandClassId, _valueElement );
// Get size of values
int intSize;
if ( TIXML_SUCCESS == _valueElement->QueryIntAttribute( "size", &intSize ) )
{
if( intSize == 1 || intSize == 2 || intSize == 4 )
{
m_size = intSize;
}
else
{
Log::Write( LogLevel_Info, "Value size is invalid. Only 1, 2 & 4 supported for node %d, class 0x%02x, instance %d, index %d", _nodeId, _commandClassId, GetID().GetInstance(), GetID().GetIndex() );
}
}
else
{
Log::Write( LogLevel_Info, "Value list size is not set, assuming 4 bytes for node %d, class 0x%02x, instance %d, index %d", _nodeId, _commandClassId, GetID().GetInstance(), GetID().GetIndex() );
}
// Read the items
m_items.clear();
TiXmlElement const* itemElement = _valueElement->FirstChildElement();
while( itemElement )
{
char const* str = itemElement->Value();
if( str && !strcmp( str, "Item" ) )
{
char const* labelStr = itemElement->Attribute( "label" );
int value = 0;
if (itemElement->QueryIntAttribute( "value", &value ) != TIXML_SUCCESS) {
Log::Write( LogLevel_Info, "Item value %s is wrong type or does not exist in xml configuration for node %d, class 0x%02x, instance %d, index %d", labelStr, _nodeId, _commandClassId, GetID().GetInstance(), GetID().GetIndex() );
continue;
}
if(( m_size == 1 && value > 255 ) || ( m_size == 2 && value > 65535) )
{
Log::Write( LogLevel_Info, "Item value %s is incorrect size in xml configuration for node %d, class 0x%02x, instance %d, index %d", labelStr, _nodeId, _commandClassId, GetID().GetInstance(), GetID().GetIndex() );
}
else
{
Item item;
item.m_label = labelStr;
item.m_value = value;
m_items.push_back( item );
}
}
itemElement = itemElement->NextSiblingElement();
}
// Set the value
bool valSet = false;
int intVal;
m_valueIdx = 0;
if ( TIXML_SUCCESS == _valueElement->QueryIntAttribute( "value", &intVal ) )
{
valSet = true;
intVal = GetItemIdxByValue( intVal );
if( intVal != -1 )
{
m_valueIdx = (int32)intVal;
}
else
{
Log::Write( LogLevel_Info, "Value is not found in xml configuration for node %d, class 0x%02x, instance %d, index %d", _nodeId, _commandClassId, GetID().GetInstance(), GetID().GetIndex() );
}
}
// Set the index
bool indSet = false;
int intInd = 0;
if ( TIXML_SUCCESS == _valueElement->QueryIntAttribute( "vindex", &intInd ) )
{
indSet = true;
if( intInd >= 0 && intInd < (int32)m_items.size() )
{
m_valueIdx = (int32)intInd;
}
else
{
Log::Write( LogLevel_Info, "Vindex is out of range for index in xml configuration for node %d, class 0x%02x, instance %d, index %d", _nodeId, _commandClassId, GetID().GetInstance(), GetID().GetIndex() );
}
}
if( !valSet && !indSet )
{
Log::Write( LogLevel_Info, "Missing default list value or vindex from xml configuration: node %d, class 0x%02x, instance %d, index %d", _nodeId, _commandClassId, GetID().GetInstance(), GetID().GetIndex() );
}
}
//-----------------------------------------------------------------------------
// <ValueList::WriteXML>
// Write ourselves to an XML document
//-----------------------------------------------------------------------------
void ValueList::WriteXML
(
TiXmlElement* _valueElement
)
{
Value::WriteXML( _valueElement );
char str[16];
snprintf( str, sizeof(str), "%d", m_valueIdx );
_valueElement->SetAttribute( "vindex", str );
snprintf( str, sizeof(str), "%d", m_size );
_valueElement->SetAttribute( "size", str );
for( vector<Item>::iterator it = m_items.begin(); it != m_items.end(); ++it )
{
TiXmlElement* pItemElement = new TiXmlElement( "Item" );
pItemElement->SetAttribute( "label", (*it).m_label.c_str() );
snprintf( str, sizeof(str), "%d", (*it).m_value );
pItemElement->SetAttribute( "value", str );
_valueElement->LinkEndChild( pItemElement );
}
}
//-----------------------------------------------------------------------------
// <ValueList::SetByValue>
// Set a new value in the device, selected by item index
//-----------------------------------------------------------------------------
bool ValueList::SetByValue
(
int32 const _value
)
{
// create a temporary copy of this value to be submitted to the Set() call and set its value to the function param
ValueList* tempValue = new ValueList( *this );
tempValue->m_valueIdx = _value;
// Set the value in the device.
bool ret = ((Value*)tempValue)->Set();
// clean up the temporary value
delete tempValue;
return ret;
}
//-----------------------------------------------------------------------------
// <ValueList::SetByLabel>
// Set a new value in the device, selected by item label
//-----------------------------------------------------------------------------
bool ValueList::SetByLabel
(
string const& _label
)
{
// Ensure the value is one of the options
int index = GetItemIdxByLabel( _label );
if( index < 0 )
{
// Item not found
return false;
}
return SetByValue( index );
}
//-----------------------------------------------------------------------------
// <ValueList::OnValueRefreshed>
// A value in a device has been refreshed
//-----------------------------------------------------------------------------
void ValueList::OnValueRefreshed
(
int32 const _value
)
{
// Ensure the value is one of the options
int32 index = GetItemIdxByValue( _value );
if( index < 0 )
{
// Item not found
return;
}
switch( VerifyRefreshedValue( (void*) &m_valueIdx, (void*) &m_valueIdxCheck, (void*) &index, 3) )
{
case 0: // value hasn't changed, nothing to do
break;
case 1: // value has changed (not confirmed yet), save _value in m_valueCheck
m_valueIdxCheck = index;
break;
case 2: // value has changed (confirmed), save _value in m_value
m_valueIdx = index;
break;
case 3: // all three values are different, so wait for next refresh to try again
break;
}
}
//-----------------------------------------------------------------------------
// <ValueList::GetItemIdxByLabel>
// Get the index of an item from its label
//-----------------------------------------------------------------------------
int32 const ValueList::GetItemIdxByLabel
(
string const& _label
)
{
for( int32 i=0; i<(int32)m_items.size(); ++i )
{
if( _label == m_items[i].m_label )
{
return i;
}
}
return -1;
}
//-----------------------------------------------------------------------------
// <ValueList::GetItemIdxByValue>
// Get the index of an item from its value
//-----------------------------------------------------------------------------
int32 const ValueList::GetItemIdxByValue
(
int32 const _value
)
{
for( int32 i=0; i<(int32)m_items.size(); ++i )
{
if( _value == m_items[i].m_value )
{
return i;
}
}
return -1;
}
//-----------------------------------------------------------------------------
// <ValueList::GetItemLabels>
// Fill a vector with the item labels
//-----------------------------------------------------------------------------
bool ValueList::GetItemLabels
(
vector<string>* o_items
)
{
if( o_items )
{
for( vector<Item>::iterator it = m_items.begin(); it != m_items.end(); ++it )
{
o_items->push_back( (*it).m_label );
}
return true;
}
return false;
}
@@ -0,0 +1,94 @@
//-----------------------------------------------------------------------------
//
// ValueList.h
//
// Represents a list of items
//
// Copyright (c) 2010 Mal Lansell <openzwave@lansell.org>
//
// SOFTWARE NOTICE AND LICENSE
//
// This file is part of OpenZWave.
//
// OpenZWave is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation, either version 3 of the License,
// or (at your option) any later version.
//
// OpenZWave is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenZWave. If not, see <http://www.gnu.org/licenses/>.
//
//-----------------------------------------------------------------------------
#ifndef _ValueList_H
#define _ValueList_H
#include <string>
#include <vector>
#include "../Defs.h"
#include "Value.h"
class TiXmlElement;
namespace OpenZWave
{
class Msg;
class Node;
/** \brief List of values sent to/received from a node.
*/
class ValueList: public Value
{
public:
/** \brief An item (element) in the list of values.
*/
struct Item
{
string m_label;
int32 m_value;
};
ValueList( uint32 const _homeId, uint8 const _nodeId, ValueID::ValueGenre const _genre, uint8 const _commandClassId, uint8 const _instance, uint8 const _index, string const& _label, string const& _units, bool const _readOnly, bool const _writeOnly, vector<Item> const& _items, int32 const _valueIdx, uint8 const _pollIntensity, uint8 const _size = 4 );
ValueList();
virtual ~ValueList(){}
bool SetByLabel( string const& _label );
bool SetByValue( int32 const _value );
void OnValueRefreshed( int32 const _valueIdx );
// From Value
virtual string const GetAsString() const { return GetItem().m_label; }
virtual bool SetFromString( string const& _value ) { return SetByLabel( _value ); }
virtual void ReadXML( uint32 const _homeId, uint8 const _nodeId, uint8 const _commandClassId, TiXmlElement const* _valueElement );
virtual void WriteXML( TiXmlElement* _valueElement );
Item const& GetItem()const{ return m_items[m_valueIdx]; }
Item const& GetNewItem()const{ return m_items[m_newValueIdx]; }
int32 const GetItemIdxByLabel( string const& _label );
int32 const GetItemIdxByValue( int32 const _value );
bool GetItemLabels( vector<string>* o_items );
uint8 const GetSize()const{ return m_size; }
private:
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_newValueIdx; // a new value to be set on the appropriate device
uint8 m_size;
};
} // namespace OpenZWave
#endif
@@ -0,0 +1,285 @@
//-----------------------------------------------------------------------------
//
// ValueRaw.cpp
//
// Represents a collection of 8-bit values
//
// Copyright (c) 2012 Greg Satz <satz@iranger.com>
//
// SOFTWARE NOTICE AND LICENSE
//
// This file is part of OpenZWave.
//
// OpenZWave is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation, either version 3 of the License,
// or (at your option) any later version.
//
// OpenZWave is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenZWave. If not, see <http://www.gnu.org/licenses/>.
//
//-----------------------------------------------------------------------------
#include "../tinyxml.h"
#include "ValueRaw.h"
#include "../Msg.h"
#include "../platform/Log.h"
#include "../Manager.h"
#include <ctime>
using namespace OpenZWave;
//-----------------------------------------------------------------------------
// <ValueRaw::ValueRaw>
// Constructor
//-----------------------------------------------------------------------------
ValueRaw::ValueRaw
(
uint32 const _homeId,
uint8 const _nodeId,
ValueID::ValueGenre const _genre,
uint8 const _commandClassId,
uint8 const _instance,
uint8 const _index,
string const& _label,
string const& _units,
bool const _readOnly,
bool const _writeOnly,
uint8 const* _value,
uint8 const _length,
uint8 const _pollIntensity
):
Value( _homeId, _nodeId, _genre, _commandClassId, _instance, _index, ValueID::ValueType_Raw, _label, _units, _readOnly, _writeOnly, false, _pollIntensity ),
m_value( NULL ),
m_valueLength( _length ),
m_valueCheck ( NULL ),
m_newValue ( NULL )
{
m_value = new uint8[_length];
memcpy( m_value, _value, _length );
m_min = 0;
m_max = 0;
}
//-----------------------------------------------------------------------------
// <ValueRaw::ValueRaw>
// Constructor (from XML)
//-----------------------------------------------------------------------------
ValueRaw::ValueRaw
(
):
m_value( NULL ),
m_valueCheck ( NULL ),
m_newValue ( NULL )
{
m_valueLength = 0;
m_min = 0;
m_max = 0;
}
//-----------------------------------------------------------------------------
// <ValueRaw::~ValueRaw>
// Destructor
//-----------------------------------------------------------------------------
ValueRaw::~ValueRaw
(
)
{
delete [] m_value;
}
string const ValueRaw::GetAsString
(
) const
{
string str = "";
char bstr[10];
for( uint32 i=0; i<m_valueLength; ++i )
{
if( i )
{
str += " ";
}
snprintf( bstr, sizeof(bstr), "0x%.2x", m_value[i] );
str += bstr;
}
return str;
}
bool ValueRaw::SetFromString
(
string const& _value
)
{
char const* p = _value.c_str();
uint8 index = 0;
uint8* value = new uint8[m_valueLength];
while( 1 )
{
char *ep = NULL;
uint32 val = (uint32)strtol( p, &ep, 16 );
if( p == ep || val >= 256 )
{
break;
}
if( index < m_valueLength )
{
value[index] = (uint8)val;
}
index++;
if( ep != NULL && *ep == '\0' )
{
break;
}
p = ep + 1;
}
bool bRet = false;
if ( index <= m_valueLength )
{
bRet = Set( value, index );
}
delete [] value;
return bRet;
}
//-----------------------------------------------------------------------------
// <ValueRaw::ReadXML>
// Apply settings from XML
//-----------------------------------------------------------------------------
void ValueRaw::ReadXML
(
uint32 const _homeId,
uint8 const _nodeId,
uint8 const _commandClassId,
TiXmlElement const* _valueElement
)
{
Value::ReadXML( _homeId, _nodeId, _commandClassId, _valueElement );
int intVal;
if( TIXML_SUCCESS == _valueElement->QueryIntAttribute( "length", &intVal ) )
{
m_valueLength = (uint8)intVal;
}
m_value = new uint8[m_valueLength];
char const* str = _valueElement->Attribute( "value" );
if( str )
{
uint8 index = 0;
while( 1 )
{
char *ep = NULL;
uint32 val = (uint32)strtol( str, &ep, 16 );
if( str == ep || val >= 256 )
{
break;
}
if( index < m_valueLength )
{
m_value[index] = (uint8)val;
}
index++;
if( ep != NULL && *ep == '\0' )
{
break;
}
str = ep + 1;
}
if( index > m_valueLength )
{
Log::Write( LogLevel_Info, "Data length mismatch for raw data. Got %d but expected %d.", index, m_valueLength );
}
}
else
{
Log::Write( LogLevel_Info, "Missing default raw value from xml configuration: node %d, class 0x%02x, instance %d, index %d", _nodeId, _commandClassId, GetID().GetInstance(), GetID().GetIndex() );
}
}
//-----------------------------------------------------------------------------
// <ValueRaw::WriteXML>
// Write ourselves to an XML document
//-----------------------------------------------------------------------------
void ValueRaw::WriteXML
(
TiXmlElement* _valueElement
)
{
Value::WriteXML( _valueElement );
_valueElement->SetAttribute( "value", GetAsString().c_str() );
char str[8];
snprintf( str, sizeof(str), "%d", GetLength() );
_valueElement->SetAttribute( "length", str );
}
//-----------------------------------------------------------------------------
// <ValueRaw::Set>
// Set a new value in the device
//-----------------------------------------------------------------------------
bool ValueRaw::Set
(
uint8 const* _value,
uint8 const _length
)
{
// create a temporary copy of this value to be submitted to the Set() call and set its value to the function param
ValueRaw* tempValue = new ValueRaw( *this );
tempValue->m_value = new uint8[_length];
memcpy( tempValue->m_value, _value, _length );
tempValue->m_valueLength = _length;
// Set the value in the device.
bool ret = ((Value*)tempValue)->Set();
// clean up the temporary value
delete tempValue;
return ret;
}
//-----------------------------------------------------------------------------
// <ValueRaw::OnValueRefreshed>
// A value in a device has been refreshed
//-----------------------------------------------------------------------------
void ValueRaw::OnValueRefreshed
(
uint8 const* _value,
uint8 const _length
)
{
switch( VerifyRefreshedValue( (void*)m_value, (void*)m_valueCheck, (void*)_value, 6, _length ) )
{
case 0: // value hasn't changed, nothing to do
break;
case 1: // value has changed (not confirmed yet), save _value in m_valueCheck
if( m_valueCheck != NULL )
{
delete [] m_valueCheck;
}
m_valueCheck = new uint8[_length];
memcpy( m_valueCheck, _value, _length );
break;
case 2: // value has changed (confirmed), save _value in m_value
if( m_value != NULL )
{
delete [] m_value;
}
m_value = new uint8[_length];
memcpy( m_value, _value, _length );
break;
case 3: // all three values are different, so wait for next refresh to try again
break;
}
}
@@ -0,0 +1,75 @@
//-----------------------------------------------------------------------------
//
// ValueRaw.h
//
// Represents a collection of 8-bit values
//
// Copyright (c) 2013 Greg Satz <satz@iranger.com>
//
// SOFTWARE NOTICE AND LICENSE
//
// This file is part of OpenZWave.
//
// OpenZWave is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation, either version 3 of the License,
// or (at your option) any later version.
//
// OpenZWave is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenZWave. If not, see <http://www.gnu.org/licenses/>.
//
//-----------------------------------------------------------------------------
#ifndef _ValueRaw_H
#define _ValueRaw_H
#include <string>
#include "../Defs.h"
#include "Value.h"
class TiXmlElement;
namespace OpenZWave
{
class Msg;
class Node;
/** \brief A collection of bytes sent to/received from a node.
*/
class ValueRaw: public Value
{
public:
ValueRaw( uint32 const _homeId, uint8 const _nodeId, ValueID::ValueGenre const _genre, uint8 const _commandClassId, uint8 const _instance, uint8 const _index, string const& _label, string const& _units, bool const _readOnly, bool const _writeOnly, uint8 const* _value, uint8 const _length, uint8 const _pollIntensity );
ValueRaw();
virtual ~ValueRaw();
bool Set( uint8 const* _value, uint8 const _length );
void OnValueRefreshed( uint8 const* _value, uint8 const _length );
// From Value
virtual string const GetAsString() const;
virtual bool SetFromString( string const& _value );
virtual void ReadXML( uint32 const _homeId, uint8 const _nodeId, uint8 const _commandClassId, TiXmlElement const* _valueElement );
virtual void WriteXML( TiXmlElement* _valueElement );
uint8* GetValue()const{ return m_value; }
uint8 GetLength()const{ return m_valueLength; }
private:
uint8* m_value; // the current value
uint8 m_valueLength; // fixed length for this instance
uint8* m_valueCheck; // the previous value (used for double-checking spurious value reads)
uint8* m_newValue; // a new value to be set on the appropriate device
};
} // namespace OpenZWave
#endif
@@ -0,0 +1,351 @@
//-----------------------------------------------------------------------------
//
// ValueSchedule.cpp
//
// A one day schedule for the Climate Control Schedule command class
//
// Copyright (c) 2010 Mal Lansell <openzwave@lansell.org>
//
// SOFTWARE NOTICE AND LICENSE
//
// This file is part of OpenZWave.
//
// OpenZWave is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation, either version 3 of the License,
// or (at your option) any later version.
//
// OpenZWave is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenZWave. If not, see <http://www.gnu.org/licenses/>.
//
//-----------------------------------------------------------------------------
#include <sstream>
#include <limits.h>
#include "../tinyxml.h"
#include "ValueSchedule.h"
#include "../Msg.h"
#include "../platform/Log.h"
using namespace OpenZWave;
//-----------------------------------------------------------------------------
// <ValueSchedule::ValueSchedule>
// Constructor
//-----------------------------------------------------------------------------
ValueSchedule::ValueSchedule
(
uint32 const _homeId,
uint8 const _nodeId,
ValueID::ValueGenre const _genre,
uint8 const _commandClassId,
uint8 const _instance,
uint8 const _index,
string const& _label,
string const& _units,
bool const _readOnly,
bool const _writeOnly,
uint8 const _pollIntensity
):
Value( _homeId, _nodeId, _genre, _commandClassId, _instance, _index, ValueID::ValueType_Byte, _label, _units, _readOnly, _writeOnly, false, _pollIntensity ),
m_numSwitchPoints( 0 )
{
}
//-----------------------------------------------------------------------------
// <ValueSchedule::ValueSchedule>
// Constructor
//-----------------------------------------------------------------------------
ValueSchedule::ValueSchedule
(
):
Value(),
m_numSwitchPoints( 0 )
{
}
//-----------------------------------------------------------------------------
// <ValueSchedule::ReadXML>
// Apply settings from XML
//-----------------------------------------------------------------------------
void ValueSchedule::ReadXML
(
uint32 const _homeId,
uint8 const _nodeId,
uint8 const _commandClassId,
TiXmlElement const* _valueElement
)
{
Value::ReadXML( _homeId, _nodeId, _commandClassId, _valueElement );
// Read in the switch points
TiXmlElement const* child = _valueElement->FirstChildElement();
while( child )
{
char const* str = child->Value();
if( str )
{
if( !strcmp( str, "SwitchPoint" ) )
{
int intVal;
uint8 hours = 0;
if( TIXML_SUCCESS == child->QueryIntAttribute( "hours", &intVal ) )
{
hours = (uint8)intVal;
}
uint8 minutes = 0;
if( TIXML_SUCCESS == child->QueryIntAttribute( "minutes", &intVal ) )
{
minutes = (uint8)intVal;
}
int8 setback = 0;
if( TIXML_SUCCESS == child->QueryIntAttribute( "setback", &intVal ) )
{
setback = (int8)intVal;
}
SetSwitchPoint( hours, minutes, setback );
}
}
child = child->NextSiblingElement();
}
}
//-----------------------------------------------------------------------------
// <ValueSchedule::WriteXML>
// Write ourselves to an XML document
//-----------------------------------------------------------------------------
void ValueSchedule::WriteXML
(
TiXmlElement* _valueElement
)
{
Value::WriteXML( _valueElement );
for( uint8 i=0; i<GetNumSwitchPoints(); ++i )
{
uint8 hours;
uint8 minutes;
int8 setback;
if( GetSwitchPoint( i, &hours, &minutes, &setback ) )
{
char str[8];
TiXmlElement* switchPointElement = new TiXmlElement( "SwitchPoint" );
_valueElement->LinkEndChild( switchPointElement );
snprintf( str, sizeof(str), "%d", hours );
switchPointElement->SetAttribute( "hours", str );
snprintf( str, sizeof(str), "%d", minutes );
switchPointElement->SetAttribute( "minutes", str );
snprintf( str, sizeof(str), "%d", setback );
switchPointElement->SetAttribute( "setback", str );
}
}
}
//-----------------------------------------------------------------------------
// <ValueSchedule::Set>
// Set a new value in the device
//-----------------------------------------------------------------------------
bool ValueSchedule::Set
(
)
{
// Set the value in the device.
// TODO this needs to be checked to make sure it works as intended
return Value::Set();
}
//-----------------------------------------------------------------------------
// <ValueSchedule::OnValueRefreshed>
// A value in a device has been refreshed
//-----------------------------------------------------------------------------
void ValueSchedule::OnValueRefreshed
(
)
{
// TODO: do schedules ever report spurious values and need rechecking like other value types?
// See, for example, ValueShort::OnValueRefreshed
Value::OnValueChanged();
}
//-----------------------------------------------------------------------------
// <ValueSchedule::SetSwitchPoint>
// A value in a device has changed
//-----------------------------------------------------------------------------
bool ValueSchedule::SetSwitchPoint
(
uint8 const _hours, uint8 const _minutes, int8 const _setback
)
{
// Find where to insert this switch point. They must be sorted by ascending time value.
uint8 i;
uint8 insertAt = 0;
for( i=0; i<m_numSwitchPoints; ++i )
{
if( m_switchPoints[i].m_hours == _hours )
{
if( m_switchPoints[i].m_minutes == _minutes )
{
// There is already a switch point with this time, so we
// just update its setback value
m_switchPoints[i].m_setback = _setback;
return true;
}
if( m_switchPoints[i].m_minutes > _minutes )
{
break;
}
}
else if( m_switchPoints[i].m_hours > _hours )
{
break;
}
++insertAt;
}
if( m_numSwitchPoints >= 9 )
{
// The schedule is full
return false;
}
// Shuffle any later switch points out of the way
for( i=m_numSwitchPoints; i>insertAt; --i )
{
m_switchPoints[i].m_hours = m_switchPoints[i-1].m_hours;
m_switchPoints[i].m_minutes = m_switchPoints[i-1].m_minutes;
m_switchPoints[i].m_setback = m_switchPoints[i-1].m_setback;
}
// Insert the new switch point
m_switchPoints[insertAt].m_hours = _hours;
m_switchPoints[insertAt].m_minutes = _minutes;
m_switchPoints[insertAt].m_setback = _setback;
++m_numSwitchPoints;
return true;
}
//-----------------------------------------------------------------------------
// <ValueSchedule::RemoveSwitchPoint>
// A value in a device has changed
//-----------------------------------------------------------------------------
bool ValueSchedule::RemoveSwitchPoint
(
uint8 const _idx
)
{
if( _idx >= m_numSwitchPoints )
{
// _idx is out of range
return false;
}
// Shuffle any later switch points down to fill the gap
for( uint8 i=_idx; i<(m_numSwitchPoints-1); ++i )
{
m_switchPoints[i].m_hours = m_switchPoints[i+1].m_hours;
m_switchPoints[i].m_minutes = m_switchPoints[i+1].m_minutes;
m_switchPoints[i].m_setback = m_switchPoints[i+1].m_setback;
}
--m_numSwitchPoints;
return true;
}
//-----------------------------------------------------------------------------
// <ValueSchedule::GetSwitchPoint>
// Get the values of a switch point
//-----------------------------------------------------------------------------
bool ValueSchedule::GetSwitchPoint
(
uint8 const _idx,
uint8* o_hours,
uint8* o_minutes,
int8* o_setback
)const
{
if( _idx >= m_numSwitchPoints )
{
// _idx is out of range
return false;
}
if( o_hours )
{
*o_hours = m_switchPoints[_idx].m_hours;
}
if( o_minutes )
{
*o_minutes = m_switchPoints[_idx].m_minutes;
}
if( o_setback )
{
*o_setback = m_switchPoints[_idx].m_setback;
}
return true;
}
//-----------------------------------------------------------------------------
// <ValueSchedule::FindSwitchPoint>
// Get the index of the switch point at the specified time
//-----------------------------------------------------------------------------
bool ValueSchedule::FindSwitchPoint
(
uint8 const _hours,
uint8 const _minutes,
uint8* o_idx
)const
{
for( uint8 i=0; i<m_numSwitchPoints; ++i )
{
if( m_switchPoints[i].m_hours == _hours )
{
if( m_switchPoints[i].m_minutes == _minutes )
{
// Found a match
if( o_idx )
{
*o_idx = i;
}
return true;
}
if( m_switchPoints[i].m_minutes > _minutes )
{
// Gone past any possible match
return false;
}
}
else if( m_switchPoints[i].m_hours > _hours )
{
// Gone past any possible match
return false;
}
}
// No match found
return false;
}
@@ -0,0 +1,79 @@
//-----------------------------------------------------------------------------
//
// ValueSchedule.h
//
// A one day schedule for the Climate Control Schedule command class
//
// Copyright (c) 2010 Mal Lansell <openzwave@lansell.org>
//
// SOFTWARE NOTICE AND LICENSE
//
// This file is part of OpenZWave.
//
// OpenZWave is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation, either version 3 of the License,
// or (at your option) any later version.
//
// OpenZWave is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenZWave. If not, see <http://www.gnu.org/licenses/>.
//
//-----------------------------------------------------------------------------
#ifndef _ValueSchedule_H
#define _ValueSchedule_H
#include <string>
#include "../Defs.h"
#include "Value.h"
class TiXmlElement;
namespace OpenZWave
{
class Msg;
class Node;
/** \brief Schedule sent to/received from a node.
*/
class ValueSchedule: public Value
{
public:
ValueSchedule( uint32 const _homeId, uint8 const _nodeId, ValueID::ValueGenre const _genre, uint8 const _commandClassId, uint8 const _instance, uint8 const _index, string const& _label, string const& _units, bool const _readOnly, bool const _writeOnly, uint8 const _pollIntensity );
ValueSchedule();
virtual ~ValueSchedule(){}
bool SetSwitchPoint( uint8 const _hours, uint8 const _minutes, int8 const _setback );
bool RemoveSwitchPoint( uint8 const _idx );
void ClearSwitchPoints(){ m_numSwitchPoints = 0; }
bool GetSwitchPoint( uint8 const _idx, uint8* o_hours, uint8* o_minutes, int8* o_setback )const;
bool FindSwitchPoint( uint8 const _hours, uint8 const _minutes, uint8* o_idx )const;
uint8 GetNumSwitchPoints()const{ return m_numSwitchPoints; }
bool Set();
void OnValueRefreshed();
// From Value
virtual void ReadXML( uint32 const _homeId, uint8 const _nodeId, uint8 const _commandClassId, TiXmlElement const* _valueElement );
virtual void WriteXML( TiXmlElement* _valueElement );
private:
struct SwitchPoint
{
uint8 m_hours;
uint8 m_minutes;
int8 m_setback;
};
SwitchPoint m_switchPoints[9];
uint8 m_numSwitchPoints;
};
} // namespace OpenZWave
#endif
@@ -0,0 +1,191 @@
//-----------------------------------------------------------------------------
//
// ValueShort.cpp
//
// Represents a 16-bit value
//
// Copyright (c) 2010 Mal Lansell <openzwave@lansell.org>
//
// SOFTWARE NOTICE AND LICENSE
//
// This file is part of OpenZWave.
//
// OpenZWave is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation, either version 3 of the License,
// or (at your option) any later version.
//
// OpenZWave is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenZWave. If not, see <http://www.gnu.org/licenses/>.
//
//-----------------------------------------------------------------------------
#include <sstream>
#include <limits.h>
#include "../tinyxml.h"
#include "ValueShort.h"
#include "../Msg.h"
#include "../platform/Log.h"
#include "../Manager.h"
#include <ctime>
using namespace OpenZWave;
//-----------------------------------------------------------------------------
// <ValueShort::ValueShort>
// Constructor
//-----------------------------------------------------------------------------
ValueShort::ValueShort
(
uint32 const _homeId,
uint8 const _nodeId,
ValueID::ValueGenre const _genre,
uint8 const _commandClassId,
uint8 const _instance,
uint8 const _index,
string const& _label,
string const& _units,
bool const _readOnly,
bool const _writeOnly,
int16 const _value,
uint8 const _pollIntensity
):
Value( _homeId, _nodeId, _genre, _commandClassId, _instance, _index, ValueID::ValueType_Byte, _label, _units, _readOnly, _writeOnly, false, _pollIntensity ),
m_value( _value ),
m_valueCheck( 0 ),
m_newValue( 0 )
{
m_min = SHRT_MIN;
m_max = SHRT_MAX;
}
//-----------------------------------------------------------------------------
// <ValueShort::ValueShort>
// Constructor
//-----------------------------------------------------------------------------
ValueShort::ValueShort
(
):
Value(),
m_value( 0 ),
m_valueCheck( 0 ),
m_newValue( 0 )
{
m_min = SHRT_MIN;
m_max = SHRT_MAX;
}
string const ValueShort::GetAsString
(
) const
{
stringstream ss;
ss << GetValue();
return ss.str();
}
bool ValueShort::SetFromString
(
string const& _value
)
{
uint32 val = (uint32)atoi( _value.c_str() );
if( val < 32768 )
{
return Set( (int16)val );
}
return false;
}
//-----------------------------------------------------------------------------
// <ValueShort::ReadXML>
// Apply settings from XML
//-----------------------------------------------------------------------------
void ValueShort::ReadXML
(
uint32 const _homeId,
uint8 const _nodeId,
uint8 const _commandClassId,
TiXmlElement const* _valueElement
)
{
Value::ReadXML( _homeId, _nodeId, _commandClassId, _valueElement );
int intVal;
if( TIXML_SUCCESS == _valueElement->QueryIntAttribute( "value", &intVal ) )
{
m_value = (int16)intVal;
}
else
{
Log::Write( LogLevel_Info, "Missing default short value from xml configuration: node %d, class 0x%02x, instance %d, index %d", _nodeId, _commandClassId, GetID().GetInstance(), GetID().GetIndex() );
}
}
//-----------------------------------------------------------------------------
// <ValueShort::WriteXML>
// Write ourselves to an XML document
//-----------------------------------------------------------------------------
void ValueShort::WriteXML
(
TiXmlElement* _valueElement
)
{
Value::WriteXML( _valueElement );
char str[16];
snprintf( str, sizeof(str), "%d", m_value );
_valueElement->SetAttribute( "value", str );
}
//-----------------------------------------------------------------------------
// <ValueShort::Set>
// Set a new value in the device
//-----------------------------------------------------------------------------
bool ValueShort::Set
(
int16 const _value
)
{
// create a temporary copy of this value to be submitted to the Set() call and set its value to the function param
ValueShort* tempValue = new ValueShort( *this );
tempValue->m_value = _value;
// Set the value in the device.
bool ret = ((Value*)tempValue)->Set();
// clean up the temporary value
delete tempValue;
return ret;
}
//-----------------------------------------------------------------------------
// <ValueShort::OnValueRefreshed>
// A value in a device has been refreshed
//-----------------------------------------------------------------------------
void ValueShort::OnValueRefreshed
(
int16 const _value
)
{
switch( VerifyRefreshedValue( (void*) &m_value, (void*) &m_valueCheck, (void*) &_value, 2) )
{
case 0: // value hasn't changed, nothing to do
break;
case 1: // value has changed (not confirmed yet), save _value in m_valueCheck
m_valueCheck = _value;
break;
case 2: // value has changed (confirmed), save _value in m_value
m_value = _value;
break;
case 3: // all three values are different, so wait for next refresh to try again
break;
}
}
@@ -0,0 +1,70 @@
//-----------------------------------------------------------------------------
//
// ValueShort.h
//
// Represents a 16-bit value
//
// Copyright (c) 2010 Mal Lansell <openzwave@lansell.org>
//
// SOFTWARE NOTICE AND LICENSE
//
// This file is part of OpenZWave.
//
// OpenZWave is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation, either version 3 of the License,
// or (at your option) any later version.
//
// OpenZWave is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenZWave. If not, see <http://www.gnu.org/licenses/>.
//
//-----------------------------------------------------------------------------
#ifndef _ValueShort_H
#define _ValueShort_H
#include <string>
#include "../Defs.h"
#include "Value.h"
class TiXmlElement;
namespace OpenZWave
{
class Msg;
class Node;
/** \brief Short value sent to/received from a node.
*/
class ValueShort: public Value
{
public:
ValueShort( uint32 const _homeId, uint8 const _nodeId, ValueID::ValueGenre const _genre, uint8 const _commandClassId, uint8 const _instance, uint8 const _index, string const& _label, string const& _units, bool const _readOnly, bool const _writeOnly, int16 const _value, uint8 const _pollIntensity );
ValueShort();
virtual ~ValueShort(){}
bool Set( int16 const _value );
void OnValueRefreshed( int16 const _value );
// From Value
virtual string const GetAsString() const;
virtual bool SetFromString( string const& _value );
virtual void ReadXML( uint32 const _homeId, uint8 const _nodeId, uint8 const _commandClassId, TiXmlElement const* _valueElement );
virtual void WriteXML( TiXmlElement* _valueElement );
int16 GetValue()const{ return m_value; }
private:
int16 m_value; // the current value
int16 m_valueCheck; // the previous value (used for double-checking spurious value reads)
int16 m_newValue; // a new value to be set on the appropriate device
};
} // namespace OpenZWave
#endif
@@ -0,0 +1,204 @@
//-----------------------------------------------------------------------------
//
// ValueStore.cpp
//
// Container for Value objects
//
// Copyright (c) 2010 Mal Lansell <openzwave@lansell.org>
//
// SOFTWARE NOTICE AND LICENSE
//
// This file is part of OpenZWave.
//
// OpenZWave is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation, either version 3 of the License,
// or (at your option) any later version.
//
// OpenZWave is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenZWave. If not, see <http://www.gnu.org/licenses/>.
//
//-----------------------------------------------------------------------------
#include "ValueStore.h"
#include "Value.h"
#include "../Manager.h"
#include "../Notification.h"
using namespace OpenZWave;
//-----------------------------------------------------------------------------
// <ValueStore::ValueStore>
// Destructor
//-----------------------------------------------------------------------------
ValueStore::~ValueStore
(
)
{
map<uint32,Value*>::iterator it = m_values.begin();
while( !m_values.empty() )
{
ValueID const& valueId = it->second->GetID();
RemoveValue( valueId.GetValueStoreKey() );
it = m_values.begin();
}
}
//-----------------------------------------------------------------------------
// <ValueStore::AddValue>
// Add a value to the store
//-----------------------------------------------------------------------------
bool ValueStore::AddValue
(
Value* _value
)
{
if( !_value )
{
return false;
}
uint32 key = _value->GetID().GetValueStoreKey();
map<uint32,Value*>::iterator it = m_values.find( key );
if( it != m_values.end() )
{
// There is already a value in the store with this key, so we give up.
return false;
}
m_values[key] = _value;
_value->AddRef();
// Notify the watchers of the new value
if( Driver* driver = Manager::Get()->GetDriver( _value->GetID().GetHomeId() ) )
{
Notification* notification = new Notification( Notification::Type_ValueAdded );
notification->SetValueId( _value->GetID() );
driver->QueueNotification( notification );
}
return true;
}
//-----------------------------------------------------------------------------
// <ValueStore::RemoveValue>
// Remove a value from the store
//-----------------------------------------------------------------------------
bool ValueStore::RemoveValue
(
uint32 const& _key
)
{
map<uint32,Value*>::iterator it = m_values.find( _key );
if( it != m_values.end() )
{
Value* value = it->second;
ValueID const& valueId = value->GetID();
// First notify the watchers
if( Driver* driver = Manager::Get()->GetDriver( valueId.GetHomeId() ) )
{
Notification* notification = new Notification( Notification::Type_ValueRemoved );
notification->SetValueId( valueId );
driver->QueueNotification( notification );
}
// Now release and remove the value from the store
value->Release();
m_values.erase( it );
return true;
}
// Value not found in the store
return false;
}
////-----------------------------------------------------------------------------
//// <ValueStore::RemoveValue>
//// Remove a value from the store
////-----------------------------------------------------------------------------
//bool ValueStore::RemoveValue
//(
// ValueID const& _id
//)
//-----------------------------------------------------------------------------
// <ValueStore::RemoveCommandClassValues>
// Remove all the values associated with a command class from the store
//-----------------------------------------------------------------------------
void ValueStore::RemoveCommandClassValues
(
uint8 const _commandClassId
)
{
map<uint32,Value*>::iterator it = m_values.begin();
while( it != m_values.end() )
{
Value* value = it->second;
ValueID const& valueId = value->GetID();
if( _commandClassId == valueId.GetCommandClassId() )
{
// The value belongs to the specified command class
// First notify the watchers
if( Driver* driver = Manager::Get()->GetDriver( valueId.GetHomeId() ) )
{
Notification* notification = new Notification( Notification::Type_ValueRemoved );
notification->SetValueId( valueId );
driver->QueueNotification( notification );
}
// Now release and remove the value from the store
value->Release();
m_values.erase( it++ );
}
else
{
++it;
}
}
}
//-----------------------------------------------------------------------------
// <ValueStore::GetValue>
// Get a value from the store
//-----------------------------------------------------------------------------
Value* ValueStore::GetValue
(
uint32 const& _key
)const
{
Value* value = NULL;
map<uint32,Value*>::const_iterator it = m_values.find( _key );
if( it != m_values.end() )
{
value = it->second;
if( value )
{
// Add a reference to the value. The caller must
// call Release on the value when they are done with it.
value->AddRef();
}
}
return value;
}
////-----------------------------------------------------------------------------
//// <ValueStore::GetValue>
//// Get a value from the store
////-----------------------------------------------------------------------------
//Value* ValueStore::GetValue
//(
// ValueID const& _id
//)const
@@ -0,0 +1,70 @@
//-----------------------------------------------------------------------------
//
// ValueStore.h
//
// Container for Value objects
//
// Copyright (c) 2010 Mal Lansell <openzwave@lansell.org>
//
// SOFTWARE NOTICE AND LICENSE
//
// This file is part of OpenZWave.
//
// OpenZWave is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation, either version 3 of the License,
// or (at your option) any later version.
//
// OpenZWave is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenZWave. If not, see <http://www.gnu.org/licenses/>.
//
//-----------------------------------------------------------------------------
#ifndef _ValueStore_H
#define _ValueStore_H
#include <map>
#include "../Defs.h"
#include "ValueID.h"
class TiXmlElement;
namespace OpenZWave
{
class Value;
/** \brief Container that holds all of the values associated with a given node.
*/
class ValueStore
{
public:
typedef map<uint32,Value*>::const_iterator Iterator;
Iterator Begin(){ return m_values.begin(); }
Iterator End(){ return m_values.end(); }
ValueStore(){}
~ValueStore();
bool AddValue( Value* _value );
bool RemoveValue( uint32 const& _key );
Value* GetValue( uint32 const& _key )const;
void RemoveCommandClassValues( uint8 const _commandClassId ); // Remove all the values associated with a command class
private:
map<uint32,Value*> m_values;
};
} // namespace OpenZWave
#endif
@@ -0,0 +1,145 @@
//-----------------------------------------------------------------------------
//
// ValueStore.cpp
//
// Represents a string value
//
// Copyright (c) 2010 Mal Lansell <openzwave@lansell.org>
//
// SOFTWARE NOTICE AND LICENSE
//
// This file is part of OpenZWave.
//
// OpenZWave is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation, either version 3 of the License,
// or (at your option) any later version.
//
// OpenZWave is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenZWave. If not, see <http://www.gnu.org/licenses/>.
//
//-----------------------------------------------------------------------------
#include "../tinyxml.h"
#include "ValueString.h"
#include "../Msg.h"
#include "../platform/Log.h"
#include "../Manager.h"
using namespace OpenZWave;
//-----------------------------------------------------------------------------
// <ValueString::ValueString>
// Constructor
//-----------------------------------------------------------------------------
ValueString::ValueString
(
uint32 const _homeId,
uint8 const _nodeId,
ValueID::ValueGenre const _genre,
uint8 const _commandClassId,
uint8 const _instance,
uint8 const _index,
string const& _label,
string const& _units,
bool const _readOnly,
bool const _writeOnly,
string const& _value,
uint8 const _pollIntensity
):
Value( _homeId, _nodeId, _genre, _commandClassId, _instance, _index, ValueID::ValueType_String, _label, _units, _readOnly, _writeOnly, false, _pollIntensity ),
m_value( _value ),
m_valueCheck( "" ),
m_newValue( "" )
{
}
//-----------------------------------------------------------------------------
// <ValueString::ReadXML>
// Apply settings from XML
//-----------------------------------------------------------------------------
void ValueString::ReadXML
(
uint32 const _homeId,
uint8 const _nodeId,
uint8 const _commandClassId,
TiXmlElement const* _valueElement
)
{
Value::ReadXML( _homeId, _nodeId, _commandClassId, _valueElement );
char const* str = _valueElement->Attribute( "value" );
if( str )
{
m_value = str;
}
else
{
Log::Write( LogLevel_Alert, "Missing default string value from xml configuration: node %d, class 0x%02x, instance %d, index %d", _nodeId, _commandClassId, GetID().GetInstance(), GetID().GetIndex() );
}
}
//-----------------------------------------------------------------------------
// <ValueString::WriteXML>
// Write ourselves to an XML document
//-----------------------------------------------------------------------------
void ValueString::WriteXML
(
TiXmlElement* _valueElement
)
{
Value::WriteXML( _valueElement );
_valueElement->SetAttribute( "value", m_value.c_str() );
}
//-----------------------------------------------------------------------------
// <ValueString::Set>
// Set a new value in the device and queue a "RequestValue" to confirm it worked
//-----------------------------------------------------------------------------
bool ValueString::Set
(
string const& _value
)
{
// create a temporary copy of this value to be submitted to the Set() call and set its value to the function param
ValueString* tempValue = new ValueString( *this );
tempValue->m_value = _value;
// Set the value in the device.
bool ret = ((Value*)tempValue)->Set();
// clean up the temporary value
delete tempValue;
return ret;
}
//-----------------------------------------------------------------------------
// <ValueString::OnValueRefreshed>
// A value in a device has been refreshed
//-----------------------------------------------------------------------------
void ValueString::OnValueRefreshed
(
string const& _value
)
{
switch( VerifyRefreshedValue( (void*) &m_value, (void*) &m_valueCheck, (void*) &_value, 1) )
{
case 0: // value hasn't changed, nothing to do
break;
case 1: // value has changed (not confirmed yet), save _value in m_valueCheck
m_valueCheck = _value;
break;
case 2: // value has changed (confirmed), save _value in m_value
m_value = _value;
break;
case 3: // all three values are different, so wait for next refresh to try again
break;
}
}
@@ -0,0 +1,70 @@
//-----------------------------------------------------------------------------
//
// ValueString.h
//
// Represents a string value
//
// Copyright (c) 2010 Mal Lansell <openzwave@lansell.org>
//
// SOFTWARE NOTICE AND LICENSE
//
// This file is part of OpenZWave.
//
// OpenZWave is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation, either version 3 of the License,
// or (at your option) any later version.
//
// OpenZWave is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenZWave. If not, see <http://www.gnu.org/licenses/>.
//
//-----------------------------------------------------------------------------
#ifndef _ValueString_H
#define _ValueString_H
#include <string>
#include "../Defs.h"
#include "Value.h"
class TiXmlElement;
namespace OpenZWave
{
class Msg;
class Node;
/** \brief String value sent to/received from a node.
*/
class ValueString: public Value
{
public:
ValueString( uint32 const _homeId, uint8 const _nodeId, ValueID::ValueGenre const _genre, uint8 const _commandClassId, uint8 const _instance, uint8 const _index, string const& _label, string const& _units, bool const _readOnly, bool const _writeOnly, string const& _value, uint8 const _pollIntensity );
ValueString(){}
virtual ~ValueString(){}
bool Set( string const& _value );
void OnValueRefreshed( string const& _value );
// From Value
virtual string const GetAsString() const { return GetValue(); }
virtual bool SetFromString( string const& _value ) { return Set( _value ); }
virtual void ReadXML( uint32 const _homeId, uint8 const _nodeId, uint8 const _commandClassId, TiXmlElement const* _valueElement );
virtual void WriteXML( TiXmlElement* _valueElement );
string GetValue()const{ return m_value; }
private:
string m_value; // the current value
string m_valueCheck; // the previous value (used for double-checking spurious value reads)
string m_newValue; // a new value to be set on the appropriate device
};
} // namespace OpenZWave
#endif