From 54bd278bd1543ef339648bf00dad16dfb91a8604 Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Sat, 8 Mar 2025 21:49:06 -0500 Subject: [PATCH 1/2] Support for unit conversions with multiple factors --- CMakeLists.txt | 2 +- .../data_item/unit_conversion.cpp | 37 +++++++++++++------ src/mtconnect/entity/xml_parser.cpp | 1 - test_package/unit_conversion_test.cpp | 4 ++ 4 files changed, 31 insertions(+), 13 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2630f01f4..f9915b37e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,7 @@ set(AGENT_VERSION_MAJOR 2) set(AGENT_VERSION_MINOR 5) set(AGENT_VERSION_PATCH 0) -set(AGENT_VERSION_BUILD 2) +set(AGENT_VERSION_BUILD 3) set(AGENT_VERSION_RC "") # This minimum version is to support Visual Studio 2019 and C++ feature checking and FetchContent diff --git a/src/mtconnect/device_model/data_item/unit_conversion.cpp b/src/mtconnect/device_model/data_item/unit_conversion.cpp index 6a51aae72..0f32c0593 100644 --- a/src/mtconnect/device_model/data_item/unit_conversion.cpp +++ b/src/mtconnect/device_model/data_item/unit_conversion.cpp @@ -170,18 +170,33 @@ namespace mtconnect::device_model::data_item { return nullptr; factor = sscale / tscale; - - key = source; - key = key.append("-").append(target); - - const auto &conversion = m_conversions.find(string(key)); - // Check for no support units and not power or factor scaling. - if (conversion == m_conversions.end() && factor == 1.0) - return nullptr; - else if (conversion != m_conversions.end()) + + vector sunits; + boost::split(sunits, source, boost::is_any_of("_")); + + vector tunits; + boost::split(tunits, target, boost::is_any_of("_")); + + if (sunits.size() == tunits.size()) { - factor *= conversion->second.factor(); - offset = conversion->second.offset(); + for (auto si = sunits.begin(), ti = tunits.begin(); + si != sunits.end() && ti != tunits.end(); + si++, ti++) + { + key = *si; + key = key.append("-").append(*ti); + + const auto &conversion = m_conversions.find(string(key)); + + // Check for no support units and not power or factor scaling. + if (conversion == m_conversions.end() && factor == 1.0) + return nullptr; + else if (conversion != m_conversions.end()) + { + factor *= conversion->second.factor(); + offset = conversion->second.offset(); + } + } } if (tpower != 1.0) diff --git a/src/mtconnect/entity/xml_parser.cpp b/src/mtconnect/entity/xml_parser.cpp index af787df77..2dccd6069 100644 --- a/src/mtconnect/entity/xml_parser.cpp +++ b/src/mtconnect/entity/xml_parser.cpp @@ -123,7 +123,6 @@ namespace mtconnect::entity { } } - /// TODO: Add support for tables DataSetValue value; auto valueNode = child->children; if (valueNode) diff --git a/test_package/unit_conversion_test.cpp b/test_package/unit_conversion_test.cpp index 3874eae2d..366e88687 100644 --- a/test_package/unit_conversion_test.cpp +++ b/test_package/unit_conversion_test.cpp @@ -142,4 +142,8 @@ TEST(UnitConversionTest, check_conversion_from_kw_h_to_watt_second) auto conv = UnitConversion::make("KILOWATT/HOUR", "WATT/SECOND"); EXPECT_NEAR(0.16666, conv->convert(0.6), 0.001); EXPECT_NEAR(0.25556, conv->convert(0.92), 0.001); + + conv = UnitConversion::make("KILOWATT_HOUR", "WATT_SECOND"); + EXPECT_NEAR(2160000.0, conv->convert(0.6), 0.001); + EXPECT_NEAR(3312000.0, conv->convert(0.92), 0.001); } From 3f415d71b9070d8cbd5bf15d4a47bc2853ee6d35 Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Sat, 8 Mar 2025 21:52:29 -0500 Subject: [PATCH 2/2] formatted --- .../device_model/data_item/unit_conversion.cpp | 11 +++++------ test_package/unit_conversion_test.cpp | 2 +- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/mtconnect/device_model/data_item/unit_conversion.cpp b/src/mtconnect/device_model/data_item/unit_conversion.cpp index 0f32c0593..78fc8a439 100644 --- a/src/mtconnect/device_model/data_item/unit_conversion.cpp +++ b/src/mtconnect/device_model/data_item/unit_conversion.cpp @@ -170,24 +170,23 @@ namespace mtconnect::device_model::data_item { return nullptr; factor = sscale / tscale; - + vector sunits; boost::split(sunits, source, boost::is_any_of("_")); vector tunits; boost::split(tunits, target, boost::is_any_of("_")); - + if (sunits.size() == tunits.size()) { for (auto si = sunits.begin(), ti = tunits.begin(); - si != sunits.end() && ti != tunits.end(); - si++, ti++) + si != sunits.end() && ti != tunits.end(); si++, ti++) { key = *si; key = key.append("-").append(*ti); - + const auto &conversion = m_conversions.find(string(key)); - + // Check for no support units and not power or factor scaling. if (conversion == m_conversions.end() && factor == 1.0) return nullptr; diff --git a/test_package/unit_conversion_test.cpp b/test_package/unit_conversion_test.cpp index 366e88687..7a09bbc31 100644 --- a/test_package/unit_conversion_test.cpp +++ b/test_package/unit_conversion_test.cpp @@ -142,7 +142,7 @@ TEST(UnitConversionTest, check_conversion_from_kw_h_to_watt_second) auto conv = UnitConversion::make("KILOWATT/HOUR", "WATT/SECOND"); EXPECT_NEAR(0.16666, conv->convert(0.6), 0.001); EXPECT_NEAR(0.25556, conv->convert(0.92), 0.001); - + conv = UnitConversion::make("KILOWATT_HOUR", "WATT_SECOND"); EXPECT_NEAR(2160000.0, conv->convert(0.6), 0.001); EXPECT_NEAR(3312000.0, conv->convert(0.92), 0.001);