start work on adding a ValueBitSet - Issue #290

This commit is contained in:
Justin Hammond 2017-06-02 17:36:18 +08:00
parent 0e27e36c35
commit 4ddb3037f0
12 changed files with 393 additions and 23 deletions

View file

@ -129,6 +129,7 @@
<ClInclude Include="..\..\..\src\Scene.h" />
<ClInclude Include="..\..\..\src\Utils.h" />
<ClInclude Include="..\..\..\src\value_classes\Value.h" />
<ClInclude Include="..\..\..\src\value_classes\ValueBitSet.h" />
<ClInclude Include="..\..\..\src\value_classes\ValueBool.h" />
<ClInclude Include="..\..\..\src\value_classes\ValueButton.h" />
<ClInclude Include="..\..\..\src\value_classes\ValueByte.h" />
@ -271,6 +272,7 @@
<ClCompile Include="..\..\..\src\Scene.cpp" />
<ClCompile Include="..\..\..\src\Utils.cpp" />
<ClCompile Include="..\..\..\src\value_classes\Value.cpp" />
<ClCompile Include="..\..\..\src\value_classes\ValueBitSet.cpp" />
<ClCompile Include="..\..\..\src\value_classes\ValueBool.cpp" />
<ClCompile Include="..\..\..\src\value_classes\ValueButton.cpp" />
<ClCompile Include="..\..\..\src\value_classes\ValueByte.cpp" />

View file

@ -313,6 +313,9 @@
<ClInclude Include="..\..\..\src\value_classes\Value.h">
<Filter>Value Classes</Filter>
</ClInclude>
<ClInclude Include="..\..\..\src\value_classes\ValueBitSet.h">
<Filter>Value Classes</Filter>
</ClInclude>
<ClInclude Include="..\..\..\src\value_classes\ValueBool.h">
<Filter>Value Classes</Filter>
</ClInclude>
@ -657,6 +660,9 @@
<ClCompile Include="..\..\..\src\value_classes\Value.cpp">
<Filter>Value Classes</Filter>
</ClCompile>
<ClCompile Include="..\..\..\src\value_classes\ValueBitSet.cpp">
<Filter>Value Classes</Filter>
</ClCompile>
<ClCompile Include="..\..\..\src\value_classes\ValueBool.cpp">
<Filter>Value Classes</Filter>
</ClCompile>

View file

@ -572,6 +572,14 @@
RelativePath="..\..\..\src\value_classes\Value.h"
>
</File>
<File
RelativePath="..\..\..\src\value_classes\ValueBitSet.cpp"
>
</File>
<File
RelativePath="..\..\..\src\value_classes\ValueBitSet.h"
>
</File>
<File
RelativePath="..\..\..\src\value_classes\ValueBool.cpp"
>

View file

@ -263,6 +263,7 @@ exit 0</Command>
<ClInclude Include="..\..\..\tinyxml\tinystr.h" />
<ClInclude Include="..\..\..\tinyxml\tinyxml.h" />
<ClInclude Include="..\..\..\src\value_classes\Value.h" />
<ClInclude Include="..\..\..\src\value_classes\ValueBitSet.h" />
<ClInclude Include="..\..\..\src\value_classes\ValueBool.h" />
<ClInclude Include="..\..\..\src\value_classes\ValueByte.h" />
<ClInclude Include="..\..\..\src\value_classes\ValueDecimal.h" />
@ -380,6 +381,7 @@ exit 0</Command>
<ClCompile Include="..\..\..\tinyxml\tinyxmlerror.cpp" />
<ClCompile Include="..\..\..\tinyxml\tinyxmlparser.cpp" />
<ClCompile Include="..\..\..\src\value_classes\Value.cpp" />
<ClCompile Include="..\..\..\src\value_classes\ValueBitSet.cpp" />
<ClCompile Include="..\..\..\src\value_classes\ValueBool.cpp" />
<ClCompile Include="..\..\..\src\value_classes\ValueByte.cpp" />
<ClCompile Include="..\..\..\src\value_classes\ValueDecimal.cpp" />

View file

@ -192,6 +192,9 @@
<ClInclude Include="..\..\..\src\value_classes\Value.h">
<Filter>Value Classes</Filter>
</ClInclude>
<ClInclude Include="..\..\..\src\value_classes\ValueBitSet.h">
<Filter>Value Classes</Filter>
</ClInclude>
<ClInclude Include="..\..\..\src\value_classes\ValueBool.h">
<Filter>Value Classes</Filter>
</ClInclude>
@ -446,6 +449,9 @@
<ClCompile Include="..\..\..\src\value_classes\Value.cpp">
<Filter>Value Classes</Filter>
</ClCompile>
<ClCompile Include="..\..\..\src\value_classes\ValueBitSet.cpp">
<Filter>Value Classes</Filter>
</ClCompile>
<ClCompile Include="..\..\..\src\value_classes\ValueBool.cpp">
<Filter>Value Classes</Filter>
</ClCompile>

View file

@ -37,18 +37,15 @@ using namespace OpenZWave;
Bitfield::Bitfield() :
m_numSetBits(0),
m_value(0),
m_size(0)
m_value(0)
{
}
Bitfield::Bitfield(uint32 value, uint8 size) :
Bitfield::Bitfield(uint32 value) :
m_numSetBits(0),
m_value(value),
m_size(size)
m_value(value)
{
/* convert the value into the bitset */
for (int i = 0; i < 8 * size; i++) {
for (int i = 0; i < 8 * sizeof(uint32); i++) {
if (m_value & (1 << i)) {
Set(i);
}
@ -59,8 +56,22 @@ Bitfield::~Bitfield()
}
void Bitfield::Set( uint32 _idx )
bool Bitfield::SetValue(uint32 val) {
for (int i = 0; i < 8 * sizeof(uint32); i++) {
if (m_value & (1 << i)) {
Set(i);
}
}
return true;
}
bool Bitfield::Set( uint8 _idx )
{
if (_idx > 0x1F) {
return false;
}
if( !IsSet(_idx) )
{
uint32 newSize = (_idx>>5)+1;
@ -71,19 +82,27 @@ void Bitfield::Set( uint32 _idx )
m_bits[_idx>>5] |= (1<<(_idx&0x1f));
++m_numSetBits;
}
return true;
}
void Bitfield::Clear( uint32 _idx )
bool Bitfield::Clear( uint8 _idx )
{
if (_idx > 0x1F) {
return false;
}
if( IsSet(_idx) )
{
m_bits[_idx>>5] &= ~(1<<(_idx&0x1f));
--m_numSetBits;
}
return true;
}
bool Bitfield::IsSet( uint32 _idx )const
bool Bitfield::IsSet( uint8 _idx )const
{
if (_idx > 0x1F) {
return false;
}
if( (_idx>>5) < m_bits.size() )
{
return( ( m_bits[_idx>>5] & (1<<(_idx&0x1f)) ) !=0 );
@ -100,14 +119,14 @@ uint32 Bitfield::GetValue() const
{
uint32 value = 0;
for (unsigned int i = 0; i < m_bits.size(); i++) {
//value =
value += ( m_bits[i] << (8*i) );
}
return value;
}
uint32 Bitfield::GetSize() const
{
return m_size;
return m_bits.size() * sizeof(uint32) * 8;
}
Bitfield::Iterator Bitfield::Begin() const

View file

@ -39,13 +39,14 @@ class OPENZWAVE_EXPORT Bitfield
public:
Bitfield();
Bitfield(uint32 value, uint8 size);
Bitfield(uint32 value);
~Bitfield();
void Set( uint32 _idx );
void Clear( uint32 _idx );
bool IsSet( uint32 _idx ) const;
bool Set( uint8 _idx );
bool Clear( uint8 _idx );
bool IsSet( uint8 _idx ) const;
uint32 GetNumSetBits() const;
uint32 GetValue() const;
bool SetValue(uint32 val);
uint32 GetSize() const;
class Iterator
{
@ -76,7 +77,6 @@ private:
OPENZWAVE_EXPORT_WARNINGS_ON
uint32 m_numSetBits;
uint32 m_value;
uint8 m_size;
};
} // namespace OpenZWave

View file

@ -48,6 +48,7 @@
#include "command_classes/WakeUp.h"
#include "value_classes/ValueID.h"
#include "value_classes/ValueBitSet.h"
#include "value_classes/ValueBool.h"
#include "value_classes/ValueButton.h"
#include "value_classes/ValueByte.h"
@ -58,6 +59,7 @@
#include "value_classes/ValueSchedule.h"
#include "value_classes/ValueShort.h"
#include "value_classes/ValueString.h"
#include "value_classes/ValueBitSet.h"
using namespace OpenZWave;
@ -2289,15 +2291,19 @@ bool Manager::GetValueAsString
}
break;
}
#if 0
/* comment this out so if we miss a ValueID, GCC warns us loudly! */
default:
case ValueID::ValueType_BitSet:
{
// To keep GCC happy
if( ValueBitSet* value = static_cast<ValueBitSet*>( driver->GetValue( _id ) ) )
{
*o_value = value->GetAsString();
value->Release();
res = true;
} else {
OZW_ERROR(OZWException::OZWEXCEPTION_INVALID_VALUEID, "Invalid ValueID passed to GetValueAsString");
}
break;
}
#endif
}
}
@ -2897,6 +2903,18 @@ bool Manager::SetValue
OZW_ERROR(OZWException::OZWEXCEPTION_CANNOT_CONVERT_VALUEID, "ValueID passed to GetValueFloatPrecision is not a Decimal Value");
break;
}
case ValueID::ValueType_BitSet:
{
if( ValueBitSet* value = static_cast<ValueBitSet*>( driver->GetValue( _id ) ) )
{
res = value->SetFromString( _value );
value->Release();
} else {
OZW_ERROR(OZWException::OZWEXCEPTION_INVALID_VALUEID, "Invalid ValueID passed to SetValue");
}
break;
}
}
}
}

View file

@ -31,6 +31,7 @@
#include "Node.h"
#include "Notification.h"
#include "Msg.h"
#include "Bitfield.h"
#include "value_classes/Value.h"
#include "platform/Log.h"
#include "command_classes/CommandClass.h"
@ -60,6 +61,7 @@ static char const* c_typeName[] =
"string",
"button",
"raw",
"bitset",
"invalid type"
};
@ -609,6 +611,7 @@ int Value::VerifyRefreshedValue
}
case ValueID::ValueType_List: // List Type is treated as a int32
case ValueID::ValueType_Int: // int32
case ValueID::ValueType_BitSet: // BitSet
{
Log::Write( LogLevel_Detail, m_id.GetNodeId(), "Refreshed Value: old value=%d, new value=%d, type=%s", *((int32*)_originalValue), *((int32*)_newValue), GetTypeNameFromEnum(_type) );
break;
@ -668,6 +671,9 @@ int Value::VerifyRefreshedValue
case ValueID::ValueType_Schedule: // Schedule
/* Should not get here */
break;
case ValueID::ValueType_BitSet: // BitSet
bOriginalEqual = ( ((Bitfield *)_originalValue)->GetValue() == ((Bitfield *)_newValue)->GetValue() );
break;
}
// if this is the first refresh of the value, test to see if the value has changed
@ -716,6 +722,9 @@ int Value::VerifyRefreshedValue
case ValueID::ValueType_Schedule:
/* Should not get here */
break;
case ValueID::ValueType_BitSet: // BitSet
bCheckEqual = ( ((Bitfield *)_checkValue)->GetValue() == ((Bitfield *)_newValue)->GetValue() );;
break;
}
if( bCheckEqual )
{

View file

@ -0,0 +1,220 @@
//-----------------------------------------------------------------------------
//
// ValueBitSet.cpp
//
// Represents a boolean value
//
// Copyright (c) 2017 Justin Hammond <justin@dynam.ac>
//
// 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 "value_classes/ValueBitSet.h"
#include "Driver.h"
#include "Node.h"
#include "platform/Log.h"
#include "Manager.h"
#include <ctime>
using namespace OpenZWave;
//-----------------------------------------------------------------------------
// <ValueBitSet::ValueBitSet>
// Constructor
//-----------------------------------------------------------------------------
ValueBitSet::ValueBitSet
(
uint32 const _homeId,
uint8 const _nodeId,
ValueID::ValueGenre const _genre,
uint8 const _commandClassId,
uint8 const _instance,
uint16 const _index,
string const& _label,
string const& _units,
bool const _readOnly,
bool const _writeOnly,
uint32 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 ValueBitSet::SetFromString
(
string const& _value
)
{
int32 val = atoi( _value.c_str() );
return Set( val );
return false;
}
string const ValueBitSet::GetAsString
(
) const
{
stringstream ss;
ss << GetValue();
return ss.str();
}
uint32 ValueBitSet::GetValue
(
) const
{
return m_value.GetValue();
}
bool ValueBitSet::GetBit
(
uint8 _idx
) const
{
return m_value.IsSet(_idx);
}
//-----------------------------------------------------------------------------
// <ValueBitSet::ReadXML>
// Apply settings from XML
//-----------------------------------------------------------------------------
void ValueBitSet::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.SetValue((uint32)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() );
}
}
//-----------------------------------------------------------------------------
// <ValueBitSet::WriteXML>
// Write ourselves to an XML document
//-----------------------------------------------------------------------------
void ValueBitSet::WriteXML
(
TiXmlElement* _valueElement
)
{
Value::WriteXML( _valueElement );
char str[16];
snprintf( str, sizeof(str), "%d", m_value.GetValue() );
_valueElement->SetAttribute( "value", str );
}
//-----------------------------------------------------------------------------
// <ValueBitSet::Set>
// Set a new value in the device
//-----------------------------------------------------------------------------
bool ValueBitSet::Set
(
uint32 const _value
)
{
// create a temporary copy of this value to be submitted to the Set() call and set its value to the function param
ValueBitSet* tempValue = new ValueBitSet( *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;
}
bool ValueBitSet::SetBit
(
uint8 const _idx
)
{
// create a temporary copy of this value to be submitted to the Set() call and set its value to the function param
ValueBitSet* tempValue = new ValueBitSet( *this );
tempValue->m_value.Set(_idx);
// Set the value in the device.
bool ret = ((Value*)tempValue)->Set();
// clean up the temporary value
delete tempValue;
return ret;
}
bool ValueBitSet::ClearBit
(
uint8 const _idx
)
{
// create a temporary copy of this value to be submitted to the Set() call and set its value to the function param
ValueBitSet* tempValue = new ValueBitSet( *this );
tempValue->m_value.Clear(_idx);
// Set the value in the device.
bool ret = ((Value*)tempValue)->Set();
// clean up the temporary value
delete tempValue;
return ret;
}
//-----------------------------------------------------------------------------
// <ValueBitSet::OnValueRefreshed>
// A value in a device has been refreshed
//-----------------------------------------------------------------------------
void ValueBitSet::OnValueRefreshed
(
uint32 const _value
)
{
switch( VerifyRefreshedValue( (void*) &m_value, (void*) &m_valueCheck, (void*) &_value, ValueID::ValueType_Bool) )
{
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;
}
}

View file

@ -0,0 +1,79 @@
//-----------------------------------------------------------------------------
//
// ValueBitSet.h
//
// Represents a Range of Bits
//
// Copyright (c) 2017 Justin Hammond <justin@dynam.ac>
//
// 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 _ValueBitSet_H
#define _ValueBitSet_H
#include <string>
#include "Defs.h"
#include "value_classes/Value.h"
#include "Bitfield.h"
class TiXmlElement;
namespace OpenZWave
{
class Msg;
class Node;
class CommandClass;
/** \brief BitSet value sent to/received from a node.
* \ingroup ValueID
*/
class ValueBitSet: public Value
{
public:
ValueBitSet( uint32 const _homeId, uint8 const _nodeId, ValueID::ValueGenre const _genre, uint8 const _commandClassId, uint8 const _instance, uint16 const _index, string const& _label, string const& _units, bool const _readOnly, bool const _writeOnly, uint32 const _value, uint8 const _pollIntensity );
ValueBitSet(){}
virtual ~ValueBitSet(){}
bool Set( uint32 const _value );
bool SetBit( uint8 const _idx);
bool ClearBit(uint8 const _idx);
void OnValueRefreshed( uint32 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 );
uint32 GetValue() const;
bool GetBit(uint8 _idx) const;
private:
Bitfield m_value; // the current index in the m_items vector
Bitfield m_valueCheck; // the previous value (used for double-checking spurious value reads)
Bitfield m_newValue; // a new value to be set on the appropriate device
};
} // namespace OpenZWave
#endif

View file

@ -103,6 +103,7 @@ namespace OpenZWave
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_BitSet, /**< A collection of Bits */
ValueType_Max = ValueType_Raw /**< The highest-number type defined. Not to be used as a type itself. */
};