diff --git a/config/device_configuration.xsd b/config/device_configuration.xsd
index 993553491c..57b18c17e8 100644
--- a/config/device_configuration.xsd
+++ b/config/device_configuration.xsd
@@ -107,6 +107,11 @@
+
+
+
+
+
@@ -178,8 +183,8 @@
-
-
+
+
@@ -198,10 +203,10 @@
-
+
+
-
@@ -298,7 +303,7 @@
-
+
@@ -347,7 +352,7 @@
-
+
@@ -382,7 +387,7 @@
-
+
diff --git a/config/shenzen_neo/nas-wr01ze.xml b/config/shenzen_neo/nas-wr01ze.xml
index d9116330b5..ab231e2061 100644
--- a/config/shenzen_neo/nas-wr01ze.xml
+++ b/config/shenzen_neo/nas-wr01ze.xml
@@ -1,5 +1,5 @@
-
+
@@ -37,6 +37,7 @@ Reset procedure will delete all information on the Z‐Wave network and Z‐Wave
U.S. / Canada / Mexico
Added metadata, and added US version (type 0100) that is branded "Power Plug" with no model number displayed. There is no matching Z-Wave Alliance database entry.
+ Enabled RandomMsbBug to ignore random MSB in kWh readings.
@@ -114,6 +115,19 @@ Reset procedure will delete all information on the Z‐Wave network and Z‐Wave
+
+
+
+ true
+
+
+
+
+
+
+
+
+
diff --git a/cpp/src/CompatOptionManager.cpp b/cpp/src/CompatOptionManager.cpp
index ef4271a5b2..29e3c7bc15 100644
--- a/cpp/src/CompatOptionManager.cpp
+++ b/cpp/src/CompatOptionManager.cpp
@@ -59,7 +59,8 @@ namespace OpenZWave
{ "VerifyChanged", COMPAT_FLAG_VERIFYCHANGED, COMPAT_FLAG_TYPE_BOOL_ARRAY },
{ "EnableNotificationClear", COMPAT_FLAG_NOT_ENABLECLEAR, COMPAT_FLAG_TYPE_BOOL },
{ "EnableV1AlarmTypes", COMPAT_FLAG_NOT_V1ALARMTYPES_ENABLED, COMPAT_FLAG_TYPE_BOOL },
- { "NoRefreshAfterSet", COMPAT_FLAG_NO_REFRESH_AFTER_SET, COMPAT_FLAG_TYPE_BOOL_ARRAY }
+ { "NoRefreshAfterSet", COMPAT_FLAG_NO_REFRESH_AFTER_SET, COMPAT_FLAG_TYPE_BOOL_ARRAY },
+ { "RandomMsbBug", COMPAT_FLAG_RANDOM_MSB_BUG, COMPAT_FLAG_TYPE_BOOL_ARRAY }
};
uint16_t availableCompatFlagsCount = sizeof(availableCompatFlags) / sizeof(availableCompatFlags[0]);
diff --git a/cpp/src/CompatOptionManager.h b/cpp/src/CompatOptionManager.h
index 237e11b204..06ceb5df47 100644
--- a/cpp/src/CompatOptionManager.h
+++ b/cpp/src/CompatOptionManager.h
@@ -69,6 +69,7 @@ namespace OpenZWave
COMPAT_FLAG_NOT_ENABLECLEAR,
COMPAT_FLAG_NOT_V1ALARMTYPES_ENABLED,
COMPAT_FLAG_NO_REFRESH_AFTER_SET,
+ COMPAT_FLAG_RANDOM_MSB_BUG,
STATE_FLAG_CCVERSION,
STATE_FLAG_STATIC_REQUESTS,
STATE_FLAG_AFTERMARK,
diff --git a/cpp/src/command_classes/CommandClass.cpp b/cpp/src/command_classes/CommandClass.cpp
index e222d69d61..a68c994ea6 100644
--- a/cpp/src/command_classes/CommandClass.cpp
+++ b/cpp/src/command_classes/CommandClass.cpp
@@ -69,6 +69,7 @@ namespace OpenZWave
m_com.EnableFlag(COMPAT_FLAG_REFRESHONWAKEUP, false);
m_com.EnableFlag(COMPAT_FLAG_VERIFYCHANGED, false);
m_com.EnableFlag(COMPAT_FLAG_NO_REFRESH_AFTER_SET, false);
+ m_com.EnableFlag(COMPAT_FLAG_RANDOM_MSB_BUG, false);
m_dom.EnableFlag(STATE_FLAG_CCVERSION, 0);
m_dom.EnableFlag(STATE_FLAG_STATIC_REQUESTS, 0);
m_dom.EnableFlag(STATE_FLAG_AFTERMARK, false);
@@ -470,8 +471,8 @@ namespace OpenZWave
//
// Read a value from a variable length sequence of bytes
//-----------------------------------------------------------------------------
- std::string CommandClass::ExtractValue(uint8 const* _data, uint8* _scale, uint8* _precision, uint8 _valueOffset // = 1
- ) const
+ std::string CommandClass::ExtractValue(uint16 const _index, uint8 const* _data, uint8* _scale, uint8* _precision, uint8 _valueOffset // == 1
+ ) const
{
uint8 const size = _data[0] & c_sizeMask;
uint8 const precision = (_data[0] & c_precisionMask) >> c_precisionShift;
@@ -486,17 +487,25 @@ namespace OpenZWave
*_precision = precision;
}
+ bool mask_msb = m_com.GetFlagBool(COMPAT_FLAG_RANDOM_MSB_BUG, _index);
+
uint32 value = 0;
uint8 i;
for (i = 0; i < size; ++i)
{
+ uint8 byte = _data[i + (uint32) _valueOffset];
+ if (mask_msb && i == 0 && (byte & 0x80)) {
+ Log::Write(LogLevel_Warning, GetNodeId(), "CommandClass::ExtractValue: repair MSB");
+ byte &= 0x7f;
+ }
+
value <<= 8;
- value |= (uint32) _data[i + (uint32) _valueOffset];
+ value |= (uint32) byte;
}
// Deal with sign extension. All values are signed
std::string res;
- if (_data[_valueOffset] & 0x80)
+ if ((_data[_valueOffset] & 0x80) && ! mask_msb)
{
res = "-";
diff --git a/cpp/src/command_classes/CommandClass.h b/cpp/src/command_classes/CommandClass.h
index 92b382691e..5120b6706c 100644
--- a/cpp/src/command_classes/CommandClass.h
+++ b/cpp/src/command_classes/CommandClass.h
@@ -202,7 +202,7 @@ namespace OpenZWave
}
// Helper methods
- string ExtractValue(uint8 const* _data, uint8* _scale, uint8* _precision, uint8 _valueOffset = 1) const;
+ string ExtractValue(uint16 const _index, uint8 const* _data, uint8* _scale, uint8* _precision, uint8 _valueOffset = 1) const;
uint32 decodeDuration(uint8 data) const;
uint8 encodeDuration(uint32 seconds) const;
/**
diff --git a/cpp/src/command_classes/EnergyProduction.cpp b/cpp/src/command_classes/EnergyProduction.cpp
index d6fff20024..f62bcee3a8 100644
--- a/cpp/src/command_classes/EnergyProduction.cpp
+++ b/cpp/src/command_classes/EnergyProduction.cpp
@@ -114,7 +114,8 @@ namespace OpenZWave
{
uint8 scale;
uint8 precision = 0;
- string value = ExtractValue(&_data[2], &scale, &precision);
+ uint16 index = 0;
+ string value = ExtractValue(index, &_data[2], &scale, &precision);
uint8 paramType = _data[1];
if (paramType > 4) /* size of c_energyParameterNames minus Invalid Entry*/
{
diff --git a/cpp/src/command_classes/Meter.cpp b/cpp/src/command_classes/Meter.cpp
index 708d85fb7f..09e6c8560f 100644
--- a/cpp/src/command_classes/Meter.cpp
+++ b/cpp/src/command_classes/Meter.cpp
@@ -359,7 +359,6 @@ namespace OpenZWave
// Get the value and scale
uint8 scale;
uint8 precision = 0;
- string valueStr = ExtractValue(&_data[2], &scale, &precision);
scale = GetScale(_data, _length);
int8 meterType = (MeterType) (_data[1] & 0x1f);
@@ -370,6 +369,8 @@ namespace OpenZWave
return false;
}
+ string valueStr = ExtractValue(index, &_data[2], &scale, &precision);
+
Log::Write(LogLevel_Info, GetNodeId(), "Received Meter Report for %s (%d) with Units %s (%d) on Index %d: %s",MeterTypes.at(index).Label.c_str(), meterType, MeterTypes.at(index).Unit.c_str(), scale, index, valueStr.c_str());
Internal::VC::ValueDecimal* value = static_cast(GetValue(_instance, index));
diff --git a/cpp/src/command_classes/SensorMultilevel.cpp b/cpp/src/command_classes/SensorMultilevel.cpp
index 634c3edfa0..4c6517395e 100644
--- a/cpp/src/command_classes/SensorMultilevel.cpp
+++ b/cpp/src/command_classes/SensorMultilevel.cpp
@@ -269,7 +269,8 @@ namespace OpenZWave
uint8 scale;
uint8 precision = 0;
uint8 sensorType = _data[1];
- string valueStr = ExtractValue(&_data[2], &scale, &precision);
+ uint16 index = 0;
+ string valueStr = ExtractValue(index, &_data[2], &scale, &precision);
Node* node = GetNodeUnsafe();
if (node != NULL)
diff --git a/cpp/src/command_classes/ThermostatSetpoint.cpp b/cpp/src/command_classes/ThermostatSetpoint.cpp
index 9dde0ca533..cef14b0a61 100644
--- a/cpp/src/command_classes/ThermostatSetpoint.cpp
+++ b/cpp/src/command_classes/ThermostatSetpoint.cpp
@@ -152,7 +152,8 @@ namespace OpenZWave
{
uint8 scale;
uint8 precision = 0;
- string temperature = ExtractValue(&_data[2], &scale, &precision);
+ uint16 index = 0;
+ string temperature = ExtractValue(index, &_data[2], &scale, &precision);
value->SetUnits(scale ? "F" : "C");
value->OnValueRefreshed(temperature);
@@ -238,12 +239,12 @@ namespace OpenZWave
uint8 scale;
uint8 precision = 0;
uint8 size = _data[2] & 0x07;
- string minValue = ExtractValue(&_data[2], &scale, &precision);
- string maxValue = ExtractValue(&_data[2 + size + 1], &scale, &precision);
+ uint8 index = _data[1];
+ string minValue = ExtractValue(index, &_data[2], &scale, &precision);
+ string maxValue = ExtractValue(index, &_data[2 + size + 1], &scale, &precision);
Log::Write(LogLevel_Info, GetNodeId(), "Received capabilities of thermostat setpoint type %d, min %s max %s", (int) _data[1], minValue.c_str(), maxValue.c_str());
- uint8 index = _data[1];
// Add supported setpoint
if (index < ThermostatSetpoint_Count)
{