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) {